Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« December 2015 | (回到Blog入口) | February 2016 »

January 2016 歸檔

January 7, 2016

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

沿續前一個 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 WoT 是 esp-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);
}

留言與討論

January 27, 2016

使用 ESP8266 做為 FreeRTOS 的學習與開發環境

根據 2016 CES 的 IoT 產業新聞分析:WiFi Module 正以出乎意料外的速度,佔領 IoT 市場,並且 RTOS 與 HTML5 扮演重要的主流 IoT 技術。本文介紹如何使用 ESP8266 做為 FreeRTOS 的學習環境。

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

前言

ESP8266 是 Espressif(樂鑫信息科技有限公司) 所開發的一款 WiFi 模組,ESP8266 WiFi Module 受到開發者與自造社群的喜愛。目前可見的 ESP8266 開發模式有:

  1. Microcontrollers 搭配 ESP8266 WiFi Module,使用 microcontrollers 來控制 ESP8266,例如:Arduino + ESP8266

  2. 使用官方的 ESP8266-RTOS-SDK,使用 FreeRTOS 來開發 ESP8266 的應用程式,ESP8266 WiFi Module 可以做為主動方(即不需要 microcontroller 即可單獨執行)

  3. 使用 NodeMCU 的 ESP8266 firmware,使用 Lua script 的方式來開發 ESP8266 應用程式;ESP8266 WiFi Module 可以做為主動方(即不需要 microcontroller 即可單獨執行)

如果要把 ESP8266 做為 FreeRTOS 的學習平台,倒底要選擇那一個 SDK 呢?

開始學習 FreeRTOS

要將 ESP8266 做為 FreeRTOS 的學習平台,如果要練習修改或閱讀 FreeRTOS kernel 程式碼,就要使用開源的 FreeRTOS 版本。以下是使用 ESP8266 做為 FreeRTOS 學習或實驗平台的要點:

  • 要使用 Open Source 的 FreeRTOS 原始碼
  • 要有 ESP8266 的 Portable Layer 實作,例如 pvPortMalloc()

由 SuperHouse 社群所維護的 ESP8266 SDK 正好能滿足上述要點。此外,使用 FreeRTOS 在 ESP8266 平台上,打造 IoT 應用程式時,則是要滿足以下基本條件:

  • 使用 lwip 做為 TCP/IP Stacks
  • 具備 CoAP 的支援
  • 硬體控制部份,最好有一個 Component-based 的程式設計模式

為了方便起見,WoT.City 發起 rtos-wot 計畫,將上述開源計畫整合成一個 FreeRTOS distribution,目標是維護一個用於學習 FreeRTOS + IoT 的 FreeRTOS 特別版本(distribution)。

安裝 FreeRTOS 開發環境

以下是開發環境的架設教學,教學內容以 Mac 環境為主。

安裝 ESP Open SDK

在 MacOS 系統建置 ESP8266 的編譯環境。首先,確認是否已安裝 Xcode command line tools:

$ xcode-select --install

再使用 homebrew 安裝所需的套件:

$ brew tap homebrew/dupes
$ brew install binutils coreutils autoconf automake wget gawk libtool gperf gnu-sed --with-default-names grep bison libvorbis
$ export PATH=/usr/local/opt/gnu-sed/libexec/gnubin:/usr/local/opt/gperf/bin:$PATH

製作一個 "case-sensitive"(可區分大小寫檔名)的虛擬磁碟,大小是 8GB:

$ hdiutil create ./eos.dmg -volname "esp-open-sdk" -size 8g -fs "Case-sensitive HFS+"

將 ESP8266 Open SDK 下載至此虛擬磁碟:

$ hdiutil mount ./eos.dmg
$ cd /Volumes/esp-open-sdk
$ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
$ cd eos-open-sdk

編譯 "separated SDK":

$ make STANDALONE=n

編譯完成後的畫面:

Xtensa toolchain is built, to use it:

export PATH=/Volumes/esp-open-sdk/esp-open-sdk/xtensa-lx106-elf/bin:$PATH

Espressif ESP8266 SDK is installed. Toolchain contains only Open Source components
To link external proprietary libraries add:

xtensa-lx106-elf-gcc -I/Volumes/esp-open-sdk/esp-open-sdk/sdk/include -L/Volumes/esp-open-sdk/esp-open-sdk/sdk/lib

根據畫面提示,修改 PATH 環境變數:

$ export PATH=/Volumes/esp-open-sdk/esp-open-sdk/xtensa-lx106-elf/bin:$PATH

完成 ESP8266 Toolchain 的安裝,接下來就可以開始編譯 rtos-wot 了。

編譯 FreeRTOS Application Firmware

安裝 pyserial 套件:

$ git clone https://github.com/pyserial/pyserial.git
$ cd pyserial/
$ sudo python setup.py install

下載 rtos-wot 原始碼:

$ git clone https://github.com/wot-sdk/rtos-wot

編輯 include/ssid_config.h 檔案,設定 WiFi 的 SSID 與密碼:

#define WIFI_SSID "<the-SSID>"
#define WIFI_PASS "<your-passworld>"

完成後,挑選一個 RTOS 應用程式,並進行 firmware 編譯:

$ cd examples/blink
$ make

編譯完成後,在目前的應用程式路徑下,得到以下二個檔案:

  • firmware/0x00000.bin
  • firmware/0x20000.bin

將以上二個檔案燒錄至 ESP8266 更新即可,指令如下:

$ make flash ESPPORT=/dev/cu.SLAB_USBtoUART 

使用 Linux 環境的讀者,請另行參考這篇文章的說明。

使用 esptool 更新 ESP8266 Firmware

如果要使用 esptool.py 工具,手動更新 firmware 檔案的話,指令如下:

$ esptool.py -p /dev/cu.SLAB_USBtoUART --baud 115200 write_flash -fs 32m -fm dio -ff 40m 0x20000 ./firmware/0x20000.bin 0x00000 ./firmware/0x00000.bin

在 Mac 下使用 esptool.py 更新 NodeMCU firmware 時,需額外加上 -fm 與 -fs 二個參數。

關於 RTOS WoT 計畫

本文使用的 RTOS WoT 版本,是專為 ESP8266 製作的 FreeRTOS 學習、教學與實驗平台。RTOS WoT 的目標是打造一個 Web of Things 的 RTOS SDK。

RTOS WoT 也在 RTOS Application Layer 做了一些加強,請參考以下文章:

Reference

  • http://www.allaboutcircuits.com/projects/guts-of-the-iot-part-1-building-nodemcu-from-source-for-the-esp8266/

留言與討論

How to build a CoAP message and send it to Internet using FreeRTOS on ESP8266.

How to build a CoAP message and send it to Internet using FreeRTOS on ESP8266.

Please follow this link if you are unable to read this article.

Abstraction

This article describes how to build a CoAP message by er-coap-13 APIs. er-coap-13 is a high-level CoAP library of Contiki operating system. This article will introduce rtos-wot project which is based on esp-open-rtos from SuperHouse.

With rtos-wot, you are able to build CoAP messages with FreeRTOS and send them over ESP8266 WiFi module.

Introducing rtos-wot

rtos-wot is an open source FreeRTOS distribution for ESP8266 WiFi module. It aims to conform the W3C web of things framework and is heavily based on esp-open-rtos.

The development is still in progress.

CoAP Library

libcoap of Contiki has already been ported to rtos-wot project. The following steps explains how to build a CoAP message and send it to Internet over ESP8266 wifi module.

1. Include necessary header files.

#include "er-coap-13.h"
#include "er-coap-13-transactions.h"

2. Prepare and initialize a CoAP packet.

coap_packet_t request[1];
coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0);

In the example, the packet is initialized to COAP_TYPE_CON type and POST method.

3. Fill CoAP headers.

coap_set_header_uri_path(request, '/object/123456/send');
coap_set_header_uri_host(request, 'wot.city');

In the example, the packet headers was filled with both server URI path and server host.

4. Set the payload.

const char *payload = "{}";
coap_set_payload(request, (uint8_t *)payload, strlen(payload));

The payload is the message context. In the example, the payload is an empty JSON object.

5. Get message ID

request->mid = coap_get_mid();

6. Serialize CoAP message

coap_transaction_t *transaction = coap_new_transaction(request->mid, &ipaddr, uri->port);
transaction->packet_len = coap_serialize_message(request, transaction->packet);

7. Final step

After serializing the CoAP message, the final CoAP packet is stored at transaction->packet field. The final step is to call lwip APIs to create a UDP socket and send out the serialized message. For example, assume that the server was connected via local socket s.

write(s, transaction->packet, transaction->packet_len);

CoAP is basis of web of things framework. For push pattern of WoT, the TD (thing description) can be serialized in CoAP binary format.

Put together

Please refer to coap_send for how to put all things together.

Reports and Discussion

關於 January 2016

此頁面包含了在January 2016發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 December 2015。

後一個存檔 February 2016。

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org