จำเป็นต้องมีความผันผวนหรือไม่เมื่อเข้าถึงตัวแปรจาก> 1 ISR แต่ไม่แชร์ภายนอก ISR


9

มีการบันทึกไว้อย่างชัดเจนว่าเมื่อมีการแบ่งปันข้อมูลทั่วโลกกับ ISR และโปรแกรมหลักข้อมูลจะต้องประกาศvolatileเพื่อรับประกันการมองเห็นหน่วยความจำ (และนั่นเพียงพอสำหรับข้อมูล 1 ไบต์เท่านั้นสิ่งที่ใหญ่กว่าต้องมีการจัดการพิเศษเพื่อรับประกันอะตอม . ที่นี่เรามีกฎระเบียบที่ดี:

  • ตัวแปรที่ใช้ภายนอก ISR เท่านั้นไม่ควรเปลี่ยนแปลงได้
  • ตัวแปรที่ใช้ภายใน ISR เท่านั้นไม่ควรเปลี่ยนแปลงได้
  • ตัวแปรที่ใช้ทั้งภายในและภายนอก ISR ควรมีความผันผวน

แต่volatileจำเป็นเมื่อมีการเข้าถึงตัวแปรจาก> 1 ISR แต่ไม่ได้ใช้ร่วมกันนอก ISR ตัวอย่างเช่นฉันมีฟังก์ชั่นที่รักษาสถานะภายในโดยใช้staticตัวแปร:

void func() {
    static volatile long counter; // volatile or not?
    // Do stuff with counter etc.
}

ฟังก์ชั่นนั้นเรียกว่าสองวิธี: จากการขัดจังหวะด้วยพินและจากไลบรารี TimerOne :

  1. attachInterrupt(0, func, CHANGE);
  2. Timer1.attachInterrupt(func);

ไม่มีปัญหา atomicity เนื่องจากเมื่อมีการป้อน ISR อินเทอร์รัปต์จะถูกปิดใช้งานโดยอัตโนมัติแต่นี่volatileเป็นคำถามคอมไพเลอร์มากกว่าสิ่งที่แคชและสิ่งที่ไม่

ปลอดภัยกว่าดีกว่าขออภัยแน่นอน ...

คำตอบ:


9

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

รหัส ISR จะต้องเขียน / สร้างขึ้นภายใต้สมมติฐานว่ามันไม่มีบริบทที่รายการและรักษาบริบทของ CPU รอบการดำเนินงานของตัวเอง (ISR) ดังนั้นเช่นเดียวกับการแยกการดำเนินการที่ไม่ใช่อะตอมความผันผวนขึ้นอยู่กับในกรณีนี้ *ว่าการขัดจังหวะจะได้รับอนุญาตหรือไม่ หากไม่รับประกันการซ้อนกันตัวแปรที่แชร์จะไม่สามารถเปลี่ยนแปลงได้นอกเหนือจาก ISR นี้ในระหว่างการดำเนินการของตัวเอง หากสักวันหนึ่ง ISR ของคุณอาจถูกใช้ในสภาพแวดล้อมที่อนุญาตให้ขัดจังหวะการซ้อนข้อ จำกัด นั้นจะไม่ถูกระงับอีกต่อไป

* ในกรณีนี้ :
ฉันสมมติว่าตัวแปรบำรุงรักษาซอฟต์แวร์อยู่ที่นี่ หากเรากำลังพูดถึงตัวแปรที่สามารถอัปเดตได้โดยเหตุการณ์ฮาร์ดแวร์ตัวจับเวลาลงทะเบียนเช่นการเดิมพันทั้งหมดจะปิด: ตัวแปรนั้นผันผวนไม่ว่าจะเกิดอะไรขึ้น


ดังนั้นตราบใดที่ฉันไม่เปลี่ยนค่าเริ่มต้นของ "การขัดจังหวะไม่ทำรัง" พฤติกรรมของ Arduino ตัวแปรก็ไม่จำเป็นvolatileเพราะมันไม่ได้ถูกแก้ไขโดยสิ่งอื่นใดนอกจากรหัสที่ถูกสร้างขึ้น คอมไพเลอร์สามารถ "สมมติ" ว่า ISR รันเป็นเส้นตรงและทำเช่นนั้นตราบใดที่อินเตอร์รัปต์ไม่ซ้อนกัน นั่นทำให้รู้สึก ขอบคุณ!
Joonas Pulakka
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.