Interrupt using lilos

Guys, can anyone help me? I'm trying to use the notify from lilos RTOS to generate an interrupt, but it's not working. I don't know what else to do; I've tried everything. I changed the EXTI and tried various logics. The hardware is working; I've tested it, but the code isn't functioning.

Please help me. Thank you! The code compiles just fine.

#![no_std]
#![no_main]

use cortex_m_rt::entry;
use stm32g0xx_hal::{self as hal, exti::ExtiExt, pac::exti::exticr1::EXTI0_7_A};
use hal::{
    pac,
    prelude::*,
    interrupt,
    gpio::{Output, PushPull, gpioa::PA1, gpioa::PA4},
};
use stm32g0xx_hal::exti::Event;
use hal::stm32;
use lilos::time::Millis;
use lilos::time::sleep_for;
use lilos::exec::{run_tasks, Notify}; 
use hal::rcc::{Config, Prescaler};
use panic_halt as _;
use rtt_target::{rprint, rtt_init_print};

static mut LED_STATE: bool = false; 
static BUTTON_NOTIFY: Notify = Notify::new(); 
const PERIOD: Millis = Millis(1000);

#[entry]
fn main() -> ! {
    
    let mut cp = cortex_m::Peripherals::take().unwrap();
    let dp = stm32::Peripherals::take().expect("cannot take peripherals");

    let mut rcc = dp.RCC.freeze(Config::hsi(Prescaler::Div2));

    let gpioa = dp.GPIOA.split(&mut rcc);
    let mut led = gpioa.pa1.into_push_pull_output(); 
    let _button = gpioa.pa4.into_pull_down_input(); 

    lilos::time::initialize_sys_tick(&mut cp.SYST, 8_000_000);

    
    let exti = dp.EXTI;
    exti.listen(Event::GPIO4, stm32g0xx_hal::gpio::SignalEdge::Falling); 

    unsafe {
        cortex_m::peripheral::NVIC::unmask(interrupt::EXTI4_15);
    }

    
    let led_pisca_task =  core::pin::pin!(async {
        loop {
            
            BUTTON_NOTIFY.until(|| unsafe { LED_STATE }).await; 
            
            unsafe { LED_STATE = !LED_STATE };
        
        lilos::time::sleep_for(Millis(500)).await;
        }
    });

    let led_troca_task = core::pin::pin!(async {
        loop{
            
        BUTTON_NOTIFY.until(|| unsafe { LED_STATE }).await; 
        if unsafe { LED_STATE } {
            led.set_high().unwrap();
        } else {
            led.set_low().unwrap();
        }
    }
        
    });

    
    lilos::exec::run_tasks(&mut [led_troca_task, led_pisca_task ], lilos::exec::ALL_TASKS);
}


#[interrupt]
fn EXTI4_15() {
    BUTTON_NOTIFY.notify(); 
    let dp = stm32::Peripherals::take().expect("cannot take peripherals");
    dp.EXTI.rpr1.write(|w| w.rpif4().set_bit()); 
}


Hi.

So as a quick disclaimer at the time of writting, I did not have a working code example with an interrupt waking a task.
But after reading some of the source code of lilos, I would say, that you need to change the way the tasks are executed.
From my understanding calling fn run_tasks() is just a wrapper with specific parameters around the fn run_tasks_with_idle_and_preemption() function.
When fn run_tasks() is called, it will call fn run_tasks_with_idle_and_preemption() with an enum, which masks all Interrupts.
So what you would need to do, would be to use fn run_tasks_with_preemption(&mut [your list of tasks], lilos::exec::ALL_TASKS, Interrupt::filtered(x))] instead.
You would also need to give your interrupt a priority, that is higher than Interrupt::Filtered(x), as all Interrupts with the same numerical value or lower will be masked.

1 Like

Thank you so much for your help!!
I understood the solution, but I was reading and I'm using an ARMv6-M, which doesn't have the BASEPRI, so I cannot use Interrupts::Filtered(x). Here is the reference: Lilos GitHub - exec.rs, line 311.

I keep trying to handle the interruption in another way, but it just doesn't work. Now, the LED that is supposed to be blinking keeps its state when I press the button. If the LED is in a high state, it remains in that state. The LED that was supposed to change state never changes.

Here is the code now:


#![no_std]  
#![no_main]  

use cortex_m_rt::entry;
use stm32g0xx_hal::{self as hal, exti::ExtiExt, pac::exti::{exticr1::EXTI0_7_A, exticr4::EXTI24_31_R}};
use hal::{
    pac,
    prelude::*,
    interrupt,
    gpio::{Output, PushPull, gpioa::PA1, gpioa::PA4},
};
use lilos::exec::Interrupts;
use stm32g0xx_hal::exti::Event;
use hal::stm32;
use lilos::time::{Millis, PeriodicGate};
use lilos::time::sleep_for;
use lilos::exec::{run_tasks, Notify, run_tasks_with_preemption}; 
use hal::rcc::{Config, Prescaler};
use panic_halt as _;
use rtt_target::{rprint, rtt_init_print};

static mut LED_STATE: bool = false;  
static BUTTON_NOTIFY: Notify = Notify::new();  

#[entry]  
fn main() -> ! {  
    let mut cp = cortex_m::Peripherals::take().unwrap();
    let dp = stm32::Peripherals::take().expect("cannot take peripherals");

    let mut rcc = dp.RCC.freeze(Config::hsi(Prescaler::Div2));

    let gpioa = dp.GPIOA.split(&mut rcc);
    let mut led = gpioa.pa0.into_push_pull_output(); 
    let mut led2 = gpioa.pa2.into_push_pull_output();
    let _button = gpioa.pa4.into_pull_down_input(); 

    lilos::time::initialize_sys_tick(&mut cp.SYST, 8_000_000);

    let exti = dp.EXTI;
    exti.listen(Event::GPIO4, stm32g0xx_hal::gpio::SignalEdge::Falling); 

    unsafe {  
        cortex_m::peripheral::NVIC::unmask(interrupt::EXTI4_15);  
    }  

    let led_task = core::pin::pin!(async {  
        loop {  
            BUTTON_NOTIFY.until(|| true).await;

          
            unsafe {   
                LED_STATE = !LED_STATE;   
                
              
                if LED_STATE {  
                    led.set_high().unwrap(); 
                } else {  
                    led.set_low().unwrap(); 
                }  
            }  
            
           
            lilos::time::sleep_for(Millis(500)).await;  
        }  
    });  
  

    let led_troca_task = core::pin::pin!(async {  
        loop {  
            led2.set_high().unwrap();  
            lilos::time::sleep_for(Millis(1000)).await;  
            led2.set_low().unwrap();  
            lilos::time::sleep_for(Millis(1000)).await;  
        }  
    });  

 
    let preemption_mask = Interrupts::Masked;

    unsafe {

        run_tasks_with_preemption(
            &mut [led_task, led_troca_task], 
            lilos::exec::ALL_TASKS,         
            preemption_mask                   
        );
    }
}  


#[interrupt]  
fn EXTI4_15() {  
    BUTTON_NOTIFY.notify(); 
    unsafe {  
        let dp = stm32::Peripherals::steal();  
        dp.EXTI.rpr1.write(|w| w.rpif4().set_bit());  
    }  
}  

Nobody knows that?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.