Zephyr MCUX Camera Capture: Budget the CSI Output Format, Not the Sensor’s Pixel Width

A camera integration starts with a familiar RGB565 sensor configuration and allocates two bytes per pixel. That calculation can be wrong at the memory endpoint even when the sensor really transmits RGB565. In the Zephyr v4.2.0 MCUX CSI path with MIPI CSI-2 reception enabled, the driver accounts for a pipeline that expands that input into a 32-bit output representation.

The distinction affects much more than the image converter. It changes frame allocation, the minimum queued-memory budget, row addressing, and the evidence needed to approve a camera substitution. This article addresses that specific source-to-memory transformation. It does not claim that all Zephyr camera drivers expand pixels or that the calculations below are measured capture results.

With CONFIG_VIDEO_MCUX_MIPI_CSI2RX enabled, the documented MCUX pipeline maps sensor RGB565 to CSI XRGB32; an illustrative 320 by 240 frame therefore needs 307200 bytes at the memory endpoint, before additional allocation requirements.

Start at the device that owns captured memory

The pinned MCUX CSI driver documents implicit format conversion along the i.MX RT11xx MIPI CSI-2 Rx, Video Mux, and CSI path. Under CONFIG_VIDEO_MCUX_MIPI_CSI2RX, its format setter accepts XRGB32 or XYUV32 at the CSI endpoint and translates the request supplied to the source into RGB565 or YUYV respectively.

The same build-dependent code adjusts advertised source formats when reporting CSI capabilities. Thus a capability query on the sensor and one on the capture endpoint are not interchangeable inventories. The two devices describe different boundaries of the pipeline.

Record the actual capture device, its source, the active configuration, and the returned format together. A sensor datasheet or a successful sensor-control transaction cannot establish the layout of a later memory buffer. A board change that preserves the camera module but changes the receive path can invalidate a previous allocation calculation.

Turn negotiated format into checked arithmetic

Zephyr’s pinned video interface expresses line pitch in bytes. Keep pitch distinct from width in pixels and from the format’s component interpretation. For a full-frame buffer, the relevant storage calculation uses the accepted row pitch and frame height, subject to the endpoint’s requirements.

Consider an illustrative 320-by-240 frame in the driver’s XRGB32 path. Four bytes per pixel produce a pitch of 1,280 bytes. Multiplying that pitch by 240 gives 307,200 bytes for the frame. Allocating 320 × 240 × 2 instead would provide only 153,600 bytes. These are derived layout numbers, not a supported-mode claim for any particular camera.

Perform multiplication in a type wide enough for the intermediate result and reject dimensions that exceed allocator or API limits. A later cast to a wider type cannot repair an earlier overflow. Record the returned pitch rather than silently replacing it with a remembered sensor-side formula.

If the product supports multiple camera modes, store the complete accepted format as one configuration generation. Buffer allocation and pixel conversion should refer to that same generation. A stale converter reading an old width can produce a plausible first row and corrupt every later one.

Include the endpoint’s queue requirements in the budget

For this pinned MCUX implementation, capabilities specify at least two buffers before streaming and full-frame buffers through LINE_COUNT_HEIGHT. The illustrative two-frame payload budget is therefore 614,400 bytes before allocator overhead, alignment, application copies, and unrelated camera-processing storage.

That is not a universal Zephyr minimum. Query and check the selected endpoint, and use its buffer allocation and memory-access requirements. A product that has enough memory for one expanded frame can still be unable to establish the required capture queue.

Keep a memory worksheet with separate rows for capture buffers, conversion output, inference input, display surfaces, and temporary processing space. Identify which allocations can genuinely share storage and which must coexist. Do not claim that a zero-copy design exists merely because two APIs accept a pointer; layout and access requirements still need to match.

Before admitting a new mode, calculate the entire concurrent budget. If it does not fit, choose a qualified lower-resolution mode or a different supported processing path. Silently allocating the old two-byte size is not a memory optimization.

Treat bytesused as metadata, not a capacity check

The MCUX enqueue path derives its transfer extent from configured pitch and height and writes that value into bytesused. In the examined function, it does not compare that extent with the buffer’s size before submitting its address to the CSI transfer layer.

The application should therefore validate capacity before enqueueing. Do not wait for dequeue and treat a large bytesused value as harmless information that can be clipped afterward. Truncating the consumer’s read length cannot retroactively protect memory that was too small for capture.

This is a source-level boundary review, not proof that an undersized buffer has overwritten memory on a tested board. Test rejection in a software adapter before hardware access. Do not deliberately submit a known undersized DMA buffer on a live product to discover whether an unreviewed lower layer happens to reject it.

Keep source and capture queries visibly different

The driver’s getter asks the source for its current format and then, in the MIPI-enabled path, converts the returned format back to the capture representation. Its setter performs the reverse adaptation for the source while retaining the output-side CSI configuration. This is deliberate translation, not evidence that either endpoint ignored a successful request.

A diagnostic command should label which device answered. Printing only “camera format: RGB565” after querying the sensor can conceal the application-facing XRGB32 contract. Capture both reports during qualification and explain the expected mismatch rather than forcing both names to agree.

The non-MIPI build path does not apply this same conditional conversion. Maintain separate expectations for those configurations; never remove the four-byte allocation rule globally because a parallel-input board uses another layout. Likewise, do not silently retry a rejected capture format by changing the format token without rebuilding the associated allocation plan.

After the endpoint contract is established, qualify component interpretation with a marked reference image and the selected format specification. Keep this separate from proving that the source-to-capture mapping and expanded capacity are correct.

Preserve a reproducible mode contract

For each accepted mode, retain source format, capture format, dimensions, returned pitch, capability results, allocated capacity, buffer count, and build configuration. Include a rejection fixture for a sensor-sized allocation presented to the expanded memory endpoint. Also test that changing modes invalidates the previous buffer plan before capture resumes.

No camera, DMA transfer, memory-overrun experiment, or image-quality benchmark was executed for this article. The outcome of the source analysis is a concrete review rule: size and decode the bytes that the capture endpoint produces, not the narrower representation that entered the pipeline.

Trend context

The preserved Google Trends export for “embedded os,” worldwide web search across all categories, July 19–October 19, 2026, lists “zephyr os” at +300% and “zephyr” at +40% among RISING related queries. Those figures support Zephyr-topic continuation, not a measured rise for MCUX camera buffers or this article’s title.

Similar Posts