16#pragma GCC diagnostic push
17#pragma GCC diagnostic ignored "-Wpmf-conversions"
20#include "task_rp2040.h"
21#include "multicore_rp2040.h"
23#include "system_rp2040.h"
24#include "yahal_config.h"
29using namespace _TIMER_;
33bool multitasking_on_core[NUMBER_OF_CORES] {
false};
36void task::_setup_stack(
bool priv) {
39 _stack_ptr = _stack_base +
43 frame->crsr.psr = 0x01000000;
44 frame->crsr.pc = (void (*)(void))(&task::_run);
45 frame->crsr.r0 =
this;
46 frame->cesr.exc_return = EXC_RETURN_THREAD_PSP;
47 frame->cesr.ctrl = priv ? 0x02 : 0x03;
50void task::_context_switch() {
52 PPB.ICSR.PENDSVSET = 1;
55uint64_t task::millis() {
56 uint32_t lo = TIMER.TIMELR;
57 uint32_t hi = TIMER.TIMEHR;
58 return (((uint64_t)hi << 32l) | lo) / _ticks_per_millis;
61bool task::is_irq_context() {
65bool task::multitasking_running() {
66 return multitasking_on_core[SIO.CPUID];
69int8_t task::get_core() {
73void task::start_scheduler() {
74 assert(!multitasking_running());
75 sys_call(SYS_START_SCHEDULER);
79 if(multitasking_running() && !is_irq_context()) {
84void task::cpu_sleep() {
88void task::enterCritical() {
89 NVIC_DisableIRQ(PendSV_IRQn);
93void task::leaveCritical() {
94 NVIC_EnableIRQ(PendSV_IRQn);
98bool task::isPrivileged()
const {
100 if (_run_ptr[_core] ==
this) {
108bool task::isUsingFloat()
const {
110 if (_run_ptr[_core] ==
this) {
126 task::_tick_handler();
129uint8_t * switch_context(uint8_t * last_sp) {
130 task::_setStackPtr(last_sp);
131#ifdef CHECK_STACK_OVERFLOW
132 assert((last_sp - task::_getStackBase()) > 10);
134 task::_switchToNext();
135 return task::_getStackPtr();
140 " .syntax unified @ \n"
143 " mrs r3, control @ \n"
144 " subs r0, r0, #40 @ \n"
145 " stmia r0!,{r2-r7} @ \n"
150 " stmia r0!,{r4-r7} @ \n"
151 " subs r0, r0, #40 @ \n"
152 " bl switch_context @ \n"
153 " adds r0, r0, #24 @ \n"
154 " ldmia r0!, {r4-r7} @ \n"
160 " subs r0, r0, #40 @ \n"
161 " ldmia r0!, {r2-r7} @ \n"
163 " msr control, r3 @ \n"
169 " movs r0, #4 @ EXC_RETURN_PROCESS_STACK_POINTER \n"
171 " tst r0, r1 @ Check which stack to use \n"
173 " mrs r0, psp @ Use PSP \n"
175 "svc1: mrs r0, msp @ Use MSP \n"
176 "svc2: mov r1, lr @ R1 (LR) is second parameter \n"
177 " bl SVC_Handler_C @ Call C part of SVC_Handler \n"
178 " bx r0 @ Use return value as EXC_RETURN \n"
182uint32_t SVC_Handler_C(uint32_t * sp, uint32_t exc_return) {
185 auto * pc = (uint16_t *)sp[6];
187 uint16_t svc_arg = pc[-1] & 0xff;
194 case SYS_START_SCHEDULER:
198 multitasking_on_core[SIO.CPUID] =
true;
204 idle_tasks[SIO.CPUID].sign_up(core_t::CURRENT_CORE, 1);
207 task::_switchToHead();
211 NVIC_SetPriority(PendSV_IRQn, 3);
212 NVIC_SetPriority(SysTick_IRQn, 3);
217 PPB.SYST_RVR = (CLK_SYS / TICK_FREQUENCY)-1;
219 PPB.SYST_CSR.CLKSOURCE = 1;
220 PPB.SYST_CSR.TICKINT = 1;
221 PPB.SYST_CSR.ENABLE = 1;
224 exc_return = EXC_RETURN_THREAD_PSP;
228 __set_PSP((uint32_t)(task::_getStackPtr() +
255#pragma GCC diagnostic pop
CMSIS-Core(M) Device Peripheral Access Layer Header File for Device RP2040.
#define CONTROL_nPRIV_Msk
#define __ISB()
Instruction Synchronization Barrier.
#define __WFE
Wait For Event.
__STATIC_INLINE void __set_CONTROL(uint32_t control)
Set Control Register.
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
Set Process Stack Pointer.
__STATIC_INLINE uint32_t __get_CONTROL(void)
Enable IRQ Interrupts.
__STATIC_INLINE uint32_t __get_IPSR(void)
Get IPSR Register.
void __attribute__((noreturn))(*rom_reset_usb_boot_fn)(uint32_t
Reboot the device into BOOTSEL mode.