การใช้งาน FreeRTOS ตอนที่ 1
FreeRTOS พัฒนาขึ้นมาโดยบริษัท Real Time Engineer โดย FreeRTOS เป็นระบบปฏิบัติการที่ออกแบบมาสำหรับไมโครคอนโทรลเลอร์หรือไมโครโพรเซสเซอร์เล็กๆ เพื่อการใช้งานแบบ Multitasking (ทำงานแบบหลายงานพร้อมกัน) ในรูปแบบที่เป็น Realtime OS (Realtime แปลเป็นภาษาไทย คือ เวลาจริง แต่ความหมายที่ใช้งานกันทั่วไป คือ ระบบปฏิบัติการที่ต้องมีการตอบสนองต่อ Input ไม่เกินค่าเวลาที่กำหนด ซึ่งระบบปฏิบัติการทั่วไป ไม่สามารถทำได้) โดยในโลกของ Embedded System การตอบสนองที่ไม่เกินเวลานี้มีความสำคัญมาก เพราะหากล่าช้าไปอาจสร้างความเสียหายได้ ลองนึกถึงระบบควบคุมในรถยนต์ ที่เมื่อเหยียบเบรคแล้ว รถยนต์มีการเบรคล่าช้าไป แม้จะเสี้ยววินาทีก็ตาม อะไรจะเกิดขึ้น
บางคนอาจจะสงสัยว่าเราสามารถเขียนโปรแกรมแบบเดิมๆ ก็ได้ ทำไมต้องเขียน Multitasking ด้วย เหตุผลก็มีอยู่หลายเหตุผล เช่น ในไมโครคอนโทรลเลอร์หลายตัว มี CPU Core มากกว่า 1 ตัว เช่น ESP32 ก็มี CPU Core 2 ตัว ซึ่งหากเขียนโปรแกรมแบบเดิม ก็จะใช้ประสิทธิภาพได้เพียง 1 ตัวเท่านั้น หรือบางกรณีการเขียนโปรแกรมแบบ Multitasking จะทำให้การเขียนโปรแกรมง่ายขึ้น โดยเฉพาะกรณีที่เราต้องการให้ไมโครคอนโทรลเลอร์ทำงานหลายๆ อย่างพร้อมๆ กัน
FreeRTOS เป็นระบบปฏิบัติการที่มีการพัฒนามาเป็นเวลานาน ทำให้มีการทำงานที่ค่อนข้างเสถียร และด้วยความที่เป็น Open Source ทำให้มีผู้นำไปใช้จำนวนมาก เช่น ESP-IDF ของ ESP32 ก็สร้างจาก FreeRTOS และเมื่อปีที่ผ่านมาทาง Amazon ก็ได้ออก Amazon FreeRTOS ซึ่งเป็นตระกูลหนึ่ง (ภาษาคอมฯ จะเรียกว่า distribution) ของ RTOS โดยมีเป้าหมายให้ผู้พัฒนา Embedded Systems สามารถใช้ Amazon FreeRTOS ในการติดต่อกับระบบคลาวด์ของ Amazon ได้
FreeRTOS มีหลาย distribution แต่จะขอกล่าวถึง distribution อื่นๆ สักเล็กน้อย เช่น OpenRTOS เป็น Commercial License ของ FreeRTOS, SefeRTOS พัฒนาขึ้นเพื่อตอบสนองกับมาตรฐานความปลอดภัยต่างๆ โดยเฉพาะ นอกจากนั้นยังมีอีกหลายๆ distribution โดยผู้สนใจสามารถดูได้ที่ https://www.freertos.org/
การใช้งาน FreeRTOS กับ Arduino
ก่อนอื่นก็ต้องติดตั้ง Arduino IDE ก่อน ซึ่งผมจะไม่พูดถึงในที่นี้ เพราะมีบทความหรือคลิปมากมายเกี่ยวกับเรื่องนี้ หลังจากที่ติดตั้ง Arduino IDE เสร็จแล้ว หากต้องการใช้ FreeRTOS มีขั้นตอนดังนี้
ไปที่ Sketch -> Include Library -> Manage Libraries จะปรากฏหน้าต่าง Library Manager ขึ้นมาคล้ายๆแบบนี้
ในช่องว่างด้านบน (Topic) ให้ป้อนคำว่า FreeRTOS จะปรากฏ Library ที่ใกล้เคียงแสดงขึ้นตามตัวอย่าง
ให้เลือกติดตั้ง Library FreeRTOS โดย Richard Barry รอแป๊บนึงก็เรียบร้อย ตอนนี้เราก็มี FreeRTOS ไว้ใช้งานแล้ว
เมื่อเรามี FreeRTOS แล้ว คราวนี้จะทำอะไรดี แน่นอนครับ! สิ่งแรกที่เราจะทำก็คือ ไฟกระพริบเทพ (เดี๋ยวจะผิดประเพณี 55) แต่เราจะไม่ทำไฟกระพริบแบบธรรมดา แต่เป็นไฟกระพริบที่เกิดจาก 3 งาน (Task) ที่ต่างคนต่างทำงาน โดยเราจะต่อฮาร์ดแวร์ตามรูป โดยใช้ LED จำนวน 3 หลอด ต่อเข้าที่ขา 6, 7 และ 8 (สำหรับ R สามารถใช้ค่าอื่นได้ ระหว่าง 100–300 โอห์ม)
เราจะทำให้หลอดไฟ LED ทั้ง 3 ดวงกระพริบในอัตราที่ไม่เท่ากัน โดยดวงที่ 1 กระพริบทุกครึ่งวินาที ดวงที่ 2 กระพริบทุกวินาที และดวงที่ 3 กระพริบทุก 2 วินาที ดูโปรแกรมก่อนก็แล้วกันครับ
การใช้งานจะเริ่มด้วยการ include library “Arduino_FreeRTOS.h” จากนั้น ในส่วน setup จะเป็นการสร้าง task หรือ thread ขึ้นมา 3 task โดยใช้ฟังก์ชัน xTaskCreate โดยมีพารามิเตอร์ดังนี้
- ตัวที่ 1 ชื่อฟังก์ชันที่จะเรียกขึ้นมาทำงานเป็น Task หนึ่งในระบบ โดยในโปรแกรมนี้เราสร้างขึ้นมา 3 ฟังก์ชัน คือ redLedControllerTask, blueLedControllerTask และ yellowLedControllerTask เมื่อเราใช้ฟังก์ชัน xTaskCreate เรียกทั้ง 3 ฟังก์ชันขึ้นมา แต่ละฟังก์ชันจะทำงานเสมือนกับเป็นคนละโปรแกรมที่ทำงานไปพร้อมๆ กัน (มักเรียกว่า Task หรือ Thread)
- ตัวที่ 2 เป็นชื่อเรียกของ Task จะเห็นว่ามีลักษณะเป็นข้อความ
- ตัวที่ 3 เป็นขนาดของ Stack ที่จะจองให้ Task นั้นใช้งาน โดยเรื่องของ Stack จะอธิบายภายหลัง ในทีนี้กำหนดให้แต่ละ Task ใช้งาน Stack ได้ 128 ไบต์
- ตัวที่ 4 เป็นพารามิเตอร์ที่จะส่งเข้าไปใน Task ซึ่งในกรณีนี้เป็น Task ที่กระพริบไฟ จึงไม่จำเป็นต้องส่งพารามิเตอร์เข้าไป จึงกำหนดให้เป็น NULL
- ตัวที่ 5 เป็น Priority หรือลำดับความสำคัญของงาน ซึ่งสามารถจะกำหนดให้แต่ละงานมีลำดับความสำคัญไม่เท่ากันก็ได้ ซึ่งเรื่องนี้ก็จะกล่าวรายละเอียดภายหลัง สำหรับกรณีนี้ เราจะกำหนดให้แต่ละงานมีลำดับความสำคัญเท่ากันไปก่อน คือเป็น 1
- ตัวสุดท้าย เป็น Task Handle จะกล่าวถึงรายละเอียดภายหลังเช่นกัน ตอนนี้ใช้เป็น NULL ไปก่อน
จากนั้นก็เป็นฟังก์ชัน 3 ฟังก์ชัน ชื่อ redLedControllerTask, blueLedControllerTask และ yellowLedControllerTask โดยแต่ละฟังก์ชัน จะเริ่มจากการกำหนด pinMode และเข้า while loop ที่เป็น Infinity Loop โดยจะ delay เป็นเวลาไม่เท่ากัน และเรียกใช้คำสั่ง
digitalWrite(RED, digitalRead(RED) ^ 1)
ซึ่งเป็นคำสั่งที่จะอ่านสถานะของ LED (ใช้คำสั่ง digitalRead) จากนั้นนำมา xor (ในภาษา C การทำ xor จะใช้เครื่องหมาย ^) กับ 1 ทำให้เมื่ออ่านได้ 1 จะกลายเป็น 0 และหากอ่านได้ 0 จะกลายเป็น 1 ทำให้เมื่อเขียนกลับไปที่ LED ผ่านคำสั่ง digitalWrite จะทำให้กลับสถานะ คือ จาก 0 ก็จะเขียนกลับเป็น 1 และจาก 1 ก็จะเขียนกลับเป็น 0 ซึ่งก็คือไฟกระพริบนั่นเอง
หากสังเกตโปรแกรม จะเห็นว่าทั้ง 3 ฟังก์ชัน เป็นฟังก์ชัน Infinity Loop คือ ไม่มีวันหลุดจากฟังก์ชันได้ แต่ด้วยความสามารถในการทำ Multitasking ของ FreeRTOS จึงทำให้ฟังก์ชันทั้ง 3 ทำงานพร้อมกัน และไฟ LED แต่ละดวงก็จะกระพริบไปตามจังหวะของตนเองได้
การเขียนโปรแกรมลักษณะนี้ สามารถเขียนโดยใช้ภาษา C โดยใช้ฟังก์ชัน millis() ช่วย ก็จะทำให้เกิดผลอย่างเดียวกันก็จริง แต่หากดูที่ตัวโปรแกรมแล้ว จะเห็นว่า การเขียนโปรแกรมแบบ Multitasking ตามตัวอย่างนี้ สามารถทำความเข้าใจได้ง่ายกว่า ยิ่งโปรแกรมซับซ้อนขึ้น ก็ยิ่งจะเห็นได้อย่างชัดเจนมากขึ้น
สำหรับ FreeRTOS ในตอนแรก ก็ขอจบลงตรงนี้ ในตอนต่อๆ ไป ก็จะค่อยขยายความ ให้เห็นการใช้งานและเข้าใจการทำงานแบบ Multitasking ได้มากขึ้น