Ich möchte eine Mitgliedsfunktion einer CPP-Klasse für eine FreeRTOS taskFunction verwenden.FreeRTOS CPP Function Pointer
Hier ist meine erste Lösung
#ifndef TaskCPP_H
#define TaskCPP_H
#include "FreeRTOS.h"
#include "task.h"
template<typename T>
class TaskBase {
protected:
xTaskHandle handle;
void run() {};
public:
static void taskfun(void* parm) {
static_cast<T*>(parm)->run();
#if INCLUDE_vTaskDelete
vTaskDelete(static_cast<T*>(parm)->handle);
#else
while(1)
vTaskDelay(10000);
#endif
}
virtual ~TaskBase() {
#if INCLUDE_vTaskDelete
vTaskDelete(handle);
#endif
return;
}
};
#endif /* __TaskCPP_H__ */
#ifndef HTTPSERVER_H_
#define HTTPSERVER_H_
#include "TaskBase.h"
#include <string.h>
#include "lwip/opt.h"
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/tcp.h"
#include "lwip/api.h"
#include "lwip/ip_addr.h"
class HttpServer;
class HttpServer : public TaskBase<HttpServer> {
public:
HttpServer();
virtual ~HttpServer();
void run();
void listen(ip_addr *address, uint8_t port);
void print();
protected:
char taskName[50];
ip_addr address;
uint8_t port;
};
#endif /* HTTPSERVER_H_ */
#include "HttpServer.h"
HttpServer::HttpServer()
{
}
void HttpServer::listen(ip_addr *address, uint8_t port) {
char buf[16];
sprintf(taskName, "%s_%d\r\n", ipaddr_ntoa_r(address, buf, 16), port);
DEBUGOUT("ADDRESS Listen: %x\r\n", &taskName);
this->handle = sys_thread_new(this->taskName, &taskfun, NULL, DEFAULT_THREAD_STACKSIZE + 128, DEFAULT_THREAD_PRIO);
}
void HttpServer::run() {
while(1) {
print();
Board_LED_Toggle(LEDS_LED2);
vTaskDelay(configTICK_RATE_HZ/14);
}
}
void HttpServer::print() {
DEBUGOUT("ADDRESS Listen: %x\r\n", &taskName);
}
HttpServer::~HttpServer() {
// TODO Auto-generated destructor stub
}
Jetzt ist mein Problem iSt, dass der Kontext in der Run-Funktion nicht das gleiche ist. Drucken der Speicherplatz von taskName
unterscheidet innerhalb listen(...)
und run(...)
Meine böse Verdacht besteht, dass ein static_cast der Run-Funktion macht die Klasse Kontext verliert? Liege ich falsch?
Gibt es eine andere Idee, einen statischen Funktionszeiger auf freeRTOS einer Klassenmitgliedsfunktion bereitzustellen?
Hier sind die fehlenden Funktionen. Die main
und die sys_thread_new
, die nur ein Wrapper ist.
int main(void) {
prvSetupHardware();
HttpServer server;
server.listen(IP_ADDR_ANY, 80);
/* Start the scheduler */
vTaskStartScheduler();
/* Should never arrive here */
return 1;
}
sys_thread_t sys_thread_new(const char *pcName, void(*pxThread)(void *pvParameters), void *pvArg, int iStackSize, int iPriority)
{
xTaskHandle xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
xResult = xTaskCreate(pxThread, (signed char *) pcName, iStackSize, pvArg, iPriority, &xCreatedTask);
if(xResult == pdPASS)
{
xReturn = xCreatedTask;
}
else
{
xReturn = NULL;
}
return xReturn;
}
Was ist mit dem Code werfen, wo Sie vermutlich das Objekt erstellen und rufen 'xTaskCreate() 'damit irgendwie? – Notlikethat
Können Sie ein minimales Beispiel extrahieren? Insbesondere sind das Template-Zeug und die mehreren Dateien nicht notwendig. Fügen Sie auch nicht mehrere Bearbeitungsabsätze hinzu und überlassen Sie sie anderen, um die relevanten Informationen aus ihnen auszuwählen. Bereinigen Sie stattdessen Ihre Frage gemäß den Regeln der Website und machen Sie das Relevante offensichtlich. –
Sry, aber ich wurde nach den fehlenden Abschnitten gefragt (wo das Objekt erstellt wurde und der xTaskCreate) und ich denke nicht, dass es viele Linien außerhalb des Bereichs gibt. – Pascal