LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

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

Klasa została zaprzyjaźniona z handlerami przerwań portów szeregowych, które zostały wcześniej zadeklarowane z linkowaniem typu C, co powoduje wyłączenie manglowania nazw. Funkcje obsługi przerwań są wywoływane przez kontroler sprzętowy w momencie wystąpienia przerwania bez dodatkowych parametrów, co wymusza istnienie dostępu do instancji klasy obsługującej port szeregowy, poprzez wskaźnik lub referencję globalną. Wskaźniki dostępu do poszczególnych instancji klas przypisanych do portów szeregowych zostały umieszczone w nienazwanej przestrzeni nazw w pliku implementacji (usart_buffered.cpp), przez co dostęp do wskaźników jest możliwy tylko w obrębie danego modułu (list. 4).

 

List. 4. Fragment implementacji klasy portu szeregowego

namespace    //Object pointers for interrupt
{
    usart_buffered *usart1_obj;
    usart_buffered *usart2_obj;
}

Zadeklarowanie przyjaźni funkcji z klasą umożliwia wywołanie dowolnych metod z funkcji zaprzyjaźnionej, co zostało wykorzystane do wywołania metody isr() stanowiącej wektor obsługi przerwania. Klasa obsługi portu szeregowego zawiera dwa obiekty tx_queue, rx_queue (list. 5) klasy isix::fifo, które są wykorzystywane jako bufor nadajnika oraz bufor odbiornika. Konstruktor klasy przyjmuje cztery parametry, adres wybranego kontrolera portu szeregowego (np. USART1, USART2), prędkość transmisji z ustawionym argumentem domyślnym na 115200, wielkość kolejek FIFO ustawionych domyślnie na 192 bajty oraz tryb kontroli parzystości z domyślnym argumentem ustawionym na parity_none.

 

List. 5. Implementacja konstruktora klasy portu szeregowego

/*----------------------------------------------------------*/
//! Constructor called for usart buffered
usart_buffered::usart_buffered(USART_TypeDef *_usart, unsigned cbaudrate,
        std::size_t queue_size ,parity cpar
) : usart(_usart), tx_queue(queue_size),
   rx_queue(queue_size) , tx_en( false )
{
    if(_usart == USART1)
    {
        periphcfg_usart1(false);
    }
    else if(_usart == USART2)
    {
        periphcfg_usart2(true);
    }
    //Enable UART
    usart->CR1 = CR1_UE_SET;
    //Setup default baudrate
    set_baudrate( cbaudrate );
    set_parity( cpar );
 
    //One stop bit
    usart->CR2 = USART_StopBits_1;
 
    //Enable receiver and transmitter and anable related interrupts
    usart->CR1 |=  USART_Mode_Rx |USART_RXNEIE | USART_Mode_Tx ;
 
    if( _usart == USART1 )
    {
        usart1_obj = this;
        //Enable usart IRQ with lower priority
        nvic_set_priority( USART1_IRQn,IRQ_PRIO, IRQ_SUB );
        nvic_irq_enable( USART1_IRQn, true );
    }
    else if( _usart == USART2 )
    {
        usart2_obj = this;
        //Enable usart IRQ with lower priority
        nvic_set_priority( USART2_IRQn,IRQ_PRIO, IRQ_SUB );
        nvic_irq_enable(  USART2_IRQn, true );
    }
}