LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

ISIX-RTOS – przykład 4 – wątkowa obsługa portu szeregowego RS232

W przypadku, gdy do wskaźnika przypisanego do danego portu szeregowego został przypisany jakiś obiekt, wówczas wywoływana jest metoda isr()list. 9, odpowiedzialna za realizację procedury obsługi przerwania.

 

List. 9. Implementacja metody obsługi przerwań klasy portu szeregowego

void usart_buffered::isr()
{
    uint16_t usart_sr = usart->SR;
    if( usart_sr & USART_RXNE  )
    {
        //Received data interrupt
        unsigned char ch = usart->DR;
        //fifo_put(&hwnd->rx_fifo,ch);
        rx_queue.push_isr(ch);
    }
    if(tx_en && (usart_sr&USART_TXE) )
    {
        unsigned char ch;
        if( tx_queue.pop_isr(ch) == isix::ISIX_EOK )
        {
            usart->DR = ch;
        }
        else
        {
            usart->CR1 &= ~USART_TXEIE;
            tx_en = false;
        }
    }
}

Działanie procedury obsługi przerwania jest bardzo proste: sprowadza się do odczytania statusu, kontrolera USART oraz podjęciu odpowiedniej akcji. W przypadku, gdy przerwanie zostało wygenerowane w wyniku odebrania znaku, wówczas jest on odczytywany z rejestru danych, a następnie przekazywany do kolejki. Do wysłania znaku do kolejki FIFO używana jest nieblokująca metoda push_isr(), dedykowana procedurom obsługi przerwań. W przypadku, gdy zostało wygenerowane przerwanie, w wyniku braku danych w buforze nadawczym, wówczas znak odczytywany jest z kolejki nadawczej za pomocą nieblokującej metody pop_isr(), a następnie odczytany znak zapisywany jest do rejestru danych układu USART. W przypadku, gdy nie ma danych w kolejce, zerowana jest flaga zgłoszenia przerwania
Klasa led_receiver (list. 10) odpowiedzialna jest za odbieranie danych z portu szeregowego oraz sterowanie diodami LED w zależności od kodu odebranego znaku. Klasa dziedziczy z klasy bazowej isix::task_base.

 

List. 10. Deklaracja klasy led_receiver

//Serial receiver 
task class
class led_receiver: public isix::task_base
{
public:
    //Constructor
    led_receiver(dev::usart_buffered &_serial);
protected:
    //Main thread method
    virtual void main();
private:
    //Stack configuration
    static const unsigned STACK_SIZE = 256;
    static const unsigned TASK_PRIO = 3;
    //The usart obj ref
    dev::usart_buffered &serial;
};