This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I'm trying to understand how interrupt profiling configuration of hardware trace analyzer in CCS works on an example code.
In this example, Timer A0 and Timer A1 are configured with the same settings (up mode is selected, both TA0CCR0 and TA1CCR0 are set to the same value).
I explicitly put a delay loop into TA1_0_IRQHandler to show that if interrupts are overlapped (while one is served and the other is pending).
However, I never saw such a situation from the data captured over serial wire debug port.
Did I make a mistake inside my code or serial wire debug interface is not capable of such things (i.e., the capture rate is not fast enough)?
/* --COPYRIGHT--,BSD_EX * Copyright (c) 2013, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************* * * MSP432 CODE EXAMPLE DISCLAIMER * * MSP432 code examples are self-contained low-level programs that typically * demonstrate a single peripheral function or device feature in a highly * concise manner. For this the code may rely on the device's power-on default * register values and settings such as the clock configuration and care must * be taken when combining code from several examples to avoid potential side * effects. Also see http://www.ti.com/tool/mspdriverlib for an API functional * library & https://dev.ti.com/pinmux/ for a GUI approach to peripheral configuration. * * --/COPYRIGHT--*/ //****************************************************************************** // MSP432P401 Demo - Timer0_A3, Toggle P1.0, CCR0 Cont Mode ISR, DCO SMCLK // // Description: Toggle P1.0 using software and TA_0 ISR. Timer0_A is // configured for continuous mode, thus the timer overflows when TAR counts // to CCR0. In this example, CCR0 is loaded with 50000. // ACLK = n/a, MCLK = SMCLK = TACLK = default DCO = ~1MHz // // MSP432p401rpz // --------------- // /|\| | // | | | // --|RST | // | | // | P1.0|-->LED // // Dung Dang // Texas Instruments Inc. // October 2015 (updated) | November 2013 (created) // Built with Code Composer Studio v6.0 //****************************************************************************** #include "msp.h" #define TA0CCR0_VAL 65535 #define TA1CCR0_VAL 65535 int i; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop WDT // Configure GPIO P1DIR |= BIT0; P1OUT |= BIT0; P2DIR |= BIT0; P2OUT |= BIT0; // TA0 TA0CCTL0 = CCIE; // TACCR0 interrupt enabled TA0CCR0 = 0; TA0CTL = TASSEL__SMCLK | MC__UP; // SMCLK, continuous mode TA0CCTL0 &= ~CCIFG; TA0CCTL0 = CCIE; // TACCR0 interrupt enabled NVIC->ISER[0] = 1 << ((TA0_0_IRQn) & 31); // TA1 TA1CCTL0 = CCIE; // TACCR1 interrupt enabled TA1CCR0 = 0; TA1CTL = TASSEL__SMCLK | MC__UP; // SMCLK, continuous mode TA1CCTL0 &= ~CCIFG; TA1CCTL0 = CCIE; // TACCR0 interrupt enabled NVIC->ISER[0] |= 1 << ((TA1_0_IRQn) & 31); SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; // Enable sleep on exit from ISR __enable_interrupt(); TA0CCR0 = TA0CCR0_VAL; TA1CCR0 = TA1CCR0_VAL; while (1) { __sleep(); __no_operation(); // For debugger } } // Timer A0 interrupt service routine void TA0_0_IRQHandler(void) { TA0CCTL0 &= ~CCIFG; P1OUT ^= BIT0; //TA0CCR0 = TA0CCR0_VAL; // Add Offset to TACCR0 } // Timer A1 interrupt service routine void TA1_0_IRQHandler(void) { TA1CCTL0 &= ~CCIFG; P2OUT ^= BIT0; //TA1CCR0 = TA1CCR0_VAL; // Add Offset to TACCR0 for(i = 5000; i > 0; i--); }
//***************************************************************************** // // Copyright (C) 2012 - 2015 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // MSP432 Family Interrupt Vector Table for CGT // //**************************************************************************** #include <stdint.h> /* Forward declaration of the default fault handlers. */ static void resetISR(void); static void nmiISR(void); static void faultISR(void); static void defaultISR(void); /* External declaration for the reset handler that is to be called when the */ /* processor is started */ extern void _c_int00(void); /* External declaration for system initialization function */ extern void SystemInit(void); /* Linker variable that marks the top of the stack. */ extern unsigned long __STACK_END; /* External declarations for the interrupt handlers used by the application. */ extern void TA0_0_IRQHandler(void); extern void TA1_0_IRQHandler(void); /* To be added by user */ /* Interrupt vector table. Note that the proper constructs must be placed on this to */ /* ensure that it ends up at physical address 0x0000.0000 or at the start of */ /* the program if located at a start address other than 0. */ #pragma RETAIN(interruptVectors) #pragma DATA_SECTION(interruptVectors, ".intvecs") void (* const interruptVectors[])(void) = { (void (*)(void))((uint32_t)&__STACK_END), /* The initial stack pointer */ resetISR, /* The reset handler */ nmiISR, /* The NMI handler */ faultISR, /* The hard fault handler */ defaultISR, /* The MPU fault handler */ defaultISR, /* The bus fault handler */ defaultISR, /* The usage fault handler */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ 0, /* Reserved */ defaultISR, /* SVCall handler */ defaultISR, /* Debug monitor handler */ 0, /* Reserved */ defaultISR, /* The PendSV handler */ defaultISR, /* The SysTick handler */ defaultISR, /* PSS ISR */ defaultISR, /* CS ISR */ defaultISR, /* PCM ISR */ defaultISR, /* WDT ISR */ defaultISR, /* FPU ISR */ defaultISR, /* FLCTL ISR */ defaultISR, /* COMP0 ISR */ defaultISR, /* COMP1 ISR */ TA0_0_IRQHandler, /* TA0_0 ISR */ defaultISR, /* TA0_N ISR */ TA1_0_IRQHandler, /* TA1_0 ISR */ defaultISR, /* TA1_N ISR */ defaultISR, /* TA2_0 ISR */ defaultISR, /* TA2_N ISR */ defaultISR, /* TA3_0 ISR */ defaultISR, /* TA3_N ISR */ defaultISR, /* EUSCIA0 ISR */ defaultISR, /* EUSCIA1 ISR */ defaultISR, /* EUSCIA2 ISR */ defaultISR, /* EUSCIA3 ISR */ defaultISR, /* EUSCIB0 ISR */ defaultISR, /* EUSCIB1 ISR */ defaultISR, /* EUSCIB2 ISR */ defaultISR, /* EUSCIB3 ISR */ defaultISR, /* ADC14 ISR */ defaultISR, /* T32_INT1 ISR */ defaultISR, /* T32_INT2 ISR */ defaultISR, /* T32_INTC ISR */ defaultISR, /* AES ISR */ defaultISR, /* RTC ISR */ defaultISR, /* DMA_ERR ISR */ defaultISR, /* DMA_INT3 ISR */ defaultISR, /* DMA_INT2 ISR */ defaultISR, /* DMA_INT1 ISR */ defaultISR, /* DMA_INT0 ISR */ defaultISR, /* PORT1 ISR */ defaultISR, /* PORT2 ISR */ defaultISR, /* PORT3 ISR */ defaultISR, /* PORT4 ISR */ defaultISR, /* PORT5 ISR */ defaultISR, /* PORT6 ISR */ defaultISR, /* Reserved 41 */ defaultISR, /* Reserved 42 */ defaultISR, /* Reserved 43 */ defaultISR, /* Reserved 44 */ defaultISR, /* Reserved 45 */ defaultISR, /* Reserved 46 */ defaultISR, /* Reserved 47 */ defaultISR, /* Reserved 48 */ defaultISR, /* Reserved 49 */ defaultISR, /* Reserved 50 */ defaultISR, /* Reserved 51 */ defaultISR, /* Reserved 52 */ defaultISR, /* Reserved 53 */ defaultISR, /* Reserved 54 */ defaultISR, /* Reserved 55 */ defaultISR, /* Reserved 56 */ defaultISR, /* Reserved 57 */ defaultISR, /* Reserved 58 */ defaultISR, /* Reserved 59 */ defaultISR, /* Reserved 60 */ defaultISR, /* Reserved 61 */ defaultISR, /* Reserved 62 */ defaultISR /* Reserved 63 */ }; /* This is the code that gets called when the processor first starts execution */ /* following a reset event. Only the absolutely necessary set is performed, */ /* after which the application supplied entry() routine is called. Any fancy */ /* actions (such as making decisions based on the reset cause register, and */ /* resetting the bits in that register) are left solely in the hands of the */ /* application. */ void resetISR(void) { SystemInit(); /* Jump to the CCS C Initialization Routine. */ __asm(" .global _c_int00\n" " b.w _c_int00"); } /* This is the code that gets called when the processor receives a NMI. This */ /* simply enters an infinite loop, preserving the system state for examination */ /* by a debugger. */ static void nmiISR(void) { /* Fault trap exempt from ULP advisor */ #pragma diag_push #pragma CHECK_ULP("-2.1") /* Enter an infinite loop. */ while(1) { } #pragma diag_pop } /* This is the code that gets called when the processor receives a fault */ /* interrupt. This simply enters an infinite loop, preserving the system state */ /* for examination by a debugger. */ static void faultISR(void) { /* Fault trap exempt from ULP advisor */ #pragma diag_push #pragma CHECK_ULP("-2.1") /* Enter an infinite loop. */ while(1) { } #pragma diag_pop } /* This is the code that gets called when the processor receives an unexpected */ /* interrupt. This simply enters an infinite loop, preserving the system state */ /* for examination by a debugger. */ static void defaultISR(void) { /* Fault trap exempt from ULP advisor */ #pragma diag_push #pragma CHECK_ULP("-2.1") /* Enter an infinite loop. */ while(1) { } #pragma diag_pop }
Hi Abdullah,
I did not get similar results when using CCS v6.1.3 and MSP-EXP432P401 Rev B silicon, the TA1 interrupt would be longer than TA0 by the amount determined by the for loop which I reduced from 5000 to 10 to get the following result.
Are you using the same setup that I've described? Have you changed anything from its default setting?
Regards, Ryan
Hi Ryan,
I noticed that Timer A1 ISR should take longer than Timer A0 ISR. Now I fixed this issue and get similar results like you.
My question is that if this code makes these two interrupts occur at the same time.
If it does, why we cannot see such situations via serial wire debug interface? There is always a gap between two ISRs.
My intend is to use this tool to explain the interrupt priority to our students in practice.
**Attention** This is a public forum