Jump to content

Compiling ugfx with widgets


crteensy

Recommended Posts

I'm trying to compile (without makefiles) the label example code found in the wiki (http://wiki.ugfx.org/index.php?title=Label). It seems that I need to add GEVENT, GQUEUE and GTIMER in addition to GINPUT, because the linker complains about undefined references to functions form those modules. In another thread it has been pointed out that GTIMER uses a separate thread, and now I'm really stuck.

When I add those files from the ugfx source tree my linker stops complaining, which is fine. However, it has been noted in another thread that GTIMER uses a separate thread (viewtopic.php?f=22&t=191&p=1518&hilit=gtimer#p1518) which is simply not available in my environment. What can I do here?

Link to comment
Share on other sites

Separate threads are available even for bare metal and arduino as the GOS layer provides that emulation. For these platforms the multi-threading is co-operative but it is still multi-threading. This has been implemented in the GOS layer for exactly the reason you describe, many parts of gfx currently need that functionality.

This multi-threading can also be used by user applications and provides significant benefits to these normally non-multithreaded environments.

If RAM is very tight there is a define that can be added to your gfxconf.h to control the size of the GTimer stack.

Link to comment
Share on other sites

So that's a black box for me and I'll only complain if it blows up my stack. How far can I go down with GTIMER_THREAD_WORKAREA_SIZE (that's the one, isn't it)? I now have

///////////////////////////////////////////////////////////////////////////
// GTIMER //
///////////////////////////////////////////////////////////////////////////
//#define GFX_USE_GTIMER FALSE
#define GTIMER_THREAD_WORKAREA_SIZE 0

in my gfxconf.h, but I'm not sure if the work area size is actually used since I have not set GFX_USE_GTIMER to TRUE.

Link to comment
Share on other sites

If the GTIMER module is not enabled then the module does not require any stack.

The amount of stack required depends from application to application. We put the default to 2k because this way it works with every even so complex application that we tested so far. However, it is possible to work with 1k or even less but that needs rigorous testing to be sure that it works reliably. But that's something that you have to do.

As a general rule: All the module specific settings in your configuration file do not have any affect as long as the corresponding module is disabled.

~ Tectu

Link to comment
Share on other sites

When I try to run the touch example my system gets stuck at the call to gfxSleepMilliseconds(100) in the main loop. I've added debugging messages before and after that line, but the output that comes after that line is not shown. That might be related to threading because the gfxSleepMilliseconds function calls gfxYield() and I haven't followed things further from there because I have no on-chip debugging. This is my gfxconf:

#ifndef _GFXCONF_H
#define _GFXCONF_H

#define GFX_USE_OS_RAW32 TRUE
#define GFX_NO_OS_INIT TRUE

#define GFX_USE_GDISP TRUE
#define GDISP_NEED_CONTROL TRUE
#define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_TEXT TRUE
//#define GDISP_INCLUDE_FONT_UI1 TRUE
#define GDISP_INCLUDE_FONT_UI2 TRUE
//#define GDISP_INCLUDE_FONT_DEJAVUSANS16 TRUE
#define GDISP_INCLUDE_FONT_FIXED_7X14 TRUE
#define GDISP_INCLUDE_FONT_FIXED_5X8 TRUE
#define GDISP_INCLUDE_USER_FONTS TRUE

#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_MULTITHREAD TRUE


#define GDISP_NEED_STARTUP_LOGO TRUE

#define GFX_USE_GWIN TRUE
#define GWIN_NEED_WINDOWMANAGER TRUE
#define GWIN_NEED_WIDGET TRUE
#define GWIN_NEED_LABEL TRUE
#define GWIN_NEED_CONSOLE TRUE

///////////////////////////////////////////////////////////////////////////
// GEVENT //
///////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////
// GTIMER //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GTIMER TRUE
#define GTIMER_THREAD_WORKAREA_SIZE 2048


///////////////////////////////////////////////////////////////////////////
// GQUEUE //
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
// GINPUT //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GINPUT TRUE
#define GINPUT_NEED_MOUSE TRUE
#define GINPUT_TOUCH_STARTRAW TRUE

Link to comment
Share on other sites

The label example from the wiki also hangs in the main loop after a while (about two minutes). When I add a second label it doesn't even get past the first iteration:

#include 
#include
#include
void setup()
{
// while(!Serial.available());
Serial.println("Start");
SPI.begin();

// Initialize and clear the display
gfxInit();

// draw();

}

static GHandle ghLabel1;
static GHandle ghLabel2;

static void createWidgets(void) {
GWidgetInit wi;

// Apply some default values for GWIN
wi.customDraw = 0;
wi.customParam = 0;
wi.customStyle = 0;
wi.g.show = TRUE;

// Apply the label parameters
wi.g.y = 10;
wi.g.x = 10;
wi.g.width = 100;
wi.g.height = 20;
wi.text = "Label 1";

// Create the actual label
ghLabel1 = gwinLabelCreate(NULL, &wi);

wi.g.x = 400;
wi.g.y = 250;
ghLabel2 = gwinLabelCreate(NULL, &wi);

}

static char buf[20];

void loop()
{
// Set the widget defaults
gwinSetDefaultFont(gdispOpenFont("UI2"));
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
gdispClear(White);

// create the widget
createWidgets();

while(1) {
snprintf(buf, 20, "%" PRIu32, millis()/1000);
gwinSetText(ghLabel2, buf, TRUE);
gwinSetText(ghLabel1, "This is some text", TRUE);
gfxSleepMilliseconds(1000);
gwinSetText(ghLabel1, "Aaaand some other text", TRUE);
gfxSleepMilliseconds(1000);
}
}

so I end up with "Aaaand some other text" in the upper left corner and "0" in the lower right.

Link to comment
Share on other sites

When the gtimer module is turned on (and it will be for any gwin stuff like the label), it obviously needs a stack. Specifying 0 for the size of the stack causes the gos layer to put in a default size stack which may not be big enough for gtimer when being used with gwin. GWIN is unfortunately a heavy user of stack.

With the problems you are currently having, they could very well be stack related. Just remove the stack size define from your gfxconf.h and see if that works. Try to optimise ram usage later.

Link to comment
Share on other sites

I had the stack size set to zero only to see if it would compile with that. In the config I posted later it's set to 2048, and even without the #define the application hangs. My compiler is arm-none-eabi-gcc (the one that comes with teensyduino) with this configuration:

> arm-none-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/users/crteensy/builds/arduino/arduino-1.0.6/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/4.8.4/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native --libexecdir=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native/lib --infodir=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/install-native/arm-none-eabi --build=x86_64-linux-gnu --host=x86_64-linux-gnu --with-gmp=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/build-native/host-libs/usr --with-mpfr=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/build-native/host-libs/usr --with-mpc=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/build-native/host-libs/usr --with-isl=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/build-native/host-libs/usr --with-cloog=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/build-native/host-libs/usr --with-libelf=/home/build/toolchain/gcc-arm-none-eabi-4_8-2014q3-20140805/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r
Thread model: single
gcc version 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147] (GNU Tools for ARM Embedded Processors)

Is it possible that it's a bug caused by some optimization setting? I'll try other settings later today.

Link to comment
Share on other sites

That's a bummer. I can't test it now, but -O0 results in significantly larger code (~58 kB vs ~40 kB) and it might even be slower (I'd have to test, though). The biggest problem is that I have to modify my linker script because the startup code is now too large, which might have other implications that I'm not aware of.

If ugfx works for me with -O0 I can turn it into a library (or several) for linking and compile my other code with other optimization settings. To be honest I didn't encounter optimizer problems with -O2 and -Os until now.

Link to comment
Share on other sites

Seems to run ok with -O0. I'm a bit disappointed by that, but I'll see if I hit any speed or size issues (probably not). The label example has been running stable for about 550 seconds until I decided to try something different. The touch_driver_test works (a bit clumsy, but that's my crappy calibration and I was probably drunk while I did that) as well as touch_raw_readings. Great!

Link to comment
Share on other sites

These optimiser bugs we really should find so we can rearrange the code to fix it. Any help you can provide with that would be appreciated.

The last one I found was a ternary operator being used for an integer between two values test. The optimiser was completely stuffing up the range test. Unfortunately the test was in a macro in an chibios header file so outside our control. I ended up rewriting the block of code using the test to get around it.

Link to comment
Share on other sites

I can do that, but as it is now it shares a common header (register address definitions and bit masks) with the RA8875 display driver. Would you like a separate header with only the touch panel definitions? This should be done right before anyone starts using it.

Link to comment
Share on other sites

With the RA8875 it is a bit border line... I think we should indeed provide split drivers (GDISP only and GINPUT only) that work independent from each other as with every other touchscreen module. However, we can still provide an easier-to-use driver that is part of the /drivers/multiple directory. This way a user using the RA8875 can simply include one driver and everything else will work out of the box. It would basically be the same as for the Windows and Linux drivers.

~ Tectu

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...