mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-13 05:53:06 +01:00
#12: multiple capabilities in user task, user init function, cleanup message handling in main, clearer api
This commit is contained in:
@@ -9,16 +9,20 @@
|
||||
class GwApi{
|
||||
public:
|
||||
virtual GwRequestQueue *getQueue()=0;
|
||||
virtual void sendN2kMessage(const tN2kMsg &msg)=0;
|
||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId)=0;
|
||||
virtual void sendN2kMessage(const tN2kMsg &msg, bool convert=true)=0;
|
||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId,bool convert=true)=0;
|
||||
virtual int getSourceId()=0;
|
||||
virtual GwConfigHandler *getConfig()=0;
|
||||
virtual GwLog *getLogger()=0;
|
||||
virtual GwBoatData *getBoatData()=0;
|
||||
virtual ~GwApi(){}
|
||||
};
|
||||
#ifndef DECLARE_USERTASK
|
||||
#define DECLARE_USERTASK(task)
|
||||
#endif
|
||||
#ifndef DECLARE_INITFUNCTION
|
||||
#define DECLARE_INITFUNCTION(task)
|
||||
#endif
|
||||
#ifndef DECLARE_CAPABILITY
|
||||
#define DECLARE_CAPABILITY(name,value)
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
#include "GwExampleTask.h"
|
||||
#include "GwApi.h"
|
||||
|
||||
/**
|
||||
* an init function that ist being called before other initializations from the core
|
||||
*/
|
||||
void exampleInit(GwApi *api){
|
||||
api->getLogger()->logDebug(GwLog::LOG,"example init running");
|
||||
}
|
||||
#define INVALID_COORD -99999
|
||||
class GetBoatDataRequest: public GwMessage{
|
||||
private:
|
||||
@@ -32,8 +38,7 @@ class GetBoatDataRequest: public GwMessage{
|
||||
longitude=api->getBoatData()->Longitude->getDataWithDefault(INVALID_COORD);
|
||||
};
|
||||
};
|
||||
void exampleTask(void *param){
|
||||
GwApi *api=(GwApi*)param;
|
||||
void exampleTask(GwApi *api){
|
||||
GwLog *logger=api->getLogger();
|
||||
//get some configuration data
|
||||
bool exampleSwitch=api->getConfig()->getConfigItem(
|
||||
|
||||
@@ -23,11 +23,19 @@
|
||||
//brightness 0...255
|
||||
#define GWLED_BRIGHTNESS 64
|
||||
|
||||
void exampleTask(void *param);
|
||||
void exampleTask(GwApi *param);
|
||||
void exampleInit(GwApi *param);
|
||||
//make the task known to the core
|
||||
//the task function should not return (unless you delete the task - see example code)
|
||||
DECLARE_USERTASK(exampleTask);
|
||||
//let the core call an init function before the
|
||||
//N2K Stuff and the communication is set up
|
||||
//normally you should not need this at all
|
||||
//this function must return when done - otherwise the core will not start up
|
||||
DECLARE_INITFUNCTION(exampleInit);
|
||||
//we declare a capability that we can
|
||||
//use in config.json to only show some
|
||||
//elements when this capability is set correctly
|
||||
DECLARE_CAPABILITY(testboard,true);
|
||||
DECLARE_CAPABILITY(testboard2,true);
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"name": "exampleConfig",
|
||||
"label": "logging on",
|
||||
"label": "monitor position",
|
||||
"type": "boolean",
|
||||
"default": "false",
|
||||
"description": "switch on logging of position acquired/failed",
|
||||
|
||||
@@ -17,10 +17,7 @@ NMEA0183DataToN2K::NMEA0183DataToN2K(GwLog *logger, GwBoatData *boatData,N2kSend
|
||||
LOG_DEBUG(GwLog::LOG,"NMEA0183DataToN2K created %p",this);
|
||||
}
|
||||
|
||||
bool NMEA0183DataToN2K::parseAndSend(const char *buffer, int sourceId) {
|
||||
LOG_DEBUG(GwLog::DEBUG,"NMEA0183DataToN2K[%d] parsing %s",sourceId,buffer)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
class SNMEA0183Msg : public tNMEA0183Msg{
|
||||
public:
|
||||
@@ -821,6 +818,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual bool parseAndSend(const char *buffer, int sourceId)
|
||||
{
|
||||
LOG_DEBUG(GwLog::DEBUG + 1, "NMEA0183DataToN2K[%d] parsing %s", sourceId, buffer)
|
||||
@@ -843,7 +841,6 @@ public:
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
virtual unsigned long *handledPgns()
|
||||
{
|
||||
return converters.handledPgns();
|
||||
|
||||
@@ -13,7 +13,7 @@ class NMEA0183DataToN2K{
|
||||
N2kSender sender;
|
||||
public:
|
||||
NMEA0183DataToN2K(GwLog *logger,GwBoatData *boatData,N2kSender callback);
|
||||
virtual bool parseAndSend(const char *buffer, int sourceId);
|
||||
virtual bool parseAndSend(const char *buffer, int sourceId)=0;
|
||||
virtual unsigned long *handledPgns()=0;
|
||||
virtual int numConverters()=0;
|
||||
virtual String handledKeys()=0;
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
#include "GwUserCode.h"
|
||||
#include "GwSynchronized.h"
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
//user task handling
|
||||
class UserTask{
|
||||
|
||||
|
||||
|
||||
std::vector<GwUserTask> userTasks;
|
||||
std::vector<GwUserTask> initTasks;
|
||||
GwUserCode::Capabilities userCapabilities;
|
||||
|
||||
|
||||
|
||||
class GwUserTaskDef{
|
||||
public:
|
||||
String name;
|
||||
TaskFunction_t task;
|
||||
UserTask(String name,TaskFunction_t task){
|
||||
this->name=name;
|
||||
this->task=task;
|
||||
GwUserTaskDef(TaskFunction_t task,String name){
|
||||
userTasks.push_back(GwUserTask(name,task));
|
||||
}
|
||||
GwUserTaskDef(GwUserTaskFunction task,String name){
|
||||
userTasks.push_back(GwUserTask(name,task));
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<UserTask> userTasks;
|
||||
GwUserCode::Capabilities userCapabilities;
|
||||
|
||||
void registerUserTask(TaskFunction_t task,String name){
|
||||
userTasks.push_back(UserTask(name,task));
|
||||
}
|
||||
|
||||
class GwUserTask{
|
||||
class GwInitTask{
|
||||
public:
|
||||
GwUserTask(TaskFunction_t task,String name){
|
||||
registerUserTask(task,name);
|
||||
GwInitTask(TaskFunction_t task, String name){
|
||||
initTasks.push_back(GwUserTask(name,task));
|
||||
}
|
||||
GwInitTask(GwUserTaskFunction task, String name){
|
||||
initTasks.push_back(GwUserTask(name,task));
|
||||
}
|
||||
};
|
||||
class GwUserCapability{
|
||||
@@ -32,32 +38,37 @@ class GwUserCapability{
|
||||
userCapabilities[name]=value;
|
||||
}
|
||||
};
|
||||
#define DECLARE_USERTASK(task) GwUserTask __##task##__(task,#task);
|
||||
#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name__(#name,#value);
|
||||
#include "GwUserTasks.h"
|
||||
#define DECLARE_USERTASK(task) GwUserTaskDef __##task##__(task,#task);
|
||||
#define DECLARE_INITFUNCTION(task) GwInitTask __Init##task##__(task,#task);
|
||||
#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name##__(#name,#value);
|
||||
#include "GwApi.h"
|
||||
#include "GwUserTasks.h"
|
||||
class TaskApi : public GwApi
|
||||
{
|
||||
GwApi *api;
|
||||
int sourceId;
|
||||
SemaphoreHandle_t *mainLock;
|
||||
|
||||
public:
|
||||
TaskApi(GwApi *api, int sourceId)
|
||||
TaskApi(GwApi *api, int sourceId, SemaphoreHandle_t *mainLock)
|
||||
{
|
||||
this->sourceId = sourceId;
|
||||
this->api = api;
|
||||
this->mainLock=mainLock;
|
||||
}
|
||||
virtual GwRequestQueue *getQueue()
|
||||
{
|
||||
return api->getQueue();
|
||||
}
|
||||
virtual void sendN2kMessage(const tN2kMsg &msg)
|
||||
virtual void sendN2kMessage(const tN2kMsg &msg,bool convert)
|
||||
{
|
||||
api->sendN2kMessage(msg);
|
||||
GWSYNCHRONIZED(mainLock);
|
||||
api->sendN2kMessage(msg,convert);
|
||||
}
|
||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId)
|
||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId, bool convert)
|
||||
{
|
||||
api->sendNMEA0183Message(msg, sourceId);
|
||||
GWSYNCHRONIZED(mainLock);
|
||||
api->sendNMEA0183Message(msg, this->sourceId,convert);
|
||||
}
|
||||
virtual int getSourceId()
|
||||
{
|
||||
@@ -75,27 +86,50 @@ public:
|
||||
{
|
||||
return api->getBoatData();
|
||||
}
|
||||
virtual ~TaskApi(){};
|
||||
};
|
||||
|
||||
GwUserCode::GwUserCode(GwApi *api){
|
||||
GwUserCode::GwUserCode(GwApi *api,SemaphoreHandle_t *mainLock){
|
||||
this->logger=api->getLogger();
|
||||
this->api=api;
|
||||
this->mainLock=mainLock;
|
||||
}
|
||||
static void startAddOnTask(GwApi *api,TaskFunction_t task,int sourceId){
|
||||
TaskApi* taskApi=new TaskApi(api,sourceId);
|
||||
xTaskCreate(task,"user",2000,taskApi,3,NULL);
|
||||
void userTaskStart(void *p){
|
||||
GwUserTask *task=(GwUserTask*)p;
|
||||
if (task->isUserTask){
|
||||
task->usertask(task->api);
|
||||
}
|
||||
else{
|
||||
task->task(task->api);
|
||||
}
|
||||
delete task->api;
|
||||
task->api=NULL;
|
||||
}
|
||||
void GwUserCode::startAddOnTask(GwApi *api,GwUserTask *task,int sourceId,String name){
|
||||
task->api=new TaskApi(api,sourceId,mainLock);
|
||||
xTaskCreate(userTaskStart,name.c_str(),2000,task,3,NULL);
|
||||
}
|
||||
void GwUserCode::startUserTasks(int baseId){
|
||||
LOG_DEBUG(GwLog::DEBUG,"starting %d user tasks",userTasks.size());
|
||||
for (auto it=userTasks.begin();it != userTasks.end();it++){
|
||||
LOG_DEBUG(GwLog::LOG,"starting user task %s with id %d",it->name.c_str(),baseId);
|
||||
startAddOnTask(api,it->task,baseId);
|
||||
startAddOnTask(api,&(*it),baseId,it->name);
|
||||
baseId++;
|
||||
}
|
||||
}
|
||||
void GwUserCode::startInitTasks(int baseId){
|
||||
LOG_DEBUG(GwLog::DEBUG,"starting %d user init tasks",initTasks.size());
|
||||
for (auto it=initTasks.begin();it != initTasks.end();it++){
|
||||
LOG_DEBUG(GwLog::LOG,"starting user init task %s with id %d",it->name.c_str(),baseId);
|
||||
it->api=new TaskApi(api,baseId,mainLock);
|
||||
userTaskStart(&(*it));
|
||||
baseId++;
|
||||
}
|
||||
}
|
||||
void GwUserCode::startAddonTask(String name, TaskFunction_t task, int id){
|
||||
LOG_DEBUG(GwLog::LOG,"starting addon task %s with id %d",name.c_str(),id);
|
||||
startAddOnTask(api,task,id);
|
||||
GwUserTask *userTask=new GwUserTask(name,task); //memory leak - acceptable as only during startup
|
||||
startAddOnTask(api,userTask,id,userTask->name);
|
||||
}
|
||||
|
||||
GwUserCode::Capabilities * GwUserCode::getCapabilities(){
|
||||
|
||||
@@ -4,13 +4,34 @@
|
||||
#include <map>
|
||||
class GwLog;
|
||||
class GwApi;
|
||||
typedef void (*GwUserTaskFunction)(GwApi *);
|
||||
class GwUserTask{
|
||||
public:
|
||||
String name;
|
||||
TaskFunction_t task=NULL;
|
||||
GwUserTaskFunction usertask=NULL;
|
||||
bool isUserTask=false;
|
||||
GwApi *api=NULL;
|
||||
GwUserTask(String name,TaskFunction_t task){
|
||||
this->name=name;
|
||||
this->task=task;
|
||||
}
|
||||
GwUserTask(String name, GwUserTaskFunction task){
|
||||
this->name=name;
|
||||
this->usertask=task;
|
||||
this->isUserTask=true;
|
||||
}
|
||||
};
|
||||
class GwUserCode{
|
||||
GwLog *logger;
|
||||
GwApi *api;
|
||||
SemaphoreHandle_t *mainLock;
|
||||
void startAddOnTask(GwApi *api,GwUserTask *task,int sourceId,String name);
|
||||
public:
|
||||
typedef std::map<String,String> Capabilities;
|
||||
GwUserCode(GwApi *api);
|
||||
GwUserCode(GwApi *api, SemaphoreHandle_t *mainLock);
|
||||
void startUserTasks(int baseId);
|
||||
void startInitTasks(int baseId);
|
||||
void startAddonTask(String name,TaskFunction_t task, int id);
|
||||
Capabilities *getCapabilities();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user