Atmel Studio etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Atmel Studio etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Atmega328p Benzersiz Seri Numarası, Kod koruma

     



    Arduino UNO üzerinde bulunan mikrodenetleyici : atmega328p-u  kullanarak bir kod yazdık, derledik, bir hex dosyamız var, yazdığımız kodun, sadece "herhangi bir" atmega328p-u üzerinde çalışmasını istiyoruz, yani farklı bir mikrodenetleyiciyede çalışmasın, ya da "sadece" tek bir atmega328p-u üzerinde çalışsın istiyoruz, bir nevi kod koruma gibi, bir şekilde yazılı olan mikrodenetleyici üzerindeki kod okutularak başka bir mikrodenetleyiciye kopyalandığında çalışmasın istiyoruz.

İlk seçenek sadece kod uyumluluğunu denetlemek için kullanılabilir, hex kodu alınıp örnek olsun diye Atmega2560 a yüklendiğinde "uyumsuz olacağı düşünülerek" çalışması engellenebilir.

İkinci seçenekse, farklı bir atmega328p-u ya da atılmış olsa çalışmasın, burada kod korumadan söz edebiliriz. Peki bunu sağlamak için ne yapabiliriz? Örnek olsun diye atmega328p nin kendine özgü, her mikrodenetleyici için "benzersiz" bir seri numarası olsa, yine örnek olsun diye bu seri numarası 6F 75 57 37 37 57 FF 25 98 olsa,  ve kodumuzun en başında desek ki, mikrodenetleyicinin seri numarasını oku, bizim bildiğimiz seri numarası ile karşılaştır doğru değilse sonsuz bir döngüye gir, dolayısıyla kodun geri kalanı hiç çalışmasın. Uygun bir çözüm gibi, peki atmega328p-u bize böyle bir olanak sağlıyor mu? Datasheet e bir göz atalım:

    31.5 Serial Number The product has a serial number which offers a unique ID to identify a specified part while it is in the field. It consists of several bytes, which can be accessed from the signature address space. The Signature row includes factory-programmed data: 

 

  • ID for each device type 
  • Serial number for each device 
  • Calibration bytes for factory calibrated peripherals

 

burda bahsettiğine göre böyle bir imkan var, ancak nedir nerden buluruz nasıl okuruz gibi bir bilgi malesef yok.Ancak bu bilgiye aynı ailenin farklı bir ferdi olan atmega328pb için yayınlanan datasheet üzerinde  rastlıyoruz. 

Table 31.5 Signature Row Adressing

Siganure Byte Z-Pointer
Device Signature Byte 1 0x0000
Device Signarure Byte 2 0x0002
Device Signature Byte 3 0x0004
Rc Oscillator Calibration Byte 0x0001
Serial Number Byte 1 0x000E
Serial Number Byte 0 0x000F
Serial Number Byte 3 0x0010
Serial Number Byte 2 0x0011
Serial Number Byte 5 0x0012
Serial Number Byte 4 0x0013
Serial Number Byte 6 0x0015
Serial Number Byte 7 0x0016
Serial Number Byte 8 0x0017

     Şair burada ne anlatmak istemiş? ID for each device type ile kasıt mikrodenetleyicinin imzası yani kim olduğu bilgisi: Device Signature Byte ile verilmiş, Serial Number ise "biraz karışık olmakla birlikte" 9 ayrı adres üzerinde 8 bitlik veriler olacak şekilde; Serial Number Byte 0 ile Serial Number Byte 8 olarak kodlanmış.

    Nasıl ulaşacağız bu bilgilere ? Bu noktada boot.h yardımıza koşuyor ve bize 

boot_signature_byte_get(addr) gibi bir fonksiyon sunuyor.

boot.h main.cpp ye include edilip kullanılabilir, ;Atmel Studio için örnek kod:


#ifndef F_CPU

#define F_CPU 16000000UL

#endif

#include <avr/boot.h>

char devSignature[3]; 

char devSerial[9];

void getDevSignature(char* devsign)

{

for (size_t i = 0; i<3; i++)

{

devsign[i] = boot_signature_byte_get(i*2);

}

}

void getDevSerial(char* devSerial)

{

uint8_t add = 0;

for (size_t i = 0; i<9; i++)

{

if(i>=6)add=1;

devSerial[i+add] = boot_signature_byte_get(0x0E + i + add);

}

char tmp = devSerial[0];

devSerial[0]=devSerial[1];

devSerial[1]=tmp;

tmp = devSerial[2];

devSerial[2] = devSerial[3];

devSerial[3] = tmp;

tmp = devSerial[4];

devSerial[4] = devSerial[5];

devSerial[5] = tmp;

}

int main(void)

{

   getDevSignature(devSignature);// Device Signature -hangi mikrodenetleyici

   getDevSerial(devSerial); // Serial Number - seri numarası

}


Arduino IDE için örnek kod:

char devSerial[9];
#include <avr/boot.h>

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Device Signature : ");
for (uint8_t i = 0; i < 3; i++)
{
Serial.print(boot_signature_byte_get(0x0 + i*2),HEX);
Serial.print(" ");
}
Serial.println("");
getDevSerial(devSerial);
Serial.println("Device Serial Number : ");
for (uint8_t i = 0; i < 9; i++)
{
Serial.print(devSerial[i],HEX);Serial.print(" ");
}
}
void loop() {
// put your main code here, to run repeatedly:

}

void getDevSerial(char* devSerial)
{
uint8_t add = 0;
for (size_t i = 0; i<9; i++)
{
if(i>=6)add=1;
devSerial[i+add] = boot_signature_byte_get(0x0E + i + add);
}
char tmp = devSerial[0];
devSerial[0]=devSerial[1];
devSerial[1]=tmp;
tmp = devSerial[2];
devSerial[2] = devSerial[3];
devSerial[3] = tmp;
tmp = devSerial[4];
devSerial[4] = devSerial[5];
devSerial[5] = tmp;
}

Elimdeki 3 değişik atmega328p ile denedim her birinde farklı seri numaraları elde ettim, bir eşleşme olacağını düşünmüyorum, deneyenler yorumlara yazabilir.




-Kolay gelsin.

Arduino UNO, Atmel Studio üzerinden programlamak | AVR Programlama - Registers




Arduino üzerinde bazı şeyleri öğrendik, hazır kütüphaneler üzerinde projelerimizi çalıştırdık, ama sanki IDE üzerinde eksik bişey var gibi, mesela bir IntelliSense olaydı ne güzel olmaz mıydı? hani şu değişken adını yazmaya başladığımızda tamamlama önerileri çıkartan, ya da nesne tabanlı programlamada kullandığımız; nesne. yazınca nesnenin tüm özelliklerine ulaşabildiğimiz yardımcı pencere açan.. bunun için Arduino yu bir adım ileriye taşıyan Atmelin kendi kodlayıcısı Atmel Studio (artık yerini MicroChip Studio alıyor) mevcut, Visual Studio kullananların hemen alışacağı (neredeyse aynısı) bir kodlama arayüzü, kod yazmak için biraz datasheet karıştırmak gerekiyor. Ancak kontrolün sizde olduğunu bilmek bir ayrıcalık, Arduino IDE ile yazılmış bir led yakın söndürme kodu :


void setup() {

  // initialize digital pin LED_BUILTIN as an output.

  pinMode(LED_BUILTIN, OUTPUT);

}

// the loop function runs over and over again forever

void loop() {

  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)

  delay(1000);                       // wait for a second

  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW

  delay(1000);                       // wait for a second

}

avrdude: 924 bytes of flash written, 

924 bytes yer kaplarken, aynı işi yapan Atmel Studio ile register seviyesinde yazılmış olan şu kod :


#define F_CPU 16000000UL

#include <avr/io.h>

#include <util/delay.h>


int main(void)

{

DDRB |= (1 << DDB5);

while (1)

{

PORTB |= (1<<PORTB5);

_delay_ms(1000);

PORTB = 0;

_delay_ms(1000);

}

}

avrdude.exe: writing flash (176 bytes):

sadece 176 bytes yer kaplıyor, yaklaşık 5.25 katı, 176 bytes ile yapılabilecek işi 924 bytes ile yapmak, nerden baksak bir mühendisin fiyat/performans tarzına uymuyor. 

Peki konu sadece kodun hafızada kapladığı alan mı acaba? Hıza da bakalım mı ?

void setup() {
pinMode(3,OUTPUT);
}

void loop() {
  digitalWrite(3,HIGH);
  digitalWrite(3,LOW);
}

yukarıda gördüğünüz Arduino ide de yazılmış bir kod sizce hangi frekanslarda 3 pini açıp kapatabiliyordur?


112 Khz mi? Hey dostum tek yapabildiğin bu mu? hadi onu geçtim, 1ms lik aralıklarla yaptığın gecikmeler de neyin nesi ?

Studio 'ya ve register level 'e geçelim :

#include <avr/io.h>

int main(void)

{

DDRD |= (1<<DDD3);

/* Replace with your application code */

while (1)

{

PORTD = 8;

PORTD = 0;

}

}


Evet şimdi konuşmaya başladın : 3.2 Mhz :) 27.8 kat daha hızlı ve alt tarafta görebileceğiniz üzere 1ms lik gecikemeler de artık YOK.

Tamam, kararımızı verdik, kodumuzu yazdık, başka hiçbir ek donanım gereksinimi olmadan kodumuzu nasıl Arduino UNO kartımıza yükleyeceğiz?


Atmel Studio 7 (Version 7.0.1931) için şöyle:
Tools Menusu /  External Tools
açılan pencerede Add
Title kısmı tamamen tercihsel ne isim verirseniz, -boş bırakılamaz!
Command kısmı: C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avrdude.exe
Arguments kısmı: -C "C:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf" -v -patmega328p -carduino -PCOM7 -b115200 -D -Uflash:w:"$(ProjectDir)Debug\$(TargetName).hex":i

PCOM7, benim için geçerli Uno Com7 üzerinden çalışıyor, siz kendi portunuzu yazın.
bir kaçtane kartınız var ve hepsinde farklı com görünüyorsa Prompt for arguments işaretleyip, çalıştırıldığında arguments kısmından seri portunuzu elle değiştirebilirsiniz.

Ok deyip ayrılıyoruz pencereden, artık Tools menusu içinde "tercihsel" olarak belirlediğimiz Tool ismi görünüyor olmalı, projemizi Build/Build project menusunden derliyoruz ki "$(ProjectDir)Debug\$(TargetName).hex":i noktasında hex dosyamız oluşsun, sonrasında Tools/Tercihen verdiğimiz araç ismi ne tıklayarak kodumuzu kartımıza yükleyebiliriz.

Biraz zahmetli gibi? yazdığım kodun 5 kat daha fazla yer kaplaması benim için sorun değil diyorsan Arduino IDE devam, hayır önemli diyorsan aramıza hoşgeldin.

-Kolay gelsin.

Atmel Studio, Atmel ICE, Arduino UNO Hata Ayıklama

Geçtiğimiz günlerde siparişini verdiğim Atmel ICE elime ulaştı, 
 
    Break pointimi ekledim, Atmel-ICE, Arduino UNO bağlantısını ICSP soketi üzerinden gerçekleştirdim. Atmel-ICE ve Arduino usb ile bilgisayarıma bağlı, herşey hazır gibi. Projeyi kaydediyorum,
  Debug menüsünden Start debugging and break e tıklıyorum, hoop : Launh Failed başlıklı bir hata :
 
Failed to launch session with debugWIRE. This could be caused by reset line circuitry or disabled debugWIRE interface. Make sure that reset line is free before continuing. Do you want to use SPI to enable the DWEN fuse?
 
Arkadaş diyor ki, debugWIRE üzerinden hata ayıklama yapamıyorum, nedeni reset devresi ya da DWEN fuse nin kapalı olması olabilir, hmm.. orjinal Arduino Uno kullanıyorum, zannımca reset devresiyle alakalı bir sorun olamaz, ancak arduino IDE debug kullanmadığından DWEN fuse kapalı olabilir, ve zaten soruyor istersen DWEN fuse ü senin için aktif etmemi ister misin, Evet diyorum. Çok güzel, DWEN aktif edildi, gücü kesip tekrar bağlayın diyor, yapıyorum ve yeniden Launch Failed :
 
Setting debugWire fuse seems to have failed. Check your clock and fuse setting. 
 
Tamam, anladık ki başka bi sıkıntı var, Ancak artık başka bi sıkıntı da var, Uno nun üzerinde Blink yüklüydü ledim yanıp sönüyordu, artık yanıp sönmüyor yani UNO artık çalışmıyor ve Device Programming üzerinden Uno ya bağlanıp artık kod da atamıyorum :
 
Failed to enter programming mode. ispEnterProgMode: Error status received: Got 0xc0, expected 0x00 (Command has failed to execute on the tool)
 
Unable to enter programming mode. Verify device selection, interface settings, target power, security bit, and connections to the target device.
 
Arduino IDE üzerinden deniyelim; Examples / Blink, com port hala görüyor, bu iyiye işaret olabilir, upload diyoruz:
 
         Using Port                            : COM21
         Using Programmer               : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x26
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x26
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x26
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x26
 
 
geçmiş olsun.. hata ayıklama yapalım diye çıktığımız bu kutlu yoldan, artık çalışmayan bir arduino UNO ile geri dönüyoruz :)
 
tamam bozulmuş olabilirsin ve bu bozulma bu olaya denk gelmiş olabilir, başka bir arduino uno ile tüm süreci tekrarlıyorum: sonuç 2 tane çalışmayan Arduino UNO..
 
biraz geri saralım, ilk hatadaki atladığımız reset hattı hikayesine, Make sure that reset line is free, Hattımız free mi değil? bakalım referans dizaynda neler var?
 

 

Malesef Reset hattımız "free" değil. Usb to com bridge, aynı zamanda IDE üzerinden Arduino ya kod atmamıza olanak sağlayan ATMEGA8U2-MU ile bir bağlantı söz konusu ve işin iyi tarafı board üzerinde bu bağlantıyı ayırabileceğimiz "Reset EN" adında bir jumper mevcut, bu bağlantıyı ince bir neşterle ayırıyorum, artık reset line free..
 

 

 

Tekrar Deniyoruz,  Debug menüsünden Start debugging and break e tıklıyorum,:



sonuç şahane, break pointimiz çalıştı, o andaki tüm registerlerimizi PORT directionlarımızı ve on off durumlarını görebiliyoruz, ayynen visual studio da kullandığımız debug sistemi gibi değişkenlerimizin değerlerini görebiliyor, adım adım ilerleyebiliyor, quickWatch ekleyip özellikle takip etmek istediğimiz değişkenin peşine düşebiliyoruz.
 
    Uno nun eski haline dönebilmesi için, debug menusundan ; disable debugWire and close demek gerekiyor, ayrıca board üzerindeki iki pine iki pinli erkek pin header bağlayıp üzerine de bir jumper takıp ("eskiden harddisklerin slave master ayarı yapmak için kullandığımız jumper) la Reset Enable durumunu da kolayca kontrol edebilirsiniz. 
 
-Kolay gelsin.

 

Türksat Saat Kanalı ve IRIG-B Time Code

Türksat Saat Kanalından Saat Bilgisi Nasıl Alınır? Uyduda kanalları dolaşırken, şu Türksat Saat kanalı hep dikkatimi çekmiştir. Özellikle  S...