TDA4AEN-Q1: DMA-based DDR access protection using spinlock

Part Number: TDA4AEN-Q1

Shared data in DDR can be accessed by multi-cores. Some data, like the point cloud, is large, so we store it in DDR rather than transmit it via IPC RPMessage. Both main R5F and C7x will access the data, and we need protection against simultaneous write/read.
e.g.
C7x: Spinlock_lock() -> write point cloud to DDR via UDMA -> Spinlock_unlock()
main R5F: Spinlock_lock() -> read point cloud from DDR via UDMA -> Spinlock_unlock()

Based on spinlock descriptions in SDK, it can be used for synchronization between multi-cores, but the guideline also states the time to hold the lock should be predictable and small. In our case, the lock(DDR access) time may not be so small.
https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-j722s/11_02_01_03/exports/docs/mcu_plus_sdk_j722s_11_02_01_05/docs/api_guide_j722s/DRIVERS_SPINLOCK_PAGE.html

Is it suitable to use spinlock to protect DDR access? If not, any other suggestion?

  • Hello, Expert.

    YT is my customer.

    Could you help it?

    I saw SIE already has few recomments, but I am not sure it is reasonable.

    Thank You.

    Gibbs

  • Hello,

    On a UDMA transfer it is not correct to keep a spin lock because the spin lock expectation will be micro seconds but UDMA data transfer might take milli seconds.

    Let say C7x takes a free space in DDR and do DMA operation to fill the data , Now it informs the other core Main R5F to read via RP Message along with address . 

    Main R5F gets an interrupt from C7x and reads the address in DDR . RP message uses mail box instead of Spin lock . The data may not be present in RP Message but flag to read and address can be present.

    Regards

    Tarun Mukesh

  • Hi Tarun Mukesh,

    Our use case is more complex. Main R5F doesn't read the DDR data immediately after C7x writes it. Instead, the read/write can happen anytime, and there may be more cores(e.g. main R5F, C7x-0, C7x-1) accessing the same data. Therefore, we originally want a general protection mechanism.

    If using IPC RPMessage, C7x may need to send an IPC to main R5F when write starts, and another IPC when write finishes, so main R5F can prevent access during the write. If more cores access the data, more pairs of IPC are needed. This makes the design complex.

    Do you have other suggestion on our use case? Thanks!

    BR,

    YT

  • Hello,

    Our use case is more complex. Main R5F doesn't read the DDR data immediately after C7x writes it. Instead, the read/write can happen anytime, and there may be more cores(e.g. main R5F, C7x-0, C7x-1) accessing the same data. Therefore, we originally want a general protection mechanism.

    Even though Main R5F doesn't read DDR data immediately you can keep a flag that write happened from C7x . You can send the information to whatever cores needed.

    If using IPC RPMessage, C7x may need to send an IPC to main R5F when write starts, and another IPC when write finishes, so main R5F can prevent access during the write. If more cores access the data, more pairs of IPC are needed. This makes the design complex.

    This design is already present in IPC from our RTOS driver . All pair combinations R5F, C7x and A72 is available. This interrupt hardly takes micro seconds shouldn't be an issue.

    Even with spin lock concept , you can't just lock it for longer time . May be you can try below proposal.

    1. Shared control block in DDR (non-cached or explicitly maintained) holding buffer state: FREE / WRITING / READY / READING.
    2. Producer (C7x): Spinlock_lock() → claim a free buffer, mark WRITING → Spinlock_unlock() → run UDMA write → Spinlock_lock() → mark READY → Spinlock_unlock().
    3. Consumer (R5F): same pattern — short lock to claim a READY buffer, unlock, DMA read, short lock to release.

    Regards

    Tarun Mukesh

  • SInce you are looking kind of broadcast where everyone get same data then the proposal might work.

    • Shared control block in DDR (non-cached or explicitly maintained) holding buffer state: FREE / WRITING / READY / READING.
    • Producer (C7x): Spinlock_lock() → claim a free buffer, mark WRITING → Spinlock_unlock() → run UDMA write → Spinlock_lock() → mark READY → Spinlock_unlock().
    • Consumer (R5F): same pattern — short lock to claim a READY buffer, unlock, DMA read, short lock to release.

    The time to hold the spinlock is predictable and small (for example, a maximum hold time of less than 200 CPU cycles may be acceptable)

    Regards

    Tarun Mukesh

  • Hi Tarun Mukesh,

    If using IPC, how to prevent: when main R5F is reading the data, C7x wants to write it? This might cause main R5F to get incorrect data.

    The proposal of shortened spinlock period with buffer state may be better.

    BR,

    YT

  • Hello,

    If using IPC, how to prevent: when main R5F is reading the data, C7x wants to write it? This might cause main R5F to get incorrect data.

    The proposal of shortened spinlock period with buffer state may be better.

    we can add a flag to block it but more cores are involved it will be complex in application .Anyways it has broadcast message you can go ahead with shorter spin lock with buffer state.

    Regards

    Tarun Mukesh