jollen.org

Jollen 的 Blog
Jollen's email: jollen # jollen.org
more:  Jollen's Training

RTOS WoT (v0.1.0) 使用 FreeRTOS、 lwIP 與 C++ 元件重用

.作者:jollen/
.日期:January 7, 2016 10:57 AM


沿續前一個 Web of Things 的實驗計畫在 NodeMCU 上使用 er-coap-13,RTOS WoT 使用由 SuperHouse 開發的 esp-open-rtos 版本,進行一些實驗性質的修改。esp-open-rtos 同樣是基於 Espressif 官方的 Espressif IOT RTOS SDK,但改採 open source 版本的 FreeRTOS 與 lwIP 程式碼。

本文章採用 Markdown 語法撰寫(why?),若無法完整閱讀全文,請點擊這裡

關於 libc

標準 C 程式庫(libc)部份,esp-open-rtos 改用 newlib 來取代 Espressif 官方的標準 C 程式庫(libmain.a),並加入了 thread-safe 的支援。相關說明可參考 SuperHouse 官方的 esp-open-rtos 計畫。

RTOS WoT 目標

RTOS WoTesp-open-rtos 的一份 fork,目標是基於 FreeRTOS 設計並實作符合 W3C Web of Things 標準的 WoT server。RTOS WoT 目標是支援 constrained devices(Micro-controllers),這與目前 W3C 正在發展的 Web of Things Framework(採用 Node.js)目標不同,但未來都會經由 Web of Things 標準,讓不同的平台互通(interoperability)。

RTOS WoT v0.1.0

RTOS WoT 共有 10 個版本計畫,第一個版本(v0.1.0)的目標非常簡單:

  • 使用 C++ programming model
  • 加入 WebSocket(版本 13 以上)的支援

WebSocket 的部份還在測試中,C++ programming model 的概念說明如下。

Reusable Components

加入 C++ programming model 的想法,「不是」為了使用 C++ 來撰寫 FreeRTOS 應用程式,而是能將 device drivers 的程式碼,封裝為 component,以達到重用(reuse)的目的。

設計考量部份,只需要將 ESP8266 的 GPIO、Analog、I2C、UART 腳位,封裝為 class library 即可,但不封裝 FreeRTOS APIs。這項工作的目標,是讓 FreeRTOS 可以具備一層能重用的 device driver 架構。

實作部份,則是直接引用 ARM mbed 的程式碼,範例可參考 AnalogIn.h。有了 mbed components 的移植,未來還可以使用 mbed programming style 來撰寫 FreeRTOS 的驅動程式。

例如,要讀取 ESP8266 的 A0 數據,使用 mbed programming style 的寫法如下:

AnalogIn    AIR(17);
int a = AIR;

以下是一個 Air Quality 的完整程式碼範例:

#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "esp8266.h"
#include "math.h"

// C++ programming model
#include "AnalogIn.h"

struct userdata {
    xQueueHandle xQueue;
    xTaskHandle xHandle;
};

/* user context */
static struct userdata user;

/* ADC0 (A0)
 *
 * MP503 Air Quality Sensor -
 * http://www.seeedstudio.com/wiki/File:Air_quality_sensor_MP503.pdf
 */
AnalogIn    AIR(17);

/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
 *
 */
void readTask(void *pvParameters)
{
    struct userdata *user = (struct userdata *)pvParameters;
    int a;

    while(1) {
        // read from sensor output voltage
        a = AIR;

        if (a > 798 || a <= 10) {
            printf("Sensor is initializing. Waiting for 5 seconds...\n");
            wait(5);
            continue;
        }

        // send to queue
        xQueueSendToBack( user->xQueue, (void *) &a, portMAX_DELAY );

        // Resume the suspended task ourselves.
        if( user->xHandle != NULL ) {
            vTaskResume( user->xHandle );
        }

        wait(5);
    }
}

void transmitTask(void *pvParameters)
{
    struct userdata *user = (struct userdata *)pvParameters;

    int a;

    while(1) {
        // Suspend ourselves.
        vTaskSuspend( NULL );

        xQueueReceive(user->xQueue, &a, portMAX_DELAY);

        printf("{ \"quality\": %d }\n", a);
    }
}

extern "C" void user_init(void)
{
    uart_set_baud(0, 115200);

    user.xQueue = xQueueCreate(2, sizeof(uint32_t));
    xTaskCreate(readTask, (signed char *)"readTask", 256, &user, tskIDLE_PRIORITY+1, NULL);
    xTaskCreate(transmitTask, (signed char*)"transmitTask", 256, &user, tskIDLE_PRIORITY, &user.xHandle);
}

同樣的方式,移植 DigitalOut.h。以下是一個 GPIO 控制的完整範例:

#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"

// mbed API layer
#include "DigitalOut.h"
#include "AnalogIn.h"

// GPIO2 (D4) 
DigitalOut D4(2);

/* This task uses the mbed programming style to blink a LED.
 *
 */
void blinkenTask(void *pvParameters)
{
    while(1) {
        D4 = 1;
        wait(1)
        D4 = 0;
        wait(3);
    }
}

extern "C" void user_init(void)
{
    uart_set_baud(0, 115200);
    xTaskCreate(blinkenTask, (signed char *)"blinkenTask", 256, NULL, 2, NULL);
}

留言與討論

Tags:

純手工打造說明:技術專欄文章為 Jollen 原創,內容皆為人工撰寫,無 AI 生成。轉載請註明出處與作者,並全文引用。轉載時請在文章開頭或結尾明顯處註明「本文出處:https://www.jollen.org,已取得原作者同意並授權使用。」
訂閱電子報:不定期 Jollen's Blog 精選文章隨 Moko365 電子報寄送;請透過 Moko365 電子報訂閱(可隨時取消)。

Copyright(c) 2001–2016 www.jollen.org. All rights reserved.
Last update: 2026-07-22