Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 86da809

Browse files
author
Daniel Campora
committed
esp32: Fix asserts caused by mutex memory being in pSRAM.
Also implement empty() and full() methods for the Queue class.
1 parent a2d50d6 commit 86da809

File tree

5 files changed

+90
-25
lines changed

5 files changed

+90
-25
lines changed

esp32/mods/moduqueue.c

+40-6
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,23 @@ STATIC mp_obj_t mod_uqueue_queue(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
3636
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
3737

3838
if (args[0].u_int <= 0) {
39-
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Queue size cannot be infinite"));
39+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "queue size cannot be infinite"));
4040
}
4141

4242
int32_t maxsize = args[0].u_int;
43-
// allocate the queue storage and the queue buffer
44-
StaticQueue_t *xQueueBuffer = m_new(StaticQueue_t, 1);
45-
mp_obj_t *storage = m_new(mp_obj_t, maxsize);
4643

4744
// create the queue object
4845
mp_obj_queue_t *queue = m_new_obj_with_finaliser(mp_obj_queue_t);
46+
47+
// allocate the queue storage and the queue buffer
48+
queue->buffer = heap_caps_malloc(sizeof(StaticQueue_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
49+
if (NULL == queue->buffer) {
50+
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, "no memory available to create the queue"));
51+
}
52+
queue->storage = m_new(mp_obj_t, maxsize);
4953
queue->base.type = &mp_queue_type;
5054
queue->maxsize = maxsize;
51-
queue->handle = xQueueCreateStatic(maxsize, sizeof(mp_obj_t), (uint8_t *)storage, xQueueBuffer);
55+
queue->handle = xQueueCreateStatic(maxsize, sizeof(mp_obj_t), (uint8_t *)queue->storage, queue->buffer);
5256

5357
return queue;
5458
}
@@ -66,6 +70,15 @@ const mp_obj_module_t mp_module_uqueue = {
6670
.globals = (mp_obj_dict_t*)&mp_module_uqueue_globals,
6771
};
6872

73+
STATIC mp_obj_t mp_queue_delete(mp_obj_t self_in) {
74+
mp_obj_queue_t *self = self_in;
75+
if (self->buffer) {
76+
free(self->buffer);
77+
}
78+
return mp_const_none;
79+
}
80+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_queue_delete_obj, mp_queue_delete);
81+
6982
STATIC mp_obj_t mp_queue_put(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
7083
static const mp_arg_t allowed_args[] = {
7184
{ MP_QSTR_item, MP_ARG_REQUIRED | MP_ARG_OBJ, },
@@ -108,11 +121,32 @@ STATIC mp_obj_t mp_queue_get(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
108121
}
109122
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mp_queue_get_obj, 1, mp_queue_get);
110123

124+
STATIC mp_obj_t mp_queue_empty(mp_obj_t self_in) {
125+
mp_obj_queue_t *self = self_in;
126+
mp_obj_t buffer;
127+
if (xQueuePeek(self->handle, &buffer, 0)) {
128+
return mp_const_false;
129+
}
130+
return mp_const_true;
131+
}
132+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_queue_empty_obj, mp_queue_empty);
133+
134+
STATIC mp_obj_t mp_queue_full(mp_obj_t self_in) {
135+
mp_obj_queue_t *self = self_in;
136+
if (uxQueueSpacesAvailable(self->handle) > 0) {
137+
return mp_const_false;
138+
}
139+
return mp_const_true;
140+
}
141+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_queue_full_obj, mp_queue_full);
142+
111143
STATIC const mp_map_elem_t queue_locals_dict_table[] = {
112144
// instance methods
113-
// { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&mp_queue_delete_obj },
145+
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&mp_queue_delete_obj },
114146
{ MP_OBJ_NEW_QSTR(MP_QSTR_put), (mp_obj_t)&mp_queue_put_obj },
115147
{ MP_OBJ_NEW_QSTR(MP_QSTR_get), (mp_obj_t)&mp_queue_get_obj },
148+
{ MP_OBJ_NEW_QSTR(MP_QSTR_empty), (mp_obj_t)&mp_queue_empty_obj },
149+
{ MP_OBJ_NEW_QSTR(MP_QSTR_full), (mp_obj_t)&mp_queue_full_obj },
116150

117151
{ MP_OBJ_NEW_QSTR(MP_QSTR_Full), (mp_obj_t)&mp_type_OSError },
118152
{ MP_OBJ_NEW_QSTR(MP_QSTR_Empty), (mp_obj_t)&mp_type_OSError },

esp32/mods/moduqueue.h

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
******************************************************************************/
2020
typedef struct _mp_obj_queue_t {
2121
mp_obj_base_t base;
22+
mp_obj_t storage;
23+
StaticQueue_t *buffer;
2224
QueueHandle_t handle;
2325
uint32_t maxsize;
2426
} mp_obj_queue_t;

esp32/mpthreadport.c

+25
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,17 @@ void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, i
151151
if (esp_get_revision() > 0) {
152152
// for revision 1 devices we allocate from the internal memory of the malloc heap
153153
tcb = heap_caps_malloc(sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
154+
if (!tcb) {
155+
goto memory_error;
156+
}
154157
stack = heap_caps_malloc(*stack_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
158+
if (!stack) {
159+
goto memory_error;
160+
}
155161
th = heap_caps_malloc(sizeof(thread_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
162+
if (!th) {
163+
goto memory_error;
164+
}
156165
} else {
157166
// for revision 0 devices we allocate from the MicroPython heap which is all in the internal memory
158167
tcb = m_new(StaticTask_t, 1);
@@ -183,6 +192,11 @@ void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, i
183192
thread = th;
184193

185194
mp_thread_mutex_unlock(&thread_mutex);
195+
196+
return;
197+
198+
memory_error:
199+
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, "can't create thread"));
186200
}
187201

188202
void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
@@ -228,6 +242,17 @@ void vPortCleanUpTCB (void *tcb) {
228242
mp_thread_mutex_unlock(&thread_mutex);
229243
}
230244

245+
mp_obj_thread_lock_t *mp_thread_new_thread_lock(void) {
246+
mp_obj_thread_lock_t *self = m_new_obj(mp_obj_thread_lock_t);
247+
self->mutex = heap_caps_malloc(sizeof(mp_thread_mutex_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
248+
if (NULL == self->mutex) {
249+
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, "can't create lock"));
250+
}
251+
mp_thread_mutex_init(self->mutex);
252+
self->locked = false;
253+
return self;
254+
}
255+
231256
void mp_thread_mutex_init(mp_thread_mutex_t *mutex) {
232257
mutex->handle = xSemaphoreCreateMutexStatic(&mutex->buffer);
233258
}

esp32/mpthreadport.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,28 @@
3838
#ifndef __MICROPY_INCLUDED_ESP32_MPTHREADPORT_H__
3939
#define __MICROPY_INCLUDED_ESP32_MPTHREADPORT_H__
4040

41-
#ifndef BOOTLOADER
41+
#include "py/mpconfig.h"
42+
#include "py/mpstate.h"
43+
#include "py/obj.h"
4244
#include "freertos/FreeRTOS.h"
43-
#endif
4445

4546
#define MP_THREAD_PRIORITY 5
4647

4748
typedef struct _mp_thread_mutex_t {
48-
#ifndef BOOTLOADER
4949
SemaphoreHandle_t handle;
5050
StaticSemaphore_t buffer;
51-
#endif
5251
} mp_thread_mutex_t;
5352

53+
typedef struct _mp_obj_thread_lock_t {
54+
mp_obj_base_t base;
55+
mp_thread_mutex_t *mutex;
56+
volatile bool locked;
57+
} mp_obj_thread_lock_t;
58+
5459
void mp_thread_preinit(void *stack);
5560
void mp_thread_init(void);
5661
void mp_thread_gc_others(void);
5762
void mp_thread_deinit(void);
63+
mp_obj_thread_lock_t *mp_thread_new_thread_lock(void);
5864

5965
#endif // __MICROPY_INCLUDED_ESP32_MPTHREADPORT_H__

py/modthread.c

+13-15
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,14 @@
4747

4848
STATIC const mp_obj_type_t mp_type_thread_lock;
4949

50-
typedef struct _mp_obj_thread_lock_t {
51-
mp_obj_base_t base;
52-
mp_thread_mutex_t mutex;
53-
volatile bool locked;
54-
} mp_obj_thread_lock_t;
55-
56-
STATIC mp_obj_thread_lock_t *mp_obj_new_thread_lock(void) {
57-
mp_obj_thread_lock_t *self = m_new_obj(mp_obj_thread_lock_t);
58-
self->base.type = &mp_type_thread_lock;
59-
mp_thread_mutex_init(&self->mutex);
60-
self->locked = false;
61-
return self;
50+
STATIC mp_obj_t thread_lock_delete(mp_obj_t self_in) {
51+
mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(self_in);
52+
if (self->mutex) {
53+
free(self->mutex);
54+
}
55+
return mp_const_none;
6256
}
57+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(thread_lock_delete_obj, thread_lock_delete);
6358

6459
STATIC mp_obj_t thread_lock_acquire(size_t n_args, const mp_obj_t *args) {
6560
mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(args[0]);
@@ -69,7 +64,7 @@ STATIC mp_obj_t thread_lock_acquire(size_t n_args, const mp_obj_t *args) {
6964
// TODO support timeout arg
7065
}
7166
MP_THREAD_GIL_EXIT();
72-
int ret = mp_thread_mutex_lock(&self->mutex, wait);
67+
int ret = mp_thread_mutex_lock(self->mutex, wait);
7368
MP_THREAD_GIL_ENTER();
7469
if (ret == 0) {
7570
return mp_const_false;
@@ -87,7 +82,7 @@ STATIC mp_obj_t thread_lock_release(mp_obj_t self_in) {
8782
// TODO check if already unlocked
8883
self->locked = false;
8984
MP_THREAD_GIL_EXIT();
90-
mp_thread_mutex_unlock(&self->mutex);
85+
mp_thread_mutex_unlock(self->mutex);
9186
MP_THREAD_GIL_ENTER();
9287
return mp_const_none;
9388
}
@@ -106,6 +101,7 @@ STATIC mp_obj_t thread_lock___exit__(size_t n_args, const mp_obj_t *args) {
106101
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(thread_lock___exit___obj, 4, 4, thread_lock___exit__);
107102

108103
STATIC const mp_rom_map_elem_t thread_lock_locals_dict_table[] = {
104+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&thread_lock_delete_obj) },
109105
{ MP_ROM_QSTR(MP_QSTR_acquire), MP_ROM_PTR(&thread_lock_acquire_obj) },
110106
{ MP_ROM_QSTR(MP_QSTR_release), MP_ROM_PTR(&thread_lock_release_obj) },
111107
{ MP_ROM_QSTR(MP_QSTR_locked), MP_ROM_PTR(&thread_lock_locked_obj) },
@@ -266,7 +262,9 @@ STATIC mp_obj_t mod_thread_exit(void) {
266262
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_thread_exit_obj, mod_thread_exit);
267263

268264
STATIC mp_obj_t mod_thread_allocate_lock(void) {
269-
return MP_OBJ_FROM_PTR(mp_obj_new_thread_lock());
265+
mp_obj_thread_lock_t *self = mp_thread_new_thread_lock();
266+
self->base.type = &mp_type_thread_lock;
267+
return MP_OBJ_FROM_PTR(self);
270268
}
271269
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_thread_allocate_lock_obj, mod_thread_allocate_lock);
272270

0 commit comments

Comments
 (0)