我想对FreeRTOS taskFunction使用CPP类的成员函数。
这是我最初的解决方案
#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(...)
的内存位置不同我讨厌的怀疑是对run函数执行static_cast会松散类上下文吗?我错了吗?
还有其他想法可以提供指向Class成员函数的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;
}
最佳答案
我用这样的东西:
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 );
关于c++ - FreeRTOS CPP功能指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36606202/