ว่าด้วยเรื่องหน่วยความจำ สิ่งที่หลายคนมองข้าม : Stack Overflow & EEPROM
ตอนนี้ก็ดำเนินการมาถึงตอนที่ 4 เรียบร้อยแล้ว ใกล้จบแล้ว ๆ คิดว่าคงไม่เกิน 5 ตอนหรอกมั้ง (ฮ่า ๆ) เพราะยังเหลือเรื่อง EEPROM แล้วก็การ Optimize code กันอีกนิดหน่อย
แต่ก่อนจะเริ่มเนื้อหาถัดไป อยากพูดเรื่อง stack overflow อีกนิดนึง เพิ่มเติมจากบทความก่อนหน้านี้ ซึ่งเป็นตัวอย่างปัญหาที่เกิดขึ้นจากการใช้ Very deep recursion การเรียก function ซ้ำ ๆ ที่มีความลึกมากเกินไป บางทีอาจจะต้องใช้เวลาค่อนข้างนาน กว่าที่ program จะประมวลผลเสร็จ เดี๋ยวเจ้าของบล็อกจะลองเขียนกับ ESP8266 12e ดูนะว่าจะมีผลยังไง
เดี๋ยวเรามาดูว่าผลลัพธ์จะเป็นยังไง
ส่ง 10 เข้าไปใน Fibonacci function |
โอเคผลลัพธ์ก็จะออกมาประมาณนี้นะครับ จะยังเห็นว่า process การทำงานยังใช้เวลาไม่ถึง 1 วินาทีเลย ใครที่สงสัยเรื่อง fibonacci อ่านเพิ่มเติม ตรงนี้ได้นะ ทีนี้เราลองมาค่อย ๆ เพิ่มค่าที่จะส่งไปให้ดีกว่า
ส่ง 20 เข้าไปใน Fibonacci function |
ส่ง 30 เข้าไปใน Fibonacci function |
โอ้วว มาถึงตรงนี้ โปรแกรมมันใช้เวลาประมวลผลเกือบครึ่งวินาทีเลยแฮะ แต่ยัง ยังไม่หมดหรอก เราจะลองต่อกันไปเรื่อย ๆ
ส่ง 40 เข้าไปใน Fibonacci function |
ก็เป็นอีก 1 ตัวอย่างที่ค่อนข้างเจอบ่อยกับตัว ESP8266 การเขียน call stack ที่ลึกมาก ๆ จนทำให้มีผลกับเวลาที่ใช้ในการประมวลผล จะเกิดปัญหา wdt reset ขึ้นบ่อย เพราะฉะนั้นการเขียนโปรแกรมจึงค่อนข้างที่จะละเอียดอ่อน และพยายามให้ optimize อยู่เสมอ
EEPROM
ในบทความ ว่าด้วยเรื่องหน่วยความจำ สิ่งที่หลายคนมองข้าม ตอนที่ 1 ได้อธิบายไปแล้วว่า EEPROM เป็นหน่วยความจำแบบ non-volatile memory หรือก็คือเป็นหน่วยความจำถาวร ข้อดีของมันคือสามารถอ่านเขียนข้อมูลได้ในขณะที่โปรแกรมกำลังทำงาน แต่ก็ยังช้ากว่า SRAM อยู่มาก เพราะฉะนั้นการเก็บข้อมูลลงใน EEPROM จะเป็นการเก็บข้อมูลที่ไม่ได้ถูกใช้บ่อยมาก และไม่เหมาะกับการเก็บข้อมูลแบบ Stream เช่นการรับข้อมูล package จาก Serrial ตรง ๆ
โดยปรกติแล้วเจ้าของบล็อกมักจะเก็บค่าสถานะหรือ state ของโปรแกรมไว้ใน EEPROM เพราะเผื่อว่า เกิดกรณีที่ไฟดับ หรือ Microcontroller มีปัญหาอะไรบางอย่าง ทำให้เกิดการ reset ขึ้น ตัว Microcontroller เองก็จะดึงข้อมูล state จาก EEPROM เพื่อให้โปรแกรมพร้อมทำงานต่อจาก state เดิมล่าสุดที่ถูกเก็บไว้
https://www.arduino.cc/en/Reference/EEPROM |
ก็นึกไม่ค่อยออกหรอกว่าปัญหาใน EEPROM มันจะมีอะไรบ้าง ก็จะอ้างอิงจากประสบการณ์ตรงของเจ้าของบล็อกเลยก็แล้วกัน ฮ่า ๆ
Clear buffer ใน EEPROM ก่อนนน
ปัญหาจากที่ไม่ได้ clear buffer ใน EEPROM ก่อนจะมาใช้งาน คือบางที ก่อนหน้านี้เจ้าของบล็อกเคยใช้เขียนเกี่ยวกับ EEPROM ของอีกงานนึง เสร็จแล้วก็ไม่ได้ทำไรต่อ นาน ๆ ไปก็ลืมแล้วว่าเคยเขียน EEPROM ไว้กับ board ไหนบ้าง พอจะเอามาใช้งานอีกครั้ง ก็เขียนโปรแกรมเผลอไปอ่านค่าใน address ซักที่ แล้วมันได้เป็นค่า EEPROM ของงานก่อนหน้า เพราะงั้นก่อนที่เราจะใช้งาน EEPROM เราควร Clear buffer ออกก่อน ซึ่งตรงนี้เจ้าของบล็อกไม่อธิบายละกันเพราะไม่ได้ยากมากและก็มีคนอธิบายเยอะแล้วด้วย เพราะฉะนั้นก็ไปอ่านต่อในนี้เอาแล้วกันนะ :) EEPROM Clearระวังสับสน EEPROM ของ Arduino Library กับ ESP8266 Library ไม่เหมือนกัน !!
เนื่องจากว่า Chip IC ของทั้งสองตัวนี้อยู่คนละตะกูลกัน การเขียนโปรแกรมให้เข้าถึง hardware จึงต่างกัน เพราะฉะนั้นอาจจะทำให้เราสับสนได้ตอนเรียกใช้งาน function
ข้างบนนี้เป็น function ที่มีใน EEPROM ของ ESP8266 library
ส่วนอันนี้เป็น function ที่มีใน EEPROM ของ Arduino library
สิ่งที่แตกต่างกันคือ ESP8266 จะต้องบอกขนาด size ตอนเริ่มทำงานด้วยโดยใช้คำสั่ง begin ถ้าไม่ใช้คำสั่งนี้จะไม่สามารถเข้าถึงการใช้งาน EEPROM ได้เลย และที่แตกต่างอีกอย่างคือ เมื่อเรา write ข้อมูลลงใน EEPROM แล้วเราต้อง commit() มันทุกครั้งด้วย ถ้าไม่ commit มันก็ถือว่ายังไม่ได้เขียนข้อมูลลง EEPROM
แต่เมื่อมาดู EEPROM ในส่วนของ arduino lirbrary แทบจะไม่ต้องทำอะไรเลย แค่ write read ก็ได้ละ เพราะใน library มันจะไปเช็คเองว่า EEPROM ใน chip มันมีขนาดเท่าไหร่ เออง่ายดี
ตอนนี้ปัญหาที่นึกออกก็มีแค่นี้แหละฮะ ไว้ไปต่อกันบทความหน้า เกี่ยวกับการ optimize code กัน แต่ไม่รู้ว่าจะ optimize ได้แค่ไหนนะ ฮ่า ๆ ก็เช่นเดิม ถ้าหากมีอะไรสงสัยก็ comment ถามได้ หรือช่วย feedback กลับมาด้วยจะดีมากเพื่อเป็นการปรับปรุงเนื้อหาไปในตัว
อ่านตอนต่อไปได้ที่ ว่าด้วยเรื่องหน่วยความจำ สิ่งที่หลายคนมองข้าม ตอนที่ 5
reference : EEPROM Library , Memory of an arduino
ความคิดเห็น
แสดงความคิดเห็น