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.

Are NVIC INT priority group 0x4 (4:4 split) 3 bit fields 1st order bit of high nibble valid in TM4C priority INT assignments?

Guru 55913 points
Other Parts Discussed in Thread: SYSBIOS

TM4C1294NCPDTi3 Tivaware 5.2.7, Non-OS platform:

Tivaware function call IntPriorityGroupSet() text states priority grouping values 3-7 have the same effect.  Yet a 4:4 group priority split bits 7:5,15:13 etc.. become 3 high order bits of the priority value nibble for INTA,B,C,D leaving 1 subpriority bit. A 4:4 split produces 8 group priorities and 1 subpriority (bxxx.) and M3 example SW often set interrupt priority 0x10-0x90 and never saw an interrupt priority 0x01-0x09. The Tivaware statement priority value 3-7 has same effect seems an improper bit packed example (how to) using low order nibble to set INT priority and shown in table 3-9.

1. Does group priority 0xA0 have the same effect as priority 0xB0 creating an over lapping priority order, since both values high order bits overlap?

Note complier never posted warnings the value was invalid or overlapping.

2. Is the same overlap going to occur for interrupt priority 0xC0 and 0xD0?  

3. Is the low order bit 4 of group priority assignment bits 7:5 table 3-9 ignored or is that considered sub priority by NVIC giving purpose to the 1st nibble bit?  In other words (y) is missing in a 0x4 (4:4 split) of table 3-9 yet 1 subpriority is listed when it seems there should be no subpriority for (bxxx.  ).

  • Hello BP101

    Interrupt priority is the upper 3 bits in the byte field assigned for an interrupt. So if the interrupt priority assigned is 0xA0 or 0xB0, since the upper 3 bits are the same, they have the same priority.
  • Hi Amit,

    So where or what is considered the single subpriority of 0x4 grouping (table 3-9) being there is no sub priority bit field defined? Does table 3-9 for 0x4 grouping single sub priority imply NVIC controls nesting and sub priority ordering within the same group? Hard to know what table 3-9 row 1 is trying to relate by stating only 1 subpriority.
     
    It would seem NVIC should allow several sub priority interrupts inside 0x4 groupings of 8 priority (0x00-0xE0), within reason. NVIC determines the nesting and stacking order of active-PENDS where the lowest peripheral interrupt in the priority group holds highest priority and others simply cascade below. But not that there can only be one other subpriority INT in any single group as table 3-9 seems to relate?

  • BP101 said:
    Note complier never posted warnings the value was invalid or overlapping.

    I don't think there is a C/C++ compiler in the world that will catch that dependency issue between parameters. PC-Lint might if properly setup (I'd have to check if you can build a check that complex, I'm not 100% sure you can) and an Eiffel compiler sophisticated enough to check contracts at compile time might be able to as well. That's about it as far as I know.

    ADA has a lot of checking built in but I don't think it could catch this at compile time eiher.


    Robert

  • Hello BP101

    The subpriority depends on the PRIGROUP setting. The upper 3 bits are interpreted in accordance with the PRIGROUP setting.
  • After posting no compiler check comment figured it might be much easier to simply ASSERT test the range of user variable passed into the call used to set INT priority.

    I must have forgotten there were only 8 priority levels in the configured 3 bit split and trouble shooting GPTM edge counting issues later added several more overlapping levels.

  • Hi Amit,

    Agree yet in context of this thread priority configuration (bxxx._ ) 1 subpriority means what exactly? The explanation in datasheet seems obscure to how NVIC seemingly must work with so many peripheral INT involved.

    It would seem logical a single group priority can have several sub priory INT configured and lower value sources get priority in the group, is that wrong? My reasoning is the INT priority registers consist of a predefined index and never move, only the 3 bit priority value changes A,B,C,D. Otherwise how do we configure several subpriority of a single group just by calling IntPrioritySet()?

    Perhaps datasheet leaves out necessary detail that NVIC can only process 1 subpriority at a time configured as (bxxx._)? Datasheet explanation inferring 1 sub priority can be configured in any single group seems incorrect. Especially in light of not presenting a figure to elaborate primary group and sub priority INT levels in a tree like format.

  • Perhaps one issue is the group priority handling explanation (below) does not exactly coincide with figure 3-9. That is figure 3-9, 0x4 (bxxx.) has NONE subpriority field yet shows 1 subpriority exists.

    2.5.6: If multiple pending interrupts have the same group priority, the subpriority field determines the order in which they are processed. If multiple pending interrupts have the same group priority and subpriority, the interrupt with the lowest IRQ number is processed first.

  • Hello BP101

    A sub priority of 1 means that the interrupts clubbed in this are the same priority and will be processed in order of the interrupt number.
  • Thanks Amit and have a happy new year!
  • BP101 said:
    After posting no compiler check comment figured it might be much easier to simply ASSERT test the range of user variable passed into the call used to set INT priority.

    ASSERT will sort of work. It's a bit problematic in an embedded system because of its all or nothing approach. It's usually better to catch before running rather than while something important is happening.

    Alternatives are (in order of power, i.e. least effort for greatest result)

    1. Static analysis. PC-Lint allows specifying argument characteristics beyond just basic type information. For instance it can check for value (if it can be determined) and relationships amoung arguments. In general compilers are poor at this, they have a different task for which they are optimized. It would be nice to see Gimpel's syntax additions here widely accepted and used, they are quite powerful tools.
    2. TDD (Test Driven Development) techniques. You can test argument ranges and interactions (even to the extent of invoking background simulations if you have the tools for it). Find those issues that depend on situations static analysis cannot figure out. Tests can range from the simple to the complex and because they are repeatable (even a number of timing edge cases can be tested) and run with the full power of the PC (Need to output a 10Mb test data file and compare to known good envelopes, no problem) with no hardware dangers these free you from a lot of problems.
    3. Code reviews. Similar in result to static analysis by they require a lot of human effort and we tire easily skipping over areas.
    4. Error logging and recovery. Parameters can be checked at run time and their ranges limited to safe values and any excursions logged. This does impose run-time penalties (unlike the previous tools) but will run all the time. Recovery options include parameter limiting, return to safe state and in the extreme, resetting.
    5. Watchdog. essential for any realtime system. If the code does not execute its essential code on a regular basis, the processor resets. This should never fire in production code but it is the backup in case something was missed and the code wanders off (maybe stack overflow or similar memory issue, maybe insufficient EMC protection)

    1,2 and 5 are essential tools. 3 is encouraged but has human limitations. 4 is situation-ally dependent. Certainly at least some is used on most systems (things like overcurrent interrupts and invalid state detection) but there are often limits to how much is done. One of the basic concepts of Eiffel is that these checks are built into the function interfaces as 'contracts'. That makes it an interesting language but it is not a widespread one.

    BP101 said:
    I must have forgotten there were only 8 priority levels in the configured 3 bit split

    Yep, that happens.

    Robert

  • Note there is already an ASSERT test for only the decimal INT number. It would be simple to test the 8 HEX priority values as they never change.

    Table 3-9 and REG 58 APINT priority split are a symbolic reference of how NVIC processes IRQ priority but not how each INT priority is actually configured using IntPrioritySet(). Table 3-9 confused me to believe subpriority of a configured priority 1st bit position in the nibble was being used to set different levels based on the lowest IRQ being processed in the priority group.

    The other confusing part occurs if you don't re-read datasheet NVIC priority section several times. Then Tivaware note 3-7 same effect makes no sense, when in reality a HEX priority value is concatenated by IntPrioritySet() and writes INTPRI 3 bit registers with 0-7 priority levels not even close to the 8 bit priority codes.

    0x00=PRI0,0x20=PRI1,0x40=PRI2,0x60=PRI3,0x80=PRI4,0xA0=PRI5,0xC0=PRI6,0xE0=PRI7.

  • Hello BP101

    The NVIC is a ARM peripheral. So documentation of the same comes from ARM including the description. Additional examples and usage model is specified by ARM.
  • BP101 said:
    Note there is already an ASSERT test for only the decimal INT number. It would be simple to test the 8 HEX priority values as they never change.

    Yep, but it is subject to the limitations I noted.

    Robert

  • I don't know of any limitations assert tests are limited during compile time. Perhaps you are referring to asserts used to print debug errors from embedded SW tests that also might assert at runtime. Far as I am aware the asserts atop many of Tivaware configuration functions are stripped out at compile time if no error occurs and not part of the object or had better not be.

    The compiler will post a warning or even an error if priority value passed into IntPrioritySet() is not any one of the 8 values listed. Good example of that behavior, LWIP1.4.1 TCP protocol configurations are set to warn/inform users of ASSERT tests of misconfiguration during compile time.

  • BP101 said:
    I don't know of any limitations assert tests are limited during compile time.

    Then you have not looked at them.

    BP101 said:
    Perhaps you are referring to asserts used to print debug errors from embedded SW tests that also might assert at runtime. Far as I am aware the asserts atop many of Tivaware configuration functions are stripped out at compile time if no error occurs and not part of the object or had better not be.

    Seriously? They are modeled after the C standard asserts. They are only present if DEBUG is defined. They provide no protection otherwise.

    I will quote the entire debug.h file

    //*****************************************************************************
    //
    // debug.h - Macros for assisting debug of the driver library.
    //
    // Copyright (c) 2006-2013 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    //   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.
    // 
    // This is part of revision 1.1 of the Tiva Peripheral Driver Library.
    //
    //*****************************************************************************
    
    #ifndef __DRIVERLIB_DEBUG_H__
    #define __DRIVERLIB_DEBUG_H__
    
    //*****************************************************************************
    //
    // Prototype for the function that is called when an invalid argument is passed
    // to an API.  This is only used when doing a DEBUG build.
    //
    //*****************************************************************************
    extern void __error__(char *pcFilename, uint32_t ui32Line);
    
    //*****************************************************************************
    //
    // The ASSERT macro, which does the actual assertion checking.  Typically, this
    // will be for procedure arguments.
    //
    //*****************************************************************************
    #ifdef DEBUG
    #define ASSERT(expr) do                                                       \
                         {                                                        \
                             if(!(expr))                                          \
                             {                                                    \
                                 __error__(__FILE__, __LINE__);                   \
                             }                                                    \
                         }                                                        \
                         while(0)
    #else
    #define ASSERT(expr)
    #endif
    
    #endif // __DRIVERLIB_DEBUG_H__
    

    Note:

    • It requires DEBUG to be defined in order for checking to occur
    • Checking occurs at runtime
    • Checking occurs in the file where the assert is placed.
    • On assertion failure it calls a logging function

    Now there are compile time asserts defined in C11 but not many compilers support C11 even yet, I don't know how many support the compile time assertions. That would involve the use of the macro static_assert. However, that has limitations as well since it can only work with compile time constants.

    BP101 said:
    The compiler will post a warning or even an error if priority value passed into IntPrioritySet() is not any one of the 8 values listed.

    Really, got a screen shot of that behaviour? A call to IntPrioritySet where an assert causes a compile time error. Only compiling the one source file (and associated headers) not the library?

    BP101 said:
    LWIP1.4.1 TCP protocol configurations are set to warn/inform users of ASSERT tests of misconfiguration during compile time.

    Pretty sure that's not using ASSERT but rather IFDEF and a few cousins. It's possible they've started using static_assert, I'd like to see an example if so.

    This type of checking though, will not provide for argument checking.

    Now if you do have a small set of valid values and rather than a bare type or sized type (as TIVAWare uses) you use a typdefed enum with the limited values then a good compiler can catch invalid values. It was a poor implementation decision not to use anything other than sized types in the TIVA library IMO, and this is one reason why, it removes an avenue for simple error prevention early in the process.

    Robert

  • Robert Adsett said:
    Seriously? They are modeled after the C standard asserts. They are only present if DEBUG is defined. They provide no protection otherwise

    Exactly Tivaware declaration asserts are not meant to provide protection in the runtime binary object only compile time checking. 

    The asserts in the declaration area of Tivaware functions are not part of the output binary object and never show up in debug disassembler view. Those asserts are invoked only during compile time to check the passed variable for correct length during compile. There are no SW exception handers built into the NON-OS platform environment to handle an declaration assert failure. So adding a declaration assert to allow only the values I posted for priorities would be checked during compile time for errors and flag a warning if any value was out of that range.. 

    Agree 100% about debug runtime asserts being part of binary object yet those type of asserts never seem to be placed in the declaration area of a function and are integral part of the program flow.

  • BP101 said:
    Seriously? They are modeled after the C standard asserts. They are only present if DEBUG is defined. They provide no protection otherwise

    Exactly Tivaware declaration asserts are not meant to provide protection in the runtime binary object only compile time checking. 

    The asserts in the declaration area of Tivaware functions are not part of the output binary object and never show up in debug disassembler view. Those asserts are invoked only during compile time to check the passed variable for correct length during compile.

    [/quote]

    You have that exactly backwards. The protection exists at runtime, not at compile time.

    BP101 said:
    So adding a declaration assert to allow only the values I posted for priorities would be checked during compile time for errors and flag a warning if any value was out of that range..

    What the hell is a declaration assert!? You appear to be inventing your own vocabulary again. C Asserts do not provide compile time protection. I don't think static asserts could be used in that fashion with any confidence either.

    BP101 said:
    Agree 100% about debug runtime asserts being part of binary object yet those type of asserts never seem to be placed in the declaration area of a function and are integral part of the program flow.

    Asserts are runtime constructs. I even quoted the header declaring them which makes that painfully obvious.

    Robert

  • Robert Adsett72 said:
    You have that exactly backwards. The protection exists at runtime, not at compile time.

    It would seem that is not exactly correct either and I only mention asserts being in the deceleration area for the benefit of Tivaware function IntPrioritySet().

    Robert Adsett72 said:
    Asserts are runtime constructs. I even quoted the header declaring them which makes that painfully obvious.

    Macro asserts placed in Tivaware functions are not handled at runtime since they are not present in the binary object output data when Debug is disabled. That case assert macro exists for CCS compiler to validate the configuration variable being passed to the function is in range, but only at compile execution of Debug object. Good to point that out we perhaps should all be sure to disable Tivaware Debug engine in Release object. Past discovered if Debug was left enabled in Tivaware EMAC abstraction layer when the IOT examples SW using that engine was missing a debug handler. The compiler was adding the debug code into the binary object and bus faulting the MCU precise and watchdog was resetting the MCU. 

    Again I particularly do not want to ever find Tivaware macro asserts in the compiled binary object being used to set bits in peripheral registers of runtime Release object. CCS compiler has a Problems report tab and posts messages when the macro assert in the function is not passed valid data even when Debug is disabled. Only during compile time does Tivaware function when passed invalid assert data stop the complier from creating an output binary.

    Otherwise a functions declaration macro asserts would constitute (unhandled exceptions) Debug being disabled in runtime object, how do you explain that insane logic?  Yet LWIP has it's own Debug exception handlers when Debug enabled at compile time and Tivaware functions never have macro asserts in the object. So the compiler knows which functions the assert macros and handlers have ownership.   

    When debug is pink the macro is disabled at compile time so the compiler then removes all macro asserts from the binary object. Engineer has to first enable Debug and recompile application so the macro asserts are then added into the binary object. 

  • Deceleration area? Pray tell what's decreasing in speed?

    Note that the highlighted (in yellow) code provides no protection either at runtime nor at compile time.

    While the alternate code provides protection only at runtime.

    Robert
  • Robert Adsett72 said:
    Deceleration area? Pray tell what's decreasing in speed? 
    Note that the highlighted (in yellow) code provides no protection either at runtime nor at compile time. 
    While the alternate code provides protection only at runtime.

    To funny was supposed to be declaration not deceleration. Perhaps CCS automated code analysis is processing Tivaware function Asserts since being Debug output is disabled in that area of the code. The only debug engine enabled is LWIP and it outputs status file and other status via UARTprintf() into virtual COM port.

    It would make since compiled Release binary we should omit all debug Asserts after SW was debugged order to save flash memory space for platforms such as RTOS or Sysbios.  Again CCS compiler outputs error status in the console and IDE problems dialog boxes only during compile of Tivaware function Asserts to indicate error of any variables being passed into the range that fail the assert constraint. Hard to imagine LWIP debug is somehow causing that since the compiler assert messages never show up on virtual com port terminal output.  

  • BP101 said:
    Perhaps CCS automated code analysis is processing Tivaware function Asserts since being Debug output is disabled in that area of the code.

    Highly unlikely. It would break code to define the DEBUG macro even just for a code analysis pass. Also the analyzer would not have access to the ASSERTs when it is analyzing the code that would need to be checked.

    BP101 said:
    It would make since compiled Release binary we should omit all debug Asserts after SW was debugged order to save flash memory space for platforms such as RTOS or Sysbios.

    This is, I think, a mistake. Running a different version in release and debug is asking for problems. I know people do it. I also know I'm no the only person who thinks it is bad practice.

    As far as I'm concerned all routine testing and all regression testing should be done with the same flags and defines as the release version. Switching on specific debug assistants to find a problem that has eluded other testing is fine but the compile should revert back immediately after the search is finished.

    BP101 said:
    Again CCS compiler outputs error status in the console and IDE problems dialog boxes only during compile of Tivaware function

    I'd like to see that. I don't really credit that statement.

    Robert

  • Robert Adsett72 said:
    BP101
    Again CCS compiler outputs error status in the console and IDE problems dialog boxes only during compile of Tivaware function

    I'd like to see that. I don't really credit that statement.

    To be clear I was referring to the Tivaware function assert debug messages not the real time syntax validity checker. Spending time with RTSC Sysbios kernel required SWO debug System Analyzer support via program platform monitor of MCU's TMC/APB. RTSC package presents several ways of control over function asserts (yellow box). Seems CCS compilers check for the symbol (Debug) since the only Asserts ever invoked are LWIP related.

    Robert Adsett72 said:
    As far as I'm concerned all routine testing and all regression testing should be done with the same flags and defines as the release version

    My thought is why waste instruction cycles for code already proven to work, what good can come of that. Perhaps on a Mars rover but only when signaled from earth to invoke assert debug via kernel task command otherwise watchdog would POR the MCU if fatal SW conditions arise. Static register values set during peripheral initialization if done repeatedly adds to timing overhead, for instance reprogramming ADC sequencer FIFO's via Tivaware library versus making HWREG calls direct to the registers. Sysbios kernel might be a good choice for your style of leave all flags flying debug/release. LWIP 1.4.1 protocols have many embedded asserts but they don't fix any issue rather only reports something bad has occurred. Have seen LWIP protocol asserts swamp UART and USB connected serial VTE so bad ends up faulting MCU. Now only enable and report specific protocols and later in release object will turn off all LWIP debug engines accept invoked heap space reports that use the debug engine.

  • BP101 said:
    Again CCS compiler outputs error status in the console and IDE problems dialog boxes only during compile of Tivaware function

    I'd like to see that. I don't really credit that statement.[/quote]

    To be clear I was referring to the Tivaware function assert debug messages

    [/quote]

    So was I. I never thought there was anything else. Those asserts will only apply within the called function (they are not otherwise visible) and only at runtime.

    BP101 said:
    not the real time syntax validity checker.

    Neither I nor sage Google have any idea of what you are referring to here.

    BP101 said:
    Spending time with RTSC Sysbios kernel required SWO debug System Analyzer support via program platform monitor of MCU's TMC/APB. RTSC package presents several ways of control over function asserts (yellow box).

    I do believe that if you check you will find they are all run time asserts.

    BP101 said:
    Seems CCS compilers check for the symbol (Debug) since the only Asserts ever invoked are LWIP related.

    If the preprocessor did not behave in accordance with the definition (or not) of DEBUG then the compiler would have a very, very serious bug and be essentially unusable so I would certainly hope so.

    BP101 said:
    As far as I'm concerned all routine testing and all regression testing should be done with the same flags and defines as the release version

    My thought is why waste instruction cycles for code already proven to work, what good can come of that.

    [/quote]

    What ill can come of it? If it doesn't work with them defined then you cannot test with them defined. If it does work with them defined then there is no benefit in not defining them.

    Which naturally leads to

    BP101 said:
    Perhaps on a Mars rover but only when signaled from earth to invoke assert debug via kernel task command otherwise watchdog would POR the MCU if fatal SW conditions arise. Static register values set during peripheral initialization if done repeatedly adds to timing overhead, for instance reprogramming ADC sequencer FIFO's via Tivaware library versus making HWREG calls direct to the registers. Sysbios kernel might be a good choice for your style of leave all flags flying debug/release. LWIP 1.4.1 protocols have many embedded asserts but they don't fix any issue rather only reports something bad has occurred. Have seen LWIP protocol asserts swamp UART and USB connected serial VTE so bad ends up faulting MCU. Now only enable and report specific protocols and later in release object will turn off all LWIP debug engines accept invoked heap space reports that use the debug engine.

    Then that is the configuration to do the testing in. Also note that you are presenting a strong argument for not using IoT in a BLDC motor controller since it chews up your available resources.

    The problem with different test and release builds is basically that you are releasing an entirely different version than you are testing. A short and incomplete list of possible faults

    • Your debug code could include code required to actually work correctly. In the best case this will be immediately apparent because it simply will not run. OTOH it may be quite subtle and only happen intermittently, good luck even tracing that back to a flag.
    • Changing the code means changing the timing. This may surface previously undetected timing and race conditions.
    • The code could have relied (maybe inadvertently) on a specific patterns of code generation. Changing compiler flags will change that (and so can changing compiler versions), that after all is why they exist.
    • The compiler or support libraries may have bugs with specific settings. If you don't test with those settings then you will not find them but your customers are exposed to those side effects.

    You will have enough problems with bugs that escape your detection without deliberately introducing more.

    Robert

  • Robert Adsett72 said:
    You will have enough problems with bugs that escape your detection without deliberately introducing more.

    By neglecting to test the release version you have pushed that task to your unaware customer.

    Since you are developing embedded SW then unless you are developing throw away items (and perhaps even then) at some point your customer is going to insist you come to the working site to see and fix those bugs. That is never a pleasant experience, worse if it's outside in rain and snow.

    Robert

  • Robert Adsett72 said:
    Your debug code could include code required to actually work correctly. In the best case this will be immediately apparent because it simply will not run. OTOH it may be quite subtle and only happen intermittently, good luck even tracing that back to a flag.

    And if you are consistently good enough to avoid this issue, you are good enough not to need the statements to begin with.

    Robert