Forum: Mikrocontroller und Digitale Elektronik AVR (ATmega644) Signatur & Serialnummer auslesen


von Cybers (Gast)


Lesenswert?

Hallo zusammen,

ich möchte aus meinem ATmega644 während dem Betrieb die Signatur UND die 
Seriennummer auslesen.

Dafür habe ich das Datenblatt durchforstet und bin auf verschiedene 
REGISTER unterhalb 0x20 gestoßen. Daraus habe ich einen kleinen C 
Quellcode gebastelt. Nun meine Frage: Ist dieser korrekt? Besonders bei 
der Seriennummer kann ich schlecht feststellen ob die zurückgegebenen 
Werte wirklich die Seriennummer sind oder etwas anderes.

Falles es eine bessere Lösung zum Auslesen gibt, würde ich mich über 
Kommentare freuen.
1
void cpu_get_sig(uint8_t *sigarray) //muss 3 Bytes haben
2
{
3
  *sigarray[2] = SIGNATURE_2
4
  *sigarray[1] = SIGNATURE_1
5
  *sigarray[0] = SIGNATURE_0.
6
}
7
8
void cpu_get_sn(uint8_t *idarray) //muss 10 Bytes haben
9
{
10
  idarray[1] = boot_signature_byte_get(0x0E); //SN 2
11
  idarray[0] = boot_signature_byte_get(0x0F); //SN 1
12
  idarray[3] = boot_signature_byte_get(0x10); //SN 4
13
  idarray[2] = boot_signature_byte_get(0x11); //SN 3
14
  idarray[5] = boot_signature_byte_get(0x12); //SN 6
15
  idarray[4] = boot_signature_byte_get(0x13); //SN 5
16
  idarray[6] = boot_signature_byte_get(0x14); //Reserved
17
  idarray[7] = boot_signature_byte_get(0x15); //Wafer Number
18
  idarray[8] = boot_signature_byte_get(0x16); //Y-coordinate
19
  idarray[9] = boot_signature_byte_get(0x17); //X-coordinate  
20
}

von Oliver S. (oliverso)


Lesenswert?

Hm. Da du doch schon das Datenblatt gelesen hast...

Cybers schrieb:
> void cpu_get_sig

ist Unsinn. SIGNATURE_0 .. _2 ,kannst du im Programm nicht addressieren, 
die machen was ganz anderes.

https://www.nongnu.org/avr-libc/user-manual/group__avr__signature.html

Cybers schrieb:
> void cpu_get_sn(uint8_t *idarray) //muss 10 Bytes haben
> {
>   idarray[1] = boot_signature_byte_get(0x0E); //SN 2
>   idarray[0] = boot_signature_byte_get(0x0F); //SN 1
>   idarray[3] = boot_signature_byte_get(0x10); //SN 4
>   idarray[2] = boot_signature_byte_get(0x11); //SN 3
>   idarray[5] = boot_signature_byte_get(0x12); //SN 6
>   idarray[4] = boot_signature_byte_get(0x13); //SN 5
>   idarray[6] = boot_signature_byte_get(0x14); //Reserved
>   idarray[7] = boot_signature_byte_get(0x15); //Wafer Number
>   idarray[8] = boot_signature_byte_get(0x16); //Y-coordinate
>   idarray[9] = boot_signature_byte_get(0x17); //X-coordinate
> }

Das ist prinzipiell nicht verkehrt, nur hat der ATMega644 als Vertreter 
der Steinzeit-Megas solch neumodischen Kram wie eine Seriennummer gar 
nicht. Der hat nur 3 Byte Signature, und ein Byte "RC Oscillator 
Calibration Byte", sonst nix. ("Nix" nennt sich im Datenblatt: "reserved 
for future use.")

Oliver

: Bearbeitet durch User
von Cybers (Gast)


Lesenswert?

Oliver S. schrieb:
> ist Unsinn. SIGNATURE_0 .. _2 ,kannst du im Programm nicht addressieren,
> die machen was ganz anderes.

ok, dann doch eher so:
1
void cpu_get_sig(uint8_t *sigarray) //muss 4 Bytes haben
2
{ 
3
  *sigarray[0] = boot_signature_byte_get(0x0000); //SigByte 1
4
  *sigarray[1] = boot_signature_byte_get(0x0002); //SigByte 2
5
  *sigarray[2] = boot_signature_byte_get(0x0004); //SigByte 3
6
  *sigarray[3] = boot_signature_byte_get(0x0001); //RC Oszillator Byte
7
}

Das sollte funktionieren oder?


Oliver S. schrieb:
> Das ist prinzipiell nicht verkehrt, nur hat der ATMega644 als Vertreter
> der Steinzeit-Megas solch neumodischen Kram wie eine Seriennummer gar
> nicht. Der hat nur 3 Byte Signature, und ein Byte "RC Oscillator
> Calibration Byte", sonst nix. ("Nix" nennt sich im Datenblatt: "reserved
> for future use.")

Da bin ich mir nicht sicher. Im Datenblatt vom ATmega644P auf Seite 368 
steht:

28.3. - Signature Bytes
All Atmel microcontrollers have a three-byte signature code which 
identifies the device. This code can be
read in both serial and parallel mode, also when the device is locked. 
The three bytes reside in a
separate address space. For the device the signature bytes are given in 
the following table.

Table 28-9. Device and JTAG ID
Signature Bytes Address
0x000  |  0x001  |  0x002
0x1E   |  0x96   |  0x0A

28.4. - Calibration Byte
The device has a byte calibration
[...]
Calibrated Internal RC Oscillator on page 49

28.5. - Serial Number
Each individual part has a specific serial number. This can be used to 
identify a specify part while it is in
the field.
The serial number consists of nine bytes which can be accessed from the 
signature address space.

von Jürgen (Gast)


Lesenswert?

Cybers schrieb:
> Im Datenblatt vom ATmega644P auf Seite 368 steht:

Welchen meinst Du jetzt, den ATmega644 oder den ATmega644P?
Und welche Ausgabe des Datenblatts hast Du?

von Cybers (Gast)


Lesenswert?

ATmega644P/V - Rev.B - 08/2016

von FS (Gast)


Lesenswert?

Cybers schrieb:
> ATmega644P/V - Rev.B - 08/2016

Komisch. Das aktuelle Datenblatt zum ATmega644P/V bei Microchip (Rev. A 
- 10/2018) listet in der Versionsgeschichte gar keine Rev. B von 08/2016 
auf. In diesem gibt es unter 24.3 allerdings auch nur Signature Bytes, 
aber keine Seriennummer. Laut Datenblatt gibt es die nicht. Und 
unterhalb von 0x20 befindet sich laut 5.3 doch nur die Register File.

von S. Landolt (Gast)


Lesenswert?

Die Signatur von meinen beiden ATmega644P-20PU, beide von 0741 (also 
ziemlich alt):
1
0000  1E59 96FF 0AFF FFFF EDFF FFF7 FFFF 4837
2
0008  3130 3536 FF12 0E0A 1701 1201 1301 FFFF
3
0010  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
4
0018  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
5
6
0000  1E8D 96FF 0AFF FFFF EDFF FFF7 FFFF 4837
7
0008  3130 3536 FF16 0B0B 1701 1201 1301 FFFF
8
0010  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
9
0018  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF

Ob da in der zweiten Zeile so etwas wie eine Seriennummer steht - keine 
Ahnung.

von Jürgen (Gast)


Lesenswert?

Interessant, in der aktuellen Vesion von 2018 
(https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/ATmega164P-324P-644P-Data-Sheet-40002071A.pdf) 
und den älteren von Atmel ist davon nichts zu lesen.
Da die 2016er Versionen (ich hab ne 07 und ne 08 gefunden)  ne komplett 
überarbeitet Version ist in der die der Prozessoren 164/324 und 644 
getrennt wurden, die Von Microchip nicht wieder erwähnt wurden, kann man 
wohl von einem Fehler oder einem geplaten Feature ausgehen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

S. Landolt schrieb:
> Ob da in der zweiten Zeile so etwas wie eine Seriennummer steht - keine
> Ahnung.

Losnummer (die 1056 steht bestimmt auch auf dem Gehäuse, oder?), 
Scheibennummer im Los, X- und Y-Position auf der Scheibe – wäre jetzt 
meine Vermutung.

von Oliver S. (oliverso)


Lesenswert?

Cybers schrieb:
> Datenblatt vom ATmega644P

gilt nicht für den ATMega644 aus deiner Thread-Überschrift. Das wurde 
aber wohl schon gesagt.

Oliver

von S. Landolt (Gast)


Lesenswert?

an Jörg Wunsch:

1056?

Auf der Unterseite steht:
1
7H0165-355C9B
2
1-P0741  e3
3
TAIWAN 1
4
F3
5
6
7H0165-355C9B
7
1-P0741  e3
8
TAIWAN 2
9
E3

von S. Landolt (Gast)


Lesenswert?

> 1056?
Ah - jetzt - ja: ASCII&umstellen 1.-2.Byte!: 1056 <-> 0165

von avr (Gast)


Lesenswert?

Sieht für mich gut aus und könnte funktionieren, wenn

SIGNATURE_0, SIGNATURE_1, SIGNATURE_2, boot_signature_byte_get

die Zugriffskonventionen zum Signatur Speicher einhalten.

Falls Deine Idee nicht funktioniert, lies Abschnitt

27.8.10. Reading the Signature Row from Software

27.9.1.  SPMCSR - Store Program Memory Control and Status Register

in Deinem Datenblatt.


Auf Signatur Speicher zugreifen:
1. Adresse in Z-Pointer schreiben
2. Bits in SPMCSR setzen
3. LPM innerhalb drei CPU-Zyklen ausführen!


Z.B. in Assembler,
weil nur drei CPU-Zyklen zwischen SPMCSR und LPM erlaubt sind:

.INCLUDE "m644pdef.inc"

ldi r0, 0b00100001   ;SIGRD, SPMEN Bitmaske für SPMCSR

ldi r31, 0   ;ZH

ldi r30, 0   ;ZL=0 für Signature Byte 1 in r1

out SPMCSR, r0

lpm r1, Z

ldi r30, 2   ;ZL=2 für Signature Byte 2 in r2

out SPMCSR, r0

lpm r2, Z

ldi r30, 4   ;ZL=4 für Signature Byte 3 in r3

out SPMCSR, r0

lpm r3, Z

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

S. Landolt schrieb:
>> 1056?
> Ah - jetzt - ja: ASCII&umstellen 1.-2.Byte!: 1056 <-> 0165

Ja, die Byte-Reihenfolge ist natürlich nicht sofort ersichtlich. Ich sah 
nur 3130 3536, was erstmal sofort das "ASCII Flag" im Gehirn klingeln 
ließ. ;-)

Wahrscheinlich ist dann der erste Chip von der Scheibe #18, X-Position 
14, Y-Position 10, der zweite von der Scheibe #24 (dürfte die letzte im 
Los sein, wenn man bei 0 anfängt), X- und Y-Position 11.

avr schrieb:
> Z.B. in Assembler

Braucht man nicht, genau dafür gibt's ja dieses 
boot_signature_byte_get().

von Cybers (Gast)


Lesenswert?

Interessant. Erstmal danke an alle!
Also unter 27.8.10 (bei mir auf Seite 356) sind in meinem Datenblatt 
auch Serial Number Byte zu finden. Allerdings gehen die bei Adresse 
0x000E los.

von Cybers (Gast)


Lesenswert?

Interessant ist auch diese Seite: 
https://microchipsupport.force.com/s/article/Serial-number-in-AVR---Mega-Tiny-devices

Gibt es sie also doch? ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Cybers schrieb:
> Gibt es sie also doch? ;)

Nur eben nicht bei allen. Siehst du ja auch an obigen Dumps.

Die Losnummer, Scheibennummer und X/Y-Position dagegen scheint zumindest 
schon sehr lange beim Test mit einprogrammiert zu werden. Die habe ich 
auch schon bei anderen AVRs so gesehen.

von Cybers (Gast)


Lesenswert?

Jörg W. schrieb:
> Cybers schrieb:
>> Gibt es sie also doch? ;)
>
> Nur eben nicht bei allen. Siehst du ja auch an obigen Dumps.
> Die Losnummer, Scheibennummer und X/Y-Position dagegen scheint zumindest
> schon sehr lange beim Test mit einprogrammiert zu werden. Die habe ich
> auch schon bei anderen AVRs so gesehen.

Ok, bei dem Dump verstehe ich die Adresse nur nicht so ganz. Jeder Block 
ist 2 Bytes, aber die zweite Zeile fängt bei 08 an. Wenn ich die Blöck 
aber durchzähle komme ich auf: 0x000F also 16.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sind Wortadressen und Wort-Werte (daher hatte ich auch die Bytes 
getauscht).

Ab (Byte-)Adresse 0x0E steht dort halt die Losnummer. Jetzt, wo ich 
genau hingucke, sehe ich auch das führende "7H" der Losnummer.

von Cybers (Gast)


Lesenswert?

Da ich gerade nichts anderes zu Hand habe, hatte ich versucht bei einem 
ATmega32-16PU nur die Signature Bytes auszulesen.
1
void cpu_get_sig(uint8_t *sigarray) //muss 4 Bytes haben
2
{ 
3
  uint8_t tmp;
4
  tmp = SREG;
5
  cli();
6
  SPMCR |= (1<< SPMEN);
7
  sigarray[0] = boot_signature_byte_get(0x0000); //SigByte 1
8
  sigarray[1] = boot_signature_byte_get(0x0002); //SigByte 2
9
  sigarray[2] = boot_signature_byte_get(0x0004); //SigByte 3
10
  sigarray[3] = boot_signature_byte_get(0x0001); //RC Oszillator Byte
11
  SREG = tmp;
12
}

Raus kommt nur irgendein bullshit. Gibt es noch etwas zu beachten. 
Intern wird die Funktion (bzw. Makro) folgenermaßen umgesetzt:
1
#define boot_signature_byte_get   (       addr  )   \
2
(__extension__({                      \
3
      uint8_t __result;                         \
4
      __asm__ __volatile__                      \
5
      (                                         \
6
        "sts %1, %2\n\t"                        \
7
        "lpm %0, Z" "\n\t"                      \
8
        : "=r" (__result)                       \
9
        : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \
10
          "r" ((uint8_t)(__BOOT_SIGROW_READ)),  \
11
          "z" ((uint16_t)(addr))                \
12
      );                                        \
13
      __result;                                 \
14
}))

von avr (Gast)


Lesenswert?

Dein cpu_get_sig() sollte funktionieren, wenn Du in SPMCR die Bits SPMEN 
und *SIGRD* setzt!

Lies noch mal "27.8.10. Reading the Signature Row from Software" in 
Deinem Datenblatt.

von Cybers (Gast)


Lesenswert?

avr schrieb:
> und SIGRD setzt!

Ich hatte mich zu früh ans testen gemacht! Beim ATmega32 kann per 
Firmware die Signature Bytes nicht ausgelesen werden. Das ist nur mit 
einem Programmer möglich. Bei einem ATmega644P sollte dies aber 
funktionieren. Dann muss ich wohl eine kleine Bestellung machen. Danach 
kann ich das erst testen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Cybers schrieb:
> Beim ATmega32 kann per Firmware die Signature Bytes nicht ausgelesen
> werden.

Entsprechend sollte sich obiger Code auch gar nicht erst compilieren 
lassen, da es eben besagtes SIGRD-Bit nicht gibt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.