ringbuf tested

This commit is contained in:
Dan Halbert 2020-04-21 22:40:12 -04:00
parent 77cd93ac2d
commit fbc8719fad
11 changed files with 59 additions and 65 deletions

View File

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

View File

@ -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;

View File

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

View File

@ -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) {

View File

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

View File

@ -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;

View File

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

View File

@ -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;

View File

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

View File

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

View File

@ -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;