int SerialDriver::getc(unsigned int timeoutMs) { // Let's read (isr will check readability itself) onRxIrq(); // critical section, isr could modify cursors disableRxInterrupt(); if(isRxBufferEmpty()) { // wait for new byte while(semRxBufferEmpty.wait(0) > 0); // clear semaphore enableRxInterrupt(); // let isr work semRxBufferEmpty.wait(timeoutMs); disableRxInterrupt(); if(isRxBufferEmpty()) // still empty? nothing received! { enableRxInterrupt(); return -1; } } // get byte from rx buffer int c= (int)rxBuffer[rxOut]; rxOut= (rxOut+1) % rxBufferLength; rxCount--; // its over, isr can come enableRxInterrupt(); return c; }
void SerialDriver::onRxIrq() { // prevent fire another RxIrq now disableRxInterrupt(); // read as long as you can bool wasEmpty= isRxBufferEmpty(); while(SerialBase::readable()) { // get byte and store it to the RX buffer int c= SerialBase::_base_getc(); if(!isRxBufferFull()) { rxBuffer[rxIn]= (unsigned char)c; rxIn= (rxIn+1) % rxBufferLength; rxCount++; } else // drop byte :( numRxDrops++; } if(wasEmpty && !isRxBufferEmpty()) // more bytes can go semRxBufferEmpty.release(); // ok, let's wait for next readability enableRxInterrupt(); }
/** * Function for notifying application about new bytes received. */ static void processReceive(void) { // Set head position to not be changed during read procedure. uint16_t head = sReceiveHead; otEXPECT(isRxBufferEmpty() == false); // In case head roll back to the beginning of the buffer, notify about left // bytes from the end of the buffer. if (head < sReceiveTail) { otPlatUartReceived(&sReceiveBuffer[sReceiveTail], (UART_RX_BUFFER_SIZE - sReceiveTail)); sReceiveTail = 0; } // Notify about received bytes. if (head > sReceiveTail) { otPlatUartReceived(&sReceiveBuffer[sReceiveTail], (head - sReceiveTail)); sReceiveTail = head; } exit: return; }
* Function for checking if RX buffer is empty. * * @retval true RX buffer is empty. * @retval false RX buffer is not empty. */ static __INLINE bool isRxBufferEmpty() { return (sReceiveHead == sReceiveTail); } /** * Function for notifying application about new bytes received. */ static void processReceive(void) { VerifyOrExit(isRxBufferEmpty() == false, ;); // Set head position to not be changed during read procedure. uint16_t head = sReceiveHead; // In case head roll back to the beginning of the buffer, notify about left // bytes from the end of the buffer. if (head < sReceiveTail) { otPlatUartReceived(&sReceiveBuffer[sReceiveTail], (UART_RX_BUFFER_SIZE - sReceiveTail)); sReceiveTail = 0; } // Notify about received bytes. if (head > sReceiveTail)