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.

CCS/AM3359: Problem with interrupts

Part Number: AM3359

Tool/software: Code Composer Studio

Hello all,

im programming a beaglebone black via CCS and starter ware. Now i'm trying to make the external interrupts work but with some bigger problems.

I'm using the GNU compiler and an empty CSS project which generates a main.c and a startup_ARMCA8.S file in the project space.

I programmed everything like in this (https://e2e.ti.com/support/embedded/starterware/f/790/t/184282) example but without sucess... When i trigger the interrupt the program-counter jumps somewhere but my isr does not get executed. (i cannot say where exactly it jumps because somehow the interrupt does not get triggered when i'm souce stepping even after ienable interrupts while source stepping in the debug configurations)

Now i'm searching for the cause of this behaviour and i am wondering about one thing: in the interrupt.c there is one array (fnRAMVectors) where the isr's get registerd in. This array isn't anywhere else in the code mentioned again. The base adress of this array just is at 0x80038000. So am i mistaken or do i have to do someting with this array in order to reach my interrupt function (maybe adjust the adress or reference on it in some way)?

i hove somebody can help me here.

best regards

Christian

  • Christian,

    The example in that thread seems to have been cobbled together prior to BBB example support being added to the Processor SDK RTOS package for AM335x. There is a GPIO example that you probably should take a look at to see if it would give you a cleaner implementation of interrupts.

    If you are not familiar with the RTOS examples, they also have bare metal flavors of the examples. The installation is here http://software-dl.ti.com/processor-sdk-rtos/esd/AM335X/latest/index_FDS.html

    The example is located at C:\ti\pdk_am335x_1_0_7\packages\MyExampleProjects\GPIO_LedBlink_bbbAM335x_armTestProject

    Note that you will have to run the pdkprojectcreate.bat file to create these examples. The instructions for this is located at:

    http://processors.wiki.ti.com/index.php/Processor_SDK_RTOS_Software_Developer_Guide

    http://processors.wiki.ti.com/index.php/Rebuilding_The_PDK 

    I hope you can use this example as a clean starting point.

    Lali

  • Hello Lalindra, thanks for your reply!

    I'm familar with the RTOS implementation od the GPIOs, in fact i have the interrupts already working with RTOS but my application is very time critical sample aquisition via SPI and i try to keep the interrupt latency as short as possible. The RTOS managed interrupts are to slow thats why i want to use the starter-ware implementations in a first step.

    I think with my GPIO definitions is everything ok. I can switch my LEDs on an off, read pin values in and even my interrupt triggers the right values in the right registers. The program-counter just doesn't jump to my isr (or at least it looks this way).

    I hope someone encountered a similar problem and can help me with this.

    There is also the following thread (e2e.ti.com/.../242268) , where a similar problem with the timer interrupt. They solved it with modifing some .cmd files. I think this wasn't without the GNU compiler because my program has only a .lds file

    This is my exact code (maybe that helps also).

    #include "soc_AM335x.h"
    #include "interrupt.h"
    #include "beaglebone.h"
    #include "gpio_own.h"
    #include "pin_mux.h"
    #include "hw_control_AM335x.h"
    
    static void gpio1Isr(void)
    {
        //clear interrupt
    	GPIOPinIntClear(SOC_GPIO_0_REGS,0,14);
    	GPIOPinIntClear(SOC_GPIO_0_REGS,1,14);
    	
    	while(true); //dead loop to catch the pc if the interrupt gets triggerd
    
        GPIOPinIntEnable(SOC_GPIO_0_REGS,0,14);
        GPIOPinIntEnable(SOC_GPIO_0_REGS,1,14);
        GPIOPinIntWakeUpEnable(SOC_GPIO_0_REGS,0,14);
    }
    
    int main(void)
    {
        /* Enabling functional clocks for GPIO1 instance. */
        GPIO0ModuleClkConfig();
        GPIO1ModuleClkConfig();
    
        /* Enabling the GPIO module 0. */
        GPIOModuleEnable(SOC_GPIO_0_REGS);
        GPIOModuleReset(SOC_GPIO_0_REGS);
    
        /* Enabling the GPIO module 1. */
        GPIOModuleEnable(SOC_GPIO_1_REGS);
        GPIOModuleReset(SOC_GPIO_1_REGS);
    
    
        GpioPinMuxSetup(GPIO_1_22,CONTROL_CONF_MUXMODE(7)); // USER LED 1
        GpioPinMuxSetup(GPIO_1_23,CONTROL_CONF_MUXMODE(7)); // USER LED 2
        GpioPinMuxSetup(GPIO_1_24,CONTROL_CONF_MUXMODE(7)); // USER LED 3
    
    
        GpioPinMuxSetup(GPIO_0_14,CONTROL_CONF_GPMC_AD_CONF_GPMC_AD_RXACTIVE|0<<CONTROL_CONF_GPMC_AD_CONF_GPMC_AD_PUDEN_SHIFT|1<<CONTROL_CONF_GPMC_AD_CONF_GPMC_AD_PUTYPESEL_SHIFT|CONTROL_CONF_MUXMODE(7)); // Interrupt in
        GPIODirModeSet(SOC_GPIO_0_REGS,14,GPIO_DIR_INPUT);  // interrupt in
    
    
    
        GPIODirModeSet(SOC_GPIO_1_REGS,22,GPIO_DIR_OUTPUT); // USER LED 1
        GPIODirModeSet(SOC_GPIO_1_REGS,23,GPIO_DIR_OUTPUT); // USER LED 2
        GPIODirModeSet(SOC_GPIO_1_REGS,24,GPIO_DIR_OUTPUT); // USER LED 3
        GPIOPinWrite(SOC_GPIO_1_REGS,22,GPIO_PIN_LOW); // USER LED 1
        GPIOPinWrite(SOC_GPIO_1_REGS,23,GPIO_PIN_LOW); // USER LED 2
        GPIOPinWrite(SOC_GPIO_1_REGS,24,GPIO_PIN_LOW); // USER LED 3
    
    
        IntAINTCInit();
    
        IntMasterIRQEnable();
    
        //    GPIO interrupts
        IntSystemEnable(SYS_INT_GPIOINT0A);
        IntPrioritySet(SYS_INT_GPIOINT0A, 3, AINTC_HOSTINT_ROUTE_IRQ);
        IntRegister(SYS_INT_GPIOINT0A, gpio1Isr);
    
        // Setting the GPIO_CLK_PIN_NUMBER to raise IRQ at falling edge of input *
        GPIOIntTypeSet(SOC_GPIO_0_REGS,14, GPIO_INT_TYPE_FALL_EDGE);
    
        GPIOPinIntEnable(SOC_GPIO_0_REGS,0,14);
        GPIOPinIntEnable(SOC_GPIO_0_REGS,1,14);
        GPIOPinIntWakeUpEnable(SOC_GPIO_0_REGS,0,14);
    
    
        while(true) // main loop
        {
    	    // Blink led (works fine before triggering the external interrupt)
        	owndelay(20000000);
            GPIOPinWrite(SOC_GPIO_1_REGS,24,GPIO_PIN_LOW); // USER LED 3
        	owndelay(20000000);
            GPIOPinWrite(SOC_GPIO_1_REGS,24,GPIO_PIN_HIGH); // USER LED 3
        }
    }

  • I managed it to debug with interrupts and got some new information (but couldn't solve the problem)

    in the generated startup_ARMCA8.S are the following assembly instructions

        .section .isr_vector
        .align 4
        .globl  __isr_vector
    __isr_vector:
            LDR   pc, [pc,#24]       @ 0x00 Reset
            LDR   pc, [pc,#-8]       @ 0x04 Undefined Instruction
            LDR   pc, [pc,#24]       @ 0x08 Supervisor Call
            LDR   pc, [pc,#-8]       @ 0x0C Prefetch Abort
            LDR   pc, [pc,#-8]       @ 0x10 Data Abort
            LDR   pc, [pc,#-8]       @ 0x14 Not used
            LDR   pc, [pc,#-8]       @ 0x18 IRQ interrupt
            LDR   pc, [pc,#-8]       @ 0x1C FIQ interrupt
            .long  Entry
            .long  0
            .long  SVC_Handler
            .long  0
            .long  0
            .long  0
            .long  0
            .long  0

    when an interrupt is triggered, the PC jumps to the instruction with offset 0x18 (which is an infinite loop i think (LDR pc, [pc,#-8])) so it gets caught there. if i modify that to LDR pc, [pc,#16] i can load the address of an ISR_HANDLER similar to the SVC_Handler. In the exceptionhandler.S file is a ISR_HANDLER with save and restore context instructions and an call of INTCCommonIntrHandler.

    Now something is missing what do is have to do that my own ISR written in C is executed?

  • Hey Christian,

    i kind of had the same problem with you when trying to use the dmtimer interrupts in my beaglebone white.

    The workaround i found was to get rid of startup_ARMCA8.S!  Instead i used files under system_config folder in starterware, such as the startup.c file. Make sure though, that among the files you use from this folder you choose those which are not suitable for cgt compiler but for gcc.

    To be honest, i faced some more problems after that, like some build errors relative to the init.S file and some problems regarding the linker flags that were necessary but finally it worked out for me.

    So, since your code seems to me to call the right functions (some time later i m going to compare it with mine in case something missed my attention or if i had done something that i can't remember now), i would suggest you give it a try and include interrupt.c, startup.c, init.S and so on from system_config folder of starterware and get rid of startup_ARMCA8.S. Unless someone points out what changes should be done...

    Oh, out of curiosity, how did you manage to debug?when i faced my problem i couldn't even find where the beaglebone "stuck"...

    Hope it helps and good luck

  • Hi,

    To debug it, it helped to work with the external interrupts. I simply strated the debug mode in CCS with always activated interrupts. Then i paused the execution and pushed my Interrupt-Button. After that i did the assembly stepping and my program counter jumped to the interrupt address...

    I found some time to include the startup.c and the init.S (which i thik are essentially it - but i already had the other files for MMU funtionality) Now I think I'm facing the same problems as you. The compiler seems to miss some addresses like "=_bss_start" or "=_stack" which are used in the init.S file. Has the liker script to define them? It would help me a lot if you'd still have the liker script which worked out for you.
    Thank you for your reply, I think I am on the right way...
  • Ok I think I got it!
    i changed the following things in the linker File

    changed PROVIDE(__stack = __StackTop); to PROVIDE(_stack = __StackTop); (Note the underscore)

    added the following lines under the .bss: { ...}
    PROVIDE(_bss_start = __bss_start__);
    PROVIDE(_bss_end = __bss_end__);

    I wish TI would provide the correct files right away instead of empty interrupt-handlers which land in endless loops. Setting up CCS so you can do bare-metal programming isnt very comfortable. (Maybe I'm just spoiled by PSoC-Creator ;-) )

    Thanks to all!
  • Hey,

    i am glad you found a solution!

    Actually i think my workaround was to add an underscore in front of bss_start/end__ everywhere in the linker's file..I hope it is right..At least that helped me overcome the build errors..