Hi! My question is long, but bare with me. I am using EDK 3.2 and trying to get Microblaze XMK working from external memory. I have bootloader in BRAM, which copies the context of FLASH memory to SRAM memory and then jumps to SRAM. This context includes Xilkernel.elf and two processes: Shell.elf (This is from test/arch/microblaze/Shell.c) and Print.elf, which is simple "Hello World". Here is a snippet of my .MSS file BEGIN LIBRARY PARAMETER LIBRARY_NAME = xilkernel PARAMETER LIBRARY_VER = 1.00.a PARAMETER MAX_PROCS = 2 PARAMETER CONFIG_PROCESS = true PARAMETER CONFIG_PROCESS_EXIT = true PARAMETER CONFIG_PROCESS_KILL = true PARAMETER CONFIG_PROCESS_SLEEP = true PARAMETER CONFIG_PROCESS_YIELD = true PARAMETER THREAD_STACK_SIZE = 0x400 PARAMETER PROCESS_TABLE = ( (0x80806000, 1), (0x8080A000, 2)) PARAMETER SCHED_TYPE = 2 PARAMETER CONFIG_MUTEX = true PARAMETER CONFIG_SEMA = true PARAMETER CONFIG_MSGQ = true PARAMETER CONFIG_THREAD_SUPPORT = true PARAMETER MSGQ_TABLE = ( (10, 10), (15, 15) ) END Bootloader works correctly and I have 3 .ELF files in SRAM memory. My problem is how to generate the first interrupt to get the first process scheduled. Like said in xilkernel_v1_00_a/src/src/sys/main.c file * @file main.c * * The main routine, that starts the kernel. * * Enables the Interrupts and starts the timer Interrupt. * Initialises the system by calling sys_init() and loops. On first timer * interrupt the first process gets scheduled. From MB_XILKERNEL part the code seems to be incomplete so I have tried to add following lines to main.c file #ifdef MB_XILKERNEL /* Enable microblaze interrupts */ microblaze_enable_interrupts(); /* Start the interrupt controller */ XIntc_mMasterEnable(XPAR_MY_OPB_INTC_BASEADDR); /* Set the number of cycles the timer counts before interrupting */ XTmrCtr_mSetLoadReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, 100); /* Reset the timer and clear interrupts */ XTmrCtr_mSetControlStatusReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK); /* Enable timer interrupt in the interrupt controller */ XIntc_mEnableIntr(XPAR_MY_OPB_INTC_BASEADDR, XPAR_MY_OPB_TIMER_INTERRUPT_MASK); /* Start the timer */ XTmrCtr_mSetControlStatusReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK); #endif I was hoping to set timer to count and give interrupt so I can get the first interrupt. But I am stuck in here, end of main.c file, waiting interrupt to occur. while(1) { /* Keep looping....*/ print("Hi!\r\n") ; } return 0 ; I have checked every value of these XPAR_... and XTC_... variables and they are ok. I am guessing that I am missing Interrupt routine, like timer_int_handler or something like that. In the same folder where main.c is located there is also timer_intr.S file. If I have understood correctly this should be Microblaze Xilkernel timer_intr_handler? Why it is not working? What am I missing? Am I trying in a wrong way to get an interrupt to occur? Should there be line PARAMETER INT_HANDLER = timer_intr_handler, INT_PORT = Interrupt in my .MSS file? Thanks, Jari
Generate the first interrupt for MB XMK
Started by ●January 7, 2004
Reply by ●January 7, 20042004-01-07
Jari, Your code looks mostly fine so this could be a hardware problem. Check your MHS file to see if the interrupt pin of MicroBlaze is hooked up to the interrupt controller, and the interrupt controller is hooked up to the timer. Once you begin to see the interrupts, there are a few small issues that should be fixed before everything works. 1) MAX_PROCS should be set to at least 1 more than the number of procs you specify in the table because there is a default system idle process that needs to be created. 2) you don't need to specify the interrupt handler in the MSS file. XMK always goes to the timer interupt handler in timer_intr.S when an interrupt occurs. After the call to the process_scheduler in that code, you will need to add code to ack/clear the timer interrupt. If you want to avoid assembly language programming, the simplest thing to do is to write all this new code as a C function and use a single assembly instruction brlid to call this C function. If you want to handle additional interrupts, you could replace timer_intr.S with your own code to handle the other interrupts and call the process scheduler as appropriate. All of this has been automated in the upcoming release of our software if you would rather wait for it. 3) if you want to modify source code for XMK, please remember to copy the entire directory from $EDK/sw/ProcessorIPLib/sw_services/xilkernel* to your project directory/sw_services/xilkernel* and do not modify the sources in your project directory/<proc_name>/libsrc/xilkernel* 4) The value of 100 in the timer setup code could result in too many interrupts. You might want to increase the number of cycles before an interrupt to something bigger, like 0xffff. You could also try to run everything from BRAM and see if things work correctly. Best wishes, Mohan Jari wrote:> > Hi! > > My question is long, but bare with me. I am using EDK 3.2 and trying > to get Microblaze XMK working from external memory. I have bootloader > in BRAM, which copies the context of FLASH memory to SRAM memory and > then jumps to SRAM. This context includes Xilkernel.elf and two > processes: Shell.elf (This is from test/arch/microblaze/Shell.c) and > Print.elf, which is simple "Hello World". Here is a snippet of my .MSS > file > > BEGIN LIBRARY > PARAMETER LIBRARY_NAME = xilkernel > PARAMETER LIBRARY_VER = 1.00.a > PARAMETER MAX_PROCS = 2 > PARAMETER CONFIG_PROCESS = true > PARAMETER CONFIG_PROCESS_EXIT = true > PARAMETER CONFIG_PROCESS_KILL = true > PARAMETER CONFIG_PROCESS_SLEEP = true > PARAMETER CONFIG_PROCESS_YIELD = true > PARAMETER THREAD_STACK_SIZE = 0x400 > PARAMETER PROCESS_TABLE = ( (0x80806000, 1), (0x8080A000, 2)) > PARAMETER SCHED_TYPE = 2 > PARAMETER CONFIG_MUTEX = true > PARAMETER CONFIG_SEMA = true > PARAMETER CONFIG_MSGQ = true > PARAMETER CONFIG_THREAD_SUPPORT = true > PARAMETER MSGQ_TABLE = ( (10, 10), (15, 15) ) > END > > Bootloader works correctly and I have 3 .ELF files in SRAM memory. My > problem is how to generate the first interrupt to get the first > process scheduled. Like said in xilkernel_v1_00_a/src/src/sys/main.c > file > > * @file main.c > * > * The main routine, that starts the kernel. > * > * Enables the Interrupts and starts the timer Interrupt. > * Initialises the system by calling sys_init() and loops. On first > timer > * interrupt the first process gets scheduled. > > From MB_XILKERNEL part the code seems to be incomplete so I have tried > to add following lines to main.c file > > #ifdef MB_XILKERNEL > /* Enable microblaze interrupts */ > microblaze_enable_interrupts(); > > /* Start the interrupt controller */ > XIntc_mMasterEnable(XPAR_MY_OPB_INTC_BASEADDR); > > /* Set the number of cycles the timer counts before interrupting > */ > XTmrCtr_mSetLoadReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, 100); > > /* Reset the timer and clear interrupts */ > XTmrCtr_mSetControlStatusReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, > XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK); > > /* Enable timer interrupt in the interrupt controller */ > XIntc_mEnableIntr(XPAR_MY_OPB_INTC_BASEADDR, > XPAR_MY_OPB_TIMER_INTERRUPT_MASK); > > /* Start the timer */ > XTmrCtr_mSetControlStatusReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, > XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | > XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK); > #endif > > I was hoping to set timer to count and give interrupt so I can get the > first interrupt. But I am stuck in here, end of main.c file, waiting > interrupt to occur. > > while(1) { /* Keep looping....*/ > print("Hi!\r\n") ; > } > return 0 ; > > I have checked every value of these XPAR_... and XTC_... variables and > they are ok. I am guessing that I am missing Interrupt routine, like > timer_int_handler or something like that. In the same folder where > main.c is located there is also timer_intr.S file. If I have > understood correctly this should be Microblaze Xilkernel > timer_intr_handler? Why it is not working? What am I missing? Am I > trying in a wrong way to get an interrupt to occur? Should there be > line > > PARAMETER INT_HANDLER = timer_intr_handler, INT_PORT = Interrupt > > in my .MSS file? > > Thanks, > Jari
Reply by ●January 8, 20042004-01-08
Hi Mohan! Thank you for your answer. It was very helpful. But I have not solved the problem. I have written int_handler.c code to test the interrupt. This code is placed in BRAM and there is no XMK. I have also added the interrupt handler in my .MSS file. Now I can see both timer given interrupt and interrupt controller given interrupt in Logic Analyzer. The main function of the int_handler is the same as what I have added in XMK main.c file. But when I tried to run XMK in SRAM, there is no interrupt from timer or interrupt controller. Available BRAM size is so small that XMK do not fit in there. I have to try somehow to debug what goes wrong... Any ideas? Thanks, Jari mohan <mohan@xilinx.com> wrote in message news:<3FFC5AE3.DA700D8B@xilinx.com>...> Jari, > Your code looks mostly fine so this could be a hardware problem. Check your MHS file to see if the interrupt pin of MicroBlaze is hooked up to the interrupt controller, and the interrupt controller > is hooked up to the timer. > Once you begin to see the interrupts, there are a few small issues > that should be fixed before everything works. > 1) MAX_PROCS should be set to at least 1 more than the number of procs you specify in the table because > there is a default system idle process that needs to be created. > 2) you don't need to specify the interrupt handler in the MSS file. XMK always goes to the timer interupt handler > in timer_intr.S when an interrupt occurs. After the call to the process_scheduler in that code, you will need to add code to > ack/clear the timer interrupt. If you want to avoid assembly language programming, the simplest thing to do is to write > all this new code as a C function and use a single assembly instruction brlid to call this C function. If you want > to handle additional interrupts, you could replace timer_intr.S with your own code to handle the other interrupts and > call the process scheduler as appropriate. > All of this has been automated in the upcoming release of our software if you would rather wait for it. > 3) if you want to modify source code for XMK, please remember to copy the entire directory from $EDK/sw/ProcessorIPLib/sw_services/xilkernel* to your project directory/sw_services/xilkernel* and do > not modify the sources > in your project directory/<proc_name>/libsrc/xilkernel* > 4) The value of 100 in the timer setup code could result in too many interrupts. You might want to increase the number of cycles before an interrupt to something bigger, like 0xffff. > > You could also try to run everything from BRAM and see if things work correctly. > > Best wishes, > Mohan > > > > Jari wrote: > > > > Hi! > > > > My question is long, but bare with me. I am using EDK 3.2 and trying > > to get Microblaze XMK working from external memory. I have bootloader > > in BRAM, which copies the context of FLASH memory to SRAM memory and > > then jumps to SRAM. This context includes Xilkernel.elf and two > > processes: Shell.elf (This is from test/arch/microblaze/Shell.c) and > > Print.elf, which is simple "Hello World". Here is a snippet of my .MSS > > file > > > > BEGIN LIBRARY > > PARAMETER LIBRARY_NAME = xilkernel > > PARAMETER LIBRARY_VER = 1.00.a > > PARAMETER MAX_PROCS = 2 > > PARAMETER CONFIG_PROCESS = true > > PARAMETER CONFIG_PROCESS_EXIT = true > > PARAMETER CONFIG_PROCESS_KILL = true > > PARAMETER CONFIG_PROCESS_SLEEP = true > > PARAMETER CONFIG_PROCESS_YIELD = true > > PARAMETER THREAD_STACK_SIZE = 0x400 > > PARAMETER PROCESS_TABLE = ( (0x80806000, 1), (0x8080A000, 2)) > > PARAMETER SCHED_TYPE = 2 > > PARAMETER CONFIG_MUTEX = true > > PARAMETER CONFIG_SEMA = true > > PARAMETER CONFIG_MSGQ = true > > PARAMETER CONFIG_THREAD_SUPPORT = true > > PARAMETER MSGQ_TABLE = ( (10, 10), (15, 15) ) > > END > > > > Bootloader works correctly and I have 3 .ELF files in SRAM memory. My > > problem is how to generate the first interrupt to get the first > > process scheduled. Like said in xilkernel_v1_00_a/src/src/sys/main.c > > file > > > > * @file main.c > > * > > * The main routine, that starts the kernel. > > * > > * Enables the Interrupts and starts the timer Interrupt. > > * Initialises the system by calling sys_init() and loops. On first > > timer > > * interrupt the first process gets scheduled. > > > > From MB_XILKERNEL part the code seems to be incomplete so I have tried > > to add following lines to main.c file > > > > #ifdef MB_XILKERNEL > > /* Enable microblaze interrupts */ > > microblaze_enable_interrupts(); > > > > /* Start the interrupt controller */ > > XIntc_mMasterEnable(XPAR_MY_OPB_INTC_BASEADDR); > > > > /* Set the number of cycles the timer counts before interrupting > > */ > > XTmrCtr_mSetLoadReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, 100); > > > > /* Reset the timer and clear interrupts */ > > XTmrCtr_mSetControlStatusReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, > > XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK); > > > > /* Enable timer interrupt in the interrupt controller */ > > XIntc_mEnableIntr(XPAR_MY_OPB_INTC_BASEADDR, > > XPAR_MY_OPB_TIMER_INTERRUPT_MASK); > > > > /* Start the timer */ > > XTmrCtr_mSetControlStatusReg(XPAR_MY_OPB_TIMER_BASEADDR, 0, > > XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | > > XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK); > > #endif > > > > I was hoping to set timer to count and give interrupt so I can get the > > first interrupt. But I am stuck in here, end of main.c file, waiting > > interrupt to occur. > > > > while(1) { /* Keep looping....*/ > > print("Hi!\r\n") ; > > } > > return 0 ; > > > > I have checked every value of these XPAR_... and XTC_... variables and > > they are ok. I am guessing that I am missing Interrupt routine, like > > timer_int_handler or something like that. In the same folder where > > main.c is located there is also timer_intr.S file. If I have > > understood correctly this should be Microblaze Xilkernel > > timer_intr_handler? Why it is not working? What am I missing? Am I > > trying in a wrong way to get an interrupt to occur? Should there be > > line > > > > PARAMETER INT_HANDLER = timer_intr_handler, INT_PORT = Interrupt > > > > in my .MSS file? > > > > Thanks, > > Jari