Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How can I identify IRQ handlers that occur during a normal CPU execution?

I have a time-sensitive block of code run purely by the CPU, not within any interrupt handler or peripheral. Part of the execution is getting interrupted, and so what I would like is to simply identify which IRQ or IRQs are occurring, preferably in real time. To be clear, I am not looking for advice regarding superior techniques for time-sensitive operations, I would just like to identify which IRQ or IRQs are occurring in a particular block of code. Is there a way to do this in general, or is it a process of narrowing down the potential suspects. Detailed answers much appreciated. I am using Segger Embedded Studio in my development. Thank you!

  • We've since abandoned SPI, the buffer size was too small to store our stream of data and we had no way to advance the EasyDMA ArrayList pointer by the amount we needed when we needed to. It was a few months ago, I can try to dig some of it up in old versions of our code. Additionally, the external hardware we're working doesn't support single channel SPI. We would need to use two SPI peripherals, which would be hairy, or Quad-SPI, which I'm not sure is supported by our external hardware either.

  • Thank you for the attention by the way, your information has been helpful.

    I'm reading from a number of GPIO line values and aligning with another GPIO clock to ensure regular sampling, so no peripheral is being used currently. I am not using GPIOTE for the data/clock itself, but it is necessary to perform a GPIOTE-based action both before and after the ingestion of this data. The data ingress is all basically happening in a while loop in the main execution. I have 8-10 GPIO lines I'm reading data from.

  • So basically you are bitbanging it? I won't lecture you regarding superior techniques for time-sensitive operations, but I am not convinced that you are actually being interrupted by something. Are you sure it is not the logic or the timing of the bitbanging that could be the problem? Perhaps you have some snippets you can show?

  • I wanted to reply with what I ended up doing to accomplish the aim of my original question:

    One can access the vector table with SCB and remap to a location in RAM, assign every entry in the vector table to a function that forwards IRQs and intercepts them there:

    #include "core_cm4.h"
    
    #define VECTOR_TABLE_SIZE 256                                                   /**< Size of the vector table in bytes. (16 Cortex + 42 Nordic = 58 words. Next power of 2 = 256) */
    static uint32_t vector_table_ram_trampoline[VECTOR_TABLE_SIZE] __attribute__ ((aligned (128)));
    static uint32_t vector_table_ram[VECTOR_TABLE_SIZE] __attribute__ ((aligned (128)));
    
    
    typedef void (*irq_handler_t)(void);
    
    void irq_forwarder(void){
    
      uint32_t ipsr = __get_IPSR();
      uint8_t isr = ipsr & 0xFF; // this is the IRQ number that is occurring
    
      irq_handler_t irq_handler = (irq_handler_t)(vector_table_ram[isr]);
    
      irq_handler();
    }
    
    /*
     * Copy the interrupt vector table into RAM and set VTOR to point to it.
     * Call before anything else in main
     */
    void vector_table_init()
    {
        memcpy(vector_table_ram_trampoline, (uint32_t *) (SCB->VTOR), VECTOR_TABLE_SIZE);
        memcpy(vector_table_ram, (uint32_t *) (SCB->VTOR), VECTOR_TABLE_SIZE);
    
        __disable_irq();
        SCB->VTOR = (uint32_t)&vector_table_ram_trampoline;    // Set VTOR to point to new vector table
        for(int i=0; i<VECTOR_TABLE_SIZE; i++){
            vector_table_ram_trampoline[i] = (uint32_t) &irq_forwarder;
        }
        __enable_irq();
    }

Related