/*..........................................................................*/ int16_t QF_run(void) { QF_INT_DISABLE(); initialize(); QF_onStartup(); /* startup callback */ QF_INT_ENABLE(); for (;;) { /* the QK idle loop */ QK_onIdle(); /* invoke the QK on-idle callback */ } return (int16_t)0; /* this unreachable return is to make compiler happy */ }
/*..........................................................................*/ void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ #ifdef Q_SPY # if 0 QS_rxParse(); /* parse all the received bytes */ // Push out QS buffer to UART if (!nrf_drv_uart_tx_in_progress()) { /* is TXE empty? */ static uint16_t b; QF_INT_DISABLE(); b = QS_getByte(); QF_INT_ENABLE(); if (b != QS_EOD) { /* not End-Of-Data? */ nrf_drv_uart_tx((const uint8_t*)&b, 1); } } # else QF_INT_ENABLE(); //sd_app_evt_wait(); __WFE(); //__SEV(); __WFE(); # endif #elif defined 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. */ /* !!!CAUTION!!! * The QF_CPU_SLEEP() contains the WFI instruction, which stops the CPU * clock, which unfortunately disables the JTAG port, so the ST-Link * debugger can no longer connect to the board. For that reason, the call * to QF_CPU_SLEEP() has to be used with CAUTION. */ //QV_CPU_SLEEP(); //atomically go to SHALLOW sleep and enable interrupts __WFE(); QF_INT_ENABLE(); /* for now, just enable interrupts */ #else QF_INT_ENABLE(); /* just enable interrupts */ #endif }
//**************************************************************************** /// @description /// Initializes QXK and must be called by the application exactly once /// before QP::QF::run(). /// /// @param[in] idleStkSto pointer to the stack storage for the idle thread /// @param[in] idleStkSize idle thread stack size (in bytes) /// /// @note QP::QXK::init() must be called once before QP::QF::run(). /// void QXK::init(void * const idleStkSto, uint_fast16_t const idleStkSize) { // initialize the stack of the idle thread QXK_stackInit_(&l_idleThread, reinterpret_cast<QXThreadHandler>(l_idleThread.m_temp.act), idleStkSto, idleStkSize); // idle thread priority is zero l_idleThread.m_prio = static_cast<uint_fast8_t>(0); QF_INT_DISABLE(); QF::active_[0] = &l_idleThread; QF_INT_ENABLE(); }
/*..........................................................................*/ void QF_onIdle(void) { /* entered with interrupts DISABLED, see NOTE01 */ /* toggle the User LED on and then off, see NOTE02 */ //GPIOSetValue(LED_PORT, LED_BIT, LED_ON); /* LED on */ //GPIOSetValue(LED_PORT, LED_BIT, LED_OFF); /* LED off */ #ifdef NDEBUG /* put the CPU and peripherals to the low-power mode */ QF_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ #else QF_INT_ENABLE(); /* just enable interrupts */ #endif }
/* @(/2/0/9/1/2/1) .........................................................*/ QState CoffeeAO_setBrewStrength(CoffeeAO * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* @(/2/0/9/1/2/1) */ case Q_ENTRY_SIG: { lcd_clear(); set_cursor(0, 0); lcd_print("Use AD-Wheel"); set_cursor(0, 1); lcd_print("Use int0 to save"); printf("Changing brew strength...\n"); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/1) */ case Q_EXIT_SIG: { printf("saved brew strength: %u\n", l_CoffeeAO.current_brew_strength); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/1/0) */ case ADWHEEL_SIG: { const int led_count = 8; int i = 0; l_CoffeeAO.current_brew_strength = ((AdEvt*)e)->val * led_count / 1024; for(i = 0; i < led_count; i++) { if (i <= l_CoffeeAO.current_brew_strength) { LED_On(i); } else { LED_Off(i); } } status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/1/1) */ case INT_SIG: { QF_INT_ENABLE(); QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG)); QF_INT_DISABLE(); status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&CoffeeAO_submenu); break; } } return status_; }
/*..........................................................................*/ void QK_onIdle(void) { /* called with interrupts enabled */ /* toggle an LED on and then off (not enough LEDs, see NOTE01) */ QF_INT_DISABLE(); //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ QF_INT_ENABLE(); #ifdef Q_SPY if ((USART2->SR & 0x0080U) != 0) { /* is TXE empty? */ uint16_t b; QF_INT_DISABLE(); b = QS_getByte(); QF_INT_ENABLE(); if (b != QS_EOD) { /* not End-Of-Data? */ USART2->DR = (b & 0xFFU); /* put into the DR register */ } } #elif defined 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. */ /* !!!CAUTION!!! * The WFI instruction stops the CPU clock, which unfortunately disables * the JTAG port, so the ST-Link debugger can no longer connect to the * board. For that reason, the call to __WFI() has to be used with CAUTION. * * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and * reset the board, then connect with ST-Link Utilities and erase the part. * The trick with BOOT(0) is it gets the part to run the System Loader * instead of your broken code. When done disconnect BOOT0, and start over. */ //__WFI(); /* Wait-For-Interrupt */ #endif }
/*..........................................................................*/ void QF_onCleanup(void) { /* restore the DOS system clock tick rate... */ QF_INT_DISABLE(); outp(0x43, 0x36); /* use mode-3 for timer 0 in the 8254 */ outp(0x40, 0); /* load low byte of timer 0 */ outp(0x40, 0); /* load high byte of timer 0 */ /* restore the original DOS vectors ... */ _dos_setvect(TMR_VECTOR, l_dosTmrISR); _dos_setvect(KBD_VECTOR, l_dosKbdISR); QF_INT_ENABLE(); QS_EXIT(); /* exit QS */ _exit(0); /* exit to DOS */ }
/*..........................................................................*/ __ramfunc void QK_onIdle(void) { /* toggle first LED on and off, see NOTE01 */ QF_INT_DISABLE(); LED_ON(3); /* turn LED on */ LED_OFF(3); /* turn LED off */ QF_INT_ENABLE(); #ifdef NDEBUG /* only if not debugging (idle mode hinders debugging) */ AT91C_BASE_PMC->PMC_SCDR = 1;/* Power-Management: disable the CPU clock */ /* NOTE: an interrupt starts the CPU clock again */ #endif }
/*..........................................................................*/ void QK_onIdle(void) { QF_INT_DISABLE(); LED1_on(); /* switch LED1 on and off */ LED1_off(); QF_INT_ENABLE(); #ifdef Q_SPY if (((IFG2 & UCA0TXIFG)) != 0) { uint16_t b; QF_INT_DISABLE(); b = QS_getByte(); QF_INT_ENABLE(); if (b != QS_EOD) { UCA0TXBUF = (uint8_t)b; /* stick the byte to the TX BUF */ } } #elif defined NDEBUG __low_power_mode_1(); /* Enter LPM1; also UNLOCKS interrupts */ #endif }
/*..........................................................................*/ void QK_onIdle(void) { /* toggle LED1 on and then off, see NOTE01 */ QF_INT_DISABLE(); GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); QF_INT_ENABLE(); #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 QF_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ //GPIOF->DATA_Bits[LED_RED] = LED_RED; /* turn the Red LED on */ //GPIOF->DATA_Bits[LED_RED] = 0; /* turn the Red LED off */ #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. */ QF_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ #else QF_INT_ENABLE(); /* just enable interrupts */ #endif }
/*..........................................................................*/ void QK_onIdle(void) { QF_INT_DISABLE(); LED_ON (IDLE_LED); /* blink the IDLE LED, see NOTE01 */ LED_OFF(IDLE_LED); QF_INT_ENABLE(); #ifdef Q_SPY while (U2STAbits.UTXBF == 0U) { /* TX Buffer not full? */ uint16_t b; QF_INT_DISABLE(); b = QS_getByte(); QF_INT_ENABLE(); if (b == QS_EOD) { /* End-Of-Data reached? */ break; /* break out of the loop */ } U2TXREG = (uint8_t)b; /* stick the byte to TXREG for transmission */ } #elif defined NDEBUG Idle(); /* transition to Idle mode */ #endif }
/*..........................................................................*/ void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ /* toggle the LED on and then off, see NOTE02 */ QF_INT_DISABLE(); LPC_GPIO1->FIOSET = LED_4; /* turn LED on */ __NOP(); /* a couple of NOPs to actually see the LED glow */ __NOP(); __NOP(); __NOP(); LPC_GPIO1->FIOCLR = LED_4; /* turn LED off */ QF_INT_ENABLE(); #ifdef Q_SPY if ((LPC_UART0->LSR & 0x20U) != 0U) { /* TX Holding Register empty? */ uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ uint8_t const *block; QF_INT_DISABLE(); block = QS_getBlock(&fifo); /* try to get next block to transmit */ QF_INT_ENABLE(); while (fifo-- != 0) { /* any bytes in the block? */ LPC_UART0->THR = *block++; /* put into the FIFO */ } } #elif defined 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. */ QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ #else QF_INT_ENABLE(); /* just enable interrupts */ #endif }
//............................................................................ void QV::onIdle(void) { // NOTE: called with interrutps DISABLED, see NOTE1 // toggle LED2 on and then off, see NOTE2 P1OUT |= LED2; // turn LED2 on P1OUT &= ~LED2; // turn LED2 off #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 MSP430 MCU. // __low_power_mode_1(); // Enter LPM1; also ENABLES interrupts #else QF_INT_ENABLE(); // just enable interrupts #endif }
/*..........................................................................*/ void QF_onIdle(void) { /* invoked with interrupts DISABLED */ LED1_on(); /* switch LED1 on and off */ LED1_off(); #ifdef Q_SPY if (((IFG2 & UCA0TXIFG)) != 0) { uint16_t b = QS_getByte(); QF_INT_ENABLE(); if (b != QS_EOD) { UCA0TXBUF = (uint8_t)b; /* stick the byte to the TX BUF */ } } else { QF_INT_ENABLE(); } #elif defined NDEBUG __low_power_mode_1(); /* Enter LPM1 and ENABLE interrupts atomically */ #else QF_INT_ENABLE(); #endif }
//............................................................................ void QF::onCleanup(void) { // restore the DOS system clock tick rate... QF_INT_DISABLE(); outp(0x43, 0x36); // use mode-3 for timer 0 in the 8254 outp(0x40, 0); // load low byte of timer 0 outp(0x40, 0); // load high byte of timer 0 // restore the original DOS vectors ... _dos_setvect(TMR_VECTOR, l_dosTmrISR); _dos_setvect(KBD_VECTOR, l_dosKbdISR); _dos_setvect(SPARE_VECTOR, l_dosSpareISR); QF_INT_ENABLE(); QS_EXIT(); // exit QS _exit(0); // exit to DOS }
/*..........................................................................*/ void QV_onIdle(void) { /* NOTE: called with interrutps DISABLED, see NOTE1 */ /* toggle LED2 on and then off, see NOTE2 */ P4OUT |= LED2; /* turn LED2 on */ P4OUT &= ~LED2; /* turn LED2 off */ #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 MSP430 MCU. */ __low_power_mode_1(); /* Enter LPM1; also ENABLES interrupts */ #else QF_INT_ENABLE(); /* just enable interrupts */ #endif }
/*..........................................................................*/ void QV_onIdle(void) { /* called with interrupts DISABLED, see NOTE1 */ /* toggle the User LED, see NOTE1 , not enough LEDs to implement! */ //PORTB |= LED_L; //PORTB &= ~LED_L; #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 AVR MCU. */ SMCR = (0 << SM0) | (1 << SE); /* idle mode, adjust to your project */ QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ #else QF_INT_ENABLE(); /* just enable interrupts */ #endif }
/*..........................................................................*/ void QF_onStartup(void) { uint16_t count; /* save the origingal DOS vectors ... */ l_dosTmrISR = _dos_getvect(TMR_VECTOR); l_dosKbdISR = _dos_getvect(KBD_VECTOR); QF_INT_DISABLE(); count = (uint16_t)(((1193180 * 2) / BSP_TICKS_PER_SEC + 1) >> 1); outp(0x43, 0x36); /* use mode-3 for timer 0 in the 8254 */ outp(0x40, count & 0xFF); /* load low byte of timer 0 */ outp(0x40, (count >> 8) & 0xFF); /* load high byte of timer 0 */ _dos_setvect(TMR_VECTOR, &ISR_tmr); _dos_setvect(KBD_VECTOR, &ISR_kbd); QF_INT_ENABLE(); }
//............................................................................ void QV::onIdle(void) { // CATION: called with interrupts DISABLED, NOTE01 // toggle LED2 on and then off, see NOTE01 GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; GPIOF->DATA_Bits[LED_BLUE] = 0x00U; #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. // QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else QF_INT_ENABLE(); // just enable interrupts #endif }
/*..........................................................................*/ void QK_onIdle(void) { #ifdef Q_SPY if ((SCI3_2.SSR.BYTE & 0x80) != 0) { /* TDRE not ready? */ uint16_t b; QF_INT_DISABLE(); /* disable interrupts */ b = QS_getByte(); QF_INT_ENABLE(); /* enable interrupts */ if (b != QS_EOD) { SCI3_2.TDR = (uint8_t)b; /* put the byte to TX data register */ } } #elif (defined NDEBUG) /* low-power mode interferes with debugging */ /* stop all peripheral clocks that you can in your applicaiton ... */ sleep(); /* before entering any pending interrupt */ #endif }
/* @(/2/0/9/1/2/8) .........................................................*/ QState CoffeeAO_set_clock_m2(CoffeeAO * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* @(/2/0/9/1/2/8) */ case Q_ENTRY_SIG: { lcd_clear(); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/8/0) */ case ADWHEEL_SIG: { char clock_message[20]; int value = ((AdEvt*)e)->val * 10 / 1024; HourAndMinute* ham = &l_CoffeeAO.alarm.current_time; ham->minutes = (ham->minutes / 10) * 10 + value; sprintf(clock_message, "%02u:%02u", ham->hours, ham->minutes); set_cursor(0, 0); lcd_print(clock_message); set_cursor(4, 1); lcd_print("^"); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/8/1) */ case INT_SIG: { RtcEvt* rtc_evt = Q_NEW(RtcEvt, TIME_SET_SIG); rtc_evt->rtc.hours = l_CoffeeAO.alarm.current_time.hours; rtc_evt->rtc.minutes = l_CoffeeAO.alarm.current_time.minutes; Alarm_dispatch((QFsm *)&l_CoffeeAO.alarm, (QEvt *) rtc_evt); QF_INT_ENABLE(); QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG)); QF_INT_DISABLE(); status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&CoffeeAO_submenu); break; } } return status_; }
/*..........................................................................*/ void QK_onIdle(void) { /* test code to use the FPU ... */ float volatile x = 3.1415926F; x = x + 2.7182818F; /* toggle the Blue LED on and then off, see NOTE01 */ QF_INT_DISABLE(); GPIOF->DATA_Bits[LED_BLUE] = LED_BLUE; /* turn the Blue LED on */ GPIOF->DATA_Bits[LED_BLUE] = 0; /* turn the Blue LED off */ QF_INT_ENABLE(); #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. */ asm(" WFI"); /* Wait-For-Interrupt */ #endif }
/* RTX callbacks ===========================================================*/ void os_idle_demon(void); /* prototype */ void os_idle_demon(void) { /* The RTX idle demon is a system thread, running when no other thread * is ready to run. */ for (;;) { /* idle-loop */ QF_INT_DISABLE(); GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; /* turn LED on */ GPIOF->DATA_Bits[LED_BLUE] = 0x00U; /* turn LED off */ QF_INT_ENABLE(); #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. */ __WFI(); /* Wait-For-Interrupt */ #endif } /* idle-loop */ }
/* @(/2/0/9/1/2/2) .........................................................*/ QState CoffeeAO_startBrewingNow(CoffeeAO * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* @(/2/0/9/1/2/2) */ case Q_ENTRY_SIG: { QF_INT_ENABLE(); printf("Starting to brew\n %i", l_CoffeeAO.i++); QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, BREW_SIG)); QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG)); QF_INT_DISABLE(); status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&CoffeeAO_submenu); break; } } return status_; }
/* @(/2/0/9/1/2/11) ........................................................*/ QState CoffeeAO_set_brew_m2(CoffeeAO * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* @(/2/0/9/1/2/11) */ case Q_ENTRY_SIG: { lcd_clear(); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/11/0) */ case ADWHEEL_SIG: { char clock_message[20]; int value = ((AdEvt*)e)->val * 10 / 1024; HourAndMinute* ham = &l_CoffeeAO.alarm.alarm_time; ham->minutes = MIN((ham->minutes / 10) * 10 + value, 59); sprintf(clock_message, "%02u:%02u", ham->hours, ham->minutes); set_cursor(0, 0); lcd_print(clock_message); set_cursor(4, 1); lcd_print("^"); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/2/11/1) */ case INT_SIG: { QF_INT_ENABLE(); QActive_postFIFO((QActive *)&l_CoffeeAO, Q_NEW(QEvent, GO_BACK_SIG)); QF_INT_DISABLE(); status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&CoffeeAO_submenu); break; } } return status_; }
//............................................................................ void QXK::onIdle(void) { QF_INT_DISABLE(); if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) // rate-0 enabled? && QP::QF::noTimeEvtsActiveX(0U)) // no time events at rate-0? { // safe to disable SysTick and interrupt SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); l_activeSet &= ~(1U << SYSTICK_ACTIVE); // mark rate-0 as disabled } if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) // rate-1 enabled? && QP::QF::noTimeEvtsActiveX(1U)) // no time events at rate-1? { // safe to disable Timer0 and interrupt TIMER0->CTL &= ~(1U << 0); // disable Timer0 TIMER0->IMR &= ~(1U << 0); // disable timer interrupt l_activeSet &= ~(1U << TIMER0_ACTIVE); // mark rate-1 as disabled } QF_INT_ENABLE(); GPIOF->DATA_Bits[LED_RED] = 0xFFU; // turn LED on, see NOTE2 __WFI(); // wait for interrupt GPIOF->DATA_Bits[LED_RED] = 0x00U; // turn LED off, see NOTE2 }
/*..........................................................................*/ void QF_onIdle(void) { /* NOTE: entered with interrupts DISABLED */ QF_INT_ENABLE(); /* must at least enable interrupts */ }
/* @(/2/0/9/1/1) ...........................................................*/ QState CoffeeAO_menu(CoffeeAO * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* @(/2/0/9/1/1/0) */ case ADWHEEL_SIG: { // calculate current menu entry char menu_text[20]; struct Entry* menu_entry = &menu_entries[me->current_menu_index]; me->current_menu_index = ((AdEvt*)e)->val * me->max_menu_index / 1024; lcd_clear(); set_cursor(0, 0); switch (menu_entry->interpolate_with) { case NOTHING: strcpy(menu_text, menu_entry->menu_label); break; case BREW_STRENGTH: sprintf(menu_text, menu_entry->menu_label, l_CoffeeAO.current_brew_strength + 1); break; case IS_COFFEE_POT_IN_MACHINE: sprintf(menu_text, menu_entry->menu_label, l_CoffeeAO.is_coffee_pot_in_machine); break; case IS_AUTOMATIC_BREW_ACTIVE: sprintf(menu_text, menu_entry->menu_label, l_CoffeeAO.is_automatic_brew_active); break; } lcd_print(menu_text); set_cursor(4, 1); sprintf(menu_text, "%02u:%02u:%02u", l_CoffeeAO.alarm.real_current_time.hours, l_CoffeeAO.alarm.real_current_time.minutes, l_CoffeeAO.alarm.real_current_time.seconds); lcd_print(menu_text); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/1/1) */ case INT_SIG: { QEvent *menuEvt = Q_NEW(QEvent, menu_entries[me->current_menu_index].signal); //QEvent *menuEvt = Q_NEW(QEvent, GO_COFFEE_POT_TOGGLE_SIG); QF_INT_ENABLE(); QActive_postFIFO((QActive *)&l_CoffeeAO, menuEvt); QF_INT_DISABLE(); status_ = Q_HANDLED(); break; } /* @(/2/0/9/1/1/2) */ case GO_COFFEE_POT_TOGGLE_SIG: { status_ = Q_TRAN(&CoffeeAO_coffeePotToggle); break; } /* @(/2/0/9/1/1/3) */ case GO_TIME_BREW_TOGGLE_SIG: { status_ = Q_TRAN(&CoffeeAO_timeBrewActivatedToggle); break; } /* @(/2/0/9/1/1/4) */ case GO_SET_BREW_TIME_CLOCK_SIG: { status_ = Q_TRAN(&CoffeeAO_set_brew_h1); break; } /* @(/2/0/9/1/1/5) */ case GO_SET_TIME_OF_DAY_SIG: { status_ = Q_TRAN(&CoffeeAO_set_clock_h1); break; } /* @(/2/0/9/1/1/6) */ case GO_START_BREWING_SIG: { status_ = Q_TRAN(&CoffeeAO_startBrewingNow); break; } /* @(/2/0/9/1/1/7) */ case GO_SET_BREW_STRENGTH_SIG: { status_ = Q_TRAN(&CoffeeAO_setBrewStrength); break; } default: { status_ = Q_SUPER(&CoffeeAO_coffeemachine); break; } } return status_; }
/** * \description * The "extended" QK scheduler performs all the steps of the regular scheduler * QK_sched_() and additionally switches the Thread-Local Storage (TLS) and * handles the extended context-switch. * * \arguments * \arg[in] \c p priority of the next AO to schedule * * \note The "extended" QK scheduler needs to be called only to handle * "asynchronous" preemption, under the assumption that neither the ISRs * nor the QK idle loop use TLS or the co-processors requiring * extended context switch (see [PSiCC2] Section 10.4.3). * * \note QK_schedExt_() must be always called with interrupts DISABLED. * * \note The extended scheduler might enable interrupts internally, * but always returns with interrupts DISABLED. */ void QK_schedExt_(uint_fast8_t p) { uint_fast8_t pin = QK_currPrio_; /* save the initial priority */ /* thread-local storage used? */ #ifdef QK_TLS uint_fast8_t pprev = pin; #endif QActive *a; /* extended context-switch used? */ #ifdef QK_EXT_SAVE /* aren't we preempting the idle loop? (idle loop has prio==0) */ if (pin != (uint_fast8_t)0) { a = QF_active_[pin]; /* the pointer to the preempted AO */ QK_EXT_SAVE(a); /* save the extended context */ } #endif /* loop until have ready-to-run AOs of higher priority than the initial */ do { QEvt const *e; a = QF_active_[p]; /* obtain the pointer to the AO */ QK_currPrio_ = p; /* this becomes the current task priority */ /* thread-local storage used? */ #ifdef QK_TLS /* are we changing threads? */ if (p != pprev) { QK_TLS(a); /* switch new thread-local storage */ pprev = p; } #endif QS_BEGIN_NOCRIT_(QS_QK_SCHEDULE, QS_priv_.aoObjFilter, a) QS_TIME_(); /* timestamp */ QS_U8_((uint8_t)p); /* the priority of the AO */ QS_U8_((uint8_t)pin); /* the preempted priority */ QS_END_NOCRIT_() QF_INT_ENABLE(); /* unconditionally enable interrupts */ /* perform the run-to-completion (RTS) step... * 1. retrieve the event from the AO's event queue, which by this * time must be non-empty and QActive_get_() asserts it. * 2. dispatch the event to the AO's state machine. * 3. determine if event is garbage and collect it if so */ e = QActive_get_(a); QMSM_DISPATCH(&a->super, e); QF_gc(e); QF_INT_DISABLE(); /* disable interrupts */ /* find new highest-priority AO ready to run... */ #if (QF_MAX_ACTIVE <= 8) QPSet8_findMax(&QK_readySet_, p); #else QPSet64_findMax(&QK_readySet_, p); #endif /* is the new priority below the current preemption threshold? */ if (p <= pin) { p = (uint_fast8_t)0; } #ifndef QK_NO_MUTEX /* is the new priority below the mutex ceiling? */ else if (p <= QK_ceilingPrio_) { p = (uint_fast8_t)0; } else { /* empty */ } #endif } while (p != (uint_fast8_t)0); QK_currPrio_ = pin; /* restore the initial priority */ #if defined(QK_TLS) || defined(QK_EXT_RESTORE) /* aren't we preempting the idle loop? (idle loop has prio==0) */ if (pin != (uint_fast8_t)0) { a = QF_active_[pin]; /* the pointer to the preempted AO */ /* thread-local storage used? */ #ifdef QK_TLS QK_TLS(a); /* restore the original TLS */ #endif /* extended context-switch used? */ #ifdef QK_EXT_RESTORE QK_EXT_RESTORE(a); /* restore the extended context */ #endif } #endif }