Changes made to the source files in XilKernel v3.00a for the EDK 8.1i release cause MicroBlaze designs to not properly multi-thread. This has been exhibited on several designs using XMK combined with the lwIP library.
This problem has been fixed in the latest EDK 8.1i Service Pack, available at:
http://www.xilinx.com/xlnx/xil_sw_updates_home.jsp
The first service pack containing the fix is EDK 8.1i Service Pack 2.
A simple modification to the "mb-hw.c" file resolves this issue. This file can be found in the following directory:
$EDK/sw/lib/bsp/xilkernel_v3_00_a/src/src/arch/microblaze/
On line 278 is the definition for the pit_reset function. This function needs to be updated to the following:
void pit_reset ()
{
unsigned int control_reg;
// Obtain control register value from PIT device
control_reg = XTmrCtr_mGetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0);
// Refresh budget only if a new process is scheduled or if the timer ran out
if (did_resched || timer_need_refresh) {
// Re-load the interval value from load register and reset the interrupt occurred mask
XTmrCtr_mSetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
control_reg | XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK);
// Remove the load mask and also enable the timer
XTmrCtr_mSetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
(control_reg & (~XTC_CSR_LOAD_MASK)) | XTC_CSR_ENABLE_TMR_MASK);
did_resched = 0;
timer_need_refresh = 0;
} else {
// Enable the timer. No need to reset interrupt. That would have been covered by previous conditional
XTmrCtr_mSetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
(control_reg | XTC_CSR_ENABLE_TMR_MASK));
}
}