ringbuf tested
This commit is contained in:
parent
77cd93ac2d
commit
fbc8719fad
|
@ -198,9 +198,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||
claim_pin(self->tx_pin->pin);
|
||||
|
||||
if (self->rx_pin != NULL) {
|
||||
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
|
||||
// The LPUART ring buffer wastes one byte to distinguish between full and empty.
|
||||
self->ringbuf = gc_alloc(receiver_buffer_size + 1, false, true /*long-lived*/);
|
||||
|
||||
if (!self->rbuf.buf) {
|
||||
if (!self->ringbuf) {
|
||||
LPUART_Deinit(self->uart);
|
||||
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
|
||||
}
|
||||
|
@ -208,7 +209,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||
LPUART_TransferCreateHandle(self->uart, &self->handle, LPUART_UserCallback, self);
|
||||
// Pass actual allocated size; the LPUART routines are cognizant that
|
||||
// the capacity is one less than the size.
|
||||
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->rbuf.buf, self->rbuf.size);
|
||||
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->ringbuf, receiver_buffer_size + 1);
|
||||
|
||||
claim_pin(self->rx_pin->pin);
|
||||
}
|
||||
|
@ -225,9 +226,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||
|
||||
LPUART_Deinit(self->uart);
|
||||
|
||||
gc_free(self->rbuf.buf);
|
||||
self->rbuf.size = 0;
|
||||
self->rbuf.iput = self->rbuf.iget = 0;
|
||||
gc_free(self->ringbuf);
|
||||
|
||||
// reset_pin_number(self->rx_pin);
|
||||
// reset_pin_number(self->tx_pin);
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct {
|
|||
mp_obj_base_t base;
|
||||
LPUART_Type *uart;
|
||||
lpuart_handle_t handle;
|
||||
ringbuf_t rbuf;
|
||||
uint8_t* ringbuf;
|
||||
bool rx_ongoing;
|
||||
uint32_t baudrate;
|
||||
uint8_t character_bits;
|
||||
|
|
|
@ -102,7 +102,7 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer
|
|||
uint64_t start_ticks = supervisor_ticks_ms64();
|
||||
|
||||
// Wait for all bytes received or timeout
|
||||
while ( (ringbuf_avail(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
// Allow user to break out of a timeout with a KeyboardInterrupt.
|
||||
if ( mp_hal_is_interrupted() ) {
|
||||
|
@ -125,7 +125,7 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer
|
|||
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
|
||||
uint8_t is_nested_critical_region;
|
||||
sd_nvic_critical_region_enter(&is_nested_critical_region);
|
||||
uint16_t count = ringbuf_avail(&self->ringbuf);
|
||||
uint16_t count = ringbuf_num_filled(&self->ringbuf);
|
||||
sd_nvic_critical_region_exit(is_nested_critical_region);
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
|
|||
uint8_t is_nested_critical_region;
|
||||
sd_nvic_critical_region_enter(&is_nested_critical_region);
|
||||
// Make room for the new value by dropping the oldest packets first.
|
||||
while (ringbuf_capacity(&self->ringbuf) - ringbuf_avail(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||
uint16_t packet_length;
|
||||
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
|
||||
for (uint16_t i = 0; i < packet_length; i++) {
|
||||
|
@ -202,10 +202,7 @@ void common_hal_bleio_packet_buffer_construct(
|
|||
}
|
||||
|
||||
if (incoming) {
|
||||
// This is a macro.
|
||||
ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false);
|
||||
|
||||
if (self->ringbuf.buf == NULL) {
|
||||
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
|
||||
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +247,7 @@ void common_hal_bleio_packet_buffer_construct(
|
|||
}
|
||||
|
||||
int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
|
||||
if (ringbuf_avail(&self->ringbuf) < 2) {
|
||||
if (ringbuf_num_filled(&self->ringbuf) < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -315,25 +312,25 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
|
|||
}
|
||||
|
||||
uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) {
|
||||
uint16_t mtu;
|
||||
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
|
||||
return 0;
|
||||
}
|
||||
bleio_connection_internal_t *connection;
|
||||
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
||||
connection = &bleio_connections[i];
|
||||
if (connection->conn_handle == self->conn_handle) {
|
||||
break;
|
||||
// First, assume default MTU size.
|
||||
uint16_t mtu = BLE_GATT_ATT_MTU_DEFAULT;
|
||||
|
||||
// If there's a connection, get its actual MTU.
|
||||
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
|
||||
bleio_connection_internal_t *connection;
|
||||
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
|
||||
connection = &bleio_connections[i];
|
||||
if (connection->conn_handle == self->conn_handle) {
|
||||
if (connection->mtu != 0) {
|
||||
mtu = connection->mtu;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connection->mtu == 0) {
|
||||
mtu = BLE_GATT_ATT_MTU_DEFAULT;
|
||||
}
|
||||
if (self->characteristic->max_length > mtu) {
|
||||
mtu = self->characteristic->max_length;
|
||||
}
|
||||
uint16_t att_overhead = 3;
|
||||
return mtu - att_overhead;
|
||||
|
||||
// 3 is bytes of ATT overhead.
|
||||
return MIN(mtu - 3, self->characteristic->max_length);
|
||||
}
|
||||
|
||||
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
|
||||
|
|
|
@ -99,7 +99,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
|
|||
|
||||
switch ( event->type ) {
|
||||
case NRFX_UARTE_EVT_RX_DONE:
|
||||
ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
|
||||
ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
|
||||
|
||||
// keep receiving
|
||||
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
|
||||
|
@ -113,7 +113,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
|
|||
// Possible Error source is Overrun, Parity, Framing, Break
|
||||
// uint32_t errsrc = event->data.error.error_mask;
|
||||
|
||||
ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
|
||||
ringbuf_put_n(&self->ringbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
|
||||
|
||||
// Keep receiving
|
||||
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
|
||||
|
@ -191,9 +191,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||
// pointers like this are NOT moved, allocating the buffer
|
||||
// in the long-lived pool is not strictly necessary)
|
||||
// (This is a macro.)
|
||||
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
|
||||
|
||||
if ( !self->rbuf.buf ) {
|
||||
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
||||
nrfx_uarte_uninit(self->uarte);
|
||||
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
|
||||
}
|
||||
|
@ -227,10 +225,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||
reset_pin_number(self->rx_pin_number);
|
||||
self->tx_pin_number = NO_PIN;
|
||||
self->rx_pin_number = NO_PIN;
|
||||
|
||||
gc_free(self->rbuf.buf);
|
||||
self->rbuf.size = 0;
|
||||
self->rbuf.iput = self->rbuf.iget = 0;
|
||||
ringbuf_free(&self->ringbuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +238,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
|
|||
uint64_t start_ticks = supervisor_ticks_ms64();
|
||||
|
||||
// Wait for all bytes received or timeout
|
||||
while ( (ringbuf_avail(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
// Allow user to break out of a timeout with a KeyboardInterrupt.
|
||||
if ( mp_hal_is_interrupted() ) {
|
||||
|
@ -255,7 +250,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
|
|||
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
|
||||
|
||||
// Copy as much received data as available, up to len bytes.
|
||||
size_t rx_bytes = ringbuf_get_n(&self->rbuf, data, len);
|
||||
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
|
||||
|
||||
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
|
||||
|
||||
|
@ -312,13 +307,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
|
|||
}
|
||||
|
||||
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
|
||||
return ringbuf_avail(&self->rbuf);
|
||||
return ringbuf_num_filled(&self->ringbuf);
|
||||
}
|
||||
|
||||
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
|
||||
// prevent conflict with uart irq
|
||||
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
|
||||
ringbuf_clear(&self->rbuf);
|
||||
ringbuf_clear(&self->ringbuf);
|
||||
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef struct {
|
|||
uint32_t baudrate;
|
||||
uint32_t timeout_ms;
|
||||
|
||||
ringbuf_t rbuf;
|
||||
ringbuf_t ringbuf;
|
||||
uint8_t rx_char; // EasyDMA buf
|
||||
|
||||
uint8_t tx_pin_number;
|
||||
|
|
|
@ -211,8 +211,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||
|
||||
// Init buffer for rx and claim pins
|
||||
if (self->rx != NULL) {
|
||||
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
|
||||
if (!self->rbuf.buf) {
|
||||
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
||||
mp_raise_ValueError(translate("UART Buffer allocation error"));
|
||||
}
|
||||
claim_pin(rx);
|
||||
|
@ -248,9 +247,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
|
||||
self->tx = NULL;
|
||||
self->rx = NULL;
|
||||
gc_free(self->rbuf.buf);
|
||||
self->rbuf.size = 0;
|
||||
self->rbuf.iput = self->rbuf.iget = 0;
|
||||
ringbuf_free(&self->ringbuf);
|
||||
}
|
||||
|
||||
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
|
||||
|
@ -258,11 +255,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
|
|||
mp_raise_ValueError(translate("No RX pin"));
|
||||
}
|
||||
|
||||
size_t rx_bytes = 0;
|
||||
uint64_t start_ticks = supervisor_ticks_ms64();
|
||||
|
||||
// Wait for all bytes received or timeout, same as nrf
|
||||
while ( (ringbuf_avail(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
//restart if it failed in the callback
|
||||
if (errflag != HAL_OK) {
|
||||
|
@ -277,7 +273,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
|
|||
// Halt reception
|
||||
HAL_NVIC_DisableIRQ(self->irq);
|
||||
// Copy as much received data as available, up to len bytes.
|
||||
size_t rx_bytes = ringbuf_get_n(&self->rbuf, data, len);
|
||||
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
|
||||
HAL_NVIC_EnableIRQ(self->irq);
|
||||
|
||||
if (rx_bytes == 0) {
|
||||
|
@ -317,7 +313,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
|
|||
if ((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
|
||||
return;
|
||||
}
|
||||
ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
|
||||
ringbuf_put_n(&context->ringbuf, &context->rx_char, 1);
|
||||
errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);
|
||||
|
||||
return;
|
||||
|
@ -376,13 +372,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
|
|||
}
|
||||
|
||||
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
|
||||
return ringbuf_avail(&self->rbuf);
|
||||
return ringbuf_num_filled(&self->ringbuf);
|
||||
}
|
||||
|
||||
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
|
||||
// Halt reception
|
||||
HAL_NVIC_DisableIRQ(self->irq);
|
||||
ringbuf_clear(&self->rbuf);
|
||||
ringbuf_clear(&self->ringbuf);
|
||||
HAL_NVIC_EnableIRQ(self->irq);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct {
|
|||
const mcu_periph_obj_t *tx;
|
||||
const mcu_periph_obj_t *rx;
|
||||
|
||||
ringbuf_t rbuf;
|
||||
ringbuf_t ringbuf;
|
||||
uint8_t rx_char;
|
||||
|
||||
uint32_t baudrate;
|
||||
|
|
10
py/ringbuf.c
10
py/ringbuf.c
|
@ -37,6 +37,12 @@ bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived) {
|
|||
return r->buf != NULL;
|
||||
}
|
||||
|
||||
void ringbuf_free(ringbuf_t *r) {
|
||||
gc_free(r->buf);
|
||||
r->size = 0;
|
||||
ringbuf_clear(r);
|
||||
}
|
||||
|
||||
size_t ringbuf_capacity(ringbuf_t *r) {
|
||||
return r->size - 1;
|
||||
}
|
||||
|
@ -72,12 +78,12 @@ void ringbuf_clear(ringbuf_t *r) {
|
|||
}
|
||||
|
||||
// Number of free slots that can be written.
|
||||
size_t ringbuf_free(ringbuf_t *r) {
|
||||
size_t ringbuf_num_empty(ringbuf_t *r) {
|
||||
return (r->size + r->iget - r->iput - 1) % r->size;
|
||||
}
|
||||
|
||||
// Number of bytes available to read.
|
||||
size_t ringbuf_avail(ringbuf_t *r) {
|
||||
size_t ringbuf_num_filled(ringbuf_t *r) {
|
||||
return (r->size + r->iput - r->iget) % r->size;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,12 +45,13 @@ typedef struct _ringbuf_t {
|
|||
// ringbuf_t buf = {buf_array, sizeof(buf_array)};
|
||||
|
||||
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived);
|
||||
void ringbuf_free(ringbuf_t *r);
|
||||
size_t ringbuf_capacity(ringbuf_t *r);
|
||||
int ringbuf_get(ringbuf_t *r);
|
||||
int ringbuf_put(ringbuf_t *r, uint8_t v);
|
||||
void ringbuf_clear(ringbuf_t *r);
|
||||
size_t ringbuf_free(ringbuf_t *r);
|
||||
size_t ringbuf_avail(ringbuf_t *r);
|
||||
size_t ringbuf_num_empty(ringbuf_t *r);
|
||||
size_t ringbuf_num_filled(ringbuf_t *r);
|
||||
size_t ringbuf_put_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
|
||||
size_t ringbuf_get_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@ bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size,
|
|||
}
|
||||
|
||||
mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) {
|
||||
while (ringbuf_avail(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
|
||||
while (ringbuf_num_filled(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
if (ringbuf_avail(&self->buf) == 0 || mp_hal_is_interrupted()) {
|
||||
if (ringbuf_num_filled(&self->buf) == 0 || mp_hal_is_interrupted()) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
|
|||
uint16_t len) {
|
||||
int32_t packet_size = sizeof(uint8_t) + sizeof(ticks_ms) + sizeof(rssi) + NUM_BLEIO_ADDRESS_BYTES +
|
||||
sizeof(addr_type) + sizeof(len) + len;
|
||||
int32_t empty_space = self->buf.size - ringbuf_avail(&self->buf);
|
||||
int32_t empty_space = self->buf.size - ringbuf_num_filled(&self->buf);
|
||||
if (packet_size >= empty_space) {
|
||||
// We can't fit the packet so skip it.
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue