L'étude est basée sur Microchip Libraries for Applications v2017_03_06.
L'objectif est de faire marcher la librairie sur un PC.
Sur la base de (5), on a comme application de départ :
#include <gfx/gfx.h> bool APP_ObjectMessageCallback(GFX_GOL_TRANSLATED_ACTION action, GFX_GOL_OBJ_HEADER *header, GFX_GOL_MESSAGE *msg) { return true; } bool APP_ObjectDrawCallback(void) { } void APP_CreateScreens() { GFX_ColorSet(WHITE); GFX_ScreenClear(); } void TouchGetMsg(GFX_GOL_MESSAGE *msg) { } int main() { GFX_GOL_MESSAGE msg; GFX_Initialize(); GFX_GOL_MessageCallbackSet(APP_ObjectMessageCallback); GFX_GOL_DrawCallbackSet(APP_ObjectDrawCallback); APP_CreateScreens(); while(1) { if (GFX_GOL_ObjectListDraw() == GFX_STATUS_SUCCESS) { TouchGetMsg(&msg) GFX_GOL_ObjectMessage(&msg); } } }
Pour compiler :
gcc main.c -Iframework -I.
Il est à noter qu'il faut maintenant définir le fichier system_config.h
et implémenter les fonctions définies dans le fichier driver/gfx/drv_gfx_display.h
qui ne contient que l'interface.
N'implémenter au départ aucune des fonctions de drv_gfx_display.h
et attendre que le lieur échoue.
#ifndef system_config_h_ #define system_config_h_ #include "gxf_config.h" #endif // system_config_h_
La librairie est plutôt bien faite avec des warnings en cas de #define
non définis.
Il faut définir :
#define GFX_CONFIG_COLOR_DEPTH
avec 1, 4, 8, 16 ou 24#define GFX_EXTERNAL_FONT_RASTER_BUFFER_SIZE
: buffer of the character bitmap when sourced from external memory
Utilisé par la fonction utilisateur GFX_ExternalResourceCallback
. Le buffer doit au moins être aussi grand que le paramètre uint16_t nCount
.
#ifndef GFX_CONFIG_H_ #define GFX_CONFIG_H_ #define GFX_CONFIG_COLOR_DEPTH 24 #define GFX_EXTERNAL_FONT_RASTER_BUFFER_SIZE 100 // Sinon la couleur WHITE n'existe pas. #define GFX_CONFIG_PALETTE_DISABLE // Parce qu'on n'utilise par le compilateur Microchip. #define __prog__ #endif // GFX_CONFIG_H_
/tmp/ccYnfXb4.o : Dans la fonction « APP_CreateScreens » : main.c:(.text+0x429) : référence indéfinie vers « GFX_ColorSet » main.c:(.text+0x42e) : référence indéfinie vers « GFX_ScreenClear » /tmp/ccYnfXb4.o : Dans la fonction « main » : main.c:(.text+0x458) : référence indéfinie vers « DRV_GFX_Initialize » main.c:(.text+0x45d) : référence indéfinie vers « GFX_Initialize » main.c:(.text+0x467) : référence indéfinie vers « GFX_GOL_MessageCallbackSet » main.c:(.text+0x471) : référence indéfinie vers « GFX_GOL_DrawCallbackSet » main.c:(.text+0x480) : référence indéfinie vers « GFX_GOL_ObjectListDraw » main.c:(.text+0x49d) : référence indéfinie vers « GFX_GOL_ObjectMessage » collect2: error: ld a retourné le statut de sortie 1
gcc main.c -Iframework -I. framework/gfx/src/gfx_primitive.c
Il manque encore dans gfx_config.h
:
#define DISP_HOR_RESOLUTION XXX #define DISP_VER_RESOLUTION XXX
Et le message d'erreur suivant :
framework/gfx/src/gfx_primitive.c:4506:37: error: « FONT_RAM » non déclaré
#define GFX_CONFIG_FONT_RAM_DISABLE
gcc main.c -Iframework -I. framework/gfx/src/gfx_primitive.c
Il manque encore
#define GFX_malloc(pObj) malloc(pObj); #define GFX_free(pObj) free(pObj)
Dans le fichier gfx_types_macros.h
il y a une erreur (je pense). Il faut remplacer les ConvertColorXX
par GFX_ColorXXConvert
.
Le compilateur de Microchip a l'air d'accepter les extern inline
ce qui n'est pas le cas de gcc/clang.
Il faut remplacer les extern inline
par inline
dans les fichiers header.
sed -i "s/extern inline/inline/g" *.h
GFX_PixelGet
et GFX_PixelPut
: Lecture et écriture d'un pixel. Dans notre cas, on va se contenter d'un buffer interne à l'applicaten.static GFX_COLOR buff[DISP_VER_RESOLUTION][DISP_HOR_RESOLUTION]; GFX_COLOR GFX_PixelGet(uint16_t x, uint16_t y) { if ((x >= DISP_HOR_RESOLUTION) || (y >= DISP_VER_RESOLUTION)) { return BLACK; } return buff[y][x]; } GFX_STATUS GFX_PixelPut(uint16_t x, uint16_t y) { if ((x >= DISP_HOR_RESOLUTION) || (y >= DISP_VER_RESOLUTION)) { return GFX_STATUS_FAILURE; } buff[y][x] = GFX_ColorGet(); return GFX_STATUS_SUCCESS; }
GFX_RenderStatusGet
: on ne gère pas de temps de latence ou autre du matériel.GFX_STATUS_BIT GFX_RenderStatusGet() { return GFX_STATUS_SUCCESS_BIT; }
DRV_GFX_Initialize
: initialisation du driver graphique.void DRV_GFX_Initialize() { }
/tmp/cc5voYLX.o : Dans la fonction « GFX_Initialize » : gfx_gol.c:(.text+0x998) : référence indéfinie vers « GFX_Primitive_Initialize » /tmp/cctgOBFP.o : Dans la fonction « GFX_Initialize » : gfx_primitive.c:(.text+0x184d) : référence indéfinie vers « GFX_Primitive_Initialize »
Il faut enlever le inline
dans le fichier gfx_primitive.h
de pour la fonction void GFX_Primitive_Initialize
.
GFX_ExternalResourceCallback
: si les fonctions externes ont terminé leur travail. Toujours oui dans le cas d'un PC.GFX_STATUS GFX_ExternalResourceCallback(GFX_RESOURCE_HDR * pResource, uint32_t offset, uint16_t nCount, void * pBuffer) { return GFX_STATUS_SUCCESS; }
A ce stade là, tout marche. Une archive complète est mise à disposition en bas de la page.
GFX_ColorSet(WHITE); GFX_ScreenClear(); GFX_LineStyleSet(GFX_LINE_STYLE_THICK_SOLID); GFX_ColorSet(RED); GFX_LineDraw(0,120,60,120); GFX_ColorSet(GREEN); GFX_LineDraw(160,0,160,60); GFX_ColorSet(BLUE); GFX_LineDraw(260,120,320,120); GFX_ColorSet(BLACK); GFX_LineDraw(160,240,160,180);
Et enregistrement du résultat dans un fichier qui sera converti en image via un programme externe.
if (GFX_GOL_ObjectListDraw() == GFX_STATUS_SUCCESS) { TouchGetMsg(&msg); GFX_GOL_ObjectMessage(&msg); FILE *fp = fopen("/tmp/screen.ppm", "wb"); (void) fprintf(fp, "P6\n%d %d\n255\n", DISP_HOR_RESOLUTION, DISP_VER_RESOLUTION); for (int j = 0; j < DISP_VER_RESOLUTION; ++j) { for (int i = 0; i < DISP_HOR_RESOLUTION; ++i) { static unsigned char color[3]; color[0] = (buff[j][i] >> 16) % 256; /* red */ color[1] = (buff[j][i] >> 8) % 256; /* green */ color[2] = (buff[j][i] >> 0) % 256; /* blue */ (void) fwrite(color, 1, 3, fp); } } (void) fclose(fp); return 0; }
gcc -Iframework -I. framework/gfx/src/gfx_gol.c framework/gfx/src/gfx_primitive.c main.c
Il faut ajouter un Scheme
pour le thème en variable globale.
GFX_GOL_OBJ_SCHEME GOLSchemeDefault;
Définir le thème
GOLSchemeDefault.TextColor0 = WHITE; GOLSchemeDefault.Color0 = BLACK; GOLSchemeDefault.Color1 = GFX_RGBConvert(0x7F, 0x81, 0x7E); GOLSchemeDefault.EmbossDkColor = RED; GOLSchemeDefault.EmbossLtColor = BLUE; GOLSchemeDefault.EmbossSize = 3; GOLSchemeDefault.CommonBkColor = BLACK; GOLSchemeDefault.pFont = NULL;
et le bouton
GFX_XCHAR UP_Msg[]={'U','p', 0}; if (GFX_GOL_ButtonCreate(11, 60, 190, 125, 255, 0, GFX_GOL_BUTTON_DRAW_STATE, NULL, NULL, &UP_Msg[0], GFX_ALIGN_CENTER, &GOLSchemeDefault) == NULL) { printf("Oups...\n"); }
gcc -Iframework -I. framework/gfx/src/gfx_gol.c framework/gfx/src/gfx_primitive.c main.c framework/gfx/src/gfx_gol_button.c
Il manque le texte mais c'est normal car GOLSchemeDefault.pFont = NULL
. Cependant, l'objectif de la page n'est pas de faire une IHM qui marche mais seulement de montrer comment on peut adapter la Microchip Libraries for Applications
pour n'importe quel usage.
Microchip licenses to you the right to use, modify, copy and distribute Software only when embedded on a Microchip microcontroller or digital signal controller that is integrated into your product or third party product (pursuant to the sublicense terms in the accompanying license agreement).
Donc la librairie n'est utilisable que sur du matériel Microchip.