FEATURE: Significantly improved the FreeRTOS port

FEATURE: Added support for operating system initialisation in FreeRTOS
FEATURE: Added GFX_OS_CALL_UGFXMAIN configuration option to allow uGFXMain() to be automatically called
FEATURE: Added GFX_OS_UGFXMAIN_STACKSIZE configuration option to control uGFXMain() stack size
This commit is contained in:
inmarket 2017-03-04 15:02:55 +10:00
parent 5497e2ed1f
commit 5d8705b6e0
17 changed files with 125 additions and 9 deletions

View File

@ -19,6 +19,10 @@ FEATURE: Increase non-UTF8 font support to 0 to 255 rather than just the true as
FEATURE: Added Fb24bpp driver for RGB888 and BGR888 packed framebuffer displays FEATURE: Added Fb24bpp driver for RGB888 and BGR888 packed framebuffer displays
FEATURE: Added UC8173 driver FEATURE: Added UC8173 driver
FEATURE: Added complete support for Altera Terasic MAX10 NEEK board FEATURE: Added complete support for Altera Terasic MAX10 NEEK board
FEATURE: Significantly improved the FreeRTOS port
FEATURE: Added support for operating system initialisation in FreeRTOS
FEATURE: Added GFX_OS_CALL_UGFXMAIN configuration option to allow uGFXMain() to be automatically called
FEATURE: Added GFX_OS_UGFXMAIN_STACKSIZE configuration option to control uGFXMain() stack size
*** Release 2.7 *** *** Release 2.7 ***

View File

@ -56,6 +56,8 @@
// #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine // #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine
// #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine // #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine
// #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine // #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine
// #define GFX_OS_CALL_UGFXMAIN FALSE
// #define GFX_OS_UGFXMAIN_STACKSIZE 0
// #define GFX_EMULATE_MALLOC FALSE // #define GFX_EMULATE_MALLOC FALSE

View File

@ -19,6 +19,7 @@ static bool_t gfxInitDone = FALSE;
/* These init functions are defined by each module but not published */ /* These init functions are defined by each module but not published */
extern void _gosInit(void); extern void _gosInit(void);
extern void _gosPostInit(void);
extern void _gosDeinit(void); extern void _gosDeinit(void);
#ifdef GFX_OS_PRE_INIT_FUNCTION #ifdef GFX_OS_PRE_INIT_FUNCTION
extern void GFX_OS_PRE_INIT_FUNCTION(void); extern void GFX_OS_PRE_INIT_FUNCTION(void);
@ -77,6 +78,9 @@ extern void _gosDeinit(void);
extern void _gtransInit(void); extern void _gtransInit(void);
extern void _gtransDeinit(void); extern void _gtransDeinit(void);
#endif #endif
#if GFX_OS_CALL_UGFXMAIN
extern threadreturn_t uGFXMain(void *param);
#endif
void gfxInit(void) void gfxInit(void)
{ {
@ -130,6 +134,10 @@ void gfxInit(void)
#if GFX_USE_GWIN #if GFX_USE_GWIN
_gwinInit(); _gwinInit();
#endif #endif
_gosPostInit();
#if GFX_OS_CALL_UGFXMAIN
uGFXMain(0);
#endif
} }
void gfxDeinit(void) void gfxDeinit(void)

View File

@ -35,6 +35,10 @@ void _gosInit(void)
_gosThreadsInit(); _gosThreadsInit();
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
/* ToDo */ /* ToDo */

View File

@ -53,6 +53,10 @@ void _gosInit(void)
#endif #endif
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
/* ToDo */ /* ToDo */

View File

@ -26,6 +26,10 @@ void _gosInit(void)
_gosHeapInit(); _gosHeapInit();
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
} }

View File

@ -19,6 +19,10 @@ void _gosInit(void)
#endif #endif
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
/* ToDo */ /* ToDo */

View File

@ -22,18 +22,41 @@
#error "GOS: configUSE_COUNTING_SEMAPHORES must be defined in FreeRTOSConfig.h" #error "GOS: configUSE_COUNTING_SEMAPHORES must be defined in FreeRTOSConfig.h"
#endif #endif
#if !GFX_OS_NO_INIT && INCLUDE_xTaskGetSchedulerState != 1 && configUSE_TIMERS != 1
#error "GOS: Either INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be defined in FreeRTOSConfig.h"
#endif
#if !GFX_OS_NO_INIT && !GFX_OS_CALL_UGFXMAIN
#error "GOS: Either GFX_OS_NO_INIT or GFX_OS_CALL_UGFXMAIN must be defined for FreeRTOS"
#endif
void _gosInit(void) void _gosInit(void)
{ {
#if !GFX_OS_NO_INIT #if GFX_OS_NO_INIT && !GFX_OS_INIT_NO_WARNING
#error "GOS: Operating System initialization for FreeRTOS is not yet implemented in uGFX. Please set GFX_OS_NO_INIT to TRUE in your gfxconf.h" #warning "GOS: Operating System initialization has been turned off. Make sure you call vTaskStartScheduler()."
#endif #endif
#if !GFX_OS_INIT_NO_WARNING }
#warning "GOS: Operating System initialization has been turned off. Make sure you call vTaskStartScheduler() before gfxInit() in your application!"
#if !GFX_OS_NO_INIT && GFX_OS_CALL_UGFXMAIN
extern threadreturn_t uGFXMain(void *param);
#endif
void _gosPostInit(void)
{
#if !GFX_OS_NO_INIT && GFX_OS_CALL_UGFXMAIN
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) {
gfxThreadCreate(0, GFX_OS_UGFXMAIN_STACKSIZE, NORMAL_PRIORITY, uGFXMain, 0);
vTaskStartScheduler();
gfxHalt("Unable to start FreeRTOS scheduler. Out of memory?");
}
#endif #endif
} }
void _gosDeinit(void) void _gosDeinit(void)
{ {
#if !GFX_OS_NO_INIT
vTaskDelete(0);
#endif
} }
void* gfxRealloc(void *ptr, size_t oldsz, size_t newsz) void* gfxRealloc(void *ptr, size_t oldsz, size_t newsz)
@ -131,4 +154,11 @@ gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_
return task; return task;
} }
#if INCLUDE_eTaskGetState == 1
threadreturn_t gfxThreadWait(gfxThreadHandle thread) {
while (eTaskGetState(thread) != eDeleted)
gfxYield();
}
#endif
#endif /* GFX_USE_OS_FREERTOS */ #endif /* GFX_USE_OS_FREERTOS */

View File

@ -60,7 +60,7 @@ typedef portBASE_TYPE threadpriority_t;
#define HIGH_PRIORITY configMAX_PRIORITIES-1 #define HIGH_PRIORITY configMAX_PRIORITIES-1
/* FreeRTOS will allocate the stack when creating the thread */ /* FreeRTOS will allocate the stack when creating the thread */
#define DECLARE_THREAD_STACK(name, sz) #define DECLARE_THREAD_STACK(name, sz) uint8_t name[1]
#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param) #define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param)
#define THREAD_RETURN(retval) #define THREAD_RETURN(retval)
@ -103,9 +103,11 @@ void gfxSemSignal(gfxSem* psem);
void gfxSemSignalI(gfxSem* psem); void gfxSemSignalI(gfxSem* psem);
gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
#define gfxThreadWait(thread) {} // never used, not imlpemented #define gfxThreadMe() xTaskGetCurrentTaskHandle()
#define gfxThreadMe() {} // never used, not implemented #if INCLUDE_eTaskGetState == 1
#define gfxThreadClose(thread) {} threadreturn_t gfxThreadWait(gfxThreadHandle thread);
#endif
#define gfxThreadClose(thread)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -33,6 +33,10 @@ void _gosInit(void)
gfxMutexInit(&SystemMutex); gfxMutexInit(&SystemMutex);
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
/* ToDo */ /* ToDo */

View File

@ -25,6 +25,10 @@ void _gosInit(void)
_gosThreadsInit(); _gosThreadsInit();
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
} }

View File

@ -180,6 +180,32 @@
#ifndef GFX_OS_INIT_NO_WARNING #ifndef GFX_OS_INIT_NO_WARNING
#define GFX_OS_INIT_NO_WARNING FALSE #define GFX_OS_INIT_NO_WARNING FALSE
#endif #endif
/**
* @brief Call uGFXMain() after all initialisation
* @details Defaults to FALSE
* @note uGFXMain() is a function defined by the user in their project
* that contains the application main code. This is not expected to return
* and thus gfxInit() will also never return. This is required for some
* operating systems whose main thread never returns after starting the
* scheduler.<br>
* Its prototype is:<br>
* threadreturn_t uGFXMain(void *param);<br>
* @note uGFXMain() will always be called with a NULL paramter.
*/
#ifndef GFX_OS_CALL_UGFXMAIN
#define GFX_OS_CALL_UGFXMAIN FALSE
#endif
/**
* @brief When uGFXMain() is started as a thread, what stack size should be used
* @details Defaults to 0
* @note uGFXMain() contains the application main code. Some operating systems
* will start this as a thread. eg FreeRTOS. When it is started as a thread
* this defines how many bytes should be used for the thread stack.
* @note 0 means to use the operating systems default stack size.
*/
#ifndef GFX_OS_UGFXMAIN_STACKSIZE
#define GFX_OS_UGFXMAIN_STACKSIZE 0
#endif
/** /**
* @brief Should uGFX stuff be added to the FreeRTOS+Tracer * @brief Should uGFX stuff be added to the FreeRTOS+Tracer
* @details Defaults to FALSE * @details Defaults to FALSE

View File

@ -30,6 +30,10 @@ void _gosInit(void)
gfxMutexInit(&SystemMutex); gfxMutexInit(&SystemMutex);
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
/* ToDo */ /* ToDo */

View File

@ -53,6 +53,10 @@ void _gosInit(void)
_systickTimer.start(); _systickTimer.start();
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
} }

View File

@ -36,6 +36,10 @@ void _gosInit(void)
_gosThreadsInit(); _gosThreadsInit();
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
/* ToDo */ /* ToDo */

View File

@ -32,6 +32,10 @@ void _gosInit(void)
#endif #endif
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
} }

View File

@ -21,6 +21,10 @@ void _gosInit(void)
/* No initialization of the operating system itself is needed */ /* No initialization of the operating system itself is needed */
} }
void _gosPostInit(void)
{
}
void _gosDeinit(void) void _gosDeinit(void)
{ {
@ -102,7 +106,7 @@ gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_
HANDLE thd; HANDLE thd;
if (!(thd = CreateThread(0, stacksz, fn, param, CREATE_SUSPENDED, 0))) if (!(thd = CreateThread(0, stacksz, fn, param, CREATE_SUSPENDED, 0)))
return FALSE; return 0;
SetThreadPriority(thd, prio); SetThreadPriority(thd, prio);
ResumeThread(thd); ResumeThread(thd);