我想对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
}

现在,我的问题主义者认为运行函数内部的上下文不同。 taskNamelisten(...)内部打印run(...)的内存位置不同

我讨厌的怀疑是对run函数执行static_cast会松散类上下文吗?我错了吗?

还有其他想法可以提供指向Class成员函数的freeRTOS的静态函数指针吗?

这是缺少的功能。 mainsys_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/

10-12 14:24