8000 extmod/modbluetooth: Simplify how BLE IRQ callback is scheduled. · rlangoy/micropython@d6e0510 · GitHub < 8000 link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
[go: up one dir, main page]

Skip to content

Commit d6e0510

Browse files
committed
extmod/modbluetooth: Simplify how BLE IRQ callback is scheduled.
Instead of enqueue_irq() inspecting the ringbuf to decide whether to schedule the IRQ callback (if ringbuf is empty), maintain a flag that knows if the callback is on the schedule queue or not. This saves about 150 bytes of code (for stm32 builds), and simplifies all uses of enqueue_irq() and schedule_ringbuf().
1 parent 7f24c29 commit d6e0510

File tree

1 file changed

+28
-38
lines changed

1 file changed

+28
-38
lines changed

extmod/modbluetooth.c

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ typedef struct {
6060
mp_obj_base_t base;
6161
mp_obj_t irq_handler;
6262
uint16_t irq_trigger;
63+
bool irq_scheduled;
6364
mp_obj_t irq_data_tuple;
6465
uint8_t irq_data_addr_bytes[6];
6566
uint8_t irq_data_data_bytes[MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_BYTES_LEN];
@@ -757,9 +758,12 @@ STATIC void ringbuf_extract(ringbuf_t* ringbuf, mp_obj_tuple_t *data_tuple, size
757758

758759
STATIC mp_obj_t bluetooth_ble_invoke_irq(mp_obj_t none_in) {
759760
// This is always executing in schedule context.
761+
762+
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
763+
o->irq_scheduled = false;
764+
760765
for (;;) {
761766
MICROPY_PY_BLUETOOTH_ENTER
762-
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
763767

764768
mp_int_t event = event = ringbuf_get16(&o->ringbuf);
765769
if (event < 0) {
@@ -822,9 +826,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluetooth_ble_invoke_irq_obj, bluetooth_ble_inv
822826
// Callbacks are called in interrupt context (i.e. can't allocate), so we need to push the data
823827
// into the ringbuf and schedule the callback via mp_sched_schedule.
824828

825-
STATIC bool enqueue_irq(mp_obj_bluetooth_ble_t *o, size_t len, uint16_t event, bool *sched) {
826-
*sched = false;
827-
829+
STATIC bool enqueue_irq(mp_obj_bluetooth_ble_t *o, size_t len, uint16_t event) {
828830
if (!o || !(o->irq_trigger & event) || o->irq_handler == mp_const_none) {
829831
return false;
830832
}
@@ -849,68 +851,61 @@ STATIC bool enqueue_irq(mp_obj_bluetooth_ble_t *o, size_t len, uint16_t event, b
849851
for (int i = 0; i < n; ++i) {
850852
ringbuf_get(&o->ringbuf);
851853
}
852-
853-
// No need to schedule the handler, as the ringbuffer was non-empty.
854-
} else {
855-
// Schedule the handler only if this is the first thing in the ringbuffer.
856-
*sched = ringbuf_avail(&o->ringbuf) == 0;
857854
}
858855

859856
// Append this event, the caller will then append the arguments.
860857
ringbuf_put16(&o->ringbuf, event);
861858
return true;
862859
}
863860

864-
STATIC void schedule_ringbuf(bool sched) {
865-
if (sched) {
861+
STATIC void schedule_ringbuf(void) {
862+
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
863+
if (!o->irq_scheduled) {
864+
o->irq_scheduled = true;
866865
mp_sched_schedule(MP_OBJ_FROM_PTR(MP_ROM_PTR(&bluetooth_ble_invoke_irq_obj)), mp_const_none);
867866
}
868867
}
869868

870869
void mp_bluetooth_gap_on_connected_disconnected(uint16_t event, uint16_t conn_handle, uint8_t addr_type, const uint8_t *addr) {
871870
MICROPY_PY_BLUETOOTH_ENTER
872871
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
873-
bool sched;
874-
if (enqueue_irq(o, 2 + 1 + 6, event, &sched)) {
872+
if (enqueue_irq(o, 2 + 1 + 6, event)) {
875873
ringbuf_put16(&o->ringbuf, conn_handle);
876874
ringbuf_put(&o->ringbuf, addr_type);
877875
for (int i = 0; i < 6; ++i) {
878876
ringbuf_put(&o->ringbuf, addr[i]);
879877
}
880878
}
879+
schedule_ringbuf();
881880
MICROPY_PY_BLUETOOTH_EXIT
882-
schedule_ringbuf(sched);
883881
}
884882

885883
void mp_bluetooth_gatts_on_write(uint16_t conn_handle, uint16_t value_handle) {
886884
MICROPY_PY_BLUETOOTH_ENTER
887885
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
888-
bool sched;
889-
if (enqueue_irq(o, 2 + 2, MP_BLUETOOTH_IRQ_GATTS_WRITE, &sched)) {
886+
if (enqueue_irq(o, 2 + 2, MP_BLUETOOTH_IRQ_GATTS_WRITE)) {
890887
ringbuf_put16(&o->ringbuf, conn_handle);
891888
ringbuf_put16(&o->ringbuf, value_handle);
892889
}
890+
schedule_ringbuf();
893891
MICROPY_PY_BLUETOOTH_EXIT
894-
schedule_ringbuf(sched);
895892
}
896893

897894
#if MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE
898895
void mp_bluetooth_gap_on_scan_complete(void) {
899896
MICROPY_PY_BLUETOOTH_ENTER
900897
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
901-
bool sched;
902-
if (enqueue_irq(o, 0, MP_BLUETOOTH_IRQ_SCAN_COMPLETE, &sched)) {
898+
if (enqueue_irq(o, 0, MP_BLUETOOTH_IRQ_SCAN_COMPLETE)) {
903899
}
900+
schedule_ringbuf();
904901
MICROPY_PY_BLUETOOTH_EXIT
905-
schedule_ringbuf(sched);
906902
}
907903

908904
void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, bool connectable, const int8_t rssi, const uint8_t *data, size_t data_len) {
909905
MICROPY_PY_BLUETOOTH_ENTER
910906
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
911-
bool sched;
912907
data_len = MIN(MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_BYTES_LEN, data_len);
913-
if (enqueue_irq(o, 1 + 6 + 1 + 1 + 1 + data_len, MP_BLUETOOTH_IRQ_SCAN_RESULT, &sched)) {
908+
if (enqueue_irq(o, 1 + 6 + 1 + 1 + 1 + data_len, MP_BLUETOOTH_IRQ_SCAN_RESULT)) {
914909
ringbuf_put(&o->ringbuf, addr_type);
915910
for (int i = 0; i < 6; ++i) {
916911
ringbuf_put(&o->ringbuf, addr[i]);
@@ -923,80 +918,75 @@ void mp_bluetooth_gap_on_scan_result(uint8_t addr_type, const uint8_t *addr, boo
923918
ringbuf_put(&o->ringbuf, data[i]);
924919
}
925920
}
921+
schedule_ringbuf();
926922
MICROPY_PY_BLUETOOTH_EXIT
927-
schedule_ringbuf(sched);
928923
}
929924

930925
void mp_bluetooth_gattc_on_primary_service_result(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, mp_obj_bluetooth_uuid_t *service_uuid) {
931926
MICROPY_PY_BLUETOOTH_ENTER
932927
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
933-
bool sched;
934-
if (enqueue_irq(o, 2 + 2 + 2 + 1 + service_uuid->type, MP_BLUETOOTH_IRQ_GATTC_SERVICE_RESULT, &sched)) {
928+
if (enqueue_irq(o, 2 + 2 + 2 + 1 + service_uuid->type, MP_BLUETOOTH_IRQ_GATTC_SERVICE_RESULT)) {
935929
ringbuf_put16(&o->ringbuf, conn_handle);
936930
ringbuf_put16(&o->ringbuf, start_handle);
937931
ringbuf_put16(&o->ringbuf, end_handle);
938932
ringbuf_put_uuid(&o->ringbuf, service_uuid);
939933
}
934+
schedule_ringbuf();
940935
MICROPY_PY_BLUETOOTH_EXIT
941-
schedule_ringbuf(sched);
942936
}
943937

944938
void mp_bluetooth_gattc_on_characteristic_result(uint16_t conn_handle, uint16_t def_handle, uint16_t value_handle, uint8_t properties, mp_obj_bluetooth_uuid_t *characteristic_uuid) {
945939
MICROPY_PY_BLUETOOTH_ENTER
946940
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
947-
bool sched;
948-
if (enqueue_irq(o, 2 + 2 + 2 + 1 + characteristic_uuid->type, MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_RESULT, &sched)) {
941+
if (enqueue_irq(o, 2 + 2 + 2 + 1 + characteristic_uuid->type, MP_BLUETOOTH_IRQ_GATTC_CHARACTERISTIC_RESULT)) {
949942
ringbuf_put16(&o->ringbuf, conn_handle);
950943
ringbuf_put16(&o->ringbuf, def_handle);
951944
ringbuf_put16(&o->ringbuf, value_handle);
952945
ringbuf_put(&o->ringbuf, properties);
953946
ringbuf_put_uuid(&o->ringbuf, characteristic_uuid);
954947
}
948+
schedule_ringbuf();
955949
MICROPY_PY_BLUETOOTH_EXIT
956-
schedule_ringbuf(sched);
957950
}
958951

959952
void mp_bluetooth_gattc_on_descriptor_result(uint16_t conn_handle, uint16_t handle, mp_obj_bluetooth_uuid_t *descriptor_uuid) {
960953
MICROPY_PY_BLUETOOTH_ENTER
961954
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
962-
bool sched;
963-
if (enqueue_irq(o, 2 + 2 + 1 + descriptor_uuid->type, MP_BLUETOOTH_IRQ_GATTC_DESCRIPTOR_RESULT, &sched)) {
955+
if (enqueue_irq(o, 2 + 2 + 1 + descriptor_uuid->type, MP_BLUETOOTH_IRQ_GATTC_DESCRIPTOR_RESULT)) {
964956
ringbuf_put16(&o->ringbuf, conn_handle);
965957
ringbuf_put16(&o->ringbuf, handle);
966958
ringbuf_put_uuid(&o->ringbuf, descriptor_uuid);
967959
}
960+
schedule_ringbuf();
968961
MICROPY_PY_BLUETOOTH_EXIT
969-
schedule_ringbuf(sched);
970962
}
971963

972964
void mp_bluetooth_gattc_on_data_available(uint16_t event, uint16_t conn_handle, uint16_t value_handle, const uint8_t *data, size_t data_len) {
973965
MICROPY_PY_BLUETOOTH_ENTER
974966
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
975-
bool sched;
976967
data_len = MIN(MICROPY_PY_BLUETOOTH_MAX_EVENT_DATA_BYTES_LEN, data_len);
977-
if (enqueue_irq(o, 2 + 2 + 1 + data_len, event, &sched)) {
968+
if (enqueue_irq(o, 2 + 2 + 1 + data_len, event)) {
978969
ringbuf_put16(&o->ringbuf, conn_handle);
979970
ringbuf_put16(&o->ringbuf, value_handle);
980971
ringbuf_put(&o->ringbuf, data_len);
981972
for (int i = 0; i < data_len; ++i) {
982973
ringbuf_put(&o->ringbuf, data[i]);
983974
}
984975
}
976+
schedule_ringbuf();
985977
MICROPY_PY_BLUETOOTH_EXIT
986-
schedule_ringbuf(sched);
987978
}
988979

989980
void mp_bluetooth_gattc_on_write_status(uint16_t conn_handle, uint16_t value_handle, uint16_t status) {
990981
MICROPY_PY_BLUETOOTH_ENTER
991982
mp_obj_bluetooth_ble_t *o = MP_OBJ_TO_PTR(MP_STATE_VM(bluetooth));
992-
bool sched;
993-
if (enqueue_irq(o, 2 + 2 + 2, MP_BLUETOOTH_IRQ_GATTC_WRITE_STATUS, &sched)) {
983+
if (enqueue_irq(o, 2 + 2 + 2, MP_BLUETOOTH_IRQ_GATTC_WRITE_STATUS)) {
994984
ringbuf_put16(&o->ringbuf, conn_handle);
995985
ringbuf_put16(&o->ringbuf, value_handle);
996986
ringbuf_put16(&o->ringbuf, status);
997987
}
988+
schedule_ringbuf();
998989
MICROPY_PY_BLUETOOTH_EXIT
999-
schedule_ringbuf(sched);
1000990
}
1001991

1002992
#endif // MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE

0 commit comments

Comments
 (0)
0