16#pragma GCC diagnostic push
17#pragma GCC diagnostic ignored "-Wpmf-conversions"
20#include "task_msp432.h"
23#include "yahal_config.h"
28bool multitasking_on_core {
false};
31void task::_setup_stack(
bool priv) {
34 _stack_ptr = _stack_base +
38 frame->crsr.psr = 0x01000000;
39 frame->crsr.pc = (void (*)(void))(&task::_run);
40 frame->crsr.r0 =
this;
41 frame->cesr.exc_return = EXC_RETURN_THREAD_PSP;
42 frame->cesr.ctrl = priv ? 0x02 : 0x03;
45void task::_context_switch() {
49uint64_t task::millis() {
53bool task::is_irq_context() {
57bool task::multitasking_running() {
58 return multitasking_on_core;
61int8_t task::get_core() {
65void task::start_scheduler() {
66 assert(!multitasking_running());
67 sys_call(SYS_START_SCHEDULER);
71 if(multitasking_running()) {
76void task::cpu_sleep() {
80void task::enterCritical() {
81 NVIC_DisableIRQ(PendSV_IRQn);
87void task::leaveCritical() {
88 NVIC_EnableIRQ(PendSV_IRQn);
93bool task::isPrivileged()
const {
95 if (_run_ptr[0] ==
this) {
100 return (ctrl & 0x01) == 0;
103bool task::isUsingFloat()
const {
104 if (_run_ptr[0] ==
this) {
107 return _stack_ptr[0] & 0x10;
118 task::_tick_handler();
121uint8_t * switch_context(uint8_t * last_sp) {
122 task::_setStackPtr(last_sp);
123#ifdef CHECK_STACK_OVERFLOW
124 assert((last_sp - task::_getStackBase()) > 10);
126 task::_switchToNext();
127 return task::_getStackPtr();
132 " mrs r0, psp @ get the current SP \n"
133 " tst lr, #0x10 @ EXC_RETURN_INT_ONLY_STACK_FRAME \n"
135 " vstmdbeq r0!, {s16-s31} @ push additional FP registers \n"
137 " mrs r3, control @ \n"
138 " stmdb r0!, {r2-r11} @ save lr, control, r4-r11 \n"
139 " bl switch_context @ \n"
140 " ldmia r0!, {r2-r11} @ get lr, control, r4-r11 \n"
142 " msr control, r3 @ \n"
143 " isb @ arch recommendation \n"
144 " tst lr, #0x10 @ EXC_RETURN_INT_ONLY_STACK_FRAME \n"
146 " vldmiaeq r0!, {s16-s31} @ pop additional FP registers \n"
148 " bx lr @ jump to new task \n");
153 " tst lr, #4 @ EXC_RETURN_PROCESS_STACK_POINTER \n"
155 " mrseq r0, msp @ R0 (SP) will be first parameter \n"
156 " mrsne r0, psp @ of SCV_Handler_C, \n"
157 " tst lr, 0x20 @ EXC_RETURN_NORMAL_CALLEE_STACKING \n"
159 " addeq r0, #40 @ skip additional context if existing \n"
160 " mov r1, lr @ R1 (LR) is second parameter \n"
161 " bl SVC_Handler_C @ Call C part of SVC handler \n"
162 " bx r0 @ Use return value as EXC_RETURN \n"
166uint32_t SVC_Handler_C(uint32_t * sp, uint32_t exc_return) {
169 auto * pc = (uint16_t *)sp[6];
171 uint16_t svc_arg = pc[-1] & 0xff;
178 case SYS_START_SCHEDULER:
182 multitasking_on_core =
true;
188 idle_tasks[0].sign_up(core_t::CURRENT_CORE, 1);
191 task::_switchToHead();
194 NVIC_SetPriority(PendSV_IRQn, 0xff);
197 SysTick_Config(SystemCoreClock / TICK_FREQUENCY);
200 exc_return = EXC_RETURN_THREAD_PSP;
204 __set_PSP((uint32_t)(task::_getStackPtr() +
231#pragma GCC diagnostic pop
#define SCB_ICSR_PENDSVSET_Msk
#define __ISB()
Instruction Synchronization Barrier.
#define __DSB()
Data 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.