FreeRTOS CPP Функция Указатель

Я хочу использовать функцию-член класса CPP для функции задачи FreeRTOS.

Вот мое первоначальное решение

#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
}

Теперь моя проблема заключается в том, что контекст не совпадает внутри функции запуска. Печать ячейки памяти taskName отличается внутри listen(...) а также run(...)

Мое неприятное подозрение, что выполнение static_cast из функции run приводит к потере контекста класса? Я ошибся?

Есть ли другая идея предоставить статический указатель на функцию freeRTOS функции-члена класса?

Вот недостающие функции. main и sys_thread_new который является только оберткой.

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;
}

1

Решение

Я использую что-то вроде этого:

class MyClass{
public:
static void run( void* pvParams ){
((MyClass*)pcParams)->runInner();
}
void runInner(){
while ( true ){
// TODO code here
}
}
};

затем передайте указатель на объект при создании задачи

MyClass* x = new MyClass;
xTaskCreate( MyClass::run, taskName, stackDepth, (void*) x, taskPrio, taskHandle );

редактировать:

Предполагая, что вы хотите использовать шаблоны:

template<typename T>
void run ( T* p ){
((T*)p)->run();
}

class MyClass{
public:
void run(){
while ( true ){
// task code
}
}
}

затем создать задачу

MyClass* x = new MyClass;
xTaskCreate( run<MyClass>, taskName, stackDepth, x, taskPrio, taskHandle );

Редактировать:

Вам нужно разыграть run в (void (*)(void*))

xTaskCreate( (void (*)(void*))run<MyClass>, taskName, stackDepth, x, taskPrio, taskHandle );
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]