Foxnec Posted March 3, 2016 Report Share Posted March 3, 2016 (edited) 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. before CXT_RESTORE() after (it gets messed up somehow by having most of its content deleted, if I am understanding it correctly) Edited March 3, 2016 by Foxnec Link to comment Share on other sites More sharing options...
inmarket Posted March 4, 2016 Report Share Posted March 4, 2016 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... CPU specific assembly code, or 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: Someone sits down and writes Keil compatible assembly code that we add to that source file, and/or We get Keil to fix their C library implementation of setjmp() and longjmp() [unlikely], and/or We figure out how to patch our scheduler so that it works around the Keil library bugs (which may or may not be possible). Don't use RAW32 with the Keil compiler. Instead use ChibiOS or the Keil CMSIS operating system. 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 More sharing options...
Foxnec Posted March 5, 2016 Author Report Share Posted March 5, 2016 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 More sharing options...
Joel Bodenmann Posted March 6, 2016 Report Share Posted March 6, 2016 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 More sharing options...
Foxnec Posted March 9, 2016 Author Report Share Posted March 9, 2016 Thank you so much for the info! I will look into it! Daniel Link to comment Share on other sites More sharing options...
Sahsuvar Posted August 27, 2016 Report Share Posted August 27, 2016 Hi Is there any progression in any of those five posible solitions I faced with that __asm__ error when I change the OS alternative #define GFX_USE_OS_RAW32 TRUE thank you Link to comment Share on other sites More sharing options...
inmarket Posted August 27, 2016 Report Share Posted August 27, 2016 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 More sharing options...
Sahsuvar Posted August 27, 2016 Report Share Posted August 27, 2016 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 More sharing options...
Joel Bodenmann Posted August 27, 2016 Report Share Posted August 27, 2016 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 More sharing options...
inmarket Posted August 28, 2016 Report Share Posted August 28, 2016 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 More sharing options...
Joel Bodenmann Posted August 28, 2016 Report Share Posted August 28, 2016 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 More sharing options...
Sahsuvar Posted August 28, 2016 Report Share Posted August 28, 2016 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 More sharing options...
inmarket Posted August 28, 2016 Report Share Posted August 28, 2016 We want to avoid direct asm files. The embedded assembler can do the job just not the inline assembler. The difference is that the embedded assembler seems to work at a function level rather than the statement level. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now