|
36 | 36 |
|
37 | 37 | #include "Arduino.h"
|
38 | 38 |
|
| 39 | +#define INITIAL_QUEUE_DEPTH 64 |
| 40 | + |
39 | 41 | static QueueHandle_t _cb_queue = NULL;
|
40 |
| -static uint8_t _cb_qbuf[CFG_CALLBACK_QUEUE_LENGTH*sizeof(void*)]; |
41 |
| -static StaticQueue_t _cb_static_q; |
| 42 | +static uint32_t _cb_qdepth; |
42 | 43 |
|
43 | 44 | void adafruit_callback_task(void* arg)
|
44 | 45 | {
|
@@ -79,14 +80,26 @@ static inline bool is_isr(void)
|
79 | 80 |
|
80 | 81 | void ada_callback_queue(ada_callback_t* cb_item)
|
81 | 82 | {
|
82 |
| - if ( is_isr() ) |
83 |
| - { |
84 |
| - xQueueSendFromISR(_cb_queue, (void*) &cb_item, NULL); |
85 |
| - }else |
| 83 | + BaseType_t ret = is_isr() ? xQueueSendFromISR(_cb_queue, (void*) &cb_item, NULL) : xQueueSend(_cb_queue, (void*) &cb_item, CFG_CALLBACK_TIMEOUT); |
| 84 | + |
| 85 | + if ( ret != pdTRUE ) |
86 | 86 | {
|
87 |
| - if ( !xQueueSend(_cb_queue, (void*) &cb_item, CFG_CALLBACK_TIMEOUT) ) |
| 87 | + // run out of space, resize queue with double the size |
| 88 | + if ( ada_callback_queue_resize(2*_cb_qdepth) ) |
| 89 | + { |
| 90 | + _cb_qdepth = 2*_cb_qdepth; |
| 91 | + |
| 92 | + // try again |
| 93 | + if ( is_isr() ) |
| 94 | + { |
| 95 | + xQueueSendFromISR(_cb_queue, (void*) &cb_item, NULL); |
| 96 | + }else |
| 97 | + { |
| 98 | + xQueueSend(_cb_queue, (void*) &cb_item, CFG_CALLBACK_TIMEOUT); |
| 99 | + } |
| 100 | + }else |
88 | 101 | {
|
89 |
| - LOG_LV1("MEMORY", "AdaCallback run out of queue item, increase CFG_CALLBACK_QUEUE_LENGTH"); |
| 102 | + LOG_LV1("MEMORY", "AdaCallback run out of queue spaces"); |
90 | 103 | }
|
91 | 104 | }
|
92 | 105 | }
|
@@ -124,8 +137,37 @@ void ada_callback_invoke(const void* malloc_data, uint32_t malloc_len, const voi
|
124 | 137 | void ada_callback_init(void)
|
125 | 138 | {
|
126 | 139 | // queue to hold "Pointer to callback data"
|
127 |
| - _cb_queue = xQueueCreateStatic(CFG_CALLBACK_QUEUE_LENGTH, sizeof(void*), _cb_qbuf, &_cb_static_q); |
| 140 | + _cb_qdepth = INITIAL_QUEUE_DEPTH; |
| 141 | + _cb_queue = xQueueCreate(_cb_qdepth, sizeof(void*)); |
128 | 142 |
|
129 | 143 | TaskHandle_t callback_task_hdl;
|
130 | 144 | xTaskCreate( adafruit_callback_task, "Callback", CFG_CALLBACK_TASK_STACKSIZE, NULL, TASK_PRIO_NORMAL, &callback_task_hdl);
|
131 | 145 | }
|
| 146 | + |
| 147 | +bool ada_callback_queue_resize(uint32_t new_depth) |
| 148 | +{ |
| 149 | + // create new queue |
| 150 | + QueueHandle_t new_queue = xQueueCreate(new_depth, sizeof(void*)); |
| 151 | + VERIFY(new_queue); |
| 152 | + |
| 153 | + LOG_LV1("MEMORY", "AdaCallback increase queue depth to %d", new_depth); |
| 154 | + |
| 155 | + taskENTER_CRITICAL(); |
| 156 | + |
| 157 | + // move item from old queue |
| 158 | + ada_callback_t* cb_data; |
| 159 | + while ( xQueueReceive(_cb_queue, (void*) &cb_data, 0) ) |
| 160 | + { |
| 161 | + xQueueSend(new_queue, (void*) &cb_data, CFG_CALLBACK_TIMEOUT); |
| 162 | + } |
| 163 | + |
| 164 | + // delete old queue |
| 165 | + vQueueDelete(_cb_queue); |
| 166 | + |
| 167 | + // Switch to new queue |
| 168 | + _cb_queue = new_queue; |
| 169 | + |
| 170 | + taskEXIT_CRITICAL(); |
| 171 | + |
| 172 | + return true; |
| 173 | +} |
0 commit comments