AVR EEPROM'u doğrudan C kaynağından programlayın


11

Aşağıdaki kodu bir AVR C kaynağına eklediğinizde, ekstra bir komut veya .hex dosyasına ihtiyaç duymadan sigortaları doğrudan programlayabilirsiniz:

#include <avr/io.h>

FUSES = {
        .low =          LFUSE_DEFAULT ,
        .high =         HFUSE_DEFAULT ,
        .extended =     EFUSE_DEFAULT ,
};

EEPROM'daki değerleri programlamak için benzer bir hile var mı?

/usr/lib/avr/include/avr/fuse.hBir makro hakkında bazı yorumları nerede bulabileceğimi kontrol ettim, ancak benzer bir yorum bulamıyorum /usr/lib/avr/include/avr/eeprom.hve önişlemci şeylerini yorumlamak benim ligimin biraz dışında.

C kaynak koduna varsayılan EEPROM değerlerini ekleyebilirsem gerçekten kullanışlı olurdu. Bunu nasıl başaracağını bilen var mı?

edit1:

Bu SİGORTALAR hile yalnızca ISS zamanında yürütülür, RUN zamanında çalıştırılmaz. Dolayısıyla, kontrolörde ortaya çıkan montaj kodunda programlanmış sigorta yoktur. Bunun yerine programcı otomatik olarak ekstra FUSES programlama döngüsünde geçer.

edit2:

Linux'ta avr-gcc ve avrdude araç zincirini kullanıyorum.


Bu sadece ISS'yi programlarken mi? Çoğu önyükleyici sigortaları programlamanıza izin vermez, değil mi?
Mart'ta angelatlarge

2
Şu anda tam bir cevap yazmak için zamanım yok, ancak bir ipucu olarak EEMEM yönergesinde bir arama yapmayı deneyin. Ayrıca, programcının kullanacağı ayrı bir .EPP dosyası oluşturmak için bağlayıcı ayarını değiştirmeniz gerekebilir.
PeterJ

@angelatlarge Yalnızca ISS programlama. Bu kurulumda önyükleyici yok.
jippie

2
Buna verilen yanıtların tamamen araç zincirinin çıktısında ne kaydetmek istediğine ve programcının neyi ayrıştırmak istediğine bağlı olduğunu unutmayın. Çoğu araç zinciri özel bir bölüm oluşturacak şekilde yapılandırılabilir (ya da verileri hayali bir adrese koyabilir), bu yüzden sonuçta programcı ya onu ayıklayabilen ya da bunu yapacak özel bir komut dosyasıyla sürülebilene kadar gelir.
Chris Stratton

Yanıtlar:


7

Avr-gcc ile EEMEMmakro bkz değişkenin tanımı kullanılabilir libcdokümanlar ve bir örnek burada :

#include <avr/eeprom.h>
char myEepromString[] EEMEM = "Hello World!";

".eeprom" adlı bir bölümde yer alan karakter dizisini bildirir. Derleme sonrasında programcıya bu verilerin EEPROM'a programlanacağını söyler. Programcı yazılımınıza bağlı olarak, derleme işlemi sırasında oluşturulan ".eep" -file adını programcıya açık bir şekilde vermeniz gerekebilir veya bunu kendiliğinden bulabilir.


Ben 'beklediğimden biraz farklı bir dosya adı kullandım, ama bunlar komut satırından (ve makefile) EEPROM programlamak için dahil ettiğim komutlar:
jippie

1
Programcı tarafından kullanılan Intel Hex verilerini içeren bir dosya oluşturun:avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ihex $(src).elf $(src).eeprom.hex
jippie

1
Gerçek programlama şu şekilde yapılır:avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
jippie

7

Evet, kaynak verileri EEPROM'a varsayılan verileri elle yazabilirsiniz. İlk olarak, AVR ile Dean'in AVR EEPROM Öğreticisi ile bu harika rehbere göz atın. Ayrıca, kaynak kodu ile birlikte cihaza programlanacak makefile kullanarak EEPROM verilerini içeren bir .eep dosyası oluşturmak için daha iyi bir fikir olduğunu eklemeliyim. Bununla birlikte, çeşitli makefile ve linker işlemlerine aşina değilseniz, yine de kaynak kodu dosyanızdan yapılabilir - sadece devreye güç verilir verilmez, ilk program işlemini durdurur.

Programın başında (herhangi bir ana döngüden önce) böyle bir şey yapabilirsiniz:

#include <avr/eeprom.h>

#define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_2 52  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_3 68  // This could be anything from 0 to the highest EEPROM address

uint8_t dataByte1 = 0x7F;  // Data for address 1
uint8_t dataByte2 = 0x33;  // Data for address 2
uint8_t dataByte3 = 0xCE;  // Data for address 3

eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);

"Güncelle" fonksiyonu önce bu değerin zaten mevcut olup olmadığını kontrol eder, gereksiz yazmalardan tasarruf etmek için EEPROM ömrünü korur. Ancak, bunu çok fazla yer için yapmak biraz zaman alabilir. Tek bir konumu kontrol etmek daha iyi olabilir. İstenen değer ise, güncellemelerin geri kalanı tamamen atlanabilir. Örneğin:

if(eeprom_read_byte((uint8_t*)SOME_LOCATION) != DESIRED_VALUE){
  eeprom_write_byte((uint8_t*)SOME_LOCATION, DESIRED_VALUE);
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
  eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
  eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);
}

Büyük miktarda veriyi güncellemek istiyorsanız, gibi diğer işlevleri kullanmayı deneyin eeprom_update_block(...). Ve kesinlikle bu eğitimi okuyun; iyi yazılmış.

Tüm EEPROM güncelleme ifadelerini tek bir önişlemci koşullu ifadesine koyabilirsiniz. Bunu yapmak çok basit:

#if defined _UPDATE_EEPROM_
  #define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
  uint8_t dataByte = 0x7F;  // Data for address 1
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
#endif // _UPDATE_EEPROM_

Aşağıdakileri yapmadığınız sürece bu kod biti derlenmeyecektir:

#define _UPDATE_EEPROM_

Bunu orada bir yorum olarak bırakabilir, ardından varsayılan EEPROM değerlerini değiştirmeniz gerekirse bu seçeneği kaldırabilirsiniz. C önişlemcisi hakkında daha fazla bilgi için bu çevrimiçi kılavuza bakın . Bence en çok makrolar ve koşullu ifadeler ile ilgilenebilirsiniz.


Doğru yanıt, bağlantılı PDF'nin son paragrafında gibi görünüyor. Ch. 7 Setting Initial Values.
jippie

Evet haklısın. İlk paragrafımda bahsetmiştim, ancak .eep dosyalarını ve makefile'deki bağlayıcıyı bilmiyorsanız devam etti!
Kurt E. Clothier

1
Statik EEPROM adreslerini kullanmak kötü bir uygulamadır. Bunun yerine EEMEM özniteliğini kullanmak ve derleyicinin adres dağıtımını yönetmesine izin vermek daha iyidir. Ayrıca, her bölüm üzerinde bir CRC kontrolü uygulamak / gerçekleştirmek için tavsiye ederim. CRC başarısız olursa, ilgili bölüm başlatılmamış veya bozuk veriler içerir. Bu şekilde, verilerin bozulması durumunda önceki yapılandırmaya bir yedek mekanizma bile uygulayabilirsiniz.
Rev1.0

"Statik EEPROM adreslerini kullanmak kötü bir uygulamadır." Neden?
angelatlarge

1
EEMEMDeğişkenleri kullanırken derleyici, hangi değişkenin EEPROM'da nerede olduğunu yönetmeye özen gösterir. Bu şekilde, verilere erişirken değişkenlere yalnızca (sabit, derleyici tarafından oluşturulan) işaretçiler üzerinde işlem yaparsınız. Öte yandan, her bir değişkenin ikamet ettiği adresi açıkça tanımlarsanız, bu adreslerle kendiniz ilgilenmeniz gerekir; bunlardan hiçbirinin yanlışlıkla aynı adresi işgal etmediğinden emin olmak, birbirlerinin üzerine yazmak; veya bir değişkenin depolama boyutunun gelecekte değişmesi durumunda tüm adresleri yeniden hesaplama vb.
JimmyB
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.