Skip to content

Commit f3e50b9

Browse files
authored
Merge pull request #1581 from dhalbert/ble-drv-root-pointer
Use critical section, not lock, in CharacteristicBuffer; use a root pointer for ble_drv list
2 parents 0dc2600 + 99da3b9 commit f3e50b9

File tree

6 files changed

+41
-36
lines changed

6 files changed

+41
-36
lines changed

ports/atmel-samd/mpconfigport.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,10 @@
7979

8080
#include "peripherals/samd/dma.h"
8181

82+
#include "py/circuitpy_mpconfig.h"
83+
8284
#define MICROPY_PORT_ROOT_POINTERS \
8385
CIRCUITPY_COMMON_ROOT_POINTERS \
84-
mp_obj_t playing_audio[AUDIO_DMA_CHANNEL_COUNT] \
85-
;
86-
87-
#include "py/circuitpy_mpconfig.h"
86+
mp_obj_t playing_audio[AUDIO_DMA_CHANNEL_COUNT];
8887

8988
#endif // __INCLUDED_MPCONFIGPORT_H

ports/nrf/bluetooth/ble_drv.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,20 @@
3535
#include "nrf_soc.h"
3636
#include "nrfx_power.h"
3737
#include "py/misc.h"
38+
#include "py/mpstate.h"
3839

3940
nrf_nvic_state_t nrf_nvic_state = { 0 };
4041

4142
__attribute__((aligned(4)))
4243
static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)];
4344

44-
typedef struct event_handler {
45-
struct event_handler *next;
46-
void *param;
47-
ble_drv_evt_handler_t func;
48-
} event_handler_t;
49-
50-
static event_handler_t *m_event_handlers = NULL;
51-
5245
void ble_drv_reset() {
5346
// Linked list items will be gc'd.
54-
m_event_handlers = NULL;
47+
MP_STATE_VM(ble_drv_evt_handler_entries) = NULL;
5548
}
5649

5750
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
58-
event_handler_t *it = m_event_handlers;
51+
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
5952
while (it != NULL) {
6053
// If event handler and its corresponding param are already on the list, don't add again.
6154
if ((it->func == func) && (it->param == param)) {
@@ -65,17 +58,17 @@ void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
6558
}
6659

6760
// Add a new handler to the front of the list
68-
event_handler_t *handler = m_new_ll(event_handler_t, 1);
69-
handler->next = m_event_handlers;
61+
ble_drv_evt_handler_entry_t *handler = m_new_ll(ble_drv_evt_handler_entry_t, 1);
62+
handler->next = MP_STATE_VM(ble_drv_evt_handler_entries);
7063
handler->param = param;
7164
handler->func = func;
7265

73-
m_event_handlers = handler;
66+
MP_STATE_VM(ble_drv_evt_handler_entries) = handler;
7467
}
7568

7669
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) {
77-
event_handler_t *it = m_event_handlers;
78-
event_handler_t **prev = &m_event_handlers;
70+
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
71+
ble_drv_evt_handler_entry_t **prev = &MP_STATE_VM(ble_drv_evt_handler_entries);
7972
while (it != NULL) {
8073
if ((it->func == func) && (it->param == param)) {
8174
// Splice out the matching handler.
@@ -122,7 +115,7 @@ void SD_EVT_IRQHandler(void) {
122115
break;
123116
}
124117

125-
event_handler_t *it = m_event_handlers;
118+
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
126119
while (it != NULL) {
127120
it->func((ble_evt_t *)m_ble_evt_buf, it->param);
128121
it = it->next;

ports/nrf/bluetooth/ble_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@
5050

5151
typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
5252

53+
typedef struct ble_drv_evt_handler_entry {
54+
struct ble_drv_evt_handler_entry *next;
55+
void *param;
56+
ble_drv_evt_handler_t func;
57+
} ble_drv_evt_handler_entry_t;
58+
5359
void ble_drv_reset(void);
5460
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param);
5561
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param);

ports/nrf/common-hal/bleio/CharacteristicBuffer.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
#include "ble_drv.h"
3131
#include "ble_gatts.h"
32-
#include "sd_mutex.h"
32+
#include "nrf_nvic.h"
3333

3434
#include "lib/utils/interrupt_char.h"
3535
#include "py/runtime.h"
@@ -47,14 +47,14 @@ STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
4747
ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
4848
// Event handle must match the handle for my characteristic.
4949
if (evt_write->handle == self->characteristic->handle) {
50-
// Push all the data onto the ring buffer, but wait for any reads to finish.
51-
sd_mutex_acquire_wait_no_vm(&self->ringbuf_mutex);
50+
// Push all the data onto the ring buffer.
51+
uint8_t is_nested_critical_region;
52+
sd_nvic_critical_region_enter(&is_nested_critical_region);
5253
for (size_t i = 0; i < evt_write->len; i++) {
5354
ringbuf_put(&self->ringbuf, evt_write->data[i]);
5455
}
55-
// Don't check for errors: we're in an event handler.
56-
sd_mutex_release(&self->ringbuf_mutex);
57-
break;
56+
sd_nvic_critical_region_exit(is_nested_critical_region);
57+
break;
5858
}
5959
}
6060
}
@@ -72,7 +72,6 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
7272
// This is a macro.
7373
// true means long-lived, so it won't be moved.
7474
ringbuf_alloc(&self->ringbuf, buffer_size, true);
75-
sd_mutex_new(&self->ringbuf_mutex);
7675

7776
ble_drv_add_event_handler(characteristic_buffer_on_ble_evt, self);
7877

@@ -92,29 +91,35 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_
9291
#endif
9392
}
9493

95-
// Copy received data. Lock out writes while copying.
96-
sd_mutex_acquire_wait(&self->ringbuf_mutex);
94+
// Copy received data. Lock out write interrupt handler while copying.
95+
uint8_t is_nested_critical_region;
96+
sd_nvic_critical_region_enter(&is_nested_critical_region);
9797

9898
size_t rx_bytes = MIN(ringbuf_count(&self->ringbuf), len);
9999
for ( size_t i = 0; i < rx_bytes; i++ ) {
100100
data[i] = ringbuf_get(&self->ringbuf);
101101
}
102102

103103
// Writes now OK.
104-
sd_mutex_release_check(&self->ringbuf_mutex);
104+
sd_nvic_critical_region_exit(is_nested_critical_region);
105105

106106
return rx_bytes;
107107
}
108108

109109
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
110-
return ringbuf_count(&self->ringbuf);
110+
uint8_t is_nested_critical_region;
111+
sd_nvic_critical_region_enter(&is_nested_critical_region);
112+
uint16_t count = ringbuf_count(&self->ringbuf);
113+
sd_nvic_critical_region_exit(is_nested_critical_region);
114+
return count;
111115
}
112116

113117
void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self) {
114118
// prevent conflict with uart irq
115-
sd_mutex_acquire_wait(&self->ringbuf_mutex);
119+
uint8_t is_nested_critical_region;
120+
sd_nvic_critical_region_enter(&is_nested_critical_region);
116121
ringbuf_clear(&self->ringbuf);
117-
sd_mutex_release_check(&self->ringbuf_mutex);
122+
sd_nvic_critical_region_exit(is_nested_critical_region);
118123
}
119124

120125
bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self) {

ports/nrf/common-hal/bleio/CharacteristicBuffer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ typedef struct {
3838
uint32_t timeout_ms;
3939
// Ring buffer storing consecutive incoming values.
4040
ringbuf_t ringbuf;
41-
nrf_mutex_t ringbuf_mutex;
4241
} bleio_characteristic_buffer_obj_t;
4342

4443
#endif // MICROPY_INCLUDED_COMMON_HAL_BLEIO_CHARACTERISTICBUFFER_H

ports/nrf/mpconfigport.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#ifndef NRF5_MPCONFIGPORT_H__
2929
#define NRF5_MPCONFIGPORT_H__
3030

31+
#include "ble_drv.h"
32+
3133
#define MICROPY_CPYTHON_COMPAT (1)
3234
//#define MICROPY_MODULE_BUILTIN_INIT (1) // TODO check this
3335
//#define MICROPY_MODULE_WEAK_LINKS (1) // TODO check this
@@ -52,10 +54,11 @@
5254
// 24kiB stack
5355
#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
5456

57+
#include "py/circuitpy_mpconfig.h"
58+
5559
#define MICROPY_PORT_ROOT_POINTERS \
5660
CIRCUITPY_COMMON_ROOT_POINTERS \
57-
;
61+
ble_drv_evt_handler_entry_t* ble_drv_evt_handler_entries; \
5862

59-
#include "py/circuitpy_mpconfig.h"
6063

6164
#endif // NRF5_MPCONFIGPORT_H__

0 commit comments

Comments
 (0)