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.

Graphics Widget FaultISR()



Hi all,

I've a burning question with using the Widget tools from the Stellaris Graphic Library (FYI, I'm using LM4F232H5QD & K90DWN2-V1-FF LCD). 

The problem is that after I added some Widgets and painted them, the WidgetMessageQueueProcess() function in the while loop stops my touch screen controller (as I no longer observe periodic pulses from the timer on the ADC pins on the oscilloscope). The program then enters into the FaultISR() loop, which means that the processor receives an unexpected interrupt.

What and who caused the unexpected interrupt? The only interrupt I'm activating is the TouchScreenIntHandler that is used by ADC3 for the 4-wire resistive touchscreen.

Does anyone have any experience with the graphics library? Do appreciate it if you can advise. Thanks a lot!

Attached is a copy of my code and project properties,

Include libraries
=================
"C:\StellarisWare"
"C:\StellarisWare\boards\ek-lm4f232"

Predefined symbols
==================
ccs
PART_LM4F232H5QD
TARGET_IS_BLIZZARD_RA1

File search paths
=================
"rtsv7M4_T_le_eabi.lib"
"C:\StellarisWare\driverlib\ccs-cm4f\Debug\driverlib-cm4f.lib"
"C:\StellarisWare\grlib\ccs-cm4f\Debug\grlib-cm4f.lib"

(main.c)

#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
//#include "driverlib/flash.h"
#include "driverlib/sysctl.h"
#include "grlib/grlib.h"
#include "grlib/widget.h"
#include "grlib/canvas.h"
#include "grlib/pushbutton.h"
#include "drivers/kentec800x480x16_ssd1963_8bit.h"
#include "drivers/touch.h"

extern tCanvasWidget g_sBackground;
extern tPushButtonWidget g_sPushBtn;

void OnButtonPress(tWidget *pWidget);

Canvas(g_sBackground, WIDGET_ROOT, 0, 0,
&g_sLcd800x480x16_8bit, 0, 0, 800, 480,
CANVAS_STYLE_FILL, ClrRed, 0, 0, 0, 0, 0, 0);
Canvas(g_sHeading, &g_sBackground, 0, 0,
&g_sLcd800x480x16_8bit, 80, 48, 640, 374,
(CANVAS_STYLE_FILL | CANVAS_STYLE_OUTLINE | CANVAS_STYLE_TEXT),
ClrDarkBlue, ClrWhite, ClrWhite, g_pFontCm20, "hello-widget", 0, 0);

#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

void main(void) {

//set the clocking to run at 50MHz using the PLL (400MHz / 2 / 4). System clock must be at least 7MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

// Enable interrupts
IntMasterEnable();

//initialize the display driver
Kentec800x480x16_ssd1963Init();

//Initialise the touch screen driver
TouchScreenInit();

WidgetAdd(WIDGET_ROOT,(tWidget *)&g_sBackground);
WidgetAdd((tWidget *)&g_sBackground,(tWidget *)&g_sHeading);
WidgetPaint(WIDGET_ROOT);

while(1){
WidgetMessageQueueProcess(); //-->causes program to go to FaultISR() infinite loop;
}

}

8228.main.c

  • William Tan Wee Liang said:
    after I added some Widgets and painted them

    Would it not be insightful for you to add, "Just ONE" widget - and see if that alone confounds? 

    By simplifying - you can learn if "any" widget addition or one (or several) are problematic.

    Dave W. should shortly arrive w/ graphic.lib expertise far beyond we, "logic - cause/effect" guys...

  • If you're using the same basic vector table as we are, FaultISR doesn't indicate an errant interrupt but an access to an invalid memory location. The usual cause of this is either that you are trying to access a peripheral register space before enabling that peripheral (make sure you call SysCtlPeripheralEnable() and wait a few cycles before accessing any given peripheral) or that you are accessing an ininitialized or corrupted pointer.

    To track down the cause, you need to diagnose the fault and you can find instructions on how to do this in this application note.

  • Yes, I've tried adding just the g_sBackground CanvasWidget, and it works perfectly with my touchscreen inputs still intact.

    However, when I tried adding for example, the RectangularButtonWidget to the widget tree, a bus fault address error occurs..

    I'm just modifying the HelloWidget ccs project example on the M3 to the M4, I don't really understand what went wrong.

  • William Tan Wee Liang said:
    I'm just modifying the HelloWidget ccs project example on the M3 to the M4

    "I'm just," most always signals trouble!   At least within IAR - the M4 requires the use of a new library, "cm4f."  Have you so adapted your past code so that this library is indeed properly included?

    We note - what to us - is a "strange, new include:  #include "drivers/kentec800x480x16_ssd1963_8bit.h"  TI's Dave W. and I have discussed this SSD1963 addition on multiple occasions - so as to both extend and modernize the aging, LMI graphic library.  Thus we must ask the (perhaps) obvious - can you confirm that this file came from Kentec? 

    I would carefully note which files are included w/in your successful widget build.  Then turn to the simplest one which fails - determine which files differ from the successful one.  There have been some fairly substantial changes between M3 and M4 - look especially for slight changes to Peripheral Names (addition of a numeral suffix - for example - "PWM0_BASE, PWM_GEN_0" - where none was present in the past)  Indeed - this or similar caused our project to fault early on - often a 2nd pair of eyes will note - I stared "blindly" for 2 days and another saw this instantly...   Good luck...

     

  • There's a hint in there that may point to the root of your problem. When you converted from M3 to M4, did you add the code necessary to configure the FPU stacking mode? If not, you will find that your stack usage goes up since all the FPU registers are stacked on interrupt too. You should be able to see if this is the problem by looking at your SP when in the fault handler. Is it off the bottom of the stack memory you allocated?

    Make sure you call ROM_FPULazyStackingEnable() at the very top of main() and increase your stack size to accommodate the FPU registers.

    Once again, the way to determine exactly what is going on here is to follow the instructions in the app note I mentioned earlier and diagnose the actual source of the fault that you are seeing.

  • I'm using the default vector table for the M4 core which I grabbed from the blinky example project. I also added the TouchScreenIntHandler to ADC3 interrupt for use with the touchscreen display. 

    I tried to debug the fault using the methods in the application note you posted, but I'm still quite confused about what I'm seeing in the registers. Are there any working HelloWidget project for the M4 that is working with the Kentec LCD displays?

  • @cb1: Haha.. trouble it is..

    @Dave: Let me try increasing the stack size and I'll update you on the progress.

    Thanks you two for the advice so far!

  • Along with Dave W's advice - look at my 10:25 post - final para.   That is just what derailed us - fault just as you report...

  • Dave Wilson said:

    Make sure you call ROM_FPULazyStackingEnable() at the very top of main() and increase your stack size to accommodate the FPU registers.

    What a valuable piece of guidance - and clearly, concisely described.  Thank you. 

    Now - due to the, "unwanted" intrusion of such FPU - would you be so good as to describe how we should properly, "disable the FPU" - to insure that it does not impact long existing code - which we seek to migrate across to your M4 platform?  (and which does not require use of - nor benefit from - the FPU...)

  • Here's an ARM app note that should provide all the information you need on controlling the FPU in a Cortex-M4F.

  • @Dave W.  - received - thank you.

  • @cb1

    I did obtain the drivers/kentec800x480x16_ssd1963_8bit.h from Kentec themselves. I really have no idea about the SSD1963 addition. I've a separate program testing just the touchscreen display as well as the touchscreen controller which are both working fine. The peripheral names are correct as well.

    @Dave

    I've tried the lazy stacking function to increase stack size, but the program still pointed me to the FaultISR similar to Bus Fault Scenario 1 from the app note. When I look up the memory model, it points me to the "Reserved" section.. Hmm..

    I think I'll be moving on to develop my own buttons using tRect structures and define some button interactions on my own since I'm doing a simple GUI. Perhaps I'll look back and learn more about the HelloWidget project when it is working on the M4.

    Thank you both for the advice given! I've learnt more about debugging and stack size memory~

  • William,

      Rather than give up and move on, I would very strongly recommend you spend the extra hour to get to the bottom of this. Faults are usually caused by a simple pointer error in the code or, as I mentioned, an attempt to access a peripheral without enabling it first. If you break on FaultISR and look at the stack, the 7th word above the current stack pointer (SP) will show you the PC at the point where the fault occurred. Disassemble that address and look for memory accesses (LDR or STR instructions) in the 3  or 4 instructions prior to the faulting address. If you find any, look at the register that contains the address being accessed. If it's R4 or above, it will not have been modified and you can read it directly from the current register values (unless you've added code to FaultISR, of course). If it's R0-R3, it will be stored in one of the first 4 words above SP on the exception frame in the stack.

    Knowing the address that caused the problem, you can generally figure out what's up pretty quickly. If it's of the form 0x4xxxxxxx, it's a peripheral access. Look in hw_memmap.h and find out which peripheral owns the space containing the address then make sure you've enabled it. If the address is not in the peripheral space, try to determine what the access was doing by looking at the source corresponding to the area around the fault. You may find that the pointer is uninitialized or corrupted at that point but at least you should have enough information to rerun your code with a breakpoint before the failure so that you can step through the bad area and see what's going in.

    This may sound tedious but it will be an ENORMOUSLY useful exercise in the long run since you will definitely have to do this kind of debug in future.

  • Dave Wilson said:
    stored in one of the first 4 words - above SP - on the exception frame - in the stack.

    Say What?   The cadence and precision harkens to the Coast Guard's, "What to do when you dig your keel into a Sandbar..."   Dave - it is hard to "read" such clause-laden. hi-tech sentence - let alone fully comprehend...  (and yes - I share such guilt...)

    This advanced, valuable topic may be easy - intuitive now for you.  But there are four clauses in that complex sentence - even after I reduced its length....  A diagrammatic representation would SO aid understanding/clarity...

    Suggest that several, "Cut & Paste" extracts - showing these key guidelines in a more illustrative, Graphic Format - would help many!  (know it would assist staff/myself)

    Keep in mind that not all forum users are native English speakers - images and graphic representations are great aids to learning...  And just where IS that, "Exception Frame?"  Are not the best "maps" Graphic?

    (and I certainly urge William to follow your teachings - bet you that the added clarity of, "Cut/Paste" Register & Disassembly examples & illustrations will prove far more compelling - and thus drive both William and many others successfully forward...)

  • Hey cb1, you are not seriously complaining about someone else's writing style, are you

    ;-)

  • Just the facts Stellaris Joe - just the facts.  (and I did, "hang myself" - from the same tree limb as Dave W.)

    But yours - yesterday - was indeed super - as I memorialized. 

    Dave W's write up today - clearly I'm right - some graphic, Cut/Paste would surely be of great value. 

    Four clauses - one sentence - sounds like a very simple section of US Tax Code...  

    And way too much for most here - myself included...

  • I apologize profusely. Next time, I'll edit and remove run-on sentences like that (honestly).

    William,

      If you were unable to understand what I wrote, please let me know and I will try to explain more clearly.

    cb1,

      What Joe didn't mention is that I tend to talk just like that when I'm (a) in a hurry and (b) excited about something.

  • @ Dave W. - Believe - as forum "friends" - we know each other well enough that we can pass comments meant to be, "constructive."  And staff and I found your writing powerful and very insightful - but sufficiently involved/detailed - that we still had questions.  (even after obligatory - re-reads...)  Thus my suggestion of several, "Cut & Paste" illustrations and examples - to better "drive home" your key points.

    I do not believe that your sentence qualified as, "run-on" - but it was loaded with complexity and did have the rhythm of an expansive, legal argument.  (we could almost hear you speaking - not hard to "imagine" the pauses and cadence...  I marked those suspected pauses with hyphens - when quoting) 

    William is a smart guy - works in a Research Dept. - and he's reluctant to, "dive in" to serious, Stellaris Fault Analysis.  My point remains that several, "Cut/Paste Screen Caps. will be an extremely helpful adjunct to your otherwise excellent writing.  Especially for those who are more, "visual learners," or not native-English speakers.

    As I've stated repeatedly - here & elsewhere - yours is by far the best tech forum.  But that doesn't mean that its perfect - and our group believes that constructive feedback - where we present sound, well argued alternatives - is our best means to contribute - perhaps even improve this neat workspace... 

  • @dave,

    Thanks for your encouragement! I must admit it's pretty frustrating when I'm not too clear about the stack pointers. I will keep trying and thanks a lot for engaging!
    I decided to test just loading the widgets and not look at the touchscreen controller issue first. I took some screenshots if that makes it easy to read.

    In my widget projects,
    1) I was able to plot the g_sBackground and g_sHeading Canvas widgets to the WIDGET_ROOT without any errors
    2) However, when I tried to add further the g_sPushBtn PushButton widget, it triggered a FaultISR(). 
    Firstly, I looked up NVIC_FAULT_STAT, which had a value of 0x0002000 (or a INVSTAT, invalid state usage fault).
    Then my NVIC_FAULT_ADDR was 0xE000EDF8, which points me to NVIC_BASE from the hw_memmap.h.
    --> is it because I didn't initialise my NVIC_BASE? how can I do that?

    Secondly, I went to the core registers to look up SP.
    --> I don't really understand it when you say if it is off the bottom of the stack.  Do you view that from the memory window?
    I viewed the memory at value of the SP register (0x0000.0036), and looking up the 7th word above that (SP) will be 0x004F.031F (PC at point where fault occurred.
    I went on to disassemble and copied 0x004F.031F to the disassembly window, and got this msg:  
    "Memory map prevented reading of target memory at 0x004F031E [code=0x20000]"
    --> At this point, I'm quite confused.. Need some advice on this one.

    I'm attaching a copy of the Kentec driver files for reference sake, as well as the main.c program i'm using this time round.

    3730.kentec800x480x16_ssd1963_8bit.c

    #include "inc/hw_types.h"

    #include "inc/hw_sysctl.h"

    #include "inc/hw_memmap.h"

    #include "inc/hw_nvic.h"

    #include "inc/lm4f232h5qd.h"

     

    #include "driverlib/fpu.h"

    #include "driverlib/interrupt.h"

    #include "driverlib/sysctl.h"

    #include "driverlib/rom.h"

    #include "driverlib/gpio.h"

    #include "driverlib/systick.h"

     

    #include "grlib/grlib.h"

    #include "grlib/widget.h"

    #include "grlib/canvas.h"

    #include "grlib/pushbutton.h"

     

    #include "drivers/kentec800x480x16_ssd1963_8bit.h"

    #include "drivers/touch.h"

     

    //*****************************************************************************

    // Test 3 - Add a further PushButtonWidget to the heading as a first child

    //                   widget ()

    //*****************************************************************************

    extern tCanvasWidget g_sBackground;

    extern tPushButtonWidget g_sPushBtn;

     

    // Canvas widget acting as the title heading (declaring button widget as first child)

    Canvas(g_sHeading, &g_sBackground, 0, &g_sPushBtn,

           &g_sLcd800x480x16_8bit, 0, 0, 800, 80,

           (CANVAS_STYLE_FILL | CANVAS_STYLE_OUTLINE | CANVAS_STYLE_TEXT),

           ClrRed, ClrWhite, ClrWhite, g_pFontCm20, "Foreground", 0, 0);

     

    // Canvas widget acting as background to the display (declaring heading as first child)

    Canvas(g_sBackground, WIDGET_ROOT, 0, &g_sHeading,

           &g_sLcd800x480x16_8bit, 0, 80, 800, 400,

           CANVAS_STYLE_FILL, ClrBlack, 0, 0, 0, 0, 0, 0);

     

    // Rectangular PushButton widget (declaring heading as parent)

    RectangularButton(g_sPushBtn, &g_sHeading, 0, 0,

                      &g_sLcd800x480x16_8bit, 120, 120, 240, 80,

                      (PB_STYLE_OUTLINE | PB_STYLE_TEXT_OPAQUE | PB_STYLE_TEXT |

                       PB_STYLE_FILL),

                       ClrDarkBlue, ClrBlue, ClrWhite, ClrWhite,

                       g_pFontCmss22b, "Show Welcome", 0, 0, 0, 0, 0);

     

    //error routine if driver library encounters an error

    #ifdef DEBUG

    void

    __error__(char *pcFilename, unsigned long ulLine)

    {

    }

    #endif

     

    void main(void) {

           // Enable lazy stacking

           ROM_FPULazyStackingEnable();

     

           // Initialise system clock to 50MHz

           ROM_SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

     

           // Enable interrupts

        ROM_IntMasterEnable();

     

        // Initialize the display driver.

        Kentec800x480x16_ssd1963Init();

     

        // Add the compile-time defined widgets to the widget tree.

        WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sBackground);

     

        // Paint the widget tree to make sure they all appear on the display.

        WidgetPaint(WIDGET_ROOT);

     

           while(1){

                  // Process any messages from or for the widgets.

                  WidgetMessageQueueProcess();

           }

    }

  • William's response - ripe with Screen Caps - is what I had suggested.  Now your linking your verbage - with/to the related Screen Cap - would go far to boost comprehension.

    Have another suggestion - perhaps it would best help William (and others) if you'd deliberately cause several different faults - and then employ both Screen Caps and written description to best highlight this complex, diagnostic  process.  We do realize that a, "Fault Troubleshooting" document exists - but further detailing - from your unique perspective - is sure to prove beneficial.

    Always wise to remain, "mindful" that many (most) here do not share your focus & expertise.  Classically the tech writer, "assumes" that the reader, "knows" - and all too often - that is not the case... 

    Suspect that this effort is beyond, "instant" response.  My sense is that William (and others) would prefer a more comprehensive write-up - with illustrations & Screen Caps - than a lesser review performed under intense, "time crunch." 

    As always - your efforts - and those of the TI forum team - are commendable (unmatched!) and greatly appreciated...

  • William,

      Thanks for this information - it's very helpful and has provided us with a smoking gun. The fact that you are getting an Invalid State exception means that software tried to tell the ARM core to switch from Thumb mode into ARM mode. This is not something that a Cortex-M3 or -M4 can do since it only supports the Thumb2 instruction set so you get an exception to let you know that something horrible has happened. The mode change is signaled to the core by the lsb of the value loaded into PC. If it's a 1, this tells the core to execute in Thumb mode, if it's a 0, this indicates ARM mode.

    The fact that this is happening pretty much points us to a stack corruption problem. The toolchain would never insert an ARM-mode function into your executable (unless you had it configured for the wrong core and that's pretty unlikely) so the most likely way that a bad value could get into PC would be on the return from a function when the return address is popped off the stack. If this address gets corrupted, you end up with a bad PC value on the stack and the return faults with an Invalid State exception.

    I suspect that the act of adding the third widget to your tree has resulted in more stack usage and this is what pushed the application over the edge. To verify this, make sure that the current stack pointer (0x20000248) is within the block that you have set aside for the stack (starting at __STACK_TOP and extending downwards by the number of bytes you specify for the stack in the "Basic Options" window under "TMS470 Linker" (or "ARM Linker" if you imported an older project) in the project properties dialog. I bet you'll find that it is outside the bounds and that increasing the stack size will help. Generally, I would start with a 1024 byte stack for all applications using the widget library.

  • @Dave-

    Thrilled that you have likely solved, "William."  However the need for greater detail (with illustrations) remains.

    One hopes that the, "Greater Good" of a more generalized, broader attack is not sacrificed for this singular (one time, one fault) solution...  (and all too often others/myself note this as the m.o. (modus operandi) of this and other forums.  A more comprehensive, "method of attack" (as suggested) will significantly strengthen many Stellaris users - and greatly reduce many repetitive demands upon you and the forum support staff... 

    This is all so clear from a distance - and clearly William's use of Screen Caps and focused description - (suggested somewhere) eased and enhanced your diagnosis.  And would do the same for the Stellaris multitudes...

  • cb1,

      I agree - an in-depth set of app notes on fault diagnosis with toolchain screen shots would be enormously helpful. Unfortunately, I strongly suspect the chances of anyone here having time to produce something like that in the next 6 months is infinitesimally small. We'll have to stick to individual answers as the questions come up for now. Sorry.

  • @ Dave W,

    Thanks for your reply - and also for the quick, detailed aid to William.  (and I'm sure - to many interested, "others.")

    While our assessments of how, "best to proceed" differ - respect your sensibilities - shall cease/desist.  (this issue)

    (let the record show that having co-founded - building Sales to $17 million ( 4 years) from, "Start Up" - and then, "going public" - my past tech firm would have quickly rejected this seeming, "bandaid - repetitive" approach.  Very "Sub-Optimal" for Stellaris Users - for the skilled, TI Forum Staff - and in the long run for Stellaris MCU SALES!...)

    I do try my best to offer pertinent comments - always for the greatest good - and trust that my unique tech/business background & experience offer some, "Real World - How things are better done" value...

  • cb1 I don't understand what else you are asking for.  We have already done this.  We wrote an app note about diagnosing faults specifically to avoid the "band-aid" approach.  It steps through the common scenarios and includes screen shots.  Admittedly it uses screen shots from only one tool and not every possible one, but it should be easy to extrapolate to any tool.  We cannot predict every possible thing a user is going to do to cause a fault but based on what I have seen in the forum we are covering the most common situations.  The INVSTATE is mentioned in section 4.4.  The point is that now we have something we can hand out when someone asks for help with a fault.  Once they have been through that, then we have a common context for offering further help, presuming at that point that the person is now educated about faults to the extent provided in the app note.

  • @Stellaris Joe -

    I both mentioned and credited that past writing.  Know that you authored - and it certainly is good - but the subject is complex and indeed would benefit from further detail.  My intent was never to attack you nor that document - and I did provide multiple specifics...

    Your argument suffers with, "We cannot predict every possible," that is a poor (borderline hostile) rebuttal.  I have clearly asked for the most common - most expected ones - as a further illustration of process.  The process is complex and detailed - very likely needs further amplification.  (simply look @ Research Firm's, "William")

    Note further that, "only a single author" produced the Fault Guide.  As you know - technical subjects often benefit from exchange of views - varying perspectives - this was my point.   And you will note that Dave W. added much of his personal style - rather than directing poster William to the existing guide.  This can only improve user comprehension.

    Surely your Fault Guide is a good start - but others and myself do not believe it should serve as, "fait accompli!"   Fleshed out - as requested - it can offer far more ease of use and value. 

  • @Dave

    Thanks for your reply, and I got the program to work! Furthermore, the HelloWidget example project which I converted from M3 to M4 works finely now! I'm really grateful for your encouragement.

    Just to check if my thinking is correct.
    As you suspected, the Stack Pointer (0x20000248) was out of bounds as the default stack size was only 256 bytes.
    --> I referred to __stack in the memory browser, and the address was already starting at (0x200002A8).

      

    After changing the stack size to 1024 bytes in the "Basic options" tab under ARM Linker, the third widget appeared and no faults were triggered.
    --> the SP now points to 0x200003F0, and referring again to the __stack in the memory browser, it now starts at 0x20000000. I guess this is what you meant by it being within the bounds of the defined stack size?

      

    Thank you cb1 and Joe for your engagement in this thread too! I'm glad that I chose the TI platform!

  • I'm also glad you chose the TI platform :-) Let us know if you have any more questions and we'll do our best to help out.