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.

1 yorum:

  1. Merhaba; Arduino ya yazdıgınız programı yuklediğimde aşagıdaki gibi çıktı alıyorum.
    Sorun ne olabilir teşekkurler.


    16:45:58.692 -> Device Signature :
    16:45:58.692 -> 1E 95 F
    16:45:58.692 -> Device Serial Number :
    16:45:58.692 -> FFFFFFFF 58 FFFFFFFF FFFFFFEF FFFFFFFF FFFFFFEF 0 FFFFFFFF FFFFFFFF

    YanıtlaSil

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...