Jump to content

Basic requirements for bare metal implementation?


Recommended Posts

Posted

Hi,

I'm just start using uGFX and doing some 'hello world' testing. I'm using a bare metal STM32F103 mcu with ILI9341 320*240 touch LCD.

I've already got the 'benchmark' demo code running and have correct result. Now I'm trying to test a 'push button' widget, but I found I couldn't even get the button displayed on the screen.

My test code is based on the ugfx/demos/modules/gwin/button/main.c

My environment is Segger Embedded Studio and using the single gfx_mk.c file approach.

I noticed in the gfxconf.h it's said an OS is required but unfortunately bare metal is not in there, but I didn't see any OS specific code in the demo main.c, any to simplify my situation, I even disabled the event checking for the button, but I still can't get the button displayed. Is there any spcial requirements to use the widgets on a bare metal system? like calling some 'display refresh' function periodically? I couldn't find any documentation on this, anybody can help?

If you can help me on the display issue, maybe you can also tell me is there anything I should care about using the 'event' system on a bare metal? Thanks in advance.

Tim.

Following is my test code : (The uGFX logo is shown at the start, but then I only got a white screen)

int main(void) {
	init();		// this is GPIO init etc.

	GEvent* pe;
	static const gOrientation	orients[] = { gOrientation0, gOrientation90, gOrientation180, gOrientation270 };
	unsigned which;

	// Initialize the display
	gfxInit();

	// We are currently at gOrientation0
	which = 0;
	gdispSetOrientation(orients[which]);

	// Set the widget defaults
	gwinSetDefaultFont(gdispOpenFont("UI2"));
	gwinSetDefaultStyle(&WhiteWidgetStyle, gFalse);
	gdispClear(GFX_WHITE);

	// create the widget
	createWidgets();

	// We want to listen for widget events
	//geventListenerInit(&gl);
	//gwinAttachListener(&gl);
	while(1);
}

 

Posted

Hello & welcome to the µGFX community!

The µGFX library has been designed to run on virtually anything. So pretty much any scenario you'll encounter will work.
For convenience, there is a baremetal implementation which has been tested & is being used extensively on the STM32 platform. It's called RAW32. See https://wiki.ugfx.io/index.php/BareMetal

 

On 24/04/2022 at 07:53, jj8431 said:

noticed in the gfxconf.h it's said an OS is required but unfortunately bare metal is not in there

As shown in the linked wiki article, this should be as easy as setting GFX_OS_USE_RAW32 to GFXON in your configuration file. Everything else happens automagically under the hood when calling gfxInit().
Additionally, you might want to set GFX_CPU, GFX_COMPILER and the memory management related options explained in the wiki article linked above.

 

On 24/04/2022 at 07:53, jj8431 said:

like calling some 'display refresh' function periodically? I couldn't find any documentation on this, anybody can help?

While all of this is configurable, by default this shouldn't be necessary.
The corresponding documentation would be: https://wiki.ugfx.io/index.php/GWIN#Redrawing_mode

 

On 24/04/2022 at 07:53, jj8431 said:

If you can help me on the display issue, maybe you can also tell me is there anything I should care about using the 'event' system on a bare metal? Thanks in advance.

Nothing special is required. The demos should work out of the box. Just make sure that you're not only using the various source files (eg. main.c) but also the corresponding configuration file (gfxconf.h).
When changing values in the configuration file, be sure to perform a clean build.
Other than that: You might want to give the current git master branch a try. It contains various fixes that didn't make it into the v2.9 release. However, nothing specific to your situation. Just generally a good idea. This way you'll also be ready for the upcoming v2.10 release.

Given that your system is already up and running this should be easy to debug. Somewhere in your createWidgets() function there should be a call to gwinButtonCreate(). Assuming that the first parameter to that call is 0 / NULL, the µGFX library will allocate the memory dynamically. If this fails, the returned pointer would be NULL.
If that is the case, your stack/heap settings might be incorrect. Refer to the settings explained in the wiki article linked above.

 

If you continue experiencing problems after correctly setting the various options in your gfxconf.h please share your configuration file (by attaching it to your next post).
Please don't hesitate to ask - we're happy to help where we can!

Posted

Thank you very much for the detailed reply Joel.

I did have the config file set as the demo, but I missed one thing, it's the

#define GWIN_REDRAW_IMMEDIATE                    GFXON

The redrawing mode article is help full.

Now I know what's happened, I used the original demo code first, but didn't set the heap to a large enough size, and found it's not working. then I removed the event listening lines and changed the heap size, but apparently if you don't use the geventEventWait(),  'IMMEDIATE DRAWING' must be on. So that's the reason I can't see the button drawn on the sreen.

Is there a generic guide on how mush the heap should be for an application ? I feel I a bit lost on setting the heap size. Can uGFX give an error message or something if the heap is too small ?

 

 

Posted

Glad to hear that you got it working!

 

2 hours ago, jj8431 said:

Is there a generic guide on how mush the heap should be for an application ? I feel I a bit lost on setting the heap size.

This is non-trivial. The µGFX library has been designed to run on virtually any system with a broad range of configuration options which have compile-time impact in an effort to reduce the required resources (including RAM) to a bare minimum. How much memory is needed is really depending on not just the application overall but also your configuration & underlying system.
Especially when it comes to the GWIN module (the window manager, widgets etc.), you can choose to either use heap OR stack. The various `gwinXxxCreate()` functions accept a pointer as the first parameter. If that is NULL, then the necessary memory is dynamically allocated from the heap automatically. If you pass in a pointer, no heap allocation happens and you can instead use your stack memory (or whatever other memory you want).
I know that the above is not helpful to you but it is what it is. To give you some rough estimates, a small application with a few display pages, buttons, navigations, slider, different fonts, images and so on can work with less than 1kB of RAM.

 

2 hours ago, jj8431 said:

Can uGFX give an error message or something if the heap is too small ?

The various demos are just that: demos. The idea is to keep code complexity as low as possible to maintain the focus on the aspect of whatever the demo is supposed to be demonstrating. As such, those demos try to reduce the code size as much as possible. For example, the various widget demos use heap allocation for the widgets (see above - first parameter to gwinXxxCreate() is NULL). But we don't check the returned pointer for NULL which would indicate allocation failure - eg. due to insufficient heap capacity.
Any real world application would either not use the auto-allocation mechanism or properly check the returned pointer for NULL.
This applies to most of the µGFX API. Error codes are returned everywhere where reasonable. Places which require (or offer) dynamic allocation typically return NULL if allocation failed. Any real wold application should check for those error codes etc.
 

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