การพัฒนาเฟิร์มแวร์สำหรับไมโครคอนโทรลเลอร์

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา

วิกินี้อธิบายถึงขั้นตอนและตัวอย่างการพัฒนาเฟิร์มแวร์ลงบนบอร์ดไมโครคอนโทรลเลอร์ที่เราได้ประกอบขึ้นมา โดยเนื้อหาครอบคลุมเฉพาะสภาพแวดล้อมการพัฒนาโปรแกรมบนลินุกซ์เท่านั้น

ติดตั้งซอฟท์แวร์ที่เกี่ยวข้อง

  • Cross compiler สำหรับไมโครคอนโทรลเลอร์ตระกูล AVR รวมถึงไลบรารีที่เกี่ยวข้อง
sudo apt-get install avr-gcc avr-libc
  • AVR toolchain
sudo apt-get install binutils-avr
  • avr-dude สำหรับโหลดไบท์โค้ดลงบนแฟลชของไมโครคอนโทรลเลอร์ผ่านพอร์ต USB
sudo apt-get install avrdude

โปรแกรมตัวอย่าง

ทดลองพิมพ์โปรแกรมตัวอย่างต่อไปนี้ และบันทึกไว้ในชื่อ first.c

#define F_CPU 16000000UL // บอกไลบรารีว่า MCU ทำงานที่ 16MHz
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    PORTD = 0b00000000;  // กำหนดลอจิกขา PD7..0 เป็น 0
    DDRD  = 0b00001000;  // กำหนดให้ขา PD3 ทำหน้าที่เอาท์พุท

    while (1)
    {
        PORTD = 0b00001000;  // ส่งลอจิก 1 ไปที่ขา PD3
        _delay_ms(1000);
        PORTD = 0b00001000;  // ส่งลอจิก 0 ไปที่ขา PD3
        _delay_ms(1000);
    }

    return 0;
}

โปรแกรมข้างต้นเรียกใช้ค่าคงที่สำหรับ I/O รีจีสเตอร์จากไฟล์เฮดเดอร์ avr/io.h และฟังก์ชันหน่วงเวลาจากไฟล์เฮดเดอร์ util/delay.h

การคอมไพล์และสร้างรหัสภาษาเครื่อง

คอมไพล์โปรแกรมโดยเรียกใช้คำสั่ง avr-gcc ซึ่งเป็นครอสคอมไพเลอร์ที่ทำหน้าที่แปลโปรแกรมให้เป็นรหัสภาษาเครื่องสำหรับสถาปัตยกรรม AVR

avr-gcc -mmcu=atmega168 -O -o first.elf first.c

อ็อพชันต่าง ๆ ที่ระบุในคำสั่งข้างต้นมีหน้าที่ดังนี้

  • -mmcu=atmega168 เป็นตัวบอกคอมไพเลอร์ว่าไมโครคอนโทรลเลอร์ที่ใช้เป็นเบอร์ ATMega168
  • -O ระบุว่าให้คอมไพเลอร์ทำ code optimization ซึ่งจำเป็นต้องใช้เพื่อให้ฟังก์ชัน _delay_ms() ทำงานได้ถูกต้อง
  • -o first.elf ระบุว่าให้เอาท์พุทถูกเก็บลงในไฟล์ first.elf หากไม่ระบุโปรแกรมจะสร้างไฟล์ชื่อ a.out แทน

ผลลัพธ์ที่ได้จะอยู่ในรูปของไฟล์ฟอร์แมต ELF (Excutable and Linkable Format) ซึ่งประกอบไปด้วยเฮดเดอร์และข้อมูลเสริมอื่น ๆ อีกมากมาย อย่างไรก็ตามเราต้องการเพียงแค่ส่วนที่เป็นรหัสภาษาเครื่องของโปรแกรม ซึ่งสกัดออกมาได้โดยใช้คำสั่ง avr-objcopy ดังนี้

avr-objcopy -j .text -O ihex first.elf first.hex

อ็อพชันต่าง ๆ ที่ระบุในคำสั่งข้างต้นมีหน้าที่ดังนี้

  • -j .text สกัดข้อมูลจากเซคชัน .text ซึ่งเป็นเซคชันที่เก็บโค้ดโปรแกรมในไฟล์ ELF
  • -O ihex ส่งเอาท์พุทในรูปแบบ Intel HEX

ผลลัพธ์ที่ได้จะถูกเก็บไว้ในไฟล์ first.hex ซึ่งเป็นไฟล์ ASCII โดยภายในไฟล์จะมีข้อมูลคล้ายคลึงกับที่แสดงในตัวอย่าง

$ cat first.hex
:100000000C9434000C9451000C9451000C94510049
:100010000C9451000C9451000C9451000C9451001C
:100020000C9451000C9451000C9451000C9451000C
:100030000C9451000C9451000C9451000C945100FC
:100040000C9451000C9451000C9451000C945100EC
:100050000C9451000C9451000C9451000C945100DC
:100060000C9451000C94510011241FBECFEFD4E02A
:10007000DEBFCDBF11E0A0E0B1E0E4EEF0E002C0F1
:1000800005900D92A030B107D9F711E0A0E0B1E0E2
:1000900001C01D92A030B107E1F70E9453000C94FB
:1000A00071000C940000CFEFD4E0DEBFCDBF1BB8D1
:1000B00088E08AB988E08BB928EE33E080E991E0E6
:1000C0000197F1F721503040C9F788E08BB928EE4D
:1000D00033E080E991E00197F1F721503040C9F712
:0400E000E9CFFFCF96
:00000001FF

การเขียนโปรแกรมลงบนหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์

ดูรูป

Flow.png

ใช้คำสั่ง avrdude

avrdude -p atmega168 -c usbasp -u -U flash:w:first.hex