Howto make the right changes to get the FreeRTOS Microblaze port working with EDK 9.1 and higher ============================================================================= File freertos/source/portable/gcc/Microblaze/portasm.s: Replace all (2) appearances of __FreeRTOS_interrupt_handler With: _interrupt_handler Background: The Microblaze GCC will use the function as interrupt handler that is named _interrupt_handler() File freertos/source/portable/gcc/Microblaze/port.c: 1. Top of the file (near line 97), after static void prvSetupTimerInterrupt( void ); Add /* * Handler for the timer interrupt. */ void vTickISR( void *pvBaseAddress ); 2. In function xPortStartScheduler() (near line 206), remove extern void ( __FreeRTOS_interrupt_Handler )( void ); and /* Setup the FreeRTOS interrupt handler. Code copied from crt0.s. */ asm volatile ( "la r6, r0, __FreeRTOS_interrupt_handler\n\t" \ "sw r6, r1, r0\n\t" \ "lhu r7, r1, r0\n\t" \ "shi r7, r0, 0x12\n\t" \ "shi r6, r0, 0x16 " ); 3. Replace function prvSetupTimerInterrupt() (near line 261) with static void prvSetupTimerInterrupt( void ) { const unsigned portLONG ulCounterValue = configCPU_CLOCK_HZ / configTICK_RATE_HZ; unsigned portLONG ulMask; /* The OPB timer1 is used to generate the tick. Use the provided library functions to enable the timer and set the tick frequency. */ /* Register handler for timer 1 */ XIntc_RegisterHandler(XPAR_OPB_INTC_0_BASEADDR, XPAR_OPB_INTC_0_OPB_TIMER_1_INTERRUPT_INTR, (XInterruptHandler) vTickISR, (void *)XPAR_OPB_TIMER_1_BASEADDR); /* Set the number of cycles the timer counts before interrupting */ XTmrCtr_mSetLoadReg(XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCounterValue); /* Enable the interrupt in the interrupt controller while maintaining all the other bit settings. */ ulMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) ); ulMask |= XPAR_OPB_TIMER_1_INTERRUPT_MASK; XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, ulMask); /* Reset the timers, and clear interrupts */ XTmrCtr_mSetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK ); } Background: Read Xilinx Applciation note 778 (XAPP778) 4. Replace function vTaskISRHandler (near line 291) with void vTaskISRHandler( void ) { /* Call the Xilinx interrupt handler provided by the OPB Interrupt Controller */ XIntc_DeviceInterruptHandler(0); } File freertos/demo/MicroBlaze/serial/serial.c (If using): 1. Top of the file (near line 69), add void vSerialISR( void *pvBaseAddress ); 2. Replace function xSerialPortInitMinimal() (near line 80) with xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { unsigned portLONG ulControlReg, ulMask; /* NOTE: The baud rate used by this driver is determined by the hardware parameterization of the UART Lite peripheral, and the baud value passed to this function has no effect. */ /* Create the queues used to hold Rx and Tx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); if( ( xRxedChars ) && ( xCharsForTx ) ) { /* Disable the interrupt. */ XUartLite_mDisableIntr( XPAR_RS232_UART_BASEADDR ); /* Flush the fifos. */ ulControlReg = XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_STATUS_REG_OFFSET ); XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_CONTROL_REG_OFFSET, ulControlReg | XUL_CR_FIFO_TX_RESET | XUL_CR_FIFO_RX_RESET ); /* Enable the interrupt again. The interrupt controller has not yet been initialised so there is no chance of receiving an interrupt until the scheduler has been started. */ XUartLite_mEnableIntr( XPAR_RS232_UART_BASEADDR ); /* Enable the interrupt in the interrupt controller while maintaining all the other bit settings. */ ulMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) ); ulMask |= XPAR_RS232_UART_INTERRUPT_MASK; XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, ulMask); /* Register UART interrupt handler */ XIntc_RegisterHandler(XPAR_OPB_INTC_0_BASEADDR, XPAR_OPB_INTC_0_RS232_UART_INTERRUPT_INTR, (XInterruptHandler) vSerialISR, (void *)XPAR_RS232_UART_BASEADDR); } return ( xComPortHandle ) 0; }