Victor Posted February 17, 2017 Report Share Posted February 17, 2017 I use C++ wrapper for FreeRTOS. uGFX implements some inner functions ( like gfxSleepMilliseconds, gfxSemInit, gfxYield, etc) wrapping pure C FreeRTOS functions in gos_freertos.h/c files. How I can use my C++ FreeRTOS wrapper with uGFX? Link to comment Share on other sites More sharing options...
Joel Bodenmann Posted February 17, 2017 Report Share Posted February 17, 2017 Hello Victor, If it's a true C++ wrapper then that means that the C interface should still be accessible. Therefore, the current FreeRTOS support should still work perfectly fine for you and you'd probably just encounter a build issue. If the C functions are not accessible then the easiest way would be to create a new GOS port for FreeRTOS C++ (so you'd create gos_freertos_cpp.h/c) and use the FreeRTOS C++ interface in there. Optionally you could keep using the existing gos_freertos.h/c file and just add a macro to the configuration file which is something like GFX_FREERTOS_USE_CPP and in the existing port you'd use #if and #else to add your new FreeRTOS C++ wrapper code along the existing C one. I hope that helps. Link to comment Share on other sites More sharing options...
Victor Posted February 18, 2017 Author Report Share Posted February 18, 2017 Hello Joel, Yes. C interface is accessible, but don't correlate with C++ instance of FreeRTOS. Build without problems but when uGFX using FreeRTOS functions HardFaultHandler occurs as was expected. I tryed to replace original gos_freertos.h/c to my gos_freertos.h/cpp. It seems to me, builder apply C compiler to them. C compeler don't know these keywords like class, etc. I don't know, can I use functions declared as C functions and defined with C++, if I have correctly explained. As the result files, are something like these ( please excuse me for barbarism) : P.S. At the begining I compiled these files isolated with C++ compiler, and had been build well. But when I tryed to replace(and embed) original uGFX files, compiler began to sware to C++ lexis in my FreeRTOS wrapper. (excuse me for my english) my gos_freertos.h /* * 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/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" #include "frtosWrapper.h" /*===========================================================================*/ /* Type definitions */ /*===========================================================================*/ /* Additional types are required when FreeRTOS 7.x is used */ #if !defined(tskKERNEL_VERSION_MAJOR) && !tskKERNEL_VERSION_MAJOR == 8 typedef signed char int8_t typedef unsigned char uint8_t typedef signed int int16_t typedef unsigned int uint16_t typedef signed long int int32_t typedef unsigned long int uint32_t typedef signed long long int int64_t typedef unsigned long long int uint64_t #endif /** * 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) #define THREAD_RETURN(retval) portTickType MS2ST(portTickType ms); //Ok //typedef struct { // xSemaphoreHandle sem; // semcount_t limit; // semcount_t counter; //} gfxSem; typedef struct { tSemaphoreHandle sem; // xSemaphoreHandle sem; semcount_t limit; semcount_t counter; } gfxSem; //typedef xSemaphoreHandle gfxMutex; //typedef xTaskHandle* gfxThreadHandle; typedef tSemaphoreHandle gfxMutex; //typedef xSemaphoreHandle gfxMutex; typedef tTaskHandle* gfxThreadHandle; //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() {} #define gfxHalt(msg) {} #define gfxExit() {} //#define gfxAlloc(sz) oRTOS.Malloc(sz) //pvPortMalloc(sz) //#define gfxFree(ptr) oRTOS.Free(ptr) //vPortFree(ptr) //#define gfxYield() oRTOS.TaskYield() //taskYIELD() //#define gfxSystemTicks() oRTOS.TaskGetTickCount() //xTaskGetTickCount() void* gfxAlloc(size_t size); void gfxFree( void* p ); void gfxYield(void); TickType_t gfxSystemTicks(void); #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 gfxMutexInit(tSemaphoreHandle* s);//Ok void *gfxRealloc(void *ptr, size_t oldsz, size_t newsz); //Ok void gfxSleepMilliseconds(delaytime_t ms); //Ok void gfxSleepMicroseconds(delaytime_t ms); //Ok void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t limit); //Ok void gfxSemDestroy(gfxSem* psem); //Ok bool_t gfxSemWait(gfxSem* psem, delaytime_t ms); //Ok bool_t gfxSemWaitI(gfxSem* psem); //Ok void gfxSemSignal(gfxSem* psem); //Ok void gfxSemSignalI(gfxSem* psem); //Ok #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);//Ok #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_FREERTOS_H */ my gos_freertos.cpp /* * 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 <string.h> #if GFX_USE_OS_FREERTOS extern cRTOS oRTOS; //global instance of 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) { #if !GFX_OS_NO_INIT #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" #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!" #endif } 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); oRTOS.Free(ptr);//vPortFree(ptr); } return np; } //#define gfxAlloc(sz) oRTOS.Malloc(sz) //pvPortMalloc(sz) //#define gfxFree(ptr) oRTOS.Free(ptr) //vPortFree(ptr) //#define gfxYield() oRTOS.TaskYield() //taskYIELD() //#define gfxSystemTicks() oRTOS.TaskGetTickCount() //xTaskGetTickCount() void* gfxAlloc(size_t size) { return oRTOS.Malloc(size); } void gfxFree( void* p ) { oRTOS.Free(p); } void gfxYield(void) { oRTOS.TaskYield(); } TickType_t gfxSystemTicks(void) { return oRTOS.TaskGetTickCount(); } void gfxSleepMilliseconds(delaytime_t ms) { const portTickType ticks = ms / portTICK_PERIOD_MS; oRTOS.taskDelay(ticks); //vTaskDelay(ticks); } void gfxSleepMicroseconds(delaytime_t ms) { const portTickType ticks = (ms / 1000) / portTICK_PERIOD_MS; // delay milli seconds oRTOS.taskDelay(ticks); //vTaskDelay(ticks); // microsecond resolution delay is not supported in FreeRTOS // vUsDelay(ms%1000); } portTickType MS2ST(portTickType ms) { return (ms / portTICK_PERIOD_MS); } void gfxMutexInit(tSemaphoreHandle *s) { //*s = xSemaphoreCreateMutex(); *s = oRTOS.SemaphoreCreateMutex(); #if GFX_FREERTOS_USE_TRACE // vTraceSetMutexName(*s,"uGFXMutex"); // for FreeRTOS+Trace debug #warning "FreeRTO + Trace not wrapped" #endif } void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t limit) { if (val > limit) val = limit; psem->counter = val; psem->limit = limit; psem->sem = oRTOS.CountingSemCreate(limit,val);//psem->sem = xSemaphoreCreateCounting(limit,val); #if GFX_FREERTOS_USE_TRACE // vTraceSetSemaphoreName(psem->sem, "uGFXSema"); // for FreeRTOS+Trace debug #warning "FreeRTO + Trace not wrapped" #endif } void gfxSemDestroy(gfxSem* psem) { oRTOS.SemaphoreDelete(psem->sem);//vSemaphoreDelete(psem->sem); } bool_t gfxSemWait(gfxSem* psem, delaytime_t ms) { psem->counter--; if (oRTOS.SemTake(psem->sem, MS2ST(ms)) == pdPASS) //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 (oRTOS.SemTakeFromISR(psem->sem,&xHigherPriorityTaskWoken) == pdTRUE)//if (xSemaphoreTakeFromISR(psem->sem,&xHigherPriorityTaskWoken) == pdTRUE) return TRUE; psem->counter++; return FALSE; } void gfxSemSignal(gfxSem* psem) { oRTOS.EnterCritical();//taskENTER_CRITICAL(); if (psem->counter < psem->limit) { psem->counter++; oRTOS.SemGive(psem->sem);//xSemaphoreGive(psem->sem); } oRTOS.BranchToSheduler();//taskYIELD(); oRTOS.ExitCritical();//taskEXIT_CRITICAL(); } void gfxSemSignalI(gfxSem* psem) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; if (psem->counter < psem->limit) { psem->counter++; oRTOS.SemGiveFromISR(psem->sem,&xHigherPriorityTaskWoken);//xSemaphoreGiveFromISR(psem->sem,&xHigherPriorityTaskWoken); } } gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) { // xTaskHandle task = NULL; tTaskHandle* 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) { if (oRTOS.TaskCreate(fn, "uGFX_TASK", stacksz, param, prio, task )!= pdPASS) { for (;;); } return task; } #endif /* GFX_USE_OS_FREERTOS */ Link to comment Share on other sites More sharing options...
Joel Bodenmann Posted February 18, 2017 Report Share Posted February 18, 2017 Hello Victor, Mixing C++ and C code is not always as trivial as it looks. There are always some nasty things to keep in mind like not including C headers after C++ headers and similar things. Inclusion order matters here. You indeed have to create a C++ file for your FreeRTOS port. In that, you can declare your C functions (the ones required by GOS) and the linker will be able to link them properly. There are other things you have to keep in mind like encapsulating your function prototypes in the extern "C" blocks: #ifdef __cplusplus extern "C" { #endif ... #ifdef __cplusplus } #endif I can't have a closer look at your files right now (and I can't try it) but I've attached a GOS port that I wrote some time ago that allows using µGFX inside of a Qt application. The Qt stuff is all C++ as well just like your FreeRTOS C++ wrapper. Have a look at those files. Maybe that helps: gos_qt.h gos_qt.cpp Note that I wrote a simple wrapper class around the QThread class because the QThread class doesn't offer certain things that are required. I assume that the FreeRTOS C++ wrapper won't require that workaround. Please don't hesitate to ask if you have any other questions. We're happy to help where ever we can. Just currently on the road so not much I can do right now. Link to comment Share on other sites More sharing options...
inmarket Posted February 19, 2017 Report Share Posted February 19, 2017 If the c freerros functions are available then it should all just work when you use the c++ wrapper for other freertos calls. The hardfault that you got is likely related to something else. Debug that first before going to the trouble of writing a probably unneeded cpp freertos gos port. Link to comment Share on other sites More sharing options...
Joel Bodenmann Posted February 19, 2017 Report Share Posted February 19, 2017 Yes indeed. Otherwise it's just not a wrapper. A C++ wrapper wouldn't do anything other than calling the equivalent C functions. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now