Description
Summary
When I run a some simple Arduino sketchs (ArduinoCore-zephyr), that loops reading in from a camera and then displays them on some Video device, like Giga Display shield, or ST7789, the display takes longer to display an image than it takes the camera to capture the next, I see a lot of messages
like:
[00:00:07.207,000] <dbg> video_stm32_dcmi: HAL_DCMI_FrameEventCallback: Failed to get buffer from fifo
[00:00:07.439,000] <dbg> video_stm32_dcmi: HAL_DCMI_FrameEventCallback: Failed to get buffer from fifo
[00:00:07.670,000] <dbg> video_stm32_dcmi: HAL_DCMI_FrameEventCallback: Failed to get buffer from fifo
[00:00:07.902,000] <dbg> video_stm32_dcmi: HAL_DCMI_FrameEventCallback: Failed to get buffer from fifo
...
And when I complete the drawing of an image, if I simply ask for an image, I get the oldest one, which could be really old...
Would prefer to get the most recent one...
Secondary: wondering if we continue to use the memcpy of the video buffer frame to one of the other buffers, if in some cases
we may desire to have these two buffers in different memory regions. For example, have the main camera buffer in the processors
main memory and the secondary ones in SDRAM..
Secondary question: occasionally I see some messages about memory corruption. Wondering are the kernel FIFO apis thread/interrupt safe?
That is, could some of these corruptions be caused by k_fifo_put or k_fifo_put code being interrupted. LIke in my example suppose when I completed using a frame to display, the enqueue call gets interrupted...
Describe the solution you'd like
Maybe add an option, that says when you don't have any more free buffers, reuse the oldest. Maybe something like: CONFIG_VIDEO_BUFFER_POOL_REUSE_OLDEST
Something like:
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
struct video_stm32_dcmi_data *dev_data =
CONTAINER_OF(hdcmi, struct video_stm32_dcmi_data, hdcmi);
struct video_buffer *vbuf;
HAL_DCMI_Suspend(hdcmi);
vbuf = k_fifo_get(&dev_data->fifo_in, K_NO_WAIT);
#ifdef CONFIG_VIDEO_BUFFER_POOL_REUSE_OLDEST
if (vbuf == NULL) {
vbuf = k_fifo_get(&dev_data->fifo_out, K_NO_WAIT);
}
#endif
if (vbuf == NULL) {
LOG_DBG("Failed to get buffer from fifo");
goto resume;
}
vbuf->timestamp = k_uptime_get_32();
memcpy(vbuf->buffer, dev_data->vbuf->buffer, vbuf->bytesused);
k_fifo_put(&dev_data->fifo_out, vbuf);
resume:
HAL_DCMI_Resume(hdcmi);
}
Again wondering about FIFO being safe...
Alternatives
For now might have the user code, for example in my example sketch, could for example, keep asking for buffers until it says it does not have any more and then return all but the last one which I display.
And/Or while the code is waiting for the display to finish, it keep timings and at certain intervals have it toss any available images.
Additional Context
Side note: I was trying to test the latest stuff out on the Nicla Vision, as this is the only board I have that has a zephyr example
for Video. But not sure if it is currently working?
#90326
That is if I run simple sample, like hello world on it, the kernel monitor window on the Serial pins shows:
*** Booting Zephyr OS build v4.1.0-7111-g4ec435165753 ***
Hello World! arduino_nicla_vision/stm32h747xx/m7
And on this example I see nothing, just the green LED is on...