หลาย ๆ ท่านที่กำลังเขียนโปรแกรมหรือเคยเรียนเขียนโปรแกรมมาอาจจะรู้จักกันดีกับฟังก์ชันที่ชื่อว่า main ซึ่งในภาษา C นั้น ฟังก์ชัน main มักจะถูกบอกกล่าวว่าเป็นจุดเริ่มต้นของการทำงานโปรแกรม จริง ๆ แล้วในเชิงลึกนั้น โปรแกรมนั้นไม่ได้เริ่มจาก ฟังก์ชัน main แต่จะเริ่มจากสิ่งที่เรียกว่า startup routine ซึ่งเจ้าสิ่งนี้แหละเป็นส่วนสำคัญต่อการทำให้โปรแกรมทำงานครับ ทั้งนี้ผู้เขียนได้นำบทความที่น่าสนใจของเรื่องนี้จากต่างประเทศ มาแปลให้ผู้ที่สนใจได้อ่านกันครับ
สงสัยจริง ๆ ก่อนฟังก์ชัน main มีอะไร?
การเขียนโปรแกรมโดยใช้ภาษา C บน Windows หรือ Linux/UNIX จะเขียนโปรแกรมตั้งแต่ในฟังก์ชัน main เป็นต้นไป อย่างไรก็ตาม ดังที่กล่าวขั้นต้นโปรแกรมไม่ได้เริ่มต้นด้วยฟังก์ชัน main ก่อนหน้าฟังก์ชัน main นั้นจะมีสิ่งที่เรียกว่า startup routine อยู่ครับ
ในเชิงงาน embedded หรือ งานที่เกี่ยวข้องกับบอร์ด microcontroller จำเป็นต้องทำความเข้าใจ startup routine เพื่อให้โปรแกรมทำงาน อีกทั้งในบางครั้งการดีบักโปรแกรมโดยที่ไม่รู้ว่า startup routine มีการทำงานอะไรอยู่อาจไม่ใช่เรื่องดีนักยิ่งเป็นงานที่เกี่ยวข้องกับ microcontroller ด้วย
เมื่อเปิดเครื่องเราก็จะเรียก startup routine ขึ้นมายังไงล่ะ
โปรแกรมในเชิง embedded โดยปกติมักจะทำงานบน microcontroller การทำงานของ startup routine นั้น เมื่อ microcontroller เริ่มทำงาน การทำงานจะแตกต่างกันไปตาม processor นั้น ๆ แต่โครงสร้างลักษณะจะมีความคล้ายกันหากเพื่อน ๆ เข้าใจคอนเซปต์จากตัวอย่างที่อธิบาย ก็จะสามารถนำไปต่อยอดได้ครับ
อ้างอิง URL
เมื่ออุปกรณ์หรือบอร์ดเริ่มทำงาน กล่าวคือ เมื่อเปิดเครื่องหรือกดปุ่มรีเซ็ต ตัว processor จะถูกบังคับให้รีเซ็ต ((1) ในรูปข้างต้น) สิ่งนี้จะเรียกว่าการขัดจังหวะ (interrupt) เป็นการขัดจังหวะการทำงานคำสั่งบังคับสำหรับให้ processor นั้น “ทำงานจากสถานะเริ่มต้น ไม่ว่าสถานะปัจจุบันจะเป็นอย่างไร” เมื่อการขัดจังหวะแบบบังคับรีเซ็ตเข้ามา processor จะอ่านข้อมูลจากในแอดเดรสที่ถูกกำหนดไว้ (กำหนดให้เป็นรีเซ็ตในพื้นที่ memory พิเศษของบอร์ดนั้น ๆ เราจะเรียกว่า reset vector) โดยข้อมูลการทำงานใน reset vector จะแตกต่างกันไปตาม processor ที่ใช้
ภายใน reset vector จะมีคำสั่งจัมพ์ (Jump)ไปแอดเดรสที่กำหนดซึ่งแอดเดรสปลายทางมีข้อมูลหรือโปรแกรมที่จะรันอยู่ครับ ถ้าหากปลายทางเนื้อหาที่เขียนเป็นโปรแกรม โปรแกรมจะถูกสั่งให้ทำงานขึ้นมา และการควบคุมก็จะถูกโอนย้ายไปที่แอดเดรสนั้นเช่นเดียวกัน สรุปได้ง่าย ๆ ว่าโปรแกรมจะถูกรันขึ้นมาด้วยหลักการนี้ครับ โปรแกรมที่ถูกรัน ณ เวลานี้ จะถูกเรียกว่า startup routine นั่นเองครับ
เอ๊ะ! แล้ว startup routine ข้างใน มีอะไรบ้างนะ ?
startup routine จะทำงานเริ่มต้นก่อนการรันโปรแกรม C ขึ้นมา เมื่อพัฒนาโปรแกรมแอปพลิเคชันบน Windows หรือ Linux/UNIX เพื่อน ๆ จะไม่รับรู้ถึงการมีอยู่ของ startup routine เลย เนื่องจากสภาพแวดล้อมการทำงานของโปรแกรมจะเหมือนกันเสมอ (ไม่จำเป็นต้องเปลี่ยนในแต่ละครั้ง) และ compiler C จะเชื่อมโยง startup routine เข้ากับระบบโดยอัตโนมัติ (บนระบบ UNIX นั้น startup routine คือ ไลบรารีมาตรฐาน ซึ่งอยู่ด้วยกันภายใต้ชื่อ crt0.o)
อย่างไรก็ตามในเชิง embedded นั้นมีอุปกรณ์ต่าง ๆ ที่เชื่อมอยู่ หรือ memory ที่มีขนาดที่หลากหลายมากหน้าหลายตาแตกต่างกันไปค่อนข้างเยอะ การประมวลผลเองก็จะแตกต่างกันไปตามอุปกรณ์
นอกจากนี้ วิธีการ initialize ของอุปกรณ์ยังแตกต่างกันไปตาม processor ที่ใช้ ดังนั้น startup routine จึงมีความสำคัญอย่างมาก อย่างที่บอกกับผู้อ่านไปข้างต้นว่าเราไม่สามารถสร้างโปรแกรม embedded ได้หากเรายังไม่เข้าใจ startup routine ครับ
เรามาดูกันดีกว่าครับว่า startup routine นั้นทำอะไรกันบ้าง
1. การตั้งค่า stack
2. การตั้งค่าข้อมูลที่จำเป็นสำหรับการทำงานของโปรแกรม
3. ถ่ายโอนข้อมูลโปรแกรมจากพื้นที่ ROM ไปยังพื้นที่ RAM
3.1 การเคลียร์พื้นที่ memory ที่ไม่ได้มีค่าเริ่มต้นเป็น 0
4. การตั้งค่าโหมดการทำงานของไมโครคอมพิวเตอร์
5. การเริ่มต้นของ registers ต่าง ๆ สำหรับการใช้ฟังก์ชันที่มีอยู่ในไมโครคอมพิวเตอร์
6. การเริ่มต้นทำงานฮาร์ดแวร์
7. การตรวจสอบสถานะฮาร์ดแวร์
stack เป็นพื้นที่ RAM สำหรับตัวแปรที่จำเป็นเมื่อเรียกใช้โปรแกรม อีกทั้งตัว startup routine มักจะกำหนดใช้พื้นที่ stack เช่นกัน นอกจาก stack แล้วค่าคงที่และตัวแปร global ยังจำเป็นสำหรับการทำงานของโปรแกรม สิ่งเหล่านี้จะต้องเริ่มต้นหรือเคลียร์ค่าเป็น 0
ต่อมาค่าคงที่บางค่าอาจต้องอ้างอิงจาก ROM และคัดลอกไปยัง RAM นั่นคือการถ่ายโอนข้อมูลค่าจากพื้นที่ ROM ไปยังพื้นที่ RAM
จาก (4) ในรูปข้างต้น startup routine ถูกเขียนขึ้นเพื่อเรียกใช้ฟังก์ชันหลักของโปรแกรมภาษา C โดยตรง แต่เมื่อใช้ไลบรารีมาตรฐานภาษา C จะต้องดำเนินการ Initialization ไลบรารีมาตรฐานด้วย
นอกเหนือจากการรันซอฟต์แวร์เองแล้ว จำเป็นต้องมีการเริ่มต้นเพื่อใช้ processor และฮาร์ดแวร์อื่น ๆ การเริ่มต้นเหล่านี้ถูกเข้ารหัส ซึ่งจะต้องอ้างอิงกับเอกสารของ processor และฮาร์ดแวร์นั้น ๆ
หลังจากการเตรียมการเบื้องต้นเหล่านี้เสร็จเรียบร้อยแล้ว ฟังก์ชัน main ของโปรแกรมก็จะถูกเรียกขึ้นมานั่นเองครับ ((4) ในรูปข้างต้น)
สำหรับบทความ ก็จะขอจบเพียงเท่านี้นะครับ ขอขอบคุณบทความดีๆจาก http://www.kumikomi.net/ ด้วยครับ
Reference : http://www.kumikomi.net/archives/2003/05/10kumi.php?page=7