From c16c5b968f7dd52d48749ad647d8ef7415b07efc Mon Sep 17 00:00:00 2001 From: qiyongzhong0 <917768104@qq.com> Date: Sun, 30 Aug 2020 14:35:09 +0800 Subject: fix dataqueue, limit queue size to usable values (2,4,8,16...) to avoid errors when put_index exceed 0xffff. --- components/drivers/src/dataqueue.c | 1 + 1 file changed, 1 insertion(+) (limited to 'components/drivers/src/dataqueue.c') diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c index 5a802c0711..ba4a921da0 100644 --- a/components/drivers/src/dataqueue.c +++ b/components/drivers/src/dataqueue.c @@ -28,6 +28,7 @@ rt_data_queue_init(struct rt_data_queue *queue, void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event)) { RT_ASSERT(queue != RT_NULL); + RT_ASSERT((0x10000 % size) == 0); queue->evt_notify = evt_notify; -- cgit v1.3.1 From 44baf269f79903d83359f23aab60ca17560e422c Mon Sep 17 00:00:00 2001 From: qiyongzhong0 <917768104@qq.com> Date: Fri, 18 Sep 2020 09:33:34 +0800 Subject: fix bug of dataqueue --- components/drivers/include/ipc/dataqueue.h | 11 +-- components/drivers/src/dataqueue.c | 117 +++++++++++++++++++++-------- 2 files changed, 93 insertions(+), 35 deletions(-) (limited to 'components/drivers/src/dataqueue.c') diff --git a/components/drivers/include/ipc/dataqueue.h b/components/drivers/include/ipc/dataqueue.h index d90be76ffb..0262f4702b 100644 --- a/components/drivers/include/ipc/dataqueue.h +++ b/components/drivers/include/ipc/dataqueue.h @@ -17,8 +17,7 @@ #define RT_DATAQUEUE_EVENT_LWM 0x03 struct rt_data_item; -#define RT_DATAQUEUE_SIZE(dq) ((dq)->put_index - (dq)->get_index) -#define RT_DATAQUEUE_EMPTY(dq) ((dq)->size - RT_DATAQUEUE_SIZE(dq)) + /* data queue implementation */ struct rt_data_queue { @@ -26,10 +25,11 @@ struct rt_data_queue rt_uint16_t size; rt_uint16_t lwm; - rt_bool_t waiting_lwm; - rt_uint16_t get_index; - rt_uint16_t put_index; + rt_uint16_t get_index : 15; + rt_uint16_t is_empty : 1; + rt_uint16_t put_index : 15; + rt_uint16_t is_full : 1; struct rt_data_item *queue; @@ -60,5 +60,6 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue, rt_size_t *size); void rt_data_queue_reset(struct rt_data_queue *queue); rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue); +rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue); #endif diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c index ba4a921da0..7aea0ab246 100644 --- a/components/drivers/src/dataqueue.c +++ b/components/drivers/src/dataqueue.c @@ -28,7 +28,7 @@ rt_data_queue_init(struct rt_data_queue *queue, void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event)) { RT_ASSERT(queue != RT_NULL); - RT_ASSERT((0x10000 % size) == 0); + RT_ASSERT(size > 0); queue->evt_notify = evt_notify; @@ -38,10 +38,12 @@ rt_data_queue_init(struct rt_data_queue *queue, queue->get_index = 0; queue->put_index = 0; + queue->is_empty = 1; + queue->is_full = 0; rt_list_init(&(queue->suspended_push_list)); rt_list_init(&(queue->suspended_pop_list)); - + queue->queue = (struct rt_data_item *)rt_malloc(sizeof(struct rt_data_item) * size); if (queue->queue == RT_NULL) { @@ -61,14 +63,14 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue, rt_thread_t thread; rt_err_t result; - RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); RT_ASSERT(queue != RT_NULL); + RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); result = RT_EOK; thread = rt_thread_self(); level = rt_hw_interrupt_disable(); - while (queue->put_index - queue->get_index == queue->size) + while (queue->is_full) { /* queue is full */ if (timeout == 0) @@ -109,9 +111,18 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue, if (result != RT_EOK) goto __exit; } - queue->queue[queue->put_index % queue->size].data_ptr = data_ptr; - queue->queue[queue->put_index % queue->size].data_size = data_size; + queue->queue[queue->put_index].data_ptr = data_ptr; + queue->queue[queue->put_index].data_size = data_size; queue->put_index += 1; + if (queue->put_index == queue->size) + { + queue->put_index = 0; + } + queue->is_empty = 0; + if (queue->put_index == queue->get_index) + { + queue->is_full = 1; + } /* there is at least one thread in suspended list */ if (!rt_list_isempty(&(queue->suspended_pop_list))) @@ -151,8 +162,8 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue, rt_thread_t thread; rt_err_t result; - RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); RT_ASSERT(queue != RT_NULL); + RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); RT_ASSERT(data_ptr != RT_NULL); RT_ASSERT(size != RT_NULL); @@ -160,7 +171,7 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue, thread = rt_thread_self(); level = rt_hw_interrupt_disable(); - while (queue->get_index == queue->put_index) + while (queue->is_empty) { /* queue is empty */ if (timeout == 0) @@ -201,12 +212,20 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue, goto __exit; } - *data_ptr = queue->queue[queue->get_index % queue->size].data_ptr; - *size = queue->queue[queue->get_index % queue->size].data_size; - + *data_ptr = queue->queue[queue->get_index].data_ptr; + *size = queue->queue[queue->get_index].data_size; queue->get_index += 1; + if (queue->get_index == queue->size) + { + queue->get_index = 0; + } + queue->is_full = 0; + if (queue->put_index == queue->get_index) + { + queue->is_empty = 1; + } - if ((queue->put_index - queue->get_index) <= queue->lwm) + if (rt_data_queue_len(queue) <= queue->lwm) { /* there is at least one thread in suspended list */ if (!rt_list_isempty(&(queue->suspended_push_list))) @@ -251,20 +270,18 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue, { rt_ubase_t level; - RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); RT_ASSERT(queue != RT_NULL); + RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); - level = rt_hw_interrupt_disable(); - - if (queue->get_index == queue->put_index) + if (queue->is_empty) { - rt_hw_interrupt_enable(level); - return -RT_EEMPTY; } - *data_ptr = queue->queue[queue->get_index % queue->size].data_ptr; - *size = queue->queue[queue->get_index % queue->size].data_size; + level = rt_hw_interrupt_disable(); + + *data_ptr = queue->queue[queue->get_index].data_ptr; + *size = queue->queue[queue->get_index].data_size; rt_hw_interrupt_enable(level); @@ -274,10 +291,20 @@ RTM_EXPORT(rt_data_queue_peak); void rt_data_queue_reset(struct rt_data_queue *queue) { + rt_ubase_t level; struct rt_thread *thread; - register rt_ubase_t temp; + RT_ASSERT(queue != RT_NULL); RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); + + level = rt_hw_interrupt_disable(); + + queue->get_index = 0; + queue->put_index = 0; + queue->is_empty = 1; + queue->is_full = 0; + + rt_hw_interrupt_enable(level); rt_enter_critical(); /* wakeup all suspend threads */ @@ -286,7 +313,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue) while (!rt_list_isempty(&(queue->suspended_pop_list))) { /* disable interrupt */ - temp = rt_hw_interrupt_disable(); + level = rt_hw_interrupt_disable(); /* get next suspend thread */ thread = rt_list_entry(queue->suspended_pop_list.next, @@ -303,14 +330,14 @@ void rt_data_queue_reset(struct rt_data_queue *queue) rt_thread_resume(thread); /* enable interrupt */ - rt_hw_interrupt_enable(temp); + rt_hw_interrupt_enable(level); } /* resume on push list */ while (!rt_list_isempty(&(queue->suspended_push_list))) { /* disable interrupt */ - temp = rt_hw_interrupt_disable(); + level = rt_hw_interrupt_disable(); /* get next suspend thread */ thread = rt_list_entry(queue->suspended_push_list.next, @@ -327,7 +354,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue) rt_thread_resume(thread); /* enable interrupt */ - rt_hw_interrupt_enable(temp); + rt_hw_interrupt_enable(level); } rt_exit_critical(); @@ -339,19 +366,49 @@ rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue) { rt_ubase_t level; - RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); RT_ASSERT(queue != RT_NULL); - - level = rt_hw_interrupt_disable(); + RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); /* wakeup all suspend threads */ rt_data_queue_reset(queue); + level = rt_hw_interrupt_disable(); queue->magic = 0; - rt_free(queue->queue); - rt_hw_interrupt_enable(level); + + rt_free(queue->queue); return RT_EOK; } RTM_EXPORT(rt_data_queue_deinit); + +rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue) +{ + rt_ubase_t level; + rt_int16_t len; + + RT_ASSERT(queue != RT_NULL); + RT_ASSERT(queue->magic == DATAQUEUE_MAGIC); + + if (queue->is_empty) + { + return 0; + } + + level = rt_hw_interrupt_disable(); + + if (queue->put_index > queue->get_index) + { + len = queue->put_index - queue->get_index; + } + else + { + len = queue->size + queue->put_index - queue->get_index; + } + + rt_hw_interrupt_enable(level); + + return len; +} +RTM_EXPORT(rt_data_queue_len); + -- cgit v1.3.1 From 967cc968e8d3a3f2b371b84a0b95619d4974e421 Mon Sep 17 00:00:00 2001 From: qiyongzhong0 <917768104@qq.com> Date: Fri, 18 Sep 2020 09:45:47 +0800 Subject: fix difference of style --- components/drivers/src/dataqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/drivers/src/dataqueue.c') diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c index 7aea0ab246..bfe8e12573 100644 --- a/components/drivers/src/dataqueue.c +++ b/components/drivers/src/dataqueue.c @@ -43,7 +43,7 @@ rt_data_queue_init(struct rt_data_queue *queue, rt_list_init(&(queue->suspended_push_list)); rt_list_init(&(queue->suspended_pop_list)); - + queue->queue = (struct rt_data_item *)rt_malloc(sizeof(struct rt_data_item) * size); if (queue->queue == RT_NULL) { -- cgit v1.3.1 From a233495718046fb4832fe802c781a87ecc3b5914 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Thu, 31 Dec 2020 16:02:42 +0800 Subject: Typo: rt_data_queue_peak() in dataqueue --- components/drivers/audio/audio.c | 4 ++-- components/drivers/include/ipc/dataqueue.h | 2 +- components/drivers/serial/serial.c | 2 +- components/drivers/src/dataqueue.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'components/drivers/src/dataqueue.c') diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c index 12b9b48a43..c3f8723db6 100644 --- a/components/drivers/audio/audio.c +++ b/components/drivers/audio/audio.c @@ -45,7 +45,7 @@ static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio) dst_size = buf_info->block_size; /* check replay queue is empty */ - if (rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK) + if (rt_data_queue_peek(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK) { /* ack stop event */ if (audio->replay->event & REPLAY_EVT_STOP) @@ -64,7 +64,7 @@ static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio) /* copy data from memory pool to hardware device fifo */ while (index < dst_size) { - result = rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size); + result = rt_data_queue_peek(&audio->replay->queue, (const void **)&data, &src_size); if (result != RT_EOK) { LOG_D("under run %d, remain %d", audio->replay->pos, remain_bytes); diff --git a/components/drivers/include/ipc/dataqueue.h b/components/drivers/include/ipc/dataqueue.h index 0262f4702b..76203c404d 100644 --- a/components/drivers/include/ipc/dataqueue.h +++ b/components/drivers/include/ipc/dataqueue.h @@ -55,7 +55,7 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue, const void **data_ptr, rt_size_t *size, rt_int32_t timeout); -rt_err_t rt_data_queue_peak(struct rt_data_queue *queue, +rt_err_t rt_data_queue_peek(struct rt_data_queue *queue, const void **data_ptr, rt_size_t *size); void rt_data_queue_reset(struct rt_data_queue *queue); diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c index cb4c40c7c2..3b8edf74d5 100644 --- a/components/drivers/serial/serial.c +++ b/components/drivers/serial/serial.c @@ -1268,7 +1268,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event) tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx; rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0); - if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK) + if (rt_data_queue_peek(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK) { /* transmit next data node */ tx_dma->activated = RT_TRUE; diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c index bfe8e12573..1651417bb9 100644 --- a/components/drivers/src/dataqueue.c +++ b/components/drivers/src/dataqueue.c @@ -264,7 +264,7 @@ __exit: } RTM_EXPORT(rt_data_queue_pop); -rt_err_t rt_data_queue_peak(struct rt_data_queue *queue, +rt_err_t rt_data_queue_peek(struct rt_data_queue *queue, const void** data_ptr, rt_size_t *size) { @@ -287,7 +287,7 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue, return RT_EOK; } -RTM_EXPORT(rt_data_queue_peak); +RTM_EXPORT(rt_data_queue_peek); void rt_data_queue_reset(struct rt_data_queue *queue) { -- cgit v1.3.1