Jump to content

F429Discovery/RAW32 - HardFault after mouse calibration


Foxnec

Recommended Posts

Hello, I am trying to get uGFX working on STM32F429-Discovery (with Keil MDK4 and using stdperiph libs), and so far I have managed to get the LCD and the touch panel working - with one problem. As long as i am in the process of calibration (blue screen), everything works fine, as soon as I finish calibration, the device goes into hard fault while switching context (or so it seems).

 

Attached is a picture of my IDE - the highligthed instruction in disassembly is exactly where it goes bang. I have noticed that while the calibration is running, the program enters into gfxXSwitch() with a "random" value in R6 register but when it gets to this point in the execution, it is reset to 0x0. After the calibration though, R6 retains its value, which i believe causes a jump to a wrong address. EDIT: I have also attached the call stacks before CXT_RESTORE is called and then just before the fault.

 

Thank you in advance for your help,

Daniel.

problem.png

before CXT_RESTORE()

callstackbefore.PNG.2ac4444ca437dcd63eec

after (it gets messed up somehow by having most of its content deleted, if I am understanding it correctly)

callstackafter.PNG.1f002d478e734accef29f

Edited by Foxnec
Link to comment
Share on other sites

Unfortunately this is a known bug/problem with the Keil compiler - probably in the Keil C runtime library.

uGFX requires a multi-thread system. RAW32 provides this by implementing a very simple non-preemptive (cooperative) scheduler.

RAW32 provides this scheduler via one of two means...

  1. CPU specific assembly code, or
  2. Using the C runtime library setjmp() and longjmp() calls.

See /src/gos/gos_x_threads.c for details.

For Keil option 1 is not currently available as the assembly code has been written in GCC format which the Keil compiler does not understand.

Option 2 does not work for Keil either as the setjmp and longjmp implementation in the Keil C library likely has a bug in it. Note that for option 2 to work the compiler must provide implementations for these two routines that match the code model and CPU of the compilation for the rest of the application. I suspect, but have not confirmed with testing, that that is where Keil is failing.

There are five possible solutions:

  1. Someone sits down and writes Keil compatible assembly code that we add to that source file, and/or
  2. We get Keil to fix their C library implementation of setjmp() and longjmp() [unlikely], and/or
  3. We figure out how to patch our scheduler so that it works around the Keil library bugs (which may or may not be possible).
  4. Don't use RAW32 with the Keil compiler. Instead use ChibiOS or the Keil CMSIS operating system.
  5. Use the GCC compiler option in the Keil IDE rather than the ARMCC compiler. This may work - we haven't tested it.

Our preferred solution is option 2, and then option 1. Both require more time than we currently have available although it is on our TODO list.

Perhaps you would like to help in option 1 or 3 and contribute it back to the community? It is something we would really appreciate.

When looking at option 3 look particularly at these things...

  • The function calling convention or ABI.
  • Make sure that stack boundary checking is turned off.
  • Try with various levels of optimisation as it could be the optimiser that is breaking things.

 

Link to comment
Share on other sites

Hello, thank you for a prompt and exhaustive reply! I would have never figured something like that out by myself :-)

I am afraid I am not a proficient enough programmer to even take a shot at modifying your scheduler, but I will surely take a look at it just in case. I will, however, consider finally implementing an RTOS, as my project (a snowball-type hobby project running for months :-) ) has reached a point where it would benefit from running an RTOS even before i started playing with ugfx.

Thank you again,

Daniel 

Link to comment
Share on other sites

You might want to have a look at ChibiOS: http://chibios.org
It's a very good and mature RTOS that comes with it's own, complete HAL (optional, of course). µGFX is known to work very well on ChibiOS. Actually, µGFX started out as an official ChibiOS extension called ChibiOS/GFX.

Otherwise you can have a look at the the list of the operating systems that are already supported by µGFX: http://ugfx.org/platforms.html

Link to comment
Share on other sites

  • 5 months later...

Since the last article we have made changes to the c library handling so it may (or may not) now work with the Keil c library routines.

There has been no progress on rewritting the asm calls to be Keil compatible as there are other working solutions (eg switch to gcc) and we are short on man power. Hopefully sometime soon this will become important enough for someone so that they volunteer the time to update the asm code for Keil.

Link to comment
Share on other sites

I am Working on it with my lack of knowledge at assambly language but it looks like easy syntax problem

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0097a/armcc_cihccdja.htm

  ****      __asm__ volatile (    "push    {r4, r5, r6, r7, r8, r9, r10, r11, lr}    \n\t"
                            "str    sp, %[oldtcxt]                            \n\t"
                            "ldr    sp, %[newtcxt]                            \n\t"
                            : [newtcxt] "=m" (newt->cxt)
                            : [oldtcxt] "m" (oldt->cxt)
                            : "memory");  *****

at the link this syntax is not acceptable isn't it ? 

Thx

Link to comment
Share on other sites

Hello @Sahsuvar and welcome to the community!

If memory serves me right it is indeed just a syntax problem. As @inmarket mentioned we currently just lack the man power to take care of everything. If you can get it fixed, we would love to put a version of the code that works with the Keil compiler into the official µGFX library. Note that you can use the GFX_COMPILER_KEIL macro to write Keil specific stuff.

One of the reasons why this currently isn't that high on our ToDo list is because most of the people that use Keil (with the µGFX library) are using Keil RTX as the underlying system (RTOS). In that case the Raw32 port is not used.

Link to comment
Share on other sites

Looking at that doc reference it looks like the armcc compiler cannot do the required functionality using the inline assembler. In particular it allows no reference to the real registers, access to sp & lr are prohibited and storing of register values on the stack is also prohibited (which actually makes it pretty useless). 

There is an alternative called "embedded assembly" which does not have those restrictions. Unfortunately in my brief scan i couldn't see how to use it.

I will leave it to you to investigate further.

Link to comment
Share on other sites

As @inmarket mentioned the issue seems to be a restriction in the compiler used by Keil. Your options are:

  • Using a different underlying system such as Keil RTX, FreeRTOS or ChibiOS which are very well tested with µGFX (or any of the other alternatives)
  • Change your Keil project to use GCC instead of ARMCC
  • Investigate on how to use the "Embedded Assembly" alternative (link: http://www.keil.com/support/man/docs/armcc/armcc_chr1359124253861.htm) which appears to not have these restrictions.
Link to comment
Share on other sites

Yes I noticed that physical registers are not directly accesable in armcc so the job is not so easy. May be we (or you) can write an external .asm file with a label "threads" and  inline assembly comands send it to  that label but there are input variables? I am not an asm guru. Or can you turn it into a assembled .lib file ?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...