.
บทความนี้เป็นการเขียนบันทึกขั้นตอนการติดตั้งและใช้งานซอฟต์แวร์ที่เกี่ยวข้องกับการเขียนโค้ดภาษา C ร่วมกับ FreeRTOS สำหรับบอร์ดไมโครคอนโทรลเลอร์ ESP32 โดยใช้ระบบปฏิบัติการ Linux เช่น Ubuntu หรือ Raspbian OS ในการทำงาน (Host Computer)
ซอฟต์แวร์ที่จะต้องติดตั้งคือ ESP-IDF 4.x (IoT Development Framework for the ESP32 and ESP32-S Series of SoCs) ของบริษัท Espressif ซึ่งเวอร์ชันปัจจุบันที่ได้ลองใช้คือ ESP-IDF 4.3 รองรับชิป ESP32 หลายรุ่น เช่น ESP32 (เวอร์ชันแรก) และ ESP32-S Series (ESP32-S2 และ ESP32-S3) เป็นต้น
ข้อสังเกต: ถ้าต้องการเขียนโค้ดด้วยภาษา C/C++ สำหรับ ESP32 เราก็อาจเลือกใช้งาน Arduino IDE ร่วมกับ Arduino Core for ESP32 ซึ่งมาพร้อมกับ FreeRTOS หรือ IDE ตัวเลือกอื่น เช่น VSCODE หรือ PlatformIO ได้เลย สามารถใช้คำสั่งต่าง ๆ ของ Arduino API ได้ ไม่จำเป็นต้องใช้คำสั่งต่าง ๆ ใน C API ของ ESP-IDF
จากเอกสารออนไลน์ [FreeRTOS-ESP32 API]ระบุไว้ว่า
ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v10.2.0.
.
ในบทความนี้เราจะใช้บอร์ด ESP32 ที่มีหน่วยความจำ Flash 4MB ราคาไม่แพง พอจะหาซื้อมาใช้งานได้
สำหรับระบบปฏิบัติการอื่น สามารถศึกษาขั้นตอนการติดตั้งได้จาก https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/
ขั้นตอนแรก: ติดตั้ง ESP-IDF เวอร์ชัน 4.x
.
ในตัวอย่างการทำคำสั่งต่อไปนี้ เราจะเลือกไดเรกทอรีสำหรับการติดตั้งโปรแกรมต่าง ๆ ที่เกี่ยวข้องไว้ใน $HOME/esp/esp-idf
ของผู้ใช้งาน
ให้ทำคำสั่งตามลำดับต่อไปนี้
## install the ESP-IDF 4.3# set the ESPIDF path and export as a variable environment
$ export ESPIDF=$HOME/esp/esp-idf# make a new directory for the ESPIDF path
$ mkdir -p $ESPIDF && cd $ESPIDF# download the necessary software repository from github
$ git clone https://github.com/espressif/esp-idf.git $ESPIDF# download and install all submodules
$ git submodule update --init --recursive
ก่อนทำขั้นตอนถัดไป แนะนำให้แก้ไขการเลือกใช้คำสั่ง Python Interpreter โดยเปลี่ยนจาก python
(Python 2.7.x) ให้เป็น python3
(เช่น Python 3.7.x)
ใช้คำสั่ง nano เพื่อแก้ไขไฟล์ ./tools/idf_tools.py
หรือจะใช้ Editor อื่นแทนก็ได้
$ nano ./tools/idf_tools.py
แก้ไขที่บรรทัดแรก เปลี่ยนจาก
#!/usr/bin/env python
ให้เป็น
#!/usr/bin/env python3
จากนั้นทำคำสั่งต่อไปนี้ เพื่อดาวน์โหลดและติดตั้งโปรแกรมต่าง ๆ ที่เกี่ยวข้อง
$ ./install.sh
เมื่อทำมาถึงขั้นตอนนี้แล้ว เราจะสร้าง Python Virtual Environment เอาไว้ใช้งานสำหรับ ESP-IDF Tools
# create Python 3 virtual environment
$ python3 -m venv $ESPIDF/build-venv# activate Python3 virtual environment
$ source $ESPIDF/build-venv/bin/activate# export environment variables for ESPIDF tools
$ source $ESPIDF/export.sh# update PIP
$ pip install --upgrade pip# install required Python3 packages via PIP
$ pip install -r $ESPIDF/requirements.txt# exit the current Python virtual environment
$ deactivate
.
คำสั่งสุดท้ายที่ได้ทำไปในขั้นตอนที่แล้ว เป็นการจบหรือออกจากการทำงาน Python Virtual Environment และถ้าเราจะเริ่มใช้งานใหม่อีกครั้ง ก็มีลำดับคำสั่งดังนี้
$ export ESPIDF=$HOME/esp/esp-idf
$ source $ESPIDF/build-venv/bin/activate
$ source $ESPIDF/export.sh
การสร้างโปรเจกต์ ESP32 Application
.
ถัดไปเราจะสร้างไดเรกทอรีเอาไว้สำหรับเก็บไฟล์โปรเจกต์ใหม่ เช่น
$ mkdir -p $HOME/esp32_freertos && cd $HOME/esp32_freertos
เราจะลองใช้ตัวอย่างโปรเจกต์ที่มีอยู่แล้ว คือ hello_world
ที่มาพร้อมกับ ESP-IDF 4.x โดยสำเนาไฟล์ มาเป็นโปรเจกต์ใหม่ แล้วลองทำขั้นตอน Build ดูว่า สามารถคอมไพล์โค้ดได้หรือไม่ ถ้าทำได้สำเร็จ จะได้ไฟล์ .bin นำไปใช้ทดลองกับบอร์ด ESP32 ได้เลย
$ cp -r $IDF_PATH/examples/get-started/hello_world .
$ cd ./hello_world
$ idf.py set-target esp32
$ idf.py menuconfig
ในขั้นตอนการทำ MenuConfig ลองดูว่า มีการตั้งค่าในเมนูต่าง ๆ อย่างไรไว้แล้วบ้าง (สามารถกดคีย์ลูกศรหรือ Arrow Keys เลื่อนขึ้นหรือลง ไปทางซ้ายหรือขวาได้) เช่น ตรวจสอบดูว่า การตั้งค่าสำหรับขนาดของหน่วยความจำ Flash (Memory Size) เท่ากับ 4MB หรือไม่ ถ้ามีการเปลี่ยนแปลงการตั้งค่าใด ๆ อย่าลืมทำการบันทึก เช่น กดคีย์ S [Save] และจบการทำงานโดยกดคีย์ Q [Quit]
จากนั้นทำคำสั่งต่อไปนี้ เพื่อคอมไพล์โค้ดทั้งหมดของโปรเจกต์
$ idf.py build
ถ้าทำได้สำเร็จ ลองทำคำสั่งต่อไปนี้ เพื่ออัปโหลดไฟล์ .bin ที่ได้ ไปยังบอร์ดทดลอง ให้เสียบสาย USB เชื่อมต่อกับบอร์ด ESP32 ก่อน โดยทั่วไปแล้ว จะมีชื่อของอุปกรณ์ (Device Name) ตรงกับ /dev/ttyUSB0
มีการเลือกใช้ค่า Baudrate เท่ากับ 460800
$ idf.py -p /dev/ttyUSB0 -b 460800 flash
ถ้าต้องการดูข้อความที่ถูกส่งออกทาง USB-to-Serial ของบอร์ด ESP32 เมื่อโปรแกรมตัวอย่างเริ่มทำงาน ให้ทำคำสั่งต่อไปนี้ ถ้าต้องจากจบการทำงานหรือออกจากหน้า Console ให้กดคีย์ Ctrl+]
$ idf.py -p /dev/ttyUSB0 monitor
# press Ctrl+] to quit the program
.
ตัวอย่างการสร้างทาสก์สำหรับ ESP32-FreeRTOS
.
ถัดไปเรามาลองสร้างโปรเจกต์และไฟล์ที่เกี่ยวข้องเพื่อใช้งาน FreeRTOS ในเบื้องต้น โดยเริ่มต้นด้วยการสร้างไดเรกทอรีใหม่ ดังนี้
$ mkdir -p esp32_freertos_demo && cd esp32_freertos_demo
$ mkdir -p main
จากนั้นจะต้องสร้างไฟล์ CMakeLists.txt
สำหรับโปรเจกต์ และสร้างไฟล์ main/main.c
และ main/CMakeLists.txt
ตามโครงสร้างต่อไปนี้ (ไฟล์นอกเหนือจากนั้น จะถูกสร้างขึ้นโดยอัตโนมัติ)
- CMakeLists.txt
- Makefile
- sdkconfig
- main/
- CMakeLists.txt
- component.mk
- main.c
ไฟล์ ./CMakeLists.txt
cmake_minimum_required(VERSION 3.5)include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(freertos_demo)
ไฟล์ ./main/CMakeLists.txt
idf_component_register(SRCS "main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
set(COMPONENT_REQUIRES freertos)
ไฟล์ ./main/main.c
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"#define LED_GPIO 2 // use built-in LED pinvoid blink_task(void *pvParameters); // forward declarationvoid app_main() {
xTaskCreate( &blink_task, "led_blink_task",
configMINIMAL_STACK_SIZE,
NULL, tskIDLE_PRIORITY+1, NULL );
}void blink_task(void *pvParameters) { // task entry function
gpio_pad_select_gpio(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
uint32_t state = 0; while(1) { // endless loop
gpio_set_level(LED_GPIO, state); // update output
vTaskDelay( 500/portTICK_PERIOD_MS ); // delay 500msec
state ^= 1; // toggle state
}
vTaskDelete(NULL); // Let the task delete itself.
}
ข้อสังเกต: ฟังก์ชัน void app_main() {}
เป็นฟังก์ชันหลักของ ESP32 Application Code ภายในมีการใช้คำสั่ง xTaskCreate()
เพื่อสร้างทาสก์ของ FreeRTOS จำนวนหนึ่งทาสก์
อีกประการหนึ่งคือ การทำงานของ FreeRTOS Task Scheduler จะเริ่มทำงานโดยอัตโนมัติด้วยคำสั่ง vTaskStartScheduler()
ก่อนที่จะมีการฟังก์ชัน app_main()
.
จากนั้นทำขั้นตอน Build ด้วยคำสั่งนี้ (เลือกชิปเป้าหมาย หรือ Target เป็น esp32
)
$ idf.py set-target esp32$ idf.py build
ถ้าต้องการปรับเปลี่ยนการตั้งค่าสำหรับ FreeRTOS เช่น TICK Rate เท่ากับ 100 Hz (Default) เราสามารถเปลี่ยนให้เป็น 1000 Hz ได้ โดยทำคำสั่ง
$ idf.py menuconfig$ idf.py build
เลือกไปที่เมนู “Component config” แล้วไปที่เมนู “FreeRTOS” เปลี่ยนค่าให้เป็น 1000 (ค่าที่เลือกได้ต้องอยู่ในช่วง 100–1000) บันทึกการเปลี่ยนแปลง จากนั้นต้องทำคำสั่งเพื่อคอมไพล์โค้ดอีกครั้ง
เมื่อทำขั้นตอน Build แล้ว จะได้ไฟล์ .bin ดังนี้
./build/freertos_demo.bin
ถ้าต้องการทดสอบการทำงานของโค้ดตัวอย่างโดยใช้บอร์ด ESP32 ให้ทำคำสั่งต่อไปนี้ แล้วสังเกตการกระพริบที่ LED ของบอร์ด
$ idf.py -p /dev/ttyUSB0 -b 460800 flash
สรุป: เราได้เห็นขั้นตอนการติดตั้งโปรแกรมต่าง ๆ ที่เกี่ยวข้องกับการทดลองเขียนโค้ดภาษา C เพื่อใช้งาน FreeRTOS ร่วมกับบอร์ด ESP32 และลองสร้างและคอมไพล์โค้ดตัวอย่าง เพื่อนำไปทดลองกับฮาร์ดแวร์จริง
ข้อสังเกต: ในกรณีที่มีการเขียนโค้ดที่มีความซับซ้อน มีหลายไฟล์ในโปรเจกต์ ก็อาจจะเลือกใช้ IDE เช่น Eclipse IDE หรือ VSCode เพื่ออำนวยความสะดวกในการเขียนโค้ด