Moin
ich habe da ihrgendwas noch nicht so richtig verstanden.
Vieleicht könnt ihr mir ja sagen wo ich da falsch denke.
ich möchte eine globale variable anlegen und zwar uint8 RX_BLE[16]
ich habe 3 .c files
main.c mit:
int main()
{
// lade Globale variablen vor
RX_BLE[1]=0x00;
RX_BLE[2]=0x00;
RX_BLE[3]=0x00;
RX_BLE[4]=0x00;
RX_BLE[5]=0x00;
RX_BLE[6]=0x00;
RX_BLE[7]=0x00;
RX_BLE[8]=0x00;
RX_BLE[9]=0x00;
RX_BLE[10]=0x00;
RX_BLE[11]=0x00;
RX_BLE[12]=0x00;
RX_BLE[13]=0x00;
RX_BLE[14]=0x00;
RX_BLE[15]=0x00;
RX_BLE[16]=0x00;
........
for(;;)
{ .........
}
}
BLE.c
void HandleBLE_RXTraffic(void * eventparam)
{
while(n!=0)
{
RX_BLE[i]=RxBLEparm->handleValPair.value.val[i];
n--;
i++;
if(RX_BLE[3]==1)
{
TEST_OUT_1_Write(!TEST_OUT_1_Read());
}
}
Uart.c
hier sollen später die RX_BLE Daten wenn eine anfrage auf die daten
kommt in den uart übergeben werden.
deswegen wollte ich die daten global machen
habe sie also auserhalb des mains so definiert:
uint8 RX_BLE[17];
und dann in den Header BLE.h geschrieben
extern uint8 RX_BLE[17];
der kompiler meckert auch nicht aber ich bekomme nicht die richtigen
daten (Byte3 müsste 1 sein).
wenn ich aber es lokal mache bekomme ich das richtige ergebniss die
daten kommen aloso richtig an.
also so geht
BLE.c
void HandleBLE_RXTraffic(void * eventparam)
{
uint8 RX_BLE[17];
while(n!=0)
{
RX_BLE[i]=RxBLEparm->handleValPair.value.val[i];
n--;
i++;
if(RX_BLE[3]==1)
{
TEST_OUT_1_Write(!TEST_OUT_1_Read());
}
}
was mache ich falsch.
Habe bis jetzt leider nur asm gemacht und da ist ja alles was ich
definiere global also sorry wenn ihr sagt es ist quatsch die varialbe
global anzulegen.
ach ja RX_BLE wird momentan nur in BLE.c aufgerufen eswegen verstehe ich
auch nicht warum er anscheinend auf 2 speicherpätze zugreift.
Heidi
little_H schrieb: > // lade Globale variablen vor > RX_BLE[1]=0x00; Überflüssiger Quatsch. Globale Variablen sind mit 0 initialisiert. > der kompiler meckert auch nicht aber ich bekomme nicht die richtigen > daten (Byte3 müsste 1 sein). Vermutlich hast du an irgendeiner Stelle ein "volatile" vergessen, um dem Compiler mitzuteilen, dass der entsprechende Wert sich von außerhalb seines Sichtbarkeitsbereichs (bspw. aus einem Interrupt) ändern kann. Das kann man aber nur sagen, wenn man das komplette Projekt sieht. Du solltest deinen Variablen treffendere Namen geben, statt da alles in ein großes globales Array zu knallen.
Beitrag #5227223 wurde von einem Moderator gelöscht.
Wenn es mit dem lokalen Array funktioniert, dann überschreibt jemand Dein globales, ursprüngliches Array. Also z.B. ein Interrupt. Oder es ist doch noch etwa anderes anders.
volatile habe ich niergens hingeschrieben da die Variable momentan nur in der funktion benutzt wird ich will sie aber im nächsten schritt im uart int. benutzen aber auch da werden sie nicht geändert sie werden einfach nur rausgesendet.
vermutlich wird ein array erst richtig gefüllt, aber durch eine Racekondition danach ausgenullt. Ab wann ist die füllende Instanz aktiv? Du kannst mal ganz einfach das Ausnullen durch das Besetzen mit einer festen Signatur (z.B. 0xa5) autauschen. Wenn Du zum zeitpunkt, an dem der Test gegen 3 gemacht wird, 0xa5 da findest, kam das Initialisieren später. Willkommen in der wunderbaren Welt der nebenläufigen Programmierung!
@little_H (Gast) >volatile habe ich niergens hingeschrieben da die Variable momentan nur >in der funktion benutzt wird ich will Schon mal was von Satzbau gehört? Ohne Punkt und Komma schreiben ist nicht nur schlechter Stil sondern bisweilen auch unverständlich. > sie aber im nächsten schritt im >uart int. benutzen aber auch da werden sie nicht geändert sie werden >einfach nur rausgesendet. Das reicht um Probleme zu machen, denn die Variable muss dabei gelesen werden. https://www.mikrocontroller.net/articles/Interrupt#Volatile_Variablen
@Falk Brunner Tut mir leid ich war abgelenkt. Versuche es nicht mehr vorkommen zu lassen. :-( @ Adapter (Gast) Habe den test schnell mal gemacht. Init schein ok zu sein Es ist auch so das die Daten immer wieder kommen(alle 50ms). Momentan sind es immer die selbe Daten(zum testen). Ich habe auch die alles mit einem neuen Namen nochmal angelegt falls doch ihrgenwo was reinspielt. wenn ich die Daten jetzt nur in BLE.c und noch nicht weiter benutze, muss ich sie dann auch schon kenzeichnen? und muss das so ausehen: also auserhalb des mains so definieren volatile uint8 RX_BLE[17]; und dann in den Header BLE.h so extern volatile uint8 RX_BLE[17]; ist das richtig
Mach aber nur die Variablen "volatile", die das auch brauchen. U. U. muss das nicht das ganze Array sein.
Hilft auch nicht. Noch wer ne Idee. Ist übrigens ein Cypress chip falls das noch ne wichtige info ist. Ich wünsche mir glaube ich mein assembler zurück da hat man solche probeme nicht.
little_H schrieb: > Ich wünsche mir glaube ich mein assembler zurück da hat man solche > probeme nicht. Assembler hilft gegen Programmierfehler? Das wäre neu …
Kannst Du mal wenn nicht den vollständigen Code wenigstens den map file veröffentlichen?
Der Funktion als Pointer übergeben. Rx oder Tx Buffer da anlegen wo sie benötigt werden oder per initBLE(rxBuf,rxBufSize); auf pointer übergeben aber mit der Größe des buffers!. alle internen Funktionen verwenden den static Pointer vom Buffer. Das nennt man Struktur vom Code. Der zugebender maßen nicht immer einfach ist. Blöd ist nur wenn man zu spät merkt das man unten doch hätte ein Fenster mehr einbauen können. Um das zu vermeiden nimmt man sich einen Stift und macht sich Gedanken über die Struktur des Codes. Außerdem lauern bei dem Code Style erheblich Risiken ;)
Jörg W. schrieb: > Assembler hilft gegen Programmierfehler? Das wäre neu Ja - nämlich gegen die Programmierfehler, die aus un- oder falsch verstandenen Details von C herrühren. little_H schrieb: > void HandleBLE_RXTraffic(void * eventparam) > { > while(n!=0) > { > RX_BLE[i]=RxBLEparm->handleValPair.value.val[i]; > n--; > i++; So, meine Kritik: Erstens, wo ist bei dem Gezeigten das Initialisieren von n und i geblieben? Schreibst du vielleicht in die Irre mit RX_BLE[i]= ... ? Zweitens, nur ne Formsache: Wenn deine RX_BLE Membes schon "in den uart übergeben" werden sollen, dann solltest du das auch als char RX_BLE[16] deklarieren, denn es sind ja wohl Char's, oder? Aber das ist keine Formsache: uint8 RX_BLE[16] ... RX_BLE[1]=0x00; ... ... RX_BLE[16]=0x00; little_H schrieb: > Uart.c > > hier sollen später die RX_BLE Daten wenn eine anfrage auf die daten > kommt in den uart übergeben werden. OK, du hast aus meiner Sicht eher seltsame Ansichten, was in einen Unit namens Uart.c hinein soll, aber bittesehr. Ich würde dir da eher anraten, dort lediglich die tatsächliche UART-Bedienung aka Low-Level-Treiber hineinzuschreiben und deinen Algorithmus in eine separate Quelle zu verlagern. Das würde dann auch den quellübergreifenden Zugriff auf deine 16 RX_BLS's beseitigen. Nochwas: Schreibe für so eine separate Quelle eine Init-Funktion, die all die unit-internen Dinge richtig aufsetzt, anstatt sowas in main tun zu wollen. Und du kannst dort auch sowas wie memset oder ne eigene einfache Schleife nehmen, als stattdessen alle 16 Char's separat zu nullen. Und vertraue in diesem speziellen Punkt dem Jörg nicht gar zu sehr, denn was er gepostet hat, ist lediglich der fromme Wunsch der C-Programmierer, daß ab Start des µC der RAM ausgenullt sein soll. Sätze, die in einem C-Papier stehen sind das Eine, die Realität ist oft was Anderes. W.S.
little_H schrieb: > Noch wer ne Idee. Nochmal: Dein gezeigter Code ist nicht lauffähig. Dein echter Code wird ja sicher ohne Warnungen compilieren, ansonsten einfach einschalten. Wenn er dann immer noch nicht funktionieren sollte, stelle ihn hier ein und das Problem löst sich beim drüberschauen. (ggf. mit Angabe der Warnmeldungen) Im gezeigten Codefragment ist volatile nicht das Problem (da das Element ja Deinen Angaben nach vorher auf 1 gesetzt wird). Wenn Du einen Debugger hast, steppe dadurch. Sperre die Interrupts (dann kann die Variable niemand überschreiben) Stelle sicher, dass wirklich eine 1 reingeschrieben wird. Notfalls hangle dich von der Zeile vor dem if zurück zum Schreiben per RxBLEparm->handleValPair.value.val[i].
Vorschlag für globale Variabeln in einer main.h:
1 | // Globals
|
2 | #ifdef globals_main
|
3 | #define ex
|
4 | #else
|
5 | #define ex extern
|
6 | #endif
|
7 | |
8 | ex v u8 down_timer1; |
9 | ex v u16 TIM3_CNT; |
10 | ex v u8 ir_start; |
11 | ...
|
Die Variabeln werden nur an einer Stelle initialisiert/deklariert.
little_H schrieb: > was mache ich falsch. Du stellst keinen compilierbaren Testcode bereit, mit dem man den Fehler analysieren könnte. Bisher hat (fast) jeder Fragesteller, der nur Schnipselchen postet, nur solche gepostet, die den Fehler nicht enthalten oder die nicht dem tatsächlich getesteten Code entsprechen.
grundschüler schrieb: > Vorschlag für globale Variabeln in einer main.h: Kann man machen, aber wirklich toll finde ich das inzwischen nicht mehr. > ex v u8 down_timer1; Auf Bezeichner wie "u8" sollte man mittlerweile zugunsten der seit knapp 20 Jahren in <stdint.h> standardisierten uint8_t, uint_fast8_t etc. ohnehin verzichten … > ex v u16 TIM3_CNT; … und GROSSBUCHSTABEN sind von jeher per üblicher Konvention für Makros da. > Die Variabeln werden nur an einer Stelle initialisiert/deklariert. Spätestens, wenn man globale Variable explizit (also nicht nur implizit mit 0) initialisieren möchte, ist so ein Headerfile, wie von dir zitiert, eher unpraktikabel. Du fängst dann nämlich noch an, einen weiteren klumpigen Makro dranzuhängen für den/die Initializer, so a la:
1 | #ifdef globals_main
|
2 | # define INIT(x) = x
|
3 | #else
|
4 | # define INIT(x)
|
5 | #endif
|
6 | |
7 | // …
|
8 | |
9 | ex v u8 ir_start INIT(42); |
Ich finde das alles eher obfuscated.
also was jetzt ??? uint8 RX_BLE[16]; oder uint8 RX_BLE[17]; Zugriffe auf RX_BLE[16] wären nur erlaubt bei der zweiten Deklaration !!! Indizes von Arrays beginnen immer bei 0 und die Grösse beim deklarieren ist immer in Anzahl Elemente. wenn du also typ array[16]; schreibts, kannst du auf array[0] bis array[15] zugreifen ...
Jörg W. schrieb: > Kann man machen, aber wirklich toll finde ich das inzwischen nicht mehr. Danke, zumindest kein völliger Verriss. Das Problem, das ich immer hatte - und was mich immer extrem geärgert hat - war, dass bei Trennung von Initialisierung und Deklaration Änderungen an mehreren Stellen im Code vorgenommen werden müssen. Mit der expliziten Initialisierung hast du recht. Das muss man dann konventionell machen. >Auf Bezeichner wie "u8" sollte man mittlerweile zugunsten der seit knapp 20 Jahren in <stdint.h> standardisierten uint8_t, uint_fast8_t etc. ohnehin verzichten … uint8_t ist wegen des '_' eine Menge Tastenarbeit. Ich meine, bei ARMs ist u8 als "#define u8 uint8_t" sogar irgendwo im Standard-code enthalten. u8 geht wesentlich schneller, ist völlig eindeutig und wegen des häufigen Gebrauchs für faule Menschen nahezu ein Muss. >GROSSBUCHSTABEN Du hast natürlich recht, aber die Umschalttaste...
grundschüler schrieb: > Das Problem, das ich immer hatte - und was mich immer extrem geärgert > hat - war, dass bei Trennung von Initialisierung und Deklaration > Änderungen an mehreren Stellen im Code vorgenommen werden müssen. Ja, und? Wenn du eine neue Variable einführst, musst du sowieso an vielen Stellen was ändern, da kommt's darauf nun wirklich nicht an. > uint8_t ist wegen des '_' eine Menge Tastenarbeit. Ach du Schreck … Dafür fehlen mir die Worte, ehrlich gesagt. > Ich meine, bei ARMs > ist u8 als "#define u8 uint8_t" sogar irgendwo im Standard-code > enthalten. Selbst wenn: gerade im ARM-Umfeld dürfte oft ein uint_fast8_t viel angebrachter sein. uint8_t sollte man dort eigentlich nur benutzen, wenn es tatsächlich wichtig ist, dass die Variable exakt 8 Bits belegt (weil man bspw. den Überlauf von 255 nach 0 braucht oder das zu einem externen Protokoll passen muss). Ansonsten kostet die Ausmaskierung nicht genutzter Bits aus einem 32-Bit-Register zusätzlichen Code.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.