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!
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);
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?
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.
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 :/
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
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:
Also basierend auf die bisherigen Lösungsansätze sieht es jetzt so aus:
1
#include"stm32f4xx.h"
2
3
uint32_tID1;
4
uint32_tID2;
5
uint32_tID3;
6
7
intmain(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:
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...
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.
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! :)
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)
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?
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.
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?
?!? 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.
?!? 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.
Ihr macht es doch viel zu kompliziert. Guest hat es ja schon
geschrieben. Die richtige der 3 32-Bit IDs nehmen und gut ist.
UID designt keinen Geldautomaten.
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.
Appropos: Wenn es nicht viele Nodes gibt, was hält ihn davon ab eine
eigene UUID mit 8Bit zu vergeben!? Dann kann er sich sicher sein dass es
jedes Gerät nur einmal gibt.
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.
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.
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.
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).
So schlimm ist CAN nun wirklich nicht. Nur muss man das Pferd nicht am
Schwanz aufzäumen und in C programmieren, bevor man einen Hauch Ahnung
hat, wie das geht.
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.
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;
}