- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
I've created a qsys system composed of two NIOS, each one attached to its on-chip memory that contains its program. the two processors are connected to a shared RAM protected via a HW mutex core. I need that the first NIOS writes a data in the shared memory to be read by the second processor. I write the following code for the first NIOS: altera_avalon_mutex_lock( mutex, 1 ); if(altera_avalon_mutex_is_mine(mutex)) IOWR_32DIRECT(SHM,0x4,0x3); altera_avalon_mutex_unlock( mutex ); And for the second NIOS: altera_avalon_mutex_lock( mutex, 1 ); if(altera_avalon_mutex_is_mine(mutex)) { data = IORD_32DIRECT(SHM,0x4); printf ("data = %x \n",data);} altera_avalon_mutex_unlock( mutex ); However, the NIOS2 always read a strange value (different from 0x3) Please could anyone help me to solve the problem? Thanks in advance,Link Copied
11 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
please any one could answer??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did the mutex device open correctly? (i.e. is mutex not NULL)
Can you ensure that the lock on the first CPU was successful, for example by writing something from inside the if ? Are you sure the second CPU is reading the value after the first one set it?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've added this code at teh beginning of the program to test if teh mutex is not NULL:
mutex = altera_avalon_mutex_open(MUTEX_NAME); if (mutex == NULL) /* for testing only */ { error_code = ERROR_OPENED_INVALID_MUTEX; printf("error \n"); goto error; } The two cpu do not access to this if, this means that the mutex is not NULL, I also added a printf inside the if of cpu1 after wrinting data, which displays hello in console and it's OK However the data read by cpu2 is fault How to be sure that the second CPU is reading the value after the first one set it? Please help me- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Firstly make sure that the memory area you are using for SHM isn't also used by some other part of the system.
I'd then use a sequence something like: 1) CPUB: write C0 to SHM(0) 2) CPUB: wait for SHM(1) to be C1 3) CPUA: wait for SHM(0) to be C0 4) CPUA: Acquire mutex 5) A: write SMH(1) C1 6) B: Acquire mutex (should spin) 7) A: Loop for a moderate fraction of a second 8) A: Write SMH(0) C2 9) A: Release mutex - B should run 10) B: Check SHM(1) is C1 and SMH(0) C2 11) B: release mutex I've not used the Altera mutex functions, and I wouldn't consider using and of the IOWR_32DIRECT() family of functions in any code I ever wrote - they are far, far, far, far too error prone. You really need to use C pointers and structures (but not bit fields of enums) to map hardware registers. You might need access functions (to do cache bypass, or because the 'pointer' actually references a different memory space), but you need the verificatiion that the offsets match the device pointer.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Firstly make sure that the memory area you are using for SHM isn't also used by some other part of the system. I'd then use a sequence something like: 1) CPUB: write C0 to SHM(0) 2) CPUB: wait for SHM(1) to be C1 3) CPUA: wait for SHM(0) to be C0 4) CPUA: Acquire mutex 5) A: write SMH(1) C1 6) B: Acquire mutex (should spin) 7) A: Loop for a moderate fraction of a second 8) A: Write SMH(0) C2 9) A: Release mutex - B should run 10) B: Check SHM(1) is C1 and SMH(0) C2 11) B: release mutex I've not used the Altera mutex functions, and I wouldn't consider using and of the IOWR_32DIRECT() family of functions in any code I ever wrote - they are far, far, far, far too error prone. You really need to use C pointers and structures (but not bit fields of enums) to map hardware registers. You might need access functions (to do cache bypass, or because the 'pointer' actually references a different memory space), but you need the verificatiion that the offsets match the device pointer. --- Quote End --- Please could you tell me how to make CPUB waiting for SHM(1) to be C1?? isn't this guaranteed by the mutex?? if one processor acquires the mutex, it doesn't mean that the other can't acquire it?? if you can provide me an example of code, I'll be very thankful,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
while (IORD_32DIRECT(SHM,0x4) != C1) continue; Without the mutex held.
You need to use mutex to make sure nothing happens between two separate actions (eg reading 2 variables, or a read-modify-write sequence), you don't need one to just read a variable - since you can't care whether you get the old or new value. Note that the loop above relies on the compiler not moving the memory read outside the loop. IORD_32DIRECT() is (hopefully) 'asm volatile' so can't be moved, if you are reading a normal C variable (accessed uncached) you need to declare the variable volatile (eg: volatile int x;)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- while (IORD_32DIRECT(SHM,0x4) != C1) continue; Without the mutex held. You need to use mutex to make sure nothing happens between two separate actions (eg reading 2 variables, or a read-modify-write sequence), you don't need one to just read a variable - since you can't care whether you get the old or new value. Note that the loop above relies on the compiler not moving the memory read outside the loop. IORD_32DIRECT() is (hopefully) 'asm volatile' so can't be moved, if you are reading a normal C variable (accessed uncached) you need to declare the variable volatile (eg: volatile int x;) --- Quote End --- Hi, I can't solve the problem the first cpu writes 4 in @ 0x0 in the second cpu: while (IORD_32DIRECT(SHM,0x0) != 4) {printf("waiting \n");} printf("data read = %d \n",IORD_32DIRECT(SHM,0x0) ); The cpu2 display a series of waiting in the console, this means that it doexn't read the right value written by cpu1 So , please what can i do?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you sure that both CPU are connected to the same shared memory, that SHM is the correct address, and that this memory isn't used for anything else? (including the text, ro, rw, bss, stack and head sections)
I'd suggest to put SignalTap probes on the shared memory control signals to verify that the first CPU is correctly writing the value and see what the second one is reading.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Are you sure that both CPU are connected to the same shared memory, that SHM is the correct address, and that this memory isn't used for anything else? (including the text, ro, rw, bss, stack and head sections) I'd suggest to put SignalTap probes on the shared memory control signals to verify that the first CPU is correctly writing the value and see what the second one is reading. --- Quote End --- Yes I'm sure that both CPU are connected to the shared RAM, this memory is only connected to cpu data masters, to clk and reset signals Could you please tell how use and put SignalTap probes on the shared mem? what are signal tap probes? is there any tutorial??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See this manual for SignalTap:
http://www.altera.com/literature/hb/qts/qts_qii53009.pdf In addition to the suggestions to Daixiwen, I would also suggest double checking that the memory contents are consistent from perspective of CPUA, and then as a small step forward, use the system-console to come in separately and dump the memory contents. I guess you could also use the memory window in Eclipse but system-console is more direct.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The SignalTap section of the Quartus manual is well written: http://www.altera.com/literature/hb/qts/qts_qii53009.pdf
You will need to find the control signals to your memory block, and monitor the address, read, write, read_data and write_data signals. Then you can trigger on either the read or the write signal to see what is happening.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page