Forum Discussion
Hi, Kian,
Thank you for supporting the case. It seems it indeed is a race condition or no protection access to the share resource.
One correction: when the code was changed from:
altera_avalon_fifo_clear_event(FIFO_CSR_BASE, ALTERA_AVALON_FIFO_EVENT_AE_MSK);
altera_avalon_fifo_write_ienable(FIFO_CSR_BASE, ALTERA_AVALON_FIFO_IENABLE_AE_MSK);
to:
// FIFO_CSR_BASE = 0x610020
// ALTERA_AVALON_FIFO_EVENT_AE_MSK = 0x08
// ALTERA_AVALON_FIFO_IENABLE_AE_MSK = 0x08
OS_ENTER_CRITICAL();
altera_avalon_fifo_clear_event(0x610020, 0x08);
altera_avalon_fifo_write_ienable(0x610020, 0x08);
OS_EXIT_CRITICAL();
The exception in fact happened in a different function in a different task. The exception is the first line of the following code:
nLevel = altera_avalon_fifo_read_level(TRIGGERDATA_FIFO_IN_CSR_BASE);
nStatus = altera_avalon_fifo_read_status(TRIGGERDATA_FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_STATUS_ALL));
The TRIGGERDATA_FIFO_IN_CSR_BASE is a different symbolic constant to the same value or address: 0x610020, which is same as FIFO_CSR_BASE used in the previously exception-causing function: altera_avalon_fifo_write_ienable().
After comment out these two lines:
nLevel = altera_avalon_fifo_read_level(TRIGGERDATA_FIFO_IN_CSR_BASE);
nStatus = altera_avalon_fifo_read_status(TRIGGERDATA_FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_STATUS_ALL))
No exception happened anymore.
So I used the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() to modify the code in both tasks as follows:
In one task (higher priority), changed from:
altera_avalon_fifo_clear_event(FIFO_CSR_BASE, ALTERA_AVALON_FIFO_EVENT_AE_MSK);
altera_avalon_fifo_write_ienable(FIFO_CSR_BASE, ALTERA_AVALON_FIFO_IENABLE_AE_MSK);
to:
// FIFO_CSR_BASE = 0x610020
// ALTERA_AVALON_FIFO_EVENT_AE_MSK = 0x08
// ALTERA_AVALON_FIFO_IENABLE_AE_MSK = 0x08
OS_ENTER_CRITICAL();
altera_avalon_fifo_clear_event(FIFO_CSR_BASE, ALTERA_AVALON_FIFO_EVENT_AE_MSK);
altera_avalon_fifo_write_ienable(FIFO_CSR_BASE, ALTERA_AVALON_FIFO_IENABLE_AE_MSK);
OS_EXIT_CRITICAL();
In the other task (lower priority):
Changed from:
nLevel = altera_avalon_fifo_read_level(TRIGGERDATA_FIFO_IN_CSR_BASE);
nStatus = altera_avalon_fifo_read_status(TRIGGERDATA_FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_STATUS_ALL))
to:
OS_ENTER_CRITICAL();
nLevel = altera_avalon_fifo_read_level(TRIGGERDATA_FIFO_IN_CSR_BASE);
nStatus = altera_avalon_fifo_read_status(TRIGGERDATA_FIFO_IN_CSR_BASE, ALTERA_AVALON_FIFO_STATUS_ALL))
OS_EXIT_CRITICAL();
Doing so, the access to same memory or FIFO peripheral 0x610020 is synchronized or protected by temporarily disabling the processor's interrupts.
Most likely the changes will fix the exception/hang/lockup. But I have not get the it tested yet. I will let you know the test result.
Two questions:
1. During disabled interrupts period, the task will not switch while executing the code within the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL(). which only delays the tasks switch and/or increases the interrupt response time momentarily, right?
2. Shall a mutex with PIP (priority inheritance priority) be used instead of critical section?
Thank you, Kian.
Patrick