การประกาศตัวแปรด้วย @ ใน C


11

ฉันกำลังอ่านโค้ด C และพบคำประกาศนี้ในโปรแกรม:

unsigned char serv_ctr @0x0002;

ใครสามารถชี้ให้ฉันดูเอกสารประกอบหรืออธิบายว่า"@ 0x0002"สำหรับอะไรในคอมไพเลอร์ Mplab XC8 v1.35 C


14
ฉันเดาว่ามันเป็นส่วนขยายของคอมไพเลอร์เพื่อวางตัวแปรที่ที่อยู่เฉพาะ
ยูจีน Sh.

2
คำถามอาจเป็นประโยชน์ต่อแท็ก #mplab เนื่องจากปรากฏว่านี่เป็นข้อมูลเฉพาะของ Mplab
sylvainulg

เพื่อรับมัน: นี่เป็นหัวข้อในเว็บไซต์นี้หรือไม่? ฉันคิดว่านี่เป็นของ SO หรือว่าไม่เป็นไรที่จะขอโปรแกรม micro controler ที่นี่ นี่จะทำให้ชัดเจนเล็กน้อยว่าคำถามนี้ควรอยู่ที่ไหน
ลา SE

6
@KamiKaze ฉันสามารถขอหัวข้ออะไรได้บ้างที่นี่? แสดงรายการ "การเขียนเฟิร์มแวร์สำหรับแอปพลิเคชันโลหะเปลือยหรือ RTOS" ตามหัวข้อและ "ซอฟต์แวร์โปรแกรมสำหรับพีซี" เป็นหัวข้อปิด เนื่องจากสิ่งนี้ดูเหมือนจะเกี่ยวกับการเขียนโปรแกรมระบบฝังตัวมันจะปรากฏขึ้นอย่างรวดเร็วในหัวข้อ ว่ามันอาจยังจะอยู่ในหัวข้อกองมากเกินไม่ได้ด้วยตัวเองทำให้มันปิดหัวข้อที่นี่
CVn

@ KamiKaze ขอบคุณที่ถามฉันมีคำถามที่คล้ายกัน (ฉันไม่ใช่ผู้ใช้ปกติของ SE นี้)
GPPK

คำตอบ:


20

นี่คือการระบุที่อยู่ที่แน่นอนที่จะวางตัวแปรที่
จากคู่มือคอมไพเลอร์ XC8หน้า 27, ส่วน 2.5.2 การระบุที่อยู่แบบสัมบูรณ์ :

ตัวแปรและฟังก์ชั่นสามารถวางไว้ที่ที่อยู่ที่แน่นอนโดยใช้__at()โครงสร้าง
......
2.5.2.2 ความแตกต่าง
คอมไพเลอร์ 8 บิตได้ใช้สัญลักษณ์ @เพื่อระบุที่อยู่ที่แน่นอน


6

@เป็นส่วนขยายที่ไม่ได้มาตรฐานสำหรับภาษา C ซึ่งช่วยให้คุณสามารถประกาศตัวแปรที่อยู่เฉพาะ สามารถใช้สำหรับการลงทะเบียนฮาร์ดแวร์ที่แมปหน่วยความจำเป็นต้นซึ่งในกรณีนี้จะต้องประกาศตัวแปรด้วยvolatileดังนั้นตัวอย่างของคุณไม่ถูกต้อง

คอมไพเลอร์อื่น ๆ ใช้สิ่งที่คล้าย__attribute__(section...หรือ#pragma ...ทั้งหมดนั้นไม่ใช่ซีมาตรฐาน

เหตุผลเดียวที่มีเหตุผล (ถ้ามี) ทำไมโซ่เครื่องมือถึงทำเช่นนี้คือการเปิดใช้งานการดีบักลงทะเบียนกับ debuggers เส็งเคร็ง ไวยากรณ์ที่ไม่ได้มาตรฐานจะช่วยให้มั่นใจว่าการลงทะเบียนกลายเป็นส่วนหนึ่งของเอาต์พุต linker และข้อมูลการดีบัก ซึ่งจะช่วยให้คุณสามารถดูการลงทะเบียนในดีบักเกอร์ได้เช่นเดียวกับที่คุณสามารถดูตัวแปรอื่น ๆ

หากคุณมีดีบักเกอร์ที่ดีจะมีการสนับสนุนและการรับรู้ของ MCU ที่เฉพาะเจาะจงของคุณ จากนั้นคุณไม่จำเป็นต้องใช้อึที่ไม่ได้มาตรฐานในรหัส C แต่คุณสามารถเขียน C มาตรฐานแบบพกพาที่บริสุทธิ์แทน:

#define serv_ctr ( *(volatile uint8_t*)0x0002u )

1
ในขณะที่คอมไพเลอร์จะต้องยอมรับแบบฟอร์มหลังการใช้งานจะได้รับอนุญาตให้แมปหมายเลขไปยังที่อยู่ในลักษณะที่เหมาะสม ยิ่งไปกว่านั้นคอมไพเลอร์ส่วนใหญ่ที่ฉันเคยเห็นใช้@แพลตฟอร์มสัญกรณ์เป้าหมายที่มีพื้นที่หน่วยความจำหลายแห่งหรือปัญหาอื่น ๆ ดังนั้นสิ่งที่ประกาศโดยใช้@สัญกรณ์ส่วนใหญ่จะทำงานแตกต่างจากสิ่งที่สามารถทำได้
supercat

1

นามสกุลสั้น:

สิ่งนี้ไม่ทำงานอีกต่อไปตั้งแต่ xc8 2.0 ขึ้นไป ตอนนี้คุณต้องเขียน:

unsigned char serv_ctr __at(0x0002);

เพื่อใส่ตัวแปร ( serv_ctr) ที่ที่อยู่แบบสัมบูรณ์ ( 0x0002)

ด้วย XC8 2.0 คุณสามารถรวบรวมรหัสเก่าของคุณโดยใช้@ไวยากรณ์ได้หากคุณตั้งค่าคอมไพเลอร์ให้ใช้รูปแบบ "C90" การตั้งค่ามีลักษณะดังนี้ภายใต้ "XC8 Global Options" และเรียกว่า "C standard"


คอมไพเลอร์ระบบฝังตัวอื่น ๆ จำนวนมากสนับสนุน@ไวยากรณ์เช่นกัน
Lundin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.