I have to transmit fixed buffer size from dma ISR to thread, input_buffers_queue_t seems to be the appropriate tool.
In my application, after few iterations, it fails because of memory corruption, probably because of misuse. The only example of use i have found is in hal_serial_usb.
I have reproduced my problem with a very simple example with a writer and a reader in two thread, and it fails with the same symptoms.
what I do is (using ChibiOS 20.3.x) :
global var declaration :
Code: Select all
#define BUFFER_SIZE 64U
#define QUEUE_LEN 32U
static uint8_t readWriteBuffer[BUFFER_SIZE * QUEUE_LEN];
static input_buffers_queue_t readWriteQueue;
initialization in main :
Code: Select all
ibqObjectInit(&readWriteQueue, false, readWriteBuffer,
BUFFER_SIZE, QUEUE_LEN,
NULL, NULL);
in writer thread :
Code: Select all
chSysLock();
uint8_t * const qbuf = ibqGetEmptyBufferI(&readWriteQueue);
if (qbuf != NULL) {
memcpy(qbuf, source, BUFFER_SIZE);
ibqPostFullBufferI(&readWriteQueue, BUFFER_SIZE);
}
chSysUnlock();
in reader thread:
Code: Select all
uint8_t dest[BUFFER_SIZE];
size_t cnt=0;
while (true) {
const msg_t n = ibqReadTimeout(&readWriteQueue, dest, sizeof(dest),
TIME_INFINITE);
// doing something with dest
chDbgAssert(n != 0, "ibqReadTimeout");
}
it works for 29 iterations then i have memory corruption in ibqPostFullBufferI.
Any advice are welcome on the good way to correctly use buffer queue !
EDIT:
I have tried the zero copy read API with same problem :
in reader thread:
Code: Select all
while (true) {
const msg_t status = ibqGetFullBufferTimeout(&readWriteQueue, TIME_INFINITE);
chDbgAssert(status == MSG_OK, "ibqGetFullBufferTimeout");
// doing something with readWriteQueue.ptr
ibqReleaseEmptyBuffer(&readWriteQueue);
}
Alexandre