ringbuf cleanup
This commit is contained in:
parent
32d8dd425f
commit
ea15a9118a
@ -93,6 +93,7 @@ bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer
|
|||||||
void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) {
|
void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) {
|
||||||
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
||||||
bleio_characteristic_clear_observer(self->characteristic);
|
bleio_characteristic_clear_observer(self->characteristic);
|
||||||
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,13 +37,13 @@
|
|||||||
#include "supervisor/shared/tick.h"
|
#include "supervisor/shared/tick.h"
|
||||||
|
|
||||||
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
|
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
|
||||||
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
|
if (len + sizeof(uint16_t) > ringbuf_size(&self->ringbuf)) {
|
||||||
// This shouldn't happen.
|
// This shouldn't happen.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Push all the data onto the ring buffer.
|
// Push all the data onto the ring buffer.
|
||||||
// Make room for the new value by dropping the oldest packets first.
|
// Make room for the new value by dropping the oldest packets first.
|
||||||
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
while (ringbuf_size(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||||
uint16_t packet_length;
|
uint16_t packet_length;
|
||||||
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
||||||
for (uint16_t i = 0; i < packet_length; i++) {
|
for (uint16_t i = 0; i < packet_length; i++) {
|
||||||
@ -264,5 +264,6 @@ bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
|
|||||||
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
||||||
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
||||||
bleio_characteristic_clear_observer(self->characteristic);
|
bleio_characteristic_clear_observer(self->characteristic);
|
||||||
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,9 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
self->sigint_enabled = sigint_enabled;
|
self->sigint_enabled = sigint_enabled;
|
||||||
|
|
||||||
if (rx != NULL) {
|
if (rx != NULL) {
|
||||||
|
// Use the provided buffer when given.
|
||||||
if (receiver_buffer != NULL) {
|
if (receiver_buffer != NULL) {
|
||||||
|
ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size);
|
||||||
self->ringbuf = (ringbuf_t) { receiver_buffer, receiver_buffer_size };
|
self->ringbuf = (ringbuf_t) { receiver_buffer, receiver_buffer_size };
|
||||||
} else {
|
} else {
|
||||||
// Initially allocate the UART's buffer in the long-lived part of the
|
// Initially allocate the UART's buffer in the long-lived part of the
|
||||||
@ -217,7 +219,6 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
// self->buffer, so do it manually. (However, as long as internal
|
// self->buffer, so do it manually. (However, as long as internal
|
||||||
// pointers like this are NOT moved, allocating the buffer
|
// pointers like this are NOT moved, allocating the buffer
|
||||||
// in the long-lived pool is not strictly necessary)
|
// in the long-lived pool is not strictly necessary)
|
||||||
// (This is a macro.)
|
|
||||||
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
||||||
m_malloc_fail(receiver_buffer_size);
|
m_malloc_fail(receiver_buffer_size);
|
||||||
}
|
}
|
||||||
@ -337,7 +338,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||||||
pl011->CR = 0;
|
pl011->CR = 0;
|
||||||
}
|
}
|
||||||
active_uart[self->uart_id] = NULL;
|
active_uart[self->uart_id] = NULL;
|
||||||
ringbuf_free(&self->ringbuf);
|
ringbuf_deinit(&self->ringbuf);
|
||||||
uart_status[self->uart_id] = STATUS_FREE;
|
uart_status[self->uart_id] = STATUS_FREE;
|
||||||
common_hal_reset_pin(self->tx_pin);
|
common_hal_reset_pin(self->tx_pin);
|
||||||
common_hal_reset_pin(self->rx_pin);
|
common_hal_reset_pin(self->rx_pin);
|
||||||
|
@ -36,11 +36,11 @@ typedef struct {
|
|||||||
const mcu_pin_obj_t *rx_pin;
|
const mcu_pin_obj_t *rx_pin;
|
||||||
const mcu_pin_obj_t *cts_pin;
|
const mcu_pin_obj_t *cts_pin;
|
||||||
const mcu_pin_obj_t *rts_pin;
|
const mcu_pin_obj_t *rts_pin;
|
||||||
uint8_t uart_id;
|
|
||||||
uint32_t baudrate;
|
uint32_t baudrate;
|
||||||
uint32_t timeout_ms;
|
uint32_t timeout_ms;
|
||||||
bool sigint_enabled;
|
|
||||||
ringbuf_t ringbuf;
|
ringbuf_t ringbuf;
|
||||||
|
bool sigint_enabled;
|
||||||
|
uint8_t uart_id;
|
||||||
} busio_uart_obj_t;
|
} busio_uart_obj_t;
|
||||||
|
|
||||||
extern void reset_uart(void);
|
extern void reset_uart(void);
|
||||||
|
@ -72,11 +72,7 @@ void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buff
|
|||||||
void *static_handler_entry) {
|
void *static_handler_entry) {
|
||||||
self->characteristic = characteristic;
|
self->characteristic = characteristic;
|
||||||
self->timeout_ms = timeout * 1000;
|
self->timeout_ms = timeout * 1000;
|
||||||
|
ringbuf_init(&self->ringbuf, buffer, buffer_size);
|
||||||
self->ringbuf.buf = (uint8_t *)buffer;
|
|
||||||
self->ringbuf.size = buffer_size;
|
|
||||||
self->ringbuf.iget = 0;
|
|
||||||
self->ringbuf.iput = 0;
|
|
||||||
|
|
||||||
if (static_handler_entry != NULL) {
|
if (static_handler_entry != NULL) {
|
||||||
ble_event_add_handler_entry((ble_event_handler_entry_t *)static_handler_entry, characteristic_buffer_on_ble_evt, self);
|
ble_event_add_handler_entry((ble_event_handler_entry_t *)static_handler_entry, characteristic_buffer_on_ble_evt, self);
|
||||||
@ -131,6 +127,7 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o
|
|||||||
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
||||||
ble_event_remove_handler(characteristic_buffer_on_ble_evt, self);
|
ble_event_remove_handler(characteristic_buffer_on_ble_evt, self);
|
||||||
self->characteristic = NULL;
|
self->characteristic = NULL;
|
||||||
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@
|
|||||||
|
|
||||||
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, const struct os_mbuf *mbuf) {
|
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, const struct os_mbuf *mbuf) {
|
||||||
size_t len = OS_MBUF_PKTLEN(mbuf);
|
size_t len = OS_MBUF_PKTLEN(mbuf);
|
||||||
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
|
if (len + sizeof(uint16_t) > ringbuf_size(&self->ringbuf)) {
|
||||||
// This shouldn't happen but can if our buffer size was much smaller than
|
// This shouldn't happen but can if our buffer size was much smaller than
|
||||||
// the writes the client actually makes.
|
// the writes the client actually makes.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make room for the new value by dropping the oldest packets first.
|
// Make room for the new value by dropping the oldest packets first.
|
||||||
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
while (ringbuf_size(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||||
uint16_t packet_length;
|
uint16_t packet_length;
|
||||||
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
||||||
for (uint16_t i = 0; i < packet_length; i++) {
|
for (uint16_t i = 0; i < packet_length; i++) {
|
||||||
@ -164,10 +164,7 @@ void _common_hal_bleio_packet_buffer_construct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
self->ringbuf.buf = (uint8_t *)incoming_buffer;
|
ringbuf_init(&self->ringbuf, (uint8_t *)incoming_buffer, incoming_buffer_size);
|
||||||
self->ringbuf.size = incoming_buffer_size;
|
|
||||||
self->ringbuf.iget = 0;
|
|
||||||
self->ringbuf.iput = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->packet_queued = false;
|
self->packet_queued = false;
|
||||||
@ -219,8 +216,7 @@ void common_hal_bleio_packet_buffer_construct(
|
|||||||
size_t incoming_buffer_size = 0;
|
size_t incoming_buffer_size = 0;
|
||||||
uint32_t *incoming_buffer = NULL;
|
uint32_t *incoming_buffer = NULL;
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size);
|
ringbuf_init(&self->ringbuf, (uint8_t *)incoming_buffer, incoming_buffer_size);
|
||||||
incoming_buffer = m_malloc(incoming_buffer_size, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *outgoing1 = NULL;
|
uint32_t *outgoing1 = NULL;
|
||||||
@ -414,5 +410,6 @@ bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
|
|||||||
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
||||||
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
||||||
ble_event_remove_handler(packet_buffer_on_ble_client_evt, self);
|
ble_event_remove_handler(packet_buffer_on_ble_client_evt, self);
|
||||||
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,10 +90,7 @@ void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buff
|
|||||||
self->characteristic = characteristic;
|
self->characteristic = characteristic;
|
||||||
self->timeout_ms = timeout * 1000;
|
self->timeout_ms = timeout * 1000;
|
||||||
|
|
||||||
self->ringbuf.buf = (uint8_t *)buffer;
|
ringbuf_init(&self->ringbuf, buffer, buffer_size);
|
||||||
self->ringbuf.size = buffer_size;
|
|
||||||
self->ringbuf.iget = 0;
|
|
||||||
self->ringbuf.iput = 0;
|
|
||||||
|
|
||||||
if (static_handler_entry != NULL) {
|
if (static_handler_entry != NULL) {
|
||||||
ble_drv_add_event_handler_entry((ble_drv_evt_handler_entry_t *)static_handler_entry, characteristic_buffer_on_ble_evt, self);
|
ble_drv_add_event_handler_entry((ble_drv_evt_handler_entry_t *)static_handler_entry, characteristic_buffer_on_ble_evt, self);
|
||||||
@ -159,6 +156,7 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o
|
|||||||
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
if (!common_hal_bleio_characteristic_buffer_deinited(self)) {
|
||||||
ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self);
|
ble_drv_remove_event_handler(characteristic_buffer_on_ble_evt, self);
|
||||||
self->characteristic = NULL;
|
self->characteristic = NULL;
|
||||||
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#include "supervisor/shared/bluetooth/serial.h"
|
#include "supervisor/shared/bluetooth/serial.h"
|
||||||
|
|
||||||
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
|
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
|
||||||
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
|
if (len + sizeof(uint16_t) > ringbuf_size(&self->ringbuf)) {
|
||||||
// This shouldn't happen but can if our buffer size was much smaller than
|
// This shouldn't happen but can if our buffer size was much smaller than
|
||||||
// the writes the client actually makes.
|
// the writes the client actually makes.
|
||||||
return;
|
return;
|
||||||
@ -52,7 +52,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
|
|||||||
uint8_t is_nested_critical_region;
|
uint8_t is_nested_critical_region;
|
||||||
sd_nvic_critical_region_enter(&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.
|
// Make room for the new value by dropping the oldest packets first.
|
||||||
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
while (ringbuf_size(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
|
||||||
uint16_t packet_length;
|
uint16_t packet_length;
|
||||||
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t));
|
||||||
for (uint16_t i = 0; i < packet_length; i++) {
|
for (uint16_t i = 0; i < packet_length; i++) {
|
||||||
@ -233,10 +233,7 @@ void _common_hal_bleio_packet_buffer_construct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
self->ringbuf.buf = (uint8_t *)incoming_buffer;
|
ringbuf_init(&self->ringbuf, (uint8_t *)incoming_buffer, incoming_buffer_size);
|
||||||
self->ringbuf.size = incoming_buffer_size;
|
|
||||||
self->ringbuf.iget = 0;
|
|
||||||
self->ringbuf.iput = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self->packet_queued = false;
|
self->packet_queued = false;
|
||||||
@ -502,7 +499,9 @@ bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
|
||||||
|
|
||||||
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
if (!common_hal_bleio_packet_buffer_deinited(self)) {
|
||||||
ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self);
|
ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self);
|
||||||
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,24 +213,20 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
|
|
||||||
// Init buffer for rx
|
// Init buffer for rx
|
||||||
if (rx != NULL) {
|
if (rx != NULL) {
|
||||||
self->allocated_ringbuf = true;
|
|
||||||
// Use the provided buffer when given.
|
// Use the provided buffer when given.
|
||||||
if (receiver_buffer != NULL) {
|
if (receiver_buffer != NULL) {
|
||||||
self->ringbuf.buf = receiver_buffer;
|
ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size);
|
||||||
self->ringbuf.size = receiver_buffer_size - 1;
|
} else {
|
||||||
self->ringbuf.iput = 0;
|
|
||||||
self->ringbuf.iget = 0;
|
|
||||||
self->allocated_ringbuf = false;
|
|
||||||
// Initially allocate the UART's buffer in the long-lived part of the
|
// Initially allocate the UART's buffer in the long-lived part of the
|
||||||
// heap. UARTs are generally long-lived objects, but the "make long-
|
// heap. UARTs are generally long-lived objects, but the "make long-
|
||||||
// lived" machinery is incapable of moving internal pointers like
|
// lived" machinery is incapable of moving internal pointers like
|
||||||
// self->buffer, so do it manually. (However, as long as internal
|
// self->buffer, so do it manually. (However, as long as internal
|
||||||
// pointers like this are NOT moved, allocating the buffer
|
// pointers like this are NOT moved, allocating the buffer
|
||||||
// in the long-lived pool is not strictly necessary)
|
// in the long-lived pool is not strictly necessary)
|
||||||
// (This is a macro.)
|
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
||||||
} else if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
nrfx_uarte_uninit(self->uarte);
|
||||||
nrfx_uarte_uninit(self->uarte);
|
m_malloc_fail(receiver_buffer_size);
|
||||||
m_malloc_fail(receiver_buffer_size);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self->rx_pin_number = rx->number;
|
self->rx_pin_number = rx->number;
|
||||||
@ -282,9 +278,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||||||
self->rx_pin_number = NO_PIN;
|
self->rx_pin_number = NO_PIN;
|
||||||
self->rts_pin_number = NO_PIN;
|
self->rts_pin_number = NO_PIN;
|
||||||
self->cts_pin_number = NO_PIN;
|
self->cts_pin_number = NO_PIN;
|
||||||
if (self->allocated_ringbuf) {
|
ringbuf_deinit(&self->ringbuf);
|
||||||
ringbuf_free(&self->ringbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < MP_ARRAY_SIZE(nrfx_uartes); i++) {
|
for (size_t i = 0; i < MP_ARRAY_SIZE(nrfx_uartes); i++) {
|
||||||
if (self->uarte == &nrfx_uartes[i]) {
|
if (self->uarte == &nrfx_uartes[i]) {
|
||||||
@ -305,7 +299,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
|
|||||||
|
|
||||||
// check removed to reduce code size
|
// check removed to reduce code size
|
||||||
/*
|
/*
|
||||||
if (len > ringbuf_capacity(&self->ringbuf)) {
|
if (len > ringbuf_size(&self->ringbuf)) {
|
||||||
mp_raise_ValueError(translate("Reading >receiver_buffer_size bytes is not supported"));
|
mp_raise_ValueError(translate("Reading >receiver_buffer_size bytes is not supported"));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -44,7 +44,6 @@ typedef struct {
|
|||||||
ringbuf_t ringbuf;
|
ringbuf_t ringbuf;
|
||||||
uint8_t rx_char; // EasyDMA buf
|
uint8_t rx_char; // EasyDMA buf
|
||||||
bool rx_paused; // set by irq if no space in rbuf
|
bool rx_paused; // set by irq if no space in rbuf
|
||||||
bool allocated_ringbuf;
|
|
||||||
|
|
||||||
uint8_t tx_pin_number;
|
uint8_t tx_pin_number;
|
||||||
uint8_t rx_pin_number;
|
uint8_t rx_pin_number;
|
||||||
|
@ -155,27 +155,33 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
uart_set_hw_flow(self->uart, (cts != NULL), (rts != NULL));
|
uart_set_hw_flow(self->uart, (cts != NULL), (rts != NULL));
|
||||||
|
|
||||||
if (rx != NULL) {
|
if (rx != NULL) {
|
||||||
// Initially allocate the UART's buffer in the long-lived part of the
|
// Use the provided buffer when given.
|
||||||
// heap. UARTs are generally long-lived objects, but the "make long-
|
if (receiver_buffer != NULL) {
|
||||||
// lived" machinery is incapable of moving internal pointers like
|
ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size);
|
||||||
// self->buffer, so do it manually. (However, as long as internal
|
|
||||||
// pointers like this are NOT moved, allocating the buffer
|
|
||||||
// in the long-lived pool is not strictly necessary)
|
|
||||||
// (This is a macro.)
|
|
||||||
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
|
||||||
m_malloc_fail(receiver_buffer_size);
|
|
||||||
}
|
|
||||||
active_uarts[uart_id] = self;
|
|
||||||
if (uart_id == 1) {
|
|
||||||
self->uart_irq_id = UART1_IRQ;
|
|
||||||
irq_set_exclusive_handler(self->uart_irq_id, uart1_callback);
|
|
||||||
} else {
|
} else {
|
||||||
self->uart_irq_id = UART0_IRQ;
|
// Initially allocate the UART's buffer in the long-lived part of the
|
||||||
irq_set_exclusive_handler(self->uart_irq_id, uart0_callback);
|
// heap. UARTs are generally long-lived objects, but the "make long-
|
||||||
|
// lived" machinery is incapable of moving internal pointers like
|
||||||
|
// self->buffer, so do it manually. (However, as long as internal
|
||||||
|
// pointers like this are NOT moved, allocating the buffer
|
||||||
|
// in the long-lived pool is not strictly necessary)
|
||||||
|
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
||||||
|
uart_deinit(self->uart);
|
||||||
|
m_malloc_fail(receiver_buffer_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
irq_set_enabled(self->uart_irq_id, true);
|
|
||||||
uart_set_irq_enables(self->uart, true /* rx has data */, false /* tx needs data */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
active_uarts[uart_id] = self;
|
||||||
|
if (uart_id == 1) {
|
||||||
|
self->uart_irq_id = UART1_IRQ;
|
||||||
|
irq_set_exclusive_handler(self->uart_irq_id, uart1_callback);
|
||||||
|
} else {
|
||||||
|
self->uart_irq_id = UART0_IRQ;
|
||||||
|
irq_set_exclusive_handler(self->uart_irq_id, uart0_callback);
|
||||||
|
}
|
||||||
|
irq_set_enabled(self->uart_irq_id, true);
|
||||||
|
uart_set_irq_enables(self->uart, true /* rx has data */, false /* tx needs data */);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
|
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
|
||||||
@ -187,7 +193,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uart_deinit(self->uart);
|
uart_deinit(self->uart);
|
||||||
ringbuf_free(&self->ringbuf);
|
ringbuf_deinit(&self->ringbuf);
|
||||||
active_uarts[self->uart_id] = NULL;
|
active_uarts[self->uart_id] = NULL;
|
||||||
uart_status[self->uart_id] = STATUS_FREE;
|
uart_status[self->uart_id] = STATUS_FREE;
|
||||||
reset_pin_number(self->tx_pin);
|
reset_pin_number(self->tx_pin);
|
||||||
|
@ -214,9 +214,16 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
|||||||
|
|
||||||
// Init buffer for rx and claim pins
|
// Init buffer for rx and claim pins
|
||||||
if (self->rx != NULL) {
|
if (self->rx != NULL) {
|
||||||
|
// Use the provided buffer when given.
|
||||||
if (receiver_buffer != NULL) {
|
if (receiver_buffer != NULL) {
|
||||||
self->ringbuf = (ringbuf_t) { receiver_buffer, receiver_buffer_size };
|
ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size);
|
||||||
} else {
|
} else {
|
||||||
|
// Initially allocate the UART's buffer in the long-lived part of the
|
||||||
|
// heap. UARTs are generally long-lived objects, but the "make long-
|
||||||
|
// lived" machinery is incapable of moving internal pointers like
|
||||||
|
// self->buffer, so do it manually. (However, as long as internal
|
||||||
|
// pointers like this are NOT moved, allocating the buffer
|
||||||
|
// in the long-lived pool is not strictly necessary)
|
||||||
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
|
||||||
m_malloc_fail(receiver_buffer_size);
|
m_malloc_fail(receiver_buffer_size);
|
||||||
}
|
}
|
||||||
@ -281,7 +288,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
|||||||
self->rx = NULL;
|
self->rx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ringbuf_free(&self->ringbuf);
|
ringbuf_deinit(&self->ringbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
|
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
|
||||||
|
@ -526,7 +526,9 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||||||
|
|
||||||
// ringbuf
|
// ringbuf
|
||||||
{
|
{
|
||||||
byte buf[100];
|
#define RINGBUF_SIZE 99
|
||||||
|
|
||||||
|
byte buf[RINGBUF_SIZE];
|
||||||
ringbuf_t ringbuf;
|
ringbuf_t ringbuf;
|
||||||
ringbuf_init(&ringbuf, &buf[0], sizeof(buf));
|
ringbuf_init(&ringbuf, &buf[0], sizeof(buf));
|
||||||
|
|
||||||
@ -546,7 +548,7 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||||||
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
||||||
|
|
||||||
// Two-byte put with full ringbuf.
|
// Two-byte put with full ringbuf.
|
||||||
for (int i = 0; i < 99; ++i) {
|
for (int i = 0; i < RINGBUF_SIZE; ++i) {
|
||||||
ringbuf_put(&ringbuf, i);
|
ringbuf_put(&ringbuf, i);
|
||||||
}
|
}
|
||||||
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
||||||
@ -558,16 +560,15 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||||||
ringbuf_get(&ringbuf);
|
ringbuf_get(&ringbuf);
|
||||||
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
||||||
mp_printf(&mp_plat_print, "%d\n", ringbuf_put16(&ringbuf, 0xcc99));
|
mp_printf(&mp_plat_print, "%d\n", ringbuf_put16(&ringbuf, 0xcc99));
|
||||||
for (int i = 0; i < 97; ++i) {
|
for (int i = 0; i < RINGBUF_SIZE - 2; ++i) {
|
||||||
ringbuf_get(&ringbuf);
|
ringbuf_get(&ringbuf);
|
||||||
}
|
}
|
||||||
mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf));
|
mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf));
|
||||||
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf));
|
||||||
|
|
||||||
// Two-byte put with wrap around on first byte:
|
// Two-byte put with wrap around on first byte:
|
||||||
ringbuf.iput = 0;
|
ringbuf_clear(&ringbuf);
|
||||||
ringbuf.iget = 0;
|
for (int i = 0; i < RINGBUF_SIZE; ++i) {
|
||||||
for (int i = 0; i < 99; ++i) {
|
|
||||||
ringbuf_put(&ringbuf, i);
|
ringbuf_put(&ringbuf, i);
|
||||||
ringbuf_get(&ringbuf);
|
ringbuf_get(&ringbuf);
|
||||||
}
|
}
|
||||||
@ -575,9 +576,8 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||||||
mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf));
|
mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf));
|
||||||
|
|
||||||
// Two-byte put with wrap around on second byte:
|
// Two-byte put with wrap around on second byte:
|
||||||
ringbuf.iput = 0;
|
ringbuf_clear(&ringbuf);
|
||||||
ringbuf.iget = 0;
|
for (int i = 0; i < RINGBUF_SIZE - 1; ++i) {
|
||||||
for (int i = 0; i < 98; ++i) {
|
|
||||||
ringbuf_put(&ringbuf, i);
|
ringbuf_put(&ringbuf, i);
|
||||||
ringbuf_get(&ringbuf);
|
ringbuf_get(&ringbuf);
|
||||||
}
|
}
|
||||||
@ -585,13 +585,11 @@ STATIC mp_obj_t extra_coverage(void) {
|
|||||||
mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf));
|
mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf));
|
||||||
|
|
||||||
// Two-byte get from empty ringbuf.
|
// Two-byte get from empty ringbuf.
|
||||||
ringbuf.iput = 0;
|
ringbuf_clear(&ringbuf);
|
||||||
ringbuf.iget = 0;
|
|
||||||
mp_printf(&mp_plat_print, "%d\n", ringbuf_get16(&ringbuf));
|
mp_printf(&mp_plat_print, "%d\n", ringbuf_get16(&ringbuf));
|
||||||
|
|
||||||
// Two-byte get from ringbuf with one byte available.
|
// Two-byte get from ringbuf with one byte available.
|
||||||
ringbuf.iput = 0;
|
ringbuf_clear(&ringbuf);
|
||||||
ringbuf.iget = 0;
|
|
||||||
ringbuf_put(&ringbuf, 0xaa);
|
ringbuf_put(&ringbuf, 0xaa);
|
||||||
mp_printf(&mp_plat_print, "%d\n", ringbuf_get16(&ringbuf));
|
mp_printf(&mp_plat_print, "%d\n", ringbuf_get16(&ringbuf));
|
||||||
}
|
}
|
||||||
|
120
py/ringbuf.c
120
py/ringbuf.c
@ -27,86 +27,85 @@
|
|||||||
|
|
||||||
#include "ringbuf.h"
|
#include "ringbuf.h"
|
||||||
|
|
||||||
bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t capacity) {
|
bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t size) {
|
||||||
r->buf = buf;
|
r->buf = buf;
|
||||||
r->size = capacity;
|
r->size = size;
|
||||||
r->iget = r->iput = 0;
|
r->used = 0;
|
||||||
|
r->next_read = 0;
|
||||||
|
r->next_write = 0;
|
||||||
return r->buf != NULL;
|
return r->buf != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic initialization. This should be accessible from a root pointer.
|
// Dynamic initialization. This should be accessible from a root pointer..
|
||||||
// capacity is the number of bytes the ring buffer can hold. The actual
|
bool ringbuf_alloc(ringbuf_t *r, size_t size, bool long_lived) {
|
||||||
// size of the buffer is one greater than that, due to how the buffer
|
bool result = ringbuf_init(r, gc_alloc(size, false, long_lived), size);
|
||||||
// handles empty and full statuses.
|
return result;
|
||||||
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived) {
|
|
||||||
r->buf = gc_alloc(capacity + 1, false, long_lived);
|
|
||||||
r->size = capacity + 1;
|
|
||||||
r->iget = r->iput = 0;
|
|
||||||
return r->buf != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ringbuf_free(ringbuf_t *r) {
|
void ringbuf_deinit(ringbuf_t *r) {
|
||||||
// Free buf by letting gc take care of it. If the VM has finished already,
|
// Free buf by doing nothing and letting gc take care of it. If the VM has finished already,
|
||||||
// this will be safe.
|
// this will be safe.
|
||||||
r->buf = (uint8_t *)NULL;
|
r->buf = (uint8_t *)NULL;
|
||||||
r->size = 0;
|
r->size = 0;
|
||||||
ringbuf_clear(r);
|
ringbuf_clear(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ringbuf_capacity(ringbuf_t *r) {
|
size_t ringbuf_size(ringbuf_t *r) {
|
||||||
return r->size - 1;
|
return r->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns -1 if buffer is empty, else returns byte fetched.
|
// Return -1 if buffer is empty, else return byte fetched.
|
||||||
int ringbuf_get(ringbuf_t *r) {
|
int ringbuf_get(ringbuf_t *r) {
|
||||||
if (r->iget == r->iput) {
|
if (r->used < 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint8_t v = r->buf[r->iget++];
|
uint8_t v = r->buf[r->next_read];
|
||||||
if (r->iget >= r->size) {
|
r->next_read++;
|
||||||
r->iget = 0;
|
if (r->next_read >= r->size) {
|
||||||
|
r->next_read = 0;
|
||||||
}
|
}
|
||||||
|
r->used--;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ringbuf_get16(ringbuf_t *r) {
|
int ringbuf_get16(ringbuf_t *r) {
|
||||||
int v = ringbuf_peek16(r);
|
if (r->used < 2) {
|
||||||
if (v == -1) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
r->iget += 2;
|
|
||||||
if (r->iget >= r->size) {
|
|
||||||
r->iget -= r->size;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns -1 if no room in buffer, else returns 0.
|
|
||||||
int ringbuf_put(ringbuf_t *r, uint8_t v) {
|
|
||||||
uint32_t iput_new = r->iput + 1;
|
|
||||||
if (iput_new >= r->size) {
|
|
||||||
iput_new = 0;
|
|
||||||
}
|
|
||||||
if (iput_new == r->iget) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
r->buf[r->iput] = v;
|
|
||||||
r->iput = iput_new;
|
int high_byte = ringbuf_get(r);
|
||||||
|
int low_byte = ringbuf_get(r);
|
||||||
|
return (high_byte << 8) | low_byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return -1 if no room in buffer, else return 0.
|
||||||
|
int ringbuf_put(ringbuf_t *r, uint8_t v) {
|
||||||
|
if (r->used >= r->size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
r->buf[r->next_write] = v;
|
||||||
|
r->next_write++;
|
||||||
|
if (r->next_write >= r->size) {
|
||||||
|
r->next_write = 0;
|
||||||
|
}
|
||||||
|
r->used++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ringbuf_clear(ringbuf_t *r) {
|
void ringbuf_clear(ringbuf_t *r) {
|
||||||
r->iput = r->iget = 0;
|
r->next_write = 0;
|
||||||
|
r->next_read = 0;
|
||||||
|
r->used = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of free slots that can be written.
|
// Number of free slots that can be written.
|
||||||
size_t ringbuf_num_empty(ringbuf_t *r) {
|
size_t ringbuf_num_empty(ringbuf_t *r) {
|
||||||
return (r->size + r->iget - r->iput - 1) % r->size;
|
return r->size - r->used;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of bytes available to read.
|
// Number of bytes available to read.
|
||||||
size_t ringbuf_num_filled(ringbuf_t *r) {
|
size_t ringbuf_num_filled(ringbuf_t *r) {
|
||||||
return (r->size + r->iput - r->iget) % r->size;
|
return r->used;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the ring buffer fills up, not all bytes will be written.
|
// If the ring buffer fills up, not all bytes will be written.
|
||||||
@ -134,37 +133,12 @@ size_t ringbuf_get_n(ringbuf_t *r, uint8_t *buf, size_t bufsize) {
|
|||||||
return bufsize;
|
return bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ringbuf_peek16(ringbuf_t *r) {
|
|
||||||
if (r->iget == r->iput) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
uint32_t iget_a = r->iget + 1;
|
|
||||||
if (iget_a == r->size) {
|
|
||||||
iget_a = 0;
|
|
||||||
}
|
|
||||||
if (iget_a == r->iput) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (r->buf[r->iget] << 8) | (r->buf[iget_a]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ringbuf_put16(ringbuf_t *r, uint16_t v) {
|
int ringbuf_put16(ringbuf_t *r, uint16_t v) {
|
||||||
uint32_t iput_a = r->iput + 1;
|
if (r->size - r->used < 2) {
|
||||||
if (iput_a == r->size) {
|
|
||||||
iput_a = 0;
|
|
||||||
}
|
|
||||||
if (iput_a == r->iget) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uint32_t iput_b = iput_a + 1;
|
|
||||||
if (iput_b == r->size) {
|
ringbuf_put(r, (v >> 8) & 0xff);
|
||||||
iput_b = 0;
|
ringbuf_put(r, v & 0xff);
|
||||||
}
|
|
||||||
if (iput_b == r->iget) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
r->buf[r->iput] = (v >> 8) & 0xff;
|
|
||||||
r->buf[iput_a] = v & 0xff;
|
|
||||||
r->iput = iput_b;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
23
py/ringbuf.h
23
py/ringbuf.h
@ -33,19 +33,23 @@
|
|||||||
|
|
||||||
typedef struct _ringbuf_t {
|
typedef struct _ringbuf_t {
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
// Allocated size; capacity is one less. Don't reference this directly.
|
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t iget;
|
uint32_t used;
|
||||||
uint32_t iput;
|
uint32_t next_read;
|
||||||
|
uint32_t next_write;
|
||||||
} ringbuf_t;
|
} ringbuf_t;
|
||||||
|
|
||||||
// Note that the capacity of the buffer is N-1!
|
// For static initialization with an existing buffer, use ringbuf_init().
|
||||||
|
|
||||||
// For static initialization use ringbuf_init()
|
|
||||||
bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t capacity);
|
bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t capacity);
|
||||||
|
|
||||||
|
// For allocation of a buffer on the heap, use ringbuf_alloc().
|
||||||
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived);
|
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);
|
// Mark ringbuf as no longer in use, and allow any heap storage to be freed by gc.
|
||||||
|
void ringbuf_deinit(ringbuf_t *r);
|
||||||
|
|
||||||
|
// Note: Ringbuf operations are not atomic.
|
||||||
|
size_t ringbuf_size(ringbuf_t *r);
|
||||||
int ringbuf_get(ringbuf_t *r);
|
int ringbuf_get(ringbuf_t *r);
|
||||||
int ringbuf_put(ringbuf_t *r, uint8_t v);
|
int ringbuf_put(ringbuf_t *r, uint8_t v);
|
||||||
void ringbuf_clear(ringbuf_t *r);
|
void ringbuf_clear(ringbuf_t *r);
|
||||||
@ -54,9 +58,8 @@ size_t ringbuf_num_filled(ringbuf_t *r);
|
|||||||
size_t ringbuf_put_n(ringbuf_t *r, const uint8_t *buf, size_t bufsize);
|
size_t ringbuf_put_n(ringbuf_t *r, const uint8_t *buf, size_t bufsize);
|
||||||
size_t ringbuf_get_n(ringbuf_t *r, uint8_t *buf, size_t bufsize);
|
size_t ringbuf_get_n(ringbuf_t *r, uint8_t *buf, size_t bufsize);
|
||||||
|
|
||||||
// Note: big-endian. No-op if not enough room available for both bytes.
|
// Note: big-endian. Return -1 if can't read or write two bytes.
|
||||||
int ringbuf_get16(ringbuf_t *r);
|
int ringbuf_get16(ringbuf_t *r);
|
||||||
int ringbuf_peek16(ringbuf_t *r);
|
|
||||||
int ringbuf_put16(ringbuf_t *r, uint16_t v);
|
int ringbuf_put16(ringbuf_t *r, uint16_t v);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_PY_RINGBUF_H
|
#endif // MICROPY_INCLUDED_PY_RINGBUF_H
|
||||||
|
Loading…
Reference in New Issue
Block a user