diff --git a/docs/releases.txt b/docs/releases.txt index e5be2311..b08f970e 100644 --- a/docs/releases.txt +++ b/docs/releases.txt @@ -13,6 +13,7 @@ FEATURE: Added gwinGetColor() and gwinGetBgColor() FEATURE: Console now has an optional backing store buffer (GWIN_CONSOLE_USE_HISTORY) FEATURE: Added smooth scrolling to list widget FEATURE: Increased performance of gwinListAddItem() +FEATURE: Added FreeRTOS port FEATURE: Added gfxDeinit() FEATURE: Allow touch screen calibration in any display orientation FEATURE: New GFILE module to abstract File IO. diff --git a/gfxconf.example.h b/gfxconf.example.h index 113b05d5..6b545307 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -18,11 +18,16 @@ #ifndef _GFXCONF_H #define _GFXCONF_H -/* The operating system to use. One of these must be defined - preferably in your Makefile */ -//#define GFX_USE_OS_CHIBIOS TRUE -//#define GFX_USE_OS_WIN32 TRUE -//#define GFX_USE_OS_LINUX TRUE -//#define GFX_USE_OS_OSX TRUE + +/////////////////////////////////////////////////////////////////////////// +// GOS - One of these must be defined, preferably in your Makefile // +/////////////////////////////////////////////////////////////////////////// +//#define GFX_USE_OS_CHIBIOS FALSE +//#define GFX_USE_OS_FREERTOS FALSE + #define GFX_FREERTOS_USE_TRACE FALSE +//#define GFX_USE_OS_WIN32 FALSE +//#define GFX_USE_OS_LINUX FALSE +//#define GFX_USE_OS_OSX FALSE /////////////////////////////////////////////////////////////////////////// diff --git a/src/gos/freertos.c b/src/gos/freertos.c new file mode 100644 index 00000000..f2c03eec --- /dev/null +++ b/src/gos/freertos.c @@ -0,0 +1,166 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "gfx.h" +#include + +#if GFX_USE_OS_FREERTOS + +#if INCLUDE_vTaskDelay != 1 + #error "GOS: INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h" +#endif + +#if configUSE_MUTEXES != 1 + #error "GOS: configUSE_MUTEXES must be defined in FreeRTOSConfig.h" +#endif + +#if configUSE_COUNTING_SEMAPHORES != 1 + #error "GOS: configUSE_COUNTING_SEMAPHORES must be defined in FreeRTOSConfig.h" +#endif + +void _gosInit(void) +{ + // The user must call vTaskStartScheduler() himself before he calls gfxInit(). +} + +void _gosDeinit(void) +{ +} + +void* gfxRealloc(void *ptr, size_t oldsz, size_t newsz) +{ + void *np; + + if (newsz <= oldsz) + return ptr; + + np = gfxAlloc(newsz); + if (!np) + return 0; + + if (oldsz) { + memcpy(np, ptr, oldsz); + vPortFree(ptr); + } + + return np; +} + +void gfxSleepMilliseconds(delaytime_t ms) +{ + const portTickType ticks = ms / portTICK_PERIOD_MS; + vTaskDelay(ticks); +} + +void gfxSleepMicroseconds(delaytime_t ms) +{ + const portTickType ticks = (ms / 1000) / portTICK_PERIOD_MS; + + // delay milli seconds + vTaskDelay(ticks); + + // microsecond resolution delay is not supported in FreeRTOS + // vUsDelay(ms%1000); +} + +portTickType MS2ST(portTickType ms) +{ + return (ms / portTICK_PERIOD_MS); +} + +void gfxMutexInit(xSemaphoreHandle *s) +{ + *s = xSemaphoreCreateMutex(); + #if GFX_FREERTOS_USE_TRACE + vTraceSetMutexName(*s,"uGFXMutex"); // for FreeRTOS+Trace debug + #endif +} + +void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t limit) +{ + if (val > limit) + val = limit; + + psem->counter = val; + psem->limit = limit; + psem->sem = xSemaphoreCreateCounting(limit,val); + + #if GFX_FREERTOS_USE_TRACE + vTraceSetSemaphoreName(psem->sem, "uGFXSema"); // for FreeRTOS+Trace debug + #endif +} + +void gfxSemDestroy(gfxSem* psem) +{ + vSemaphoreDelete(psem->sem); +} + +bool_t gfxSemWait(gfxSem* psem, delaytime_t ms) +{ + psem->counter--; + + if (xSemaphoreTake(psem->sem, MS2ST(ms)) == pdPASS) + return TRUE; + + psem->counter++; + + return FALSE; +} + +bool_t gfxSemWaitI(gfxSem* psem) +{ + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + psem->counter--; + + if (xSemaphoreTakeFromISR(psem->sem,&xHigherPriorityTaskWoken) == pdTRUE) + return TRUE; + + psem->counter++; + + return FALSE; +} + +void gfxSemSignal(gfxSem* psem) +{ + taskENTER_CRITICAL(); + + if (psem->counter < psem->limit) { + psem->counter++; + xSemaphoreGive(psem->sem); + } + + taskYIELD(); + taskEXIT_CRITICAL(); +} + +void gfxSemSignalI(gfxSem* psem) +{ + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + if (psem->counter < psem->limit) { + psem->counter++; + xSemaphoreGiveFromISR(psem->sem,&xHigherPriorityTaskWoken); + } +} + +gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) +{ + xTaskHandle task = NULL; + stacksz = (size_t)stackarea; + + if (stacksz < configMINIMAL_STACK_SIZE) + stacksz = configMINIMAL_STACK_SIZE; + + if (xTaskCreate(fn, "uGFX_TASK", stacksz, param, prio, &task )!= pdPASS) { + for (;;); + } + + return task; +} + +#endif /* GFX_USE_OS_FREERTOS */ diff --git a/src/gos/freertos.h b/src/gos/freertos.h new file mode 100644 index 00000000..ccda4cbd --- /dev/null +++ b/src/gos/freertos.h @@ -0,0 +1,110 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gos/freertos.h + * @brief GOS - Operating System Support header file for FreeRTOS. + */ + +#ifndef _GOS_FREERTOS_H +#define _GOS_FREERTOS_H + +#if GFX_USE_OS_FREERTOS + +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "semphr.h" +#include "task.h" + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +/** + * bool_t, + * int8_t, uint8_t, + * int16_t, uint16_t, + * int32_t, uint32_t, + * size_t + * TRUE, FALSE + * are already defined by FreeRTOS + */ +#define TIME_IMMEDIATE 0 +#define TIME_INFINITE ((delaytime_t)-1) +typedef int8_t bool_t; +typedef uint32_t delaytime_t; +typedef portTickType systemticks_t; +typedef int32_t semcount_t; +typedef void threadreturn_t; +typedef portBASE_TYPE threadpriority_t; + +#define MAX_SEMAPHORE_COUNT ((semcount_t)(((unsigned long)((semcount_t)(-1))) >> 1)) +#define LOW_PRIORITY 0 +#define NORMAL_PRIORITY configMAX_PRIORITIES/2 +#define HIGH_PRIORITY configMAX_PRIORITIES-1 + +/* FreeRTOS will allocate the stack when creating the thread, so pass the size instead of a working area */ +#define DECLARE_THREAD_STACK(name, sz) size_t *name = (size_t *)sz +#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(void *param) +portTickType MS2ST(portTickType ms); + +typedef struct { + xSemaphoreHandle sem; + semcount_t limit; + semcount_t counter; +} gfxSem; + +typedef xSemaphoreHandle gfxMutex; +typedef xTaskHandle* gfxThreadHandle; + +/*===========================================================================*/ +/* Function declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#define gfxHalt(msg) {} +#define gfxExit() {} +#define gfxAlloc(sz) pvPortMalloc(sz) +#define gfxFree(ptr) vPortFree(ptr) +#define gfxYield() taskYIELD() +#define gfxSystemTicks() xTaskGetTickCount() +#define gfxMillisecondsToTicks(ms) MS2ST(ms) +#define gfxSystemLock() {} +#define gfxSystemUnlock() {} + +void gfxMutexInit(xSemaphoreHandle* s); +#define gfxMutexDestroy(pmutex) vSemaphoreDelete(*pmutex) +#define gfxMutexEnter(pmutex) xSemaphoreTake(*pmutex,portMAX_DELAY) +#define gfxMutexExit(pmutex) xSemaphoreGive(*pmutex) + +void *gfxRealloc(void *ptr, size_t oldsz, size_t newsz); +void gfxSleepMilliseconds(delaytime_t ms); +void gfxSleepMicroseconds(delaytime_t ms); + +void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t limit); +void gfxSemDestroy(gfxSem* psem); +bool_t gfxSemWait(gfxSem* psem, delaytime_t ms); +bool_t gfxSemWaitI(gfxSem* psem); +void gfxSemSignal(gfxSem* psem); +void gfxSemSignalI(gfxSem* psem); +#define gfxSemCounterI(psem) ((psem)->counter) +#define gfxSemCounter(psem) ((psem)->counter) +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() {} // never used, not implemented +#define gfxThreadClose(thread) {} + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_OS_FREERTOS */ +#endif /* _GOS_CHIBIOS_H */ diff --git a/src/gos/sys_defs.h b/src/gos/sys_defs.h index 0fd162dc..aba96df5 100644 --- a/src/gos/sys_defs.h +++ b/src/gos/sys_defs.h @@ -441,6 +441,8 @@ */ #elif GFX_USE_OS_CHIBIOS #include "src/gos/chibios.h" +#elif GFX_USE_OS_FREERTOS + #include "src/gos/freertos.h" #elif GFX_USE_OS_WIN32 #include "src/gos/win32.h" #elif GFX_USE_OS_LINUX diff --git a/src/gos/sys_make.mk b/src/gos/sys_make.mk index 9db29fe2..8ef22121 100644 --- a/src/gos/sys_make.mk +++ b/src/gos/sys_make.mk @@ -1,4 +1,5 @@ GFXSRC += $(GFXLIB)/src/gos/chibios.c \ + $(GFXLIB)/src/gos/freertos.c \ $(GFXLIB)/src/gos/win32.c \ $(GFXLIB)/src/gos/linux.c \ $(GFXLIB)/src/gos/osx.c \ diff --git a/src/gos/sys_options.h b/src/gos/sys_options.h index ae9916ad..cfbed057 100644 --- a/src/gos/sys_options.h +++ b/src/gos/sys_options.h @@ -27,6 +27,13 @@ #ifndef GFX_USE_OS_CHIBIOS #define GFX_USE_OS_CHIBIOS FALSE #endif + /** + * @brief Use FreeRTOS + * @details Defaults to FALSE + */ + #ifndef GFX_USE_OS_FREERTOS + #define GFX_USE_OS_FREERTOS FALSE + #endif /** * @brief Use Win32 * @details Defaults to FALSE @@ -35,7 +42,7 @@ #define GFX_USE_OS_WIN32 FALSE #endif /** - * @brief Use a linux based system running X11 + * @brief Use a linux based system running X11 * @details Defaults to FALSE */ #ifndef GFX_USE_OS_LINUX @@ -58,9 +65,16 @@ /** * @} * - * @name GOS Optional Sizing Parameters + * @name GOS Optional Parameters * @{ */ + /** + * @brief Should uGFX stuff be added to the FreeRTOS+Tracer + * @details Defaults to FALSE + */ + #ifndef GFX_FREERTOS_USE_TRACE + #define GFX_FREERTOS_USE_TRACE FALSE + #endif /** @} */ #endif /* _GOS_OPTIONS_H */ diff --git a/src/gos/sys_rules.h b/src/gos/sys_rules.h index 390e8116..f23d330b 100644 --- a/src/gos/sys_rules.h +++ b/src/gos/sys_rules.h @@ -16,16 +16,21 @@ #ifndef _GOS_RULES_H #define _GOS_RULES_H -#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 +#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS #if GFX_DISPLAY_RULE_WARNINGS #warning "GOS: No Operating System has been defined. ChibiOS (GFX_USE_OS_CHIBIOS) has been turned on for you." #endif #undef GFX_USE_OS_CHIBIOS #define GFX_USE_OS_CHIBIOS TRUE #endif -#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 != 1 * TRUE + +#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS != 1 * TRUE #error "GOS: More than one operation system has been defined as TRUE." #endif +#if GFX_FREERTOS_USE_TRACE && !GFX_USE_OS_FREERTOS + #error "GOS: GFX_FREERTOS_USE_TRACE is only available for the FreeRTOS port." +#endif + #endif /* _GOS_RULES_H */ /** @} */