There are many GUI libraries for microcontrollers and embedded systems, but many of them have limited functionality, difficulty in using and integrating, the need for mandatory use of external RAM, and some cost more than your entire project. Because of these reasons and many others, it was decided to write their own library.
I called it MakiseGui .
Before starting the development, I set myself goals:
A project created specifically for this purpose can be used as a demonstration of library features and usage examples: https://github.com/SL-RU/MakiseSDLTest
It uses SDL2 for drawing and input and has examples of using all the elements and almost all the functions of the system. It can be compiled and run on any linux distribution. On windows, too, but only theoretically, I did not try it myself.
Video of work:
The library consists of three clearly separated parts:
1) The core. The kernel consists of the interface to the driver, the functions of drawing to the driver, and the functions of drawing primitives into the buffer.
2) Driver. The driver provides all communication with hardware and software, so for each task you usually have to write your own to take into account all the moments (DMA, interrupts, etc.). The driver only transfers the image from the buffer to the iron and clears the image buffer. As examples, the project has drivers for the display on ili9340, as well as SDL2 for debugging the library on the computer. The kernel and driver can work separately, without a GUI.
3) The GUI itself. It occupies a large part of the system; all necessary functions for the operation of the interface are embodied here: containers, elements, drawing systems, focus, input, event processing, and other things.
The development of the graphical interface is as close as possible to the object-oriented for maximum simplicity of the final programming. Because of this, it has some nice features.
The simplest example that creates a button on the screen:
MHost host; // , root-, . // void click(MButton *b) { printf("Button was clicked"); // b->text = "Clicked!"; // } MButton button; //, void create_gui() { // m_create_button(&button, // host->host, //, . MHost'a mp_rel(20, 20, // 90, 30), //, "Click me", // // &click, // 0, // , 0, // &ts_button // ); } void main() { // MakiseGui, , MakiseBuffer MHost. . create_gui(); while(1) { // // // } }
In total, this example creates a button on the screen when clicked, which in the standard output stream will display "Button was clicked" and the text of the button will change.
Initialization involves only running the driver, setting the size and memory allocation for the structures and buffers of the elements. Purely formal operation. How to initialize the system can be seen here: https://github.com/SL-RU/MakiseSDLTest/blob/master/src/main.c in the start_m method ();
To start using the GUI, you need to create makise_config.h and configure it. In this file, system defines are set and the necessary display drivers are selected. https://github.com/SL-RU/MakiseSDLTest/blob/master/makise_config.h
Input is adapted to work in multi-threaded applications - it has a queue of events that are sent to the interface when you call makise_gui_input_perform (host);
Any input event is represented by the MInputData structure.
You can enter buttons (a list of standard in makise_gui_input.h MInputKeyEnum), characters (while not used anywhere) and cursor input (touch screen or mouse). The SDL example uses keyboard input and mouse input.
MContainer - container structure.
Containers contain a linked list of items. You can remove or add items from containers, move them and perform other operations.
The position of the element in the container directly affects the draw and input queue.
A linked list is made using pointers to the first and last element of the MElement list, and there are pointers to the next and previous element in the MElement structure.
Any element is represented by the MElement structure, which contains information about the element, pointers to the functions of drawing, input, focus, etc. of the element and a pointer to its contents.
At the moment there are the following elements:
Examples are the best documentation, so each element has its own usage examples. Both complex and simple.
The number of items will increase with time. Yes, there are not many necessary functions - graphics, images, and so on. But for my purposes, they are not needed yet, but if they are needed soon, I will add and publish to the library. Also do not hesitate to add your own or edit existing ones! Pull requests are welcome.
The style of an element determines its appearance. The style sets the colors of the element in a certain state. The structures MakiseStyle and MakiseStyleTheme are responsible for this. MakiseStyle contains several MakiseStyleTheme for certain states, as well as font parameters.
For a button, the style might look like this:
MakiseStyle ts_button = { MC_White, // . &F_Arial24,// 0, // // | {MC_Black, MC_Gray, MC_Gray, 0 }, // {MC_Black, MC_White, MC_White, 0 }, // {MC_White, MC_Green, MC_White, 0 }, // {MC_Green, MC_White, MC_White, 0 }, // };
Focus determines which element will go input. To control the focus, the following functions exist:
MFocusEnum makise_g_focus(MElement *el, MFocusEnum event); // MFocusEnum makise_g_host_focus_next(MHost *host);// MFocusEnum makise_g_host_focus_prev(MHost *host);//
An example library for STM32 microcontrollers was also written. The MK STM32f437VGT6 was used with a clock frequency of 180 MHz and a 2.2 "display of 230x320 pixels on the ILI9341 controller. Controls from a computer keyboard via UART.
Example code: https://github.com/SL-RU/MakiseILI9341Test
Example video:
Some documentation is in the repository. But all the main documentation is in the comments to the functions and in the examples. Ask questions! On the basis of them I will add the documentation. Many moments were not touched upon in the article or touched upon in passing. If the article is popular, I’m happy to write a few more, for example about creating a driver for the STM32 + tft display connected via FSMC for this GUI.
There are many points that need to be improved in the library and there are many ways of development. But at the moment the library is completely working and stable.
Project license is MIT. You can use the library and source code as you wish and where you want, even use it without problems in commercial projects, but at the same time I do not give any guarantees regarding the work of the library - everything is as it is.
If you want to change something in the code, fix the found bug or error, then write to the issue in the repository, or even throw pullrekvesti.
I will be glad to questions and wishes!
Source: https://habr.com/ru/post/325692/
All Articles