FPGARelated.com
Forums

Generate the first interrupt for MB XMK

Started by Jari January 7, 2004
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
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
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