กลไกบูทโหลดเดอร์และการโปรแกรมไมโครคอนโทรลเลอร์ผ่าน UART

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

ชิปไมโครคอนโทรลเลอร์ที่นำมาใช้นั้นต้องอาศัยการโปรแกรมผ่านเครื่องโปรแกรมชิป วิกินี้จะอธิบายถึงการเตรียมและบรรจุบูทโหลดเดอร์ลงไปในชิปเพื่อให้ตัวชิปสามารถโหลดโปรแกรมผ่านทางพอร์ทอนุกรมของคอมพิวเตอร์โดยไม่ต้องอาศัยเครื่องโปรแกรมชิปอีกต่อไป

บูทโหลดเดอร์สำหรับชิป AVR

ศึกษาเอกสารเกี่ยวกับ Self-Programming บนชิป AVR และดาวน์โหลดโปรแกรมตัวอย่างจากลิ้งค์ต่อไปนี้

ปรับแก้ไขการตั้งค่าของบูทโหลดเดอร์

โค้ดตัวอย่างจาก Atmel มาพร้อมกับเชลล์สคริปต์ preprocessor.sh (กรณีที่ใช้ยูนิกซ์) และไฟล์ Microsoft Excel preprocessor.xls (กรณีที่มีโปรแกรม Excel) ที่ใช้สำหรับสร้างไฟล์ defines.h ขึ้นมาเพื่อควบคุมการสร้างบูทโหลดเดอร์ให้สอดคล้องกับวงจรที่ออกแบบขึ้น เมื่อได้ไฟล์ defines.h แล้วให้เพิ่มคำสั่งสองบรรทัดนี้เข้าไปที่ท้ายสุดของไฟล์ เนื่องจากชิป ATMega168 ใช้ชื่อบิตสำหรับควบคุมการเขียน EEPROM ที่แตกต่างไปจากชิปตระกูล AVR เบอร์อื่น ๆ

#define EEMWE EEMPE
#define EEWE  EEPE

แก้ไขฟิวส์ของชิปไมโครคอนโทรลเลอร์

ชิป ATmega168 ต้องมีการปรับการตั้งค่าเพื่อให้ตัวชิปเริ่มต้นทำงานในพื้นที่บูทโหลดเดอร์แทนที่จะเริ่มทำงานในพื้นที่แอพลิเคชัน การตั้งค่าทำได้โดยการกำหนดค่าฟิวส์ในตัวชิปตามแผนผังด้านล่าง

---------------------------------------------------------------------
 ATMega88, ATMega168
---------------------------------------------------------------------
 Fuse extended byte:
 0x00 = 0 0 0 0   0 0 0 0 <-- BOOTRST (boot reset vector at 0x1800)
                    \+/
                     +------- BOOTSZ (00 = 2k bytes)
 Fuse high byte:
 0xd6 = 1 1 0 1   0 1 1 0
        ^ ^ ^ ^   ^ \-+-/
        | | | |   |   +------ BODLEVEL 0..2 (110 = 1.8 V)
        | | | |   + --------- EESAVE (preserve EEPROM over chip erase)
        | | | +-------------- WDTON (if 0: watchdog always on)
        | | +---------------- SPIEN (allow serial programming)
        | +------------------ DWEN (debug wire enable)
        +-------------------- RSTDISBL (reset pin is enabled)
 Fuse low byte:
 0xdf = 1 1 0 1   1 1 1 1
        ^ ^ \ /   \--+--/
        | |  |       +------- CKSEL 3..0 (external >8M crystal)
        | |  +--------------- SUT 1..0 (crystal osc, BOD enabled)
        | +------------------ CKOUT (if 0: Clock output enabled)
        +-------------------- CKDIV8 (if 0: divide by 8)
---------------------------------------------------------------------

บรรจุการตั้งค่าเหล่านี้ลงใน Makefile ที่มาพร้อมกับซอร์สโค้ด AVR109 โดยเพิ่มเติมบรรทัดที่ระบุว่า

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex

ให้เป็น

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -U hfuse:w:0xd6:m -U lfuse:w:0xdf:m -U efuse:w:0x00:m

Makefile ที่ให้มานั้นระบุโพรโทคอลสำหรับเครื่องโปรแกรมชิปไว้เป็น STK500 กรณีที่ใช้เครื่องโปรแกรมชิปแบบอื่นให้แก้ไขการตั้งค่าตัวแปร AVRDUDE_PROGRAMMER ให้ถูกต้อง

ดัดแปลงบูทโหลดเดอร์ให้แสดงผลบน LED

ซอร์สโค้ดบูทโหลดเดอร์ต้นฉบับนั้นไม่มีการสั่งให้แสดงผลใด ๆ เพื่อแสดงสถานะของบูทโหลดเดอร์ ให้ดัดแปลงไฟล์ main.c ดังแสดง

   if( !(PROGPIN & (1<<PROG_NO)) ) // If PROGPIN is pulled low, enter programmingmode.
   {
       // เพิ่มโค้ดให้แสดงสถานะการเข้าสู่บูทโหลดเดอร์บน LED
       :


คอมไพล์บูทโหลดเดอร์และบรรจุลงชิป

คอมไพล์บูทโหลดเดอร์ด้วยคำสั่ง make

make

จากนั้นต่อบอร์ดเข้ากับเครื่องโปรแกรมชิป แล้วสั่งอัพโหลดบูทโหลดเดอร์ลงชิปด้วยคำสั่ง

make program

ใช้งานบูทโหลดเดอร์

เมื่อชิปไมโครคอนโทรลเลอร์บรรจุบูทโหลดเดอร์เอาไว้แล้วจะสามารถสั่งให้เข้าสู่บูทโหลดเดอร์เพื่อโปรแกรมตัวเองได้โดยไม่ต้องอาศัยเครื่องโปรแกรมชิปโดยการทำให้ชิปอยู่ในสถานะที่ตรงกับเงื่อนไขที่กำหนดเอาไว้ใน defines.h (เช่นกดสวิตช์หรือเสียบจั๊มเปอร์ค้างไว้) ในระหว่างที่กดรีเซ็ท บูทโหลดเดอร์จะสื่อสารกับคอมพิวเตอร์ด้วยอักขระคำสั่งผ่านพอร์ทอนุกรม เราจึงสามารถเขียนโปรแกรมที่อ่านรหัสภาษาเครื่องจากไฟล์ .hex เพื่อส่งไปเขียนบนหน่วยความจำแฟลชของไมโครคอนโทรลเลอร์ได้โดยง่าย

อย่างไรก็ตามเนื่องจากซอฟต์แวร์ avrdude มีความสามารถในการสื่อสารกับบูทโหลดเดอร์ตามเอกสาร AVR109 อยู่แล้ว จึงสามารถใช้ avrdude โปรแกรมชิปได้ทันทีโดยระบุโพรโทคอลการสื่อสารเป็น avr109 ดังตัวอย่าง

avrdude -p atmega168 -c avr109 -P /dev/ttyUSB0 -U flash:w:first.hex:i