diff --git a/lib/api/GwApi.h b/lib/api/GwApi.h index 8d852a0..4b3f095 100644 --- a/lib/api/GwApi.h +++ b/lib/api/GwApi.h @@ -4,6 +4,7 @@ #include "N2kMessages.h" #include "NMEA0183Messages.h" #include "GWConfig.h" +#include "GwBoatData.h" //API to be used for additional tasks class GwApi{ public: @@ -13,5 +14,6 @@ class GwApi{ virtual int getSourceId()=0; virtual GwConfigHandler *getConfig()=0; virtual GwLog *getLogger()=0; + virtual GwBoatData *getBoatData()=0; }; #endif \ No newline at end of file diff --git a/lib/exampletask/GwExampleTask.cpp b/lib/exampletask/GwExampleTask.cpp new file mode 100644 index 0000000..7c67fd2 --- /dev/null +++ b/lib/exampletask/GwExampleTask.cpp @@ -0,0 +1,82 @@ + +#include "GwApi.h" + +#define INVALID_COORD -99999 +class GetBoatDataRequest: public GwMessage{ + private: + GwApi *api; + public: + double latitude; + double longitude; + GetBoatDataRequest(GwApi *api):GwMessage(F("boat data")){ + this->api=api; + } + virtual ~GetBoatDataRequest(){} + protected: + /** + * this methos will be executed within the main thread + * be sure not to make any time consuming or blocking operation + */ + virtual void processImpl(){ + //api->getLogger()->logDebug(GwLog::DEBUG,"boatData request from example task"); + /*access the values from boatData (see GwBoatData.h) + by using getDataWithDefault it will return the given default value + if there is no valid data available + so be sure to use a value that never will be a valid one + alternatively you can check using the isValid() method at each boatData item + */ + latitude=api->getBoatData()->Latitude->getDataWithDefault(INVALID_COORD); + longitude=api->getBoatData()->Longitude->getDataWithDefault(INVALID_COORD); + }; +}; +void exampleTask(void *param){ + GwApi *api=(GwApi*)param; + GwLog *logger=api->getLogger(); + //------ + //initialization goes here + //------ + bool hasPosition=false; + while(true){ + delay(1000); + /* + * getting values from the internal data store (boatData) requires some special handling + * our tasks runs (potentially) at some time on a different core then the main code + * and as the boatData has no synchronization (for performance reasons) + * we must ensure to access it only from the main thread. + * The pattern is to create a request object (a class that inherits from GwMessage - + * GetBoatDataRequest above) + * and to access the boatData in the processImpl method of this object. + * Once the object is created we enqueue it into a request queue and wait for + * the main thread to call the processImpl method (sendAndWait). + * Afterwards we can use the data we have stored in the request. + * As this request object can be accessed from different threads we must be careful + * about it's lifetime. + * The pattern below handles this correctly. We do not call delete on this object but + * instead call the "unref" Method when we don't need it any more. + */ + GetBoatDataRequest *r=new GetBoatDataRequest(api); + if (api->getQueue()->sendAndWait(r,10000) != GwRequestQueue::MSG_OK){ + r->unref(); //delete the request + api->getLogger()->logDebug(GwLog::ERROR,"request not handled"); + continue; + } + if (r->latitude == INVALID_COORD || r->longitude == INVALID_COORD){ + if (hasPosition){ + logger->logDebug(GwLog::ERROR,"position lost..."); + hasPosition=false; + } + } + else{ + //do something with the data we have from boatData + if (! hasPosition){ + logger->logDebug(GwLog::LOG,"postion now available lat=%f, lon=%f", + r->latitude,r->longitude); + hasPosition=true; + } + + } + r->unref(); //delete the request + } + vTaskDelete(NULL); + +} \ No newline at end of file diff --git a/lib/exampletask/GwExampleTask.h b/lib/exampletask/GwExampleTask.h new file mode 100644 index 0000000..64aff8d --- /dev/null +++ b/lib/exampletask/GwExampleTask.h @@ -0,0 +1,5 @@ +#ifndef _GWEXAMPLETASK_H +#define _GWEXAMPLETASK_H +//task function +void exampleTask(void *param); +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index dc73a54..b276719 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,6 +61,7 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting #include "GwLeds.h" #include "GwCounter.h" #include "GwXDRMappings.h" +#include "GwExampleTask.h" //NMEA message channels @@ -235,6 +236,9 @@ public: virtual GwLog* getLogger(){ return &logger; } + virtual GwBoatData *getBoatData(){ + return &boatData; + } }; bool delayedRestart(){ @@ -660,6 +664,7 @@ void setup() { startAddOnTask(handleButtons,100); setLedMode(LED_GREEN); startAddOnTask(handleLeds,101); + startAddOnTask(exampleTask,102); logger.logDebug(GwLog::LOG,"setup done"); } //*****************************************************************************