Deklarasi variabel dengan @ dalam C

11

Saya membaca beberapa kode C dan menemukan deklarasi ini dalam program:

unsigned char serv_ctr @0x0002;

Dapatkah seseorang mengarahkan saya ke dokumentasi, atau menjelaskan untuk apa "@ 0x0002" untuk dalam kompiler Mplab XC8 v1.35 C?

jadilah
sumber
14
Saya kira itu adalah ekstensi kompiler untuk menempatkan variabel pada alamat tertentu.
Eugene Sh.
2
pertanyaannya mungkin bermanfaat bagi tag #mplab, karena ternyata ini khusus untuk Mplab.
sylvainulg
Hanya untuk mendapatkannya: Apakah ini tentang topik di situs ini? Saya akan berpikir bahwa ini milik SO. Atau tidak apa-apa untuk meminta pemrograman pengontrol mikro di sini. Ini akan membuatnya sedikit tidak jelas di mana pertanyaan ini seharusnya.
Selamat tinggal
6
@KamiKaze Topik apa yang bisa saya tanyakan di sini? mencantumkan "penulisan firmware untuk aplikasi bare-metal atau RTOS" seperti pada topik, dan "Pemrograman perangkat lunak untuk PC" sebagai topik tidak resmi. Karena ini tampaknya tentang pemrograman sistem tertanam, maka akan tampak pada topik. Bahwa itu mungkin juga pada topik di Stack Overflow tidak dengan sendirinya membuatnya menjadi topik di sini.
CVn
@KamiKaze terima kasih telah bertanya, saya punya pertanyaan serupa (Saya bukan pengguna reguler SE ini)
GPPK

Jawaban:

20

Ini untuk menentukan alamat absolut untuk menempatkan variabel di.
Dari buku panduan kompiler XC8 halaman 27, bagian 2.5.2 Mengatasi Absolut :

Variabel dan fungsi dapat ditempatkan pada alamat absolut dengan menggunakan __at()konstruk
......
2.5.2.2 PERBEDAAN Kompiler
8-bit telah menggunakan simbol @ untuk menentukan alamat absolut

Eugene Sh.
sumber
6

@adalah ekstensi non-standar umum untuk bahasa C yang memungkinkan Anda untuk mendeklarasikan variabel di alamat tertentu. Ini dapat digunakan untuk register perangkat keras yang dipetakan oleh memori dll. Dalam hal ini variabel juga harus dideklarasikan volatile, jadi contoh Anda salah.

Kompiler lain menggunakan sesuatu seperti __attribute__(section...atau #pragma ..., semuanya non-standar C.

Satu-satunya alasan rasional (jika ada) mengapa rantai alat melakukan ini, adalah untuk mengaktifkan debugging register pada debugger jelek. Sintaks non-standar akan memastikan bahwa register menjadi bagian dari output linker dan info debug. Yang pada gilirannya memungkinkan Anda untuk menonton register di debugger jelek seperti Anda dapat menonton variabel lain.

Jika Anda memiliki debugger yang baik, itu akan memiliki dukungan dan kesadaran MCU spesifik Anda. Maka Anda tidak perlu omong kosong non-standar dalam kode C, tetapi Anda dapat menulis murni, portabel standar C sebagai gantinya:

#define serv_ctr ( *(volatile uint8_t*)0x0002u )
Lundin
sumber
1
Sementara kompiler diminta untuk menerima formulir yang terakhir, implementasi diizinkan untuk memetakan nomor ke alamat dengan cara apa pun yang mereka anggap tepat. Lebih lanjut, kebanyakan kompiler yang pernah saya lihat menggunakan @platform target notasi dengan beberapa ruang memori atau masalah lain sehingga sebagian besar hal yang dinyatakan menggunakan @notasi akan berperilaku berbeda dari apa pun yang dapat dilakukan tanpa ekstensi.
supercat
1

Perpanjangan singkat:

Ini tidak lagi berfungsi sejak xc8 2.0 dan lebih tinggi. Anda sekarang harus menulis:

unsigned char serv_ctr __at(0x0002);

untuk meletakkan variabel ( serv_ctr) di alamat absolut ( 0x0002).

Dengan XC8 2.0 dimungkinkan untuk mengkompilasi kode lama Anda menggunakan @sintaks jika Anda mengatur pengaturan kompiler untuk menggunakan format "C90". Pengaturannya terlihat seperti ini, berada di bawah "XC8 Global Options" dan disebut "C standard".

Mike
sumber
Banyak kompiler sistem embedded lainnya mendukung @sintaks juga, bukan hanya Mplab.
Lundin