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.

Interrupt problem in asm code

Other Parts Discussed in Thread: OMAP-L138

Hi, I am using OMAP-L138 and I am programming FIR filter with asm inside the DSP core. I have a problem that, whenever an interrupt occur during executing the asm code, it jumped to address 0 x e8dbd920 and never return. This problem can be avoided when i disable the  PGIE bit in CSR, during the execution of the asm code. But it is important for me to be able to execute the ISR whenever the interrupt occur when executing the asm. So, what's the cause of this problem, and what's the solution. Thank you. 

  • Does this occur for ANY interrupt?  Or just a specific one?  Could it be that you have an interrupt enabled that doesn't have a handler implemented?  

    I'd suggest setting a breakpoint in the interrupt handler and seeing why it branches to this address.  Check to be sure that the interrupt return is correct.  

    Regards,

    Dan

     

  • Because the asm FIR filter is written to link with C language, so far there isn't any interrupt problem in C environment. The only problem is during the interrupt occur when the program is half way executing the asm code. The ISR is developed by another team member of my project team, and it's stable in normal C environment, shouldn't it be stable in asm environment as well? Is there any special registers that I missed out to be configured?

  • First, let's just clarify one point.  It's all assembly code.  Whether you write it in C, or directly in assembly, it all winds up as assembly code.  The difference, in many cases, is that the compiler is better at remembering all the rules for the processor.  My best guess is that there is some set of instructions that need to be protected from interrupts.  I've seen this in cases where one instruction mis-aligns the stack pointer while the next realigns it.  But if an interrupt occurs directly between the two, the stack pointer is corrupted after return from interrupt. The solution in this case, it so disable interrupts prior to the two instructions, and re-enable them after.  So we limit the window where interrupts are disabled.

    If the ISR executes properly when it gets executed while in C code, it's not the ISR.

    Maybe the quickest way to solve this, is to play with your interrupt enable/disable. You could do this.  We know that disabling interrupts at the beginning and re-enabling them at the end of this function makes this problem go away. So, we could try the following.  When I refer to 0, 1, or fractions, 0 means the beginning of the assembly function, 1 means the end, and a fraction means part way through.

    • Disable ints at 0.  Enable at 1/2  Rebuild/Run
      • If the problem goes away, then the issue is between 0 and 1/2
        • Do this process again, except use 1/4 where we used 1/2 here (no we're checking to see if it's in the upper or lower part of the top 1/2.)
      • If the problem still exists, the issue is between 1/2 and 1.  But we should verify (just in case there are two separate issues of we've found the spot between them.
        • Disable at 1/2. Enable at 1.  
          • If the problem goes away, then we have validated that the issue is between 1/2 and 1, so we can restart this process, using 1/2 where we used 0 
          • If the problem still exists, then there are either multiple problems, or we have hit an end point.  Move the disable a little higher to see if we can get the problem to go away.  If it does, then we want to look right around this point.

    We want to recursively do this until we have narrowed down specific sections that are causing the issue.

     

    Regards,

    Dan

     

  • Hi, my asm FIR filter basically consist of an outer loop and an inner loop. The inner loop is the one that took most of the time to run, and there are certain important ISR need to be served whenever an interrupt occur. My plan is to open a small interrupt window in the inner loop. Since i'm not very familiar with the asm rules, so I would like to know if it is ok to enable the interrupt during nop period and disable it after that. Thank you.

  • It takes months of focused effort to learn how to properly write the full parallel assembly code for c6000.  Even then, it takes an extremely long time to create an algorithm (correctly).  There are many, many pitfalls in writing the parallel assembly code and so I strongly advise not to pursue it.  I recommend that you change paths slightly.  Here are some options:

    1. Use an existing FIR filter implementation from one of the TI dsp libraries.
    2. This app note details various compiler options, keywords, and pragmas that can be used to substantially improve the performance of C code.  You would have much better portability using some of those methods.
    3. If you want to write assembly code then you should write "linear assembly" (sometimes called "serial assembly").  Instructions for this can be found in Chapter 4 "Using the Assembly Optimizer" of the C6000 Compiler Reference Guide.

     

  • Thanks for your suggestion, but due to my the need of my current project development, I was told to build a FIR filter which works with 32bit fixed point data (which is not available in the library), and since speed is their concern, so I was told to build the filter in asm. After very long time to complete the filter, I was told in the very last minute that they need that filter to be interrupt enable. Since I do not have very rich experience in asm, I really appreciate guide that help me to create an interrupt window in the asm filter. Thank you.

  • Did you use linear assembly as I suggested?  If so, this should be relatively straight-forward.

  • No, the filter is coded using pure assembly instead of linear assembly, so any idea how the interrupt will work properly. Thank you. 

  • Kee Yong Ting,

    I think Brad's point was, this isn't an easy thing to debug in straight assembly.  You have to know all of the rules of the processor intimately, the rules for instruction scheduling, the rules where multiple instructions have to be protected from interrupts, etc.  There aren't many people that know all of this, and I can't speak for Brad, but I sure don't.  This processor is incredibly complex.  The benefit of the compiler and the linear assembler is that you can let to the tools take care of all of knowing all of these rules for you.

    From the beginning, you've been saying "I have to write this FIR in assembly".  But when we've asked why, the only reason that you've given to this point is that "you were told to, for performance reasons".  What is the performance that you are expecting?  Have you tried implementing in C?  If so, how far away from the benchmark are you?

    I would urge you not to initially write this in straight assembly.   There are very few people that can hand code C6x assembly so that it gets better performance than the compiler would with the appropriate optimizations.  Few people can get better performance using hand coded assembly over linear assembly.  I suspect that in using hand coded assembly, without intimate knowledge of the processor, you will expend a huge amount of effort and the result will be less performance than if you wrote the code in C with the appropriate optimizations.  Rather than intimately studying the C6000 architecture, I'd suggest studying the C6000 Compiler guide.  Be sure you are familiar with intrinsics, which allow you to access assembly instructions from within C.  Also, become familiar with compiler switches.  Another great resource is this application note.  http://www.ti.com/lit/an/spra666/spra666.pdf.  be sure you understand how the cache is architected and how placement of code and data sections can affect performance.  

    At the very least, if you write the code in C, you can look at the assembly that it generates and then base your code on it.  

    And there are many more people that understand how use the compiler to get near hand coded performance.  Both Brand and I are much better equipped to help you get better compiler generated code than we are to do hand coded assembly.

    Regards,
    Dan

     

     

  • Kee Yong Ting said:
    No, the filter is coded using pure assembly instead of linear assembly, so any idea how the interrupt will work properly. Thank you. 

    If you decide to take our advice then I think we can help you further.  Otherwise I suggest hiring a consultant to do this work -- if you can find a consultant with this expertise.