Skip to content

Commit

Permalink
[Driver] add USB Serial/JTAG read unblock
Browse files Browse the repository at this point in the history
  • Loading branch information
chipweinberger committed Nov 2, 2022
1 parent 6159dec commit e411230
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
11 changes: 11 additions & 0 deletions components/driver/include/driver/usb_serial_jtag.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ typedef struct {
*/
esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_serial_jtag_config);

/**
* @brief Unblocks usb_serial_jtag_read_bytes() if it is currently waiting to receive bytes.
*
* This will cause usb_serial_jtag_read_bytes() to return -1 with errno set to EWOULDBLOCK.
*
* @return
* - ESP_OK Success
* - ESP_INVALID_STATE If the Usb Serial JTAG driver has not been installed
*/
esp_err_t usb_serial_jtag_unblock_reads();

/**
* @brief USB_SERIAL_JTAG read bytes from USB_SERIAL_JTAG buffer
*
Expand Down
10 changes: 10 additions & 0 deletions components/driver/usb_serial_jtag.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ esp_err_t usb_serial_jtag_driver_install(usb_serial_jtag_driver_config_t *usb_se
return err;
}

esp_err_t usb_serial_jtag_unblock_reads()
{
if (p_usb_serial_jtag_obj->rx_ring_buf == NULL) {
return ESP_ERR_INVALID_STATE;
}

vRingbufferUnblockRx(p_usb_serial_jtag_obj->rx_ring_buf);
return ESP_OK;
}

int usb_serial_jtag_read_bytes(void* buf, uint32_t length, TickType_t ticks_to_wait)
{
uint8_t *data = NULL;
Expand Down
10 changes: 10 additions & 0 deletions components/esp_ringbuf/include/freertos/ringbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,16 @@ void vRingbufferGetInfo(RingbufHandle_t xRingbuffer,
UBaseType_t *uxAcquire,
UBaseType_t *uxItemsWaiting);

/**
* @brief Unblock any read function that is currently waiting. example: xRingbufferReceiveUpTo()
*
* All read functions take a xTicksToWait argument, which can be set up to
* to infinity. This function will unblock any threads currently waiting.
*
* @param[in] xRingbuffer The ring buffer who's rx will be unblocked.
*/
void vRingbufferUnblockRx(RingbufHandle_t xRingbuffer);

/**
* @brief Debugging function to print the internal pointers in the ring buffer
*
Expand Down
26 changes: 25 additions & 1 deletion components/esp_ringbuf/ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define rbBYTE_BUFFER_FLAG ( ( UBaseType_t ) 2 ) //The ring buffer is a byte buffer
#define rbBUFFER_FULL_FLAG ( ( UBaseType_t ) 4 ) //The ring buffer is currently full (write pointer == free pointer)
#define rbBUFFER_STATIC_FLAG ( ( UBaseType_t ) 8 ) //The ring buffer is statically allocated
#define rbBUFFER_UNBLOCK_RX_FLAG ( ( UBaseType_t ) 16) //A request has been made to unblock any pending reads

//Item flags
#define rbITEM_FREE_FLAG ( ( UBaseType_t ) 1 ) //Item has been retrieved and returned by application, free to overwrite
Expand Down Expand Up @@ -759,6 +760,8 @@ static size_t prvGetCurMaxSizeByteBuf(Ringbuffer_t *pxRingbuffer)
return xFreeSize;
}



static BaseType_t prvReceiveGeneric(Ringbuffer_t *pxRingbuffer,
void **pvItem1,
void **pvItem2,
Expand All @@ -772,12 +775,19 @@ static BaseType_t prvReceiveGeneric(Ringbuffer_t *pxRingbuffer,
TickType_t xTicksEnd = xTaskGetTickCount() + xTicksToWait;
TickType_t xTicksRemaining = xTicksToWait;
while (xTicksRemaining <= xTicksToWait) { //xTicksToWait will underflow once xTaskGetTickCount() > ticks_end
//Block until more free space becomes available or timeout
//Block until some bytes become available or timeout
if (xSemaphoreTake(rbGET_RX_SEM_HANDLE(pxRingbuffer), xTicksRemaining) != pdTRUE) {
xReturn = pdFALSE; //Timed out attempting to get semaphore
break;
}

// has a request been made to unblock?
if (pxRingbuffer->uxRingbufferFlags & rbBUFFER_UNBLOCK_RX_FLAG) {
pxRingbuffer->uxRingbufferFlags &= ~rbBUFFER_UNBLOCK_RX_FLAG; // clear flag
xReturn = pdFALSE;
break;
}

//Semaphore obtained, check if item can be retrieved
portENTER_CRITICAL(&pxRingbuffer->mux);
if (prvCheckItemAvail(pxRingbuffer) == pdTRUE) {
Expand Down Expand Up @@ -1421,6 +1431,18 @@ void vRingbufferGetInfo(RingbufHandle_t xRingbuffer,
portEXIT_CRITICAL(&pxRingbuffer->mux);
}

void vRingbufferUnblockRx(RingbufHandle_t xRingbuffer)
{
Ringbuffer_t *pxRingbuffer = (Ringbuffer_t *)xRingbuffer;
configASSERT(pxRingbuffer);

// is the semaphore taken?
if (uxSemaphoreGetCount(rbGET_RX_SEM_HANDLE(pxRingbuffer)) == 0) {
pxRingbuffer->uxRingbufferFlags |= rbBUFFER_UNBLOCK_RX_FLAG;
xSemaphoreGive(rbGET_RX_SEM_HANDLE(pxRingbuffer));
}
}

void xRingbufferPrintInfo(RingbufHandle_t xRingbuffer)
{
Ringbuffer_t *pxRingbuffer = (Ringbuffer_t *)xRingbuffer;
Expand All @@ -1432,3 +1454,5 @@ void xRingbufferPrintInfo(RingbufHandle_t xRingbuffer)
pxRingbuffer->pucWrite - pxRingbuffer->pucHead,
pxRingbuffer->pucAcquire - pxRingbuffer->pucHead);
}


0 comments on commit e411230

Please sign in to comment.