COUNT SerialRead(char * buf, COUNT len) { COUNT read = 0; COUNT readGeneration; BOOL wasFull = FALSE; do { IsrDisable(IRQ_LEVEL_SERIAL_READ); if ( RingBufferIsFull( &SerialInputRing ) ) { wasFull = TRUE; } read = RingBufferRead(buf, len, &SerialInputRing); readGeneration = ReadGenerationCount; IsrEnable(IRQ_LEVEL_SERIAL_READ); if (read == 0) { GenerationWait(&ReadGeneration, readGeneration, NULL); } } while (read == 0); // We were full, so lets make sure there wasn't any data buffered // in the hal. if ( wasFull ) { HalRaiseInterrupt( IRQ_LEVEL_SERIAL_READ ); } return read; }
void GPS_UART_Capture() { static char rxString[100]; static uint8_t rxStringWritePos = 0; char tmpchar = '\0'; if (RingBufferRead(&GPS_USART_RxRingBuffer, &tmpchar) == NO_ERROR) { if (tmpchar == '$') { rxStringWritePos = 0; } else if (tmpchar == '*') { rxStringWritePos = 0; // kompletter String empfangen GPS_Decode(rxString); } else { // einzelnes Datenzeichen Empfangen // anhängen des Zeichens an rxString rxString[rxStringWritePos++] = tmpchar; } } }
void SendBytesInterrupt(void) { ASSERT(IsrIsAtomic(IRQ_LEVEL_SERIAL_WRITE)); while (!RingBufferIsEmpty(&SerialOutputRing)) { char data; ASSUME(RingBufferRead(&data, sizeof(data), &SerialOutputRing), 1); HalSerialWriteChar(data); } }
COUNT PipeReadInner( char * buff, COUNT size, PIPE_READ pipe ) { BOOL wasFull; BOOL dataLeft; COUNT read; //Acquire EmptyLock - No readers can progress until there is data. SemaphoreDown( & pipe->EmptyLock, NULL ); //Acqure mutex lock - No one can do any io until //we leave the buffer. SemaphoreDown( & pipe->Mutex, NULL ); //Check and see if the buffer is full. //If it is, then the FullLock should //have been leaked, and writers should be blocking. wasFull = RingBufferIsFull( & pipe->Ring ); ASSERT( wasFull ? (pipe->FullLock.Count == 0) : TRUE ); //Perform the read. read = RingBufferRead( buff, size, & pipe->Ring ); // Ring is protected by a read lock which should prevent zero length reads. ASSERT( read > 0 ); //See if the ring buffer is empty. //If it is then we need to leak the reader lock. dataLeft = !RingBufferIsEmpty( & pipe->Ring ); //Release mutex lock - We are out of the ring, so //let other IO go if its already passed. SemaphoreUp( & pipe->Mutex ); //If the ring was full while we have exclusive access, //and we freed up some space then we should release //the writer lock so writers can go. if( wasFull && read > 0 ) { SemaphoreUp( & pipe->FullLock ); } //If there is data left in the buffer, release the //empty lock so that other readers can go. //If there is no data in the buffer, we cant let //readers progress, so we leak the lock. if( dataLeft ) { SemaphoreUp( & pipe->EmptyLock ); } return read; }
void Connection::OnSend() { _sending = false; u32 size = 0; char * buf = RingBufferRead(_sendBuf, &size); if (buf && size > 0) { if (!DoSend()) { CloseForce(); return; } _sending = true; } else { if (_closing) CloseForce(); } }
bool Connection::DoSend() { #ifdef _DEBUG OASSERT(_establish, "wtf"); #endif u32 size = 0; char * buf = RingBufferRead(_sendBuf, &size); OASSERT(buf && size > 0, "wtf"); _send.buf.buf = buf; _send.buf.len = size; _send.code = 0; _send.bytes = 0; if (SOCKET_ERROR == WSASend(_fd, &_send.buf, 1, nullptr, 0, (LPWSAOVERLAPPED)&_send, nullptr)) { _send.code = WSAGetLastError(); if (WSA_IO_PENDING != _send.code) return false; } return true; }
/** * \brief usart-hw-handshaking Application entry point.. * * Configures USART in hardware handshaking mode and * Timer Counter 0 to generate an interrupt every second. Then, start the first * transfer on the USART and wait in an endless loop. * * \return Unused (ANSI-C compatibility). */ int main( void ) { char pbaud_time[8]; uint32_t BytesRead, BytesToRead, baudrate, timeout, TxBytesLeft; uint8_t AppBufferRollOver = 0; uint8_t *pTxBuff; /* Disable watchdog*/ WDT_Disable(WDT); printf("-- USART Hardware Handshaking Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); /* Enable I and D cache */ SCB_EnableICache(); SCB_EnableDCache(); /* Configure USART pins*/ PIO_Configure(pins, PIO_LISTSIZE(pins)); /* Configure systick for 1 ms. */ TimeTick_Configure(); NVIC_SetPriority(XDMAC_IRQn , XDMA_NVIC_PRIO); printf("\n\rEnter required baudrate:"); gets(pbaud_time); baudrate = (atoi(pbaud_time)) ? (atoi(pbaud_time)): 921600; printf("\n\rEnter required timeout (in microsec):"); gets(pbaud_time); timeout = atoi(pbaud_time); if (timeout > 1000) { timeout /= 1000; timeout = ((timeout * baudrate) / 1000); } else { timeout = (timeout * baudrate) / 1000000; } timeout = (timeout) ? ((timeout > MAX_RX_TIMEOUT) ? MAX_RX_TIMEOUT : timeout) \ : MAX_RX_TIMEOUT; printf("\n\r"); /* Configure USART */ _ConfigureUsart(baudrate, timeout); printf("\n\r"); /*Enable Rx channel of USART */ USARTD_EnableRxChannels(&Usartd, &UsartRx); #ifdef FULL_DUPLEX /*Enable Tx channel of USART */ USARTD_EnableTxChannels(&Usartd, &UsartTx); #endif /* Start receiving data and start timer*/ USARTD_RcvData(&Usartd); /*Initialize Ring buffer */ pUsartBuffer = (RignBuffer_t *)malloc(sizeof(RignBuffer_t)); _initCircularBuffer(pUsartBuffer); pTxBuff = &FirstAppBuff[0]; TxBytesLeft = 0; #ifdef USE_MD5_CHECK md5_init(&pms); #endif //USE_MD5_CHECK #ifdef FULL_DUPLEX printf( "\n\r-I- USART is in Full Duplex mode \n\r"); #else printf( "\n\r-I- USART is in Half Duplex mode \n\r"); #endif printf( "\n\r-I- Please send a file to serial port (USART0) \n\r"); BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer while (1) { #ifdef USE_MD5_CHECK if (DBG_IsRxReady()) { ch = DBG_GetChar(); if (ch == 'm') { uint8_t i; md5_finish(&pms, md5); printf("\r\nmd5:"); for (i = 0; i < sizeof(md5);i++) printf("%.2x",md5[i]); printf("\r\n"); md5_init(&pms); TotalbytesReceived = 0; } } #endif /* Check Application buffer (100 KB)overflow */ if (((PingPongBufferFlag == 0) && (pTxBuff+BytesToRead) >= &FirstAppBuff[APP_BUFFER]) || (( PingPongBufferFlag == 1) && (pTxBuff+BytesToRead) >= &SecondAppBuff[APP_BUFFER])) { AppBufferRollOver = 1; // Roll over and start copying to the beginning of Application buffer to avoid errors if (PingPongBufferFlag) BytesToRead = (&SecondAppBuff[APP_BUFFER] - pTxBuff); else BytesToRead = (&FirstAppBuff[APP_BUFFER] - pTxBuff); memory_barrier(); } /* Read ring buffer */ BytesRead = RingBufferRead(pUsartBuffer, pTxBuff, BytesToRead); memory_sync(); TxBytesLeft += BytesRead; // number of bytes to send via USART Tx #ifdef USE_MD5_CHECK if (BytesRead > 0) md5_append(&pms,pTxBuff,BytesRead); #endif /* check if one of the application buffer is full and ready to send */ if (AppBufferRollOver && (TxBytesLeft == APP_BUFFER)) { AppBufferRollOver = 0; TxBytesLeft = 0; BytesRead = 0; BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer while (!UsartTx.dmaProgress); if (PingPongBufferFlag) { PingPongBufferFlag = 0; pTxBuff = &FirstAppBuff[0]; } else { PingPongBufferFlag = 1; pTxBuff = &SecondAppBuff[0]; } memory_sync(); #ifdef FULL_DUPLEX USARTD_SendData(&Usartd); #endif } /* otherwise keep storing in same application buffer from Rx DMA's ring buffer */ else { BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer pTxBuff += BytesRead; #ifdef FULL_DUPLEX /* Check for Tx timeout, if there is timeout then send the bytes left (less than 100 KB) in application buffer */ if ((GetDelayInTicks(TimeOutTimer, GetTicks()) == USART_TX_TIMEOUT) && TxBytesLeft) { // wait for any eventual USART Tx in progress while (!UsartTx.dmaProgress); FlushTxBuffer(TxBytesLeft); TimeOutTimer = GetTicks(); PingPongBufferFlag = 0; TxBytesLeft = 0; BytesRead = 0; BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer pTxBuff = &FirstAppBuff[0]; _UpdateTxConfig((uint32_t)&FirstAppBuff[0], APP_BUFFER); TRACE_INFO_WP(" TX Tiemout \n\r"); } #endif } } }
bool Connection::Out(const s32 size) { RingBufferOut(_sendBuf, size); u32 left = 0; return RingBufferRead(_sendBuf, &left) != nullptr; }