Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Mutex - uClinux (without mmu)

Hi

I have a project thar includes 2 NIOS2 CPUs. Both need to access the same memory area in an SRAM. One of the CPUs runs software developed with the NIOS2 IDE, another runs uClinux.

To control access to SRAM, I tried to use a mutex (altera_avalon_mutex). In the CPU that runs the NIOS2 IDE software, I used altera_avalon_mutex_open, altera_avalon_mutex_lock and altera_avalon_mutex_unlock functions. Since I have no access to these functions in uClinux, I develop my own lock and unlock functions based on mutex documentation (Altera) and the mutex source code.

The uClinux CPU has cpuid = 0, and the mutex address is 0x00000000.

Below is my implementation of the functions lock and unlock.

void lock(void)
{
     do
     {
           outl(0x00000001, 0x00000000); // CPUID = 0, VALUE = 1 at address 0x00000000 (register "mutex")
     }
     while (inl(0x00000000) != 0x00000001); // register "mutex" must have the written value to lock.
}
  
void unlock(void)
{
     outl(0x00000001, 0x00000001); // register "reset", RESET = 1
     outl(0x00000000, 0x00000000); // register "mutex", CPUID = 0, VALUE = 1
}
The implementation of mutex in uClinux not worked, it means that both CPUs had accessed memory at same time. Is my implementation correct? Can anyone please help me?

Thanks

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I might be off on this -- I'm not sure what the outl/inl macros do in uClinux, they might take care of this.

    Without an MMU, the NIOS uses bit 31 to flag cached or uncached accesses. Since you have two processors accessing that memory, you have to set it to make sure the access is uncached. So you actually have to read/write 0x80000000
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Also try using something other than 0 for the ID. I am using 1 and 2 for my CPUs rather than 0 and 1, but I don't remember if there was a reason for this. As far as I can tell the CPU IDs for the locks are arbitrary.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks ykozlov. I'll try to use 0x80000000 (mutex) and 0x80000001 (reset), and cpuid = 2. I'll post the results later.

    Another question: my shared SRAM has base address = 0x04000000. Should I read/write it using base address = 0x84000000?

    Thanks again
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Another question: my shared SRAM has base address = 0x04000000. Should I read/write it using base address = 0x84000000?

    --- Quote End ---

    If you want data to be immediately visible to another processor or peripheral, yes. I am pretty sure there are macros in uClinux that take care of this for you, check -- you might already be using them. (I am using the MMU version so can't check quickly myself). For Altera HAL, have a look at alt_remap_uncached and alt_dcache_flush.