ผลต่างระหว่างรุ่นของ "การพัฒนาเฟิร์มแวร์สำหรับไมโครคอนโทรลเลอร์"
Chaiporn (คุย | มีส่วนร่วม) |
Chaiporn (คุย | มีส่วนร่วม) |
||
แถว 67: | แถว 67: | ||
== การเขียนโปรแกรมลงบนหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์ == | == การเขียนโปรแกรมลงบนหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์ == | ||
− | + | โดยทั่วไปต้องอาศัยอุปกรณ์ที่เรียกว่า AVR Programmer | |
+ | |||
+ | แต่ชิปไมโครคอนโทรลเลอร์ที่แจกไปให้นั้นถูกป้อนโปรแกรมที่เรียกว่า boot loader เอาไว้ โปรแกรมนี้มีการทำงานดังรูปด้านล่าง | ||
+ | [[Image:flow.png|center|500px]] | ||
+ | |||
+ | เสียบบอร์ดไมโครคอนโทรลเลอร์เข้ากับพอร์ต USB และใช้คำสั่ง <code>lsusb</code> (อาจต้องเรียกมากกว่าหนึ่งครั้ง) จะต้องปรากฏรายการอุปกรณ์ที่มี VID:PID เป็น 16c0:05dc ดังตัวอย่าง | ||
+ | $ lsusb | ||
+ | Bus 004 Device 001: ID 0000:0000 | ||
+ | Bus 003 Device 007: ID 16c0:05dc <-- ต้องปรากฏบรรทัดนี้ (หมายเลข Bus และ Device อาจแตกต่างออกไป) | ||
+ | Bus 003 Device 001: ID 0000:0000 | ||
+ | Bus 002 Device 001: ID 0000:0000 | ||
+ | Bus 001 Device 001: ID 0000:0000 | ||
+ | |||
ใช้คำสั่ง <code>avrdude</code> | ใช้คำสั่ง <code>avrdude</code> | ||
avrdude -p atmega168 -c usbasp -u -U flash:w:first.hex | avrdude -p atmega168 -c usbasp -u -U flash:w:first.hex |
รุ่นแก้ไขเมื่อ 16:32, 14 สิงหาคม 2552
วิกินี้อธิบายถึงขั้นตอนและตัวอย่างการพัฒนาเฟิร์มแวร์ลงบนบอร์ดไมโครคอนโทรลเลอร์ที่เราได้ประกอบขึ้นมา โดยเนื้อหาครอบคลุมเฉพาะสภาพแวดล้อมการพัฒนาโปรแกรมบนลินุกซ์เท่านั้น
เนื้อหา
ติดตั้งซอฟท์แวร์ที่เกี่ยวข้อง
- ครอสคอมไพเลอร์ (cross compiler) สำหรับไมโครคอนโทรลเลอร์ตระกูล AVR รวมถึงไลบรารีที่เกี่ยวข้อง
sudo apt-get install avr-gcc avr-libc
- AVR toolchain
sudo apt-get install binutils-avr
- AVRDUDE (AVR Downloader/UploaDEr) ใช้สำหรับโหลดรหัสภาษาเครื่องลงบนหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์ผ่านพอร์ต 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
การเขียนโปรแกรมลงบนหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์
โดยทั่วไปต้องอาศัยอุปกรณ์ที่เรียกว่า AVR Programmer
แต่ชิปไมโครคอนโทรลเลอร์ที่แจกไปให้นั้นถูกป้อนโปรแกรมที่เรียกว่า boot loader เอาไว้ โปรแกรมนี้มีการทำงานดังรูปด้านล่าง
เสียบบอร์ดไมโครคอนโทรลเลอร์เข้ากับพอร์ต USB และใช้คำสั่ง lsusb
(อาจต้องเรียกมากกว่าหนึ่งครั้ง) จะต้องปรากฏรายการอุปกรณ์ที่มี VID:PID เป็น 16c0:05dc ดังตัวอย่าง
$ lsusb Bus 004 Device 001: ID 0000:0000 Bus 003 Device 007: ID 16c0:05dc <-- ต้องปรากฏบรรทัดนี้ (หมายเลข Bus และ Device อาจแตกต่างออกไป) Bus 003 Device 001: ID 0000:0000 Bus 002 Device 001: ID 0000:0000 Bus 001 Device 001: ID 0000:0000
ใช้คำสั่ง avrdude
avrdude -p atmega168 -c usbasp -u -U flash:w:first.hex