I'm using MQX on a K70. I'm trying to determine if there is a connection between the priority of a task as set in the task_template_list, and the priority of an interrupt service routine (as set in the _bsp_int_init function) used by that task. Table 3-27 in the MQX User's Guide refers to hardware priority and task priority. Where is this "task priority" set? Is the hardware priority referred to in 3-27 the same priority set using the _bsp_int_init function? If I have an isr with a priority of 4, do I have to worry about the priority of the task? The task would be waiting for an event flag to be set by the isr.
MQX provides a kernel ISR, which is written in assembly. The purpose of the kernel ISR is to save the context of the active task, switch to the interrupt stack, it calls the appropriate ISR and after the ISR is returned, it restores the context of the highest priority ready task
My whole issue is I am trying to use SPI2 with DMA. When the DMA finishes, it calls a service routine. The problem comes when I go to install the service routine with the following statements:
_int_install_isr(DMA15_INTR_VECTOR, (INT_ISR_FPTR) MLCD_isr, NULL);
_bsp_int_init(DMA15_INTR_VECTOR, SPI_INTR_PRIORITY, 0, TRUE);
DMA_INTR_VECTOR is 31
MLCD_isr is the address of the interrupt service routine
If I set SPI_INTR_PRIORITY to 6, the isr never gets called. If I set it to 4 or 5, it does get called. What priority is it comparing it against?
Also in my program, I use the SD card driver (again this is using MQX and a K70). When the SD card driver is not installed the software always resets correctly when power is applied (Freescale tower board) or the reset button is pushed. When it is installed, the code does not always restart correctly. I turn on an LED on the board after the SPI transmits a string of characters (including the isr call), that's how I know. If the SD card driver is installed (sdcard_handle = OpenSDcard(sdcard_name); ), the software does not always reset correctly. At this point the only thing that is done with the SD card is to install the driver; no other reads or writes.
I trying to figure out how to narrow down where things are going wrong. Any suggestions?
According to section 3.9.3.4 in MQX user guide, ARM Cortex-M4 BASEPRI register values for different task priorities and different values of MQX_HARDWARE_INTERRUPT_LEVEL_MAX are shown in Table 3-46 (MQX 4.0.1). You can check the table to get the BASEPRI value. For Kinetis, default MQX_HARDWARE_INTERRUPT_LEVEL_MAX is 2, if your task priority is 1, then BASEPRI = 0X60, The most significant nibble is 0x6, which means only interrupt with hardware priority level 5 to level 0 can interrupt this task. Regarding your DMA_INTR_VECGTOR issue, you can increase the ISR priority (_bsp_int_init), or lower your task priority.
Hi Daniel,
This still doesn't make much sense to me. I understand how the BASEPRI register works on Cortex-M4. Your description above about the saving the task context still does not clarify things for me. Or the notion of a kernel ISR.
Some RTOS implementations require one to inform the kernel when an interrupt is entered and when it is leaving. For example an edge interrupt on a GPIO. In that interrupt you make a call to the kernel that an ISR is called, then it might call a service to the RTOS such as a post to a queue, then it makes a call that the ISR is exiting. During this last call the kernel examines its scheduler to decide if the action (post) within the ISR readied a task for a context switch. If it does it restored the context of the newly readied task instead of the one the ISR preempted.
Can you explain how MQX handles this simple example?
Many thanks,
Kenny
User's Guide Section 3.9 Revision 12 seems to explain exactly what I requested. The part I didn't understand is that MQX seems to have a generic interrupt handler that wraps the application ISR. So when an interrupt on the Cortex-M4F is invoked this wrapper ISR is called which looks up the application installed function to call. The generic handler effectively performs the scheduler work to restore the context of whatever task is ready to run.
If this is the case then task priorities are truly only a function of the scheduler and are unrelated to the ISR priority (as they should be).
The other issue is how to install a zero-latency interrupt which has no RTOS overhead if required.
Hello Kenny,
In this graph you can see how MQX is managing the hardware interrupts:
int_kernel_isr() manages:
− saving the context of the active task
− switching to the interrupt stack
− calling the appropriate second-level (application) ISR
− restoring the context of the highest-priority ready task
So, a task can install an interrupt using:
_int_install_isr(interrupt_vector_number,isr_ptr,isr_data_ptr)
At this level of interrupt, you can call MQX services.
If you need faster IRQ, you can use Kernel interrupts with : _int_install_kernel_isr(vector_num, isr_ptr)
(check AN4376)
In this case, you can't use MQX services. You're at kernel level. And very important, to install a HW interrupt handler, you need the HW interrupt table in RAM, so your user_config.h has to define MQX_ROM_VECTORS to 0.
I hope this helps.
Best Regards,
Luis
Luis correctly described how to install kernel interrupt.
Just one note:
If you need faster IRQ, and you want use interrupt table in Flash, you can directly edit vectors.c in BSP.
I would like to recommend this only in case when you have your own BSP per project or when you made backup of vectors.c file. Just for preventing against unwanted errors in next project (with the same BSP).
The task and interrupt priorities are totally independent since one is Kernel related and the other is architecture related, based on this, the behavior within a task won't be affected if it installs an ISR of different priority