2021-09-27 02:54 AM
I want to use part of the SRAM3 shared memory for data transfer between the A7 cores and the M4 core. On the A7 core I used mmap on /dev/mem to remap the sram to user space and copy the data to/from the SRAM3 buffers. The result is however not stable.
When reading the data at the M4 side the data sometimes seems to be changed.
On the M4 side I did add an extra memory area (RAM3_ipc_shm):
MEMORY
{
RETRAM_interrupts (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00000298
FLASH_text (rx) : ORIGIN = 0x10000000, LENGTH = 128K
RAM1_data (xrw) : ORIGIN = 0x10020000, LENGTH = 128K
RAM2_ipc_shm (xrw) : ORIGIN = 0x10040000, LENGTH = 0x00008000
RAM3_ipc_shm (xrw) : ORIGIN = 0x10048000, LENGTH = 0x00004000
}
And just read /write to this area like:
volatile uint16_t *data_in = 0x10048000;
volatile uint16_t *data_out = 0x1004A000;
nof_write_bits = 16 * data_in[0];
// set output data
for (int i = 0; .....
{
// DO0-DO3 & clear data clock & clear latch
outputs0 = (data_in[4 + i] << 11) & DO03_mask;
// D04-D05
outputs1 = (data_in[4 + i] << (14 - 4)) & DO45_mask;
// read inputs
inputs0 = (uint16_t) ((DI0_GPIO_Port->IDR & DI03_mask) >> 3);
inputs1 = (uint16_t) ((DI4_GPIO_Port->IDR & DI45_mask) >> (12 - 4));
data_out[i - read_bits_offs] = inputs0 | inputs1;
}
On the A7 side:
volatile uint8_t *the_smem_buf;
volatile uint8_t *the_read_pos;
// Map the shared memory windows
the_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
the_smem_buf = static_cast<volatile uint8_t *>(mmap (NULL, 0x4000, PROT_READ | PROT_WRITE, MAP_SHARED, the_mem_fd, 0x10048000));
the_read_pos = the_smem_buf + 0x2000;
// write data to M4
for (int i = 0; i < len; i++)
the_smem_buf[i] = ((uint8_t *) pData)[i];
// read data from M4
memcpy(pData, (void *) the_read_pos, len);
I use the rpmsg mechanism to sync between writes and reads to the M4 core.
Observations: for the first 4 16 bit values in the shared data buffer everything looks OK, but when having non-zero data in higher regions, the data sometimes is missing or non-zero where it should be zero.
Any idea what goes wrong here? Do I have to add the memory area to the device tree? Or is it not possible at all to do transfer by a memory mapped area? Is there something missing in the memory map in the linker script at the M4 side?
Solved! Go to Solution.
2021-09-28 11:54 PM
Patrick and Olivier,
Thanks for your help. Took me some effort but I did find out that the synchronization between the A7 core and the M4 with RPMsg was causing the problem: at the start I send a start command over RPMsg and waited for the M4 to reply over RPMsg, but somehow another messages was received, causing a synchronization mismatch, causing a write of new data by the A7 core before the M4 had finished its cycle. I repaired this by introducing a serial id in my communication over RPMsg.
With the synchronization fixed, I could remove the sleeps of 200us and everything worked OK.
So lessons learned: mapping SRAM memory to user space with mmap on /dev/mem does work ok! No specific driver for mapping the SRAM is needed, neither the specification of the memory area in the DT (although I think it is wise to do, to be clear that the memory area is used).
2021-09-27 05:45 AM
I did find out that when doing a sleep of 200 usec just before the write and read of 1KB at the A7 core the problem seems to have disappeared.
Probably some timing issue which I don't understand. The strange thing is that the extra sleep is not between the write at the A7 side and the read on the M4 side, but just before the next write at the A7 side, it looks like that when not doing the extra sleep that some data of the previous write cycle will not be overwritten by the newly written data.. Does someone have an explanation for this behavior?
Kees van Walraven
2021-09-27 06:02 AM
Hi,
I'm not expert, but I found this post which might be relevant for you:
https://community.st.com/s/question/0D53W00000uXp2hSAC/rpmsg-sdb-cached-buffer
Regards.
2021-09-27 06:20 AM
Hi @Kvan .6 ,
post https://community.st.com/s/question/0D53W000013pGreSAE/reallocation-of-sram-memory-to-stm32mp157a may also be relevant.
You have to take care that new partitioning of SRAM3 is properly declared in Linux DT
Olivier
2021-09-28 11:54 PM
Patrick and Olivier,
Thanks for your help. Took me some effort but I did find out that the synchronization between the A7 core and the M4 with RPMsg was causing the problem: at the start I send a start command over RPMsg and waited for the M4 to reply over RPMsg, but somehow another messages was received, causing a synchronization mismatch, causing a write of new data by the A7 core before the M4 had finished its cycle. I repaired this by introducing a serial id in my communication over RPMsg.
With the synchronization fixed, I could remove the sleeps of 200us and everything worked OK.
So lessons learned: mapping SRAM memory to user space with mmap on /dev/mem does work ok! No specific driver for mapping the SRAM is needed, neither the specification of the memory area in the DT (although I think it is wise to do, to be clear that the memory area is used).