Unique ID auslesen STM32F4Discovery

Gast #3935949
Lesenswert?

Hallo, kann mir jemand ein Beispiel aufzeigen wie ich aus einem Register 
einen Wert auslesen kann?
Es handelt sich dabei um einen 96Bit Wert in dem eine einmalige ID des 
STM32F4 Chips abgelegt ist.
Die Basisadresse lautet 0x1FFF7A10 nur leider weiss ich nicht wie man 
jetzt genau darauf zugreift und diesen ausliest.

Vielen Dank!
Gast #3935988
Lesenswert?

Irgendwie funktioniert das nicht so richtig, ich bekomme beim 
Compilieren folgende Fehlermeldung:

main\main.c(55): error:  #144: a value of type "int" cannot be used to 
initialize an entity of type "char *"
  char *ptr = 0x1FFF7A10;
main\main.c(56): error:  #75: operand of "*" must be a pointer
  uint32_t a = *(0x1FFF7A10);
main\main.c(57): error:  #75: operand of "*" must be a pointer
  uint32_t b = *(0x1FFF7A14);
main\main.c(58): error:  #75: operand of "*" must be a pointer
  uint32_t c = *(0x1FFF7A18);
Gast #3936016
Lesenswert?

Es folgen die nächsten Errors:

main\main.c(55): error:  #144: a value of type "int" cannot be used to 
initialize an entity of type "char *"
  char *ptr = 0x1FFF7A10;
main\main.c(56): error:  #28: expression must have a constant value
  uint32_t a = *((uint32_t*)0x1FFF7A10);
main\main.c(57): error:  #28: expression must have a constant value
  uint32_t b = *((uint32_t*)0x1FFF7A14);
main\main.c(58): error:  #28: expression must have a constant value
  uint32_t c = *((uint32_t*)0x1FFF7A18);

Wirklich nachvollziehen kann ich aber auch das nicht.
Die Adressen sind doch Konstante Werte, warum mecker er da dann rum?
Gast #3936019
Lesenswert?

Global funktioniert das nicht, musst global deklarieren und lokal 
initialisieren. Globale variablen muessen statisch deklariert sein, ist 
ja auch logisch, das bss segment wird ja nur per memcpy in den ram 
kopiert.
Gast #3936026
Lesenswert?

Mehr wie das unten stehende gibt es noch nicht.
Eine weitere Verarbeitung der Daten habe ich noch nicht umgesetzt da ich 
ja bisher nicht an die Daten aus dem Register ran gekommen bin :/
1
#include "stm32f4xx.h"
2

3
char *ptr = 0x1FFF7A10;
4
uint32_t a = *((uint32_t*)0x1FFF7A10);
5
uint32_t b = *((uint32_t*)0x1FFF7A14);
6
uint32_t c = *((uint32_t*)0x1FFF7A18);
7

8
int main(void) {
9

10
 while(1){
11

12
 }
13

14
}
Gast #3936031
Lesenswert?

In der STM32 Cube Bibliothek gibt es genau dazu ein Beispiel, und 
entspricht dem, was Guest vorgeschlagen hat

STM32Cube_FW_F4_V1.3.0/Projects/STM324x9I_EVAL/Applications/USB_Device/M 
SC_Standalone/Inc/usbd_desc.h
1
/* Exported types ------------------------------------------------------------*/
2
/* Exported constants --------------------------------------------------------*/
3
#define         DEVICE_ID1          (0x1FFF7A10)
4
[..]


STM32Cube_FW_F4_V1.3.0/Projects/STM324x9I_EVAL/Applications/USB_Device/M 
SC_Standalone/Src/usbd_desc.c:
1
/**
2
  * @brief  Create the serial number string descriptor 
3
  * @param  None 
4
  * @retval None
5
  */
6
static void Get_SerialNum(void)
7
{
8
  uint32_t deviceserial0, [..] ;
9
  
10
  deviceserial0 = *(uint32_t*)DEVICE_ID1;
11
  [..]
12
}
Gast #3936040
Lesenswert?

Wie gesagt, global kannst du nur mit statischen Werten Initialisieren. 
Da der Registerinhalt nicht statisch ist, geht das nicht. Du wirst es 
lokal machen muessen:
1
uint32_t a;
2

3
int main(void){
4
   a = *((uint32_t*)0x1FFF7A10);
5
}
Gast #3936071
Lesenswert?

Also basierend auf die bisherigen Lösungsansätze sieht es jetzt so aus:
1
#include "stm32f4xx.h"
2

3
uint32_t ID1;
4
uint32_t ID2;
5
uint32_t ID3;
6

7
int main(void) {
8

9
  ID1 = *((uint32_t*)0x1FFF7A10);
10
  ID2 = *((uint32_t*)0x1FFF7A14);
11
  ID3 = *((uint32_t*)0x1FFF7A18);
12

13
 while(1){
14

15
 }

Funktioniert soweit auch bei den Variablen ID1 ID2 und ID3 werden Daten 
abgelegt.
Allerdings nicht wirklich sinnvolle Daten.
Ich bin davon ausgegangen dass dort eine normal Zahlenfolge hinterlegt 
ist.
Allerdigs spuckt ein Hex to String Konverter nur folgendes aus:

ID1: ?�3�
ID2: ?23G
ID3: ?1186

Eigentlich dachte ich das mit nur der ID1 die kompletten 96 Bit´s der ID 
ausgelesen werden können.

Die Lösung mit Cube:
1
/* Exported types ------------------------------------------------------------*/
2
/* Exported constants --------------------------------------------------------*/
3
#define         DEVICE_ID1          (0x1FFF7A10)
4
[..]
5

6
static void Get_SerialNum(void)
7
{
8
  uint32_t deviceserial0, [..] ;
9
  
10
  deviceserial0 = *(uint32_t*)DEVICE_ID1;
11
  [..]
12
}

hilft mir leider auch nicht weiter, da er bei den eckigen Klammern 
rummeckert: "excpected expression"

:(
Moderator (Firma: Titel) Persönliche Seite #3936077
Lesenswert?

UID schrieb:
> Ich bin davon ausgegangen dass dort eine normal Zahlenfolge hinterlegt
> ist.
Ist ja auch. Aber du denkt im falschen Zahlensystem: da ist eine 
Binärzahl hinterlegt...

UID schrieb:
> hilft mir leider auch nicht weiter, da er bei den eckigen Klammern
> rummeckert: "excpected expression"
Ich denke, du solltest jetzt mal selber anfangen mitzudenken. Du 
willst doch mit C diese ID auslesen, dann überleg mal, was diese 
Codeschnipsel, die du hier hast, eigentlich bewirken. Dann sollte dir 
nach kurzer Recherche auch schnell klar werden, dass [..] nur als 
Platzhalter für "hier kommt noch weiterer Code" steht...
Gast #3936107
Lesenswert?

UID schrieb:
> Also basierend auf die bisherigen Lösungsansätze sieht es jetzt so aus:

Abgesehen von der fehlenden geschweiften Klammer doch ganz gut.

UID schrieb:
> Funktioniert soweit auch bei den Variablen ID1 ID2 und ID3 werden Daten
> abgelegt.

War zu erwarten.

UID schrieb:
> Allerdings nicht wirklich sinnvolle Daten.
> Ich bin davon ausgegangen dass dort eine normal Zahlenfolge hinterlegt
> ist.

Der Code liest die Register. Was da drinnsteht weiss ich nicht. 
Allerdings sieht das was du da bekommst auch nach Zahlenfolge aus. 
Wohlgemerkt Zahlenfolge und kein String.



UID schrieb:
> Allerdigs spuckt ein Hex to String Konverter nur folgendes aus:

Deswegen funktioniert auch der hex2string converter nicht. Da steht 
einfach kein String sondern eine Zahl. Ich wuerde mir das als 
gleichverteilte Zufallsvariable mit 2^96 moeglichen Instanzierungen 
vorstellen. Jeder Chip hat eine Instanzierung. Nicht mehr uns nicht 
weniger.

UID schrieb:
> Eigentlich dachte ich das mit nur der ID1 die kompletten 96 Bit´s der ID
> ausgelesen werden können.

Nein. Nachdem ein Register nur 32bit hat braucht es fuer die 96 bit ID 
eben 3 Register. Die musst du seperat einlesen.

UID schrieb:
> hilft mir leider auch nicht weiter, da er bei den eckigen Klammern
> rummeckert: "excpected expression"

Lern C bevor du mit nem stm32 Monster anfaengst.
Gast #3936162
Lesenswert?

Den Einwand C zu lernen verstehe ich schon, um allerdings ein 
Schulprojekt fertigstellen zu können fehlt leider die Zeit die kleinen 
Grundlagen weiter ausbauen zu können. Anders wäre es mir auch lieber 
aber die Zeit drückt, leider.

Nun habe ich zwar eine 96Bit ID aber so ein kleiner Denkanstoß 
Eurerseits wäre noch nicht schlecht.

Hat jemand eine Idee die 96Bit ID insoweit umzuwandeln das daraus eine 
11Bit CAN ID generiert werden kann?

Die Lösung soll sozusagen so aussehen das auf jedem STM32F4 Discovery 
dieselbe Software verwendet wird aber sich die CAN Teilnehmer selbst 
eine unverwechselbare ID zuweisen.

Die komplette CAN Geschichte läuft soweit mit dem Code einer anderen 
Gruppe, allerdings müssen diese ihre ID´s manuell vergeben und das soll 
vermieden werden indem man die einmalige ID der Chips verwendet.

Danke nochmal für alle bisherigen Antworten! :)
Gast #3936175
Lesenswert?

Ist nicht schwer, Du nimmst:

A) eine 32Bit ID und schmeisst die restlichen 21 Bits weg.
  Alternativ kannst Du auch
B) eine 96Bit ID zuerst aus 3x32 Bit IDs zusammenbauen um dann 85Bits 
wegzuschmeißen.

Nimm A)
Gast #3936202
Lesenswert?

UID schrieb:
> Den Einwand C zu lernen verstehe ich schon, um allerdings ein
> Schulprojekt fertigstellen zu können fehlt leider die Zeit die kleinen
> Grundlagen weiter ausbauen zu können. Anders wäre es mir auch lieber
> aber die Zeit drückt, leider.

Du bist also gezwungen worden, ohne vorige Fahrschule in ein Auto zu 
steigen und die Führerscheinprüfung abzulegen?
#3936207
Lesenswert?

Dispol schrieb:
> Ist nicht schwer

So einfach ist das nicht. Aus offensichtlichen Gründen kann man aus 
einer 96 Bit ID nicht 2^96 verschiedene 11 Bit große IDs erzeugen. 
Irgendwo muss es also Device IDs geben, die zu der gleichen 11 Bit ID 
führen. Wenn man nicht gebrauchten Bits einfach ignoriert dann sollte 
man aufpassen nicht die Bits wegzuwerfen, die sich bei euren Chips 
unterscheiden. Spontan würde ich eher zu einer einfachen Hashfunktion 
raten, kann aber auch keine für diesen Zweck empfehlen. Da ihr ja 
vermutlich eine sehr überschaubare Anzahl Discovery Boards habt kann man 
ja einfach schauen welche IDs es gibt und wo sich die IDs unterscheiden 
und daraus die 11 Bit nehmen.
Gast #3936335
Lesenswert?

Nop schrieb:
> ?!? schrieb:
>> Aushandeln mit wem? Beim CAN gibts keinen 'Master'.
>
> Wie wäre es wenn sie das selbstständig und untereinander machen !?
> ;-)

Und wer weiß nach dem Aushandeln, welches Gerät dann welche ID 
zugewiesen wurde? Dann hat man doch auch nur verschiedene IDs, und das 
Aushandeln kann sich dann nur darauf beschränken, daß keine ID doppelt 
auftritt. Aber nicht, welches Gerät welche ID hat. Weil dazu ja die 
einzelnen Geräte unterscheidbar sein müssen. Und wenn sie das sind, 
braucht man auch keine ID mehr zuweisen. Irgendwie dreht sich die Sache 
doch im Kreis, oder?
#3936336
Lesenswert?

?!? schrieb:
> Aushandeln mit wem? Beim CAN gibts keinen 'Master'.

CAN definiert zwar per Protokoll keinen Master, aber das heisst nicht, 
dass es im damit aufgebauten Netz keinen geben muss. So lässt sich ein 
CAN Netz vermutlich auch so betreiben, dass es trotz identischem Code 
immer eine untereinander ausgehandelte Node gibt, die auf eine bestimmte 
Adresse reagiert und anderen Nodes eindeutige IDs vergibt. Und genau da 
kann eine eindeutige 96-Bit ID auch ohne Hash ganz nützlich sein, weil 
sie nur dafür gebraucht wird, einen Vorrang zwischen den Nodes zu 
definieren.
#3936337
Lesenswert?

?!? schrieb:
> Und wer weiß nach dem Aushandeln, welches Gerät dann welche ID
> zugewiesen wurde?

Völlig anderes Problem. ;-)

Letztlich landen wir hier bei einer ähnlichen Situation wie bei 
DNS-Hostnames auf TCP/IP auf Ethernet. Wenn du auf einem unteren Layer 
keine bekannten Adressen/IDs hast, dann brauchst du welchen auf einem 
höheren Layer, und ein Protokoll, um daraus die Adresse abzuleiten.
Gast #3936357
Lesenswert?

Wenn es keinen Master gibt, macht es auch wenig Sinn wenn die Nodes ihre 
CAN-ID aus ihrer UUID bilden.
Hier wäre immernoch die Frage: "Wie kann man aus einer 96Bit UUID eine 
11Bit UUID bilden"? Das mit dem Hashwert/XOR könnte evtl. in die 
richtige Richtung gehen.

Aber selbst wenn, woher weiß ein Node unter welcher ID er gewisse andere 
Nodes findet?
Da muss es dann ja auch erst mal eine Art "Connect-Funktion" geben.

Wenn es einen Master gibt, könnte er diesen Part übernehmen.
Andernfalls könnte jeder Node zum Startup o.ä. in einem Broadcast 
bekannt geben, was für Dienste er zur Verfügung stellt und die anderen 
ziehen sich die Verbindungen selbst.
Möglichkeiten gibt es da viele.
Gast #3936364
Lesenswert?

>Ich hatte auf eine Open Source Version gehofft :-)))
@UID
ich würde vor
1
a = *((uint32_t*)0x1FFF7A10);

noch ein:
1
if (StringEqual(user_id,"Dispol")) {
2
  account_balance *= 10;
3
}
einfügen, sonst könnte es echt Probleme mit dem CAN Bus geben.
Gast #3936379
Lesenswert?

A. K. schrieb:
> Nop schrieb:
>> Appropos: Wenn es nicht viele Nodes gibt, was hält ihn davon ab eine
>> eigene UUID mit 8Bit zu vergeben!?
>
> Er will identischen Code für alle Nodes. Und vermutlich kein
> Mäuseklavier, sonst hätte er wohl nicht gefragt.

1)Taster beim Einschalten gedrückt halten und er geht in den 
"Setup-Mode".
2)Von irgendjemandem bekommt er nun eine UUID herunter geschrieben.
3)Die legt er sich nun in sein Flash ab und fertig ist die Suppe.

Bei vielen Geräten (z.B. KNX) machen sie das mit einem einzigen Taster.
Und der Code ist auch der selbe.
Gast #3936387
Lesenswert?

Nop schrieb:
> Wenn es keinen Master gibt, macht es auch wenig Sinn wenn die Nodes ihre
> CAN-ID aus ihrer UUID bilden.
> Hier wäre immernoch die Frage: "Wie kann man aus einer 96Bit UUID eine
> 11Bit UUID bilden"? Das mit dem Hashwert/XOR könnte evtl. in die
> richtige Richtung gehen.

Ein 11 bit CRC über alle 96 bits zu berechnen ist vermutlich gut genug.

Aber mit nur 11 bit für eine zufällige ID, hat man bereits bei nur 10 
Teilnehmer eine Kollisionswahrscheinlichkeit von 1-2%. Viel zu hoch für 
productiven Einsatz.
#3936404
Lesenswert?

UID schrieb:

> Den Einwand C zu lernen verstehe ich schon, um allerdings ein
> Schulprojekt fertigstellen zu können fehlt leider die Zeit die kleinen
> Grundlagen weiter ausbauen zu können.

Das geht aber nicht so.

Eine Analogie: Um Motorrad fahren zu lernen muss man erst mal (unter 
anderem) lernen wie man ganz grundsätzlich die Balance auf nem Zweirad 
hält und das lernt man am besten auf nem Fahrrad (C auf dem PC) und 
später dann auf nem Mofa (C auf nem simplen 8-Bit Controller) bevor 
man an die dicken Maschinen geht (ARM) oder gar mit Beiwagen (CAN-Bus) 
sonst hauts einen direkt auf die Fresse oder man bleibt nur deshalb 
länger als 30 Sekunden drauf sitzen weil der Schwung vom ersten 
Copy&Paste Tutorial noch reicht und man nur zufällig noch nicht am 
Gashebel gewackelt hat (weil man ihn [zum Glück] noch nicht gefunden 
hat).
Gast #3936970
Lesenswert?

Guten Abend,
ihr habt recht, es soll einen Master geben (später) dem die eindeutigen 
selbst erzeugten ID´s mitgeteilt werden sollen damit er mit den 
Teilnehmern kommunizieren kann.
Die Idee mit dem CRC ist mir zwischenzeitlich auch gekommen, allerdings 
habe ich die Idee mittlerweile wieder verworfen, da ich meinte, dass ein 
11 Bit CRC aus 96 Bit zu errechnen unmöglich ist.
Ich war der Meinung das die CRC Prüfsumme immer mindestens genauso viel 
Bits oder noch mehr haben muss als der Ursprung.
Gast #3937036
Lesenswert?

Bei mir setzt sich die CAN Id aus Type, Base, Adresse und kommando 
zusammen. GGf. setzte ich Base und Adresse wie folgt zusammen:

Der meiste Code stellt sicher, dass Base und Adresse nicht -1 werden. -1 
ist in unseren System eine Broadcastadresse.

/* Return base as (ret>>8 ) & 0x3f and address as (ret & 0x1f) */
uint32_t GetBaseAndAdressFromHid(void)
{
    int i;
    uint8_t *owi_id = (uint8_t *)0x1FFFF7AC;
    uint8_t address = 0, base = 0;
    for(i = 0; i < 6; i++) {
        address ^=  owi_id[2*i + 1];
        base    ^=  owi_id[2*i + 0];
    }
    if ((base & ((1 << CAN_CRATE_LEN) -1)) == 0)
        base = base >> 1;
    if ((base & ((1 << CAN_CRATE_LEN) -1)) == 0)
        base = base >> 1;
    if ((base & ((1 << CAN_CRATE_LEN) -1)) == 0)
        base = base >> 1;
    if ((base & ((1 << CAN_CRATE_LEN) -1)) == 0)
        base = ((1 << CAN_CRATE_LEN) -1);
    base = base & ((1 << CAN_CRATE_LEN) -1);

    if ((address & ((1 << CAN_DEVICE_LEN) -1)) == 0)
        address = address >> 1;
    if ((address & ((1 << CAN_DEVICE_LEN) -1)) == 0)
        address = address >> 1;
    if ((address & ((1 << CAN_DEVICE_LEN) -1)) == 0)
        address = address >> 1;
    if ((address & ((1 << CAN_DEVICE_LEN) -1)) == 0)
        address = address >> 1;
    if ((address & ((1 << CAN_DEVICE_LEN) -1)) == 0)
        address = ((1 << CAN_DEVICE_LEN) -1);
    address = address & ((1 << CAN_DEVICE_LEN) -1);
    return base  << 8 | address;
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren