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 ); } }