Hallo,
ich hab jetzt ne Weile die Beiträge zum Thema sprintf gelesen aber
leider nichts gefunden was meinem Problem ähnelt.
Und zwar läuft die Funktion wenn ich sie nur einmal aufrufe wunderbar.
Sobald aber ein zweiter sprintf Befehl hinzukommt, erhalte ich einen
HardFault_Handler. Kann es Probleme geben wenn man die Funktion zweimal
aufruft?
ich arbeite mit einem LPC1768 und möchte Daten vom CAN-Bus ausgeben.
Hier beide anweisungen, falls ihr was seht immer her damit =)
Tom schrieb:> kmm = 123459;> char kmm[12];
was genau bezweckst du mit diesem Code?
Zuerst weißt du einer nicht deklarierten Variable den Wert 123459 zu
(schon das müsste einen Fehler ergeben). Danach deklarierst du die
Variablen (12 Stück) als char (=8bit). Solltest du kmm vorher schon
deklariert haben ergibt das auch einen Fehler da Redeklarationen
verboten sind.
Wenn du das Array mit 123459 füllen möchtest geht das so:
kmm[12]={1,2,3,4,5,9,0,0,0,0,0,0};
Wenn man ein Array nullen / mit nur einem Wert füllen will geht das so:
kmm[12]={0};
okay vielen dank für die Antworten, hab nun von der sprintf abstand
genommen und arbeite stattdessen mit einer funktion die den Wert manuell
in ein ascii zeichen umwandelt und das ganze dann ausgibt, aber vielen
dnak bis hierher.
Die Ausgabe funktioniert auch jedoch wiederum nur wenn ich eine der
beiden werte verarbeite, sobald ich den zweiten hinzuschalte erhalte ich
wieder den HardFault_Handler.
ich poste einfach mal den Code =)
1
#include"type.h"
2
#include"can.h"
3
#include"mfa_display.h"
4
5
CAN_MSGMsgBuf_TX1,MsgBuf_TX2;/* TX and RX Buffers for CAN message */
6
CAN_MSGMsgBuf_RX1,MsgBuf_RX2;/* TX and RX Buffers for CAN message */
Tom schrieb:> ich arbeite mit einem LPC1768 und möchte Daten vom CAN-Bus ausgeben.> Hier beide anweisungen, falls ihr was seht immer her damit =)
Hauptsächlich sehen wir, dass das nicht der Code ist so wie er in deinem
Programm steht. Poste bitte deinen richtigen Code.
Viele Leute hier haben die Schnauze voll davon, in im Forum eingetippten
Code nach Fehlern zu suchen, die im richtigen Code gar nicht vorhanden
sind. Dafür dürfen wir dann immer die Dinge erraten, die der Poster gut
meinend, nicht gezeigt hat.
Keine Sorge. Die Profis hier haben überhaupt kein Problem damit, 40, 50,
100 Zeilen Code zu überblicken und mit 1 oder 2 mal durchlesen zu
verstehen. Das ist unser täglich Brot.
ja ich hab ihn jetzt gepostet, mir ist eben aufgefallen, dass der
Interrupt auch auftritt, wenn ich nur einen der beiden schreibe jedoch
erst nach einigen sendevorgängen
hier nochmal was zu dem data[] array, in ihm stehen die Daten zugeordnet
zu den jeweiligen Identifiern also je nachdem welcher identifier gerade
empfangen wurde wird das dem entsprehcendem feld im array zugeordnet.
Was genau macht die Funktion
lcd_draw_double (font_vw_24px,NORMAL_STYLE,km,7,0,5,155,255);
Das 'double' im Funktionsnamen, dazu das Argument km als uint32_t, das
macht mich nervös
Die LCD Funktionen .... hast du die geschrieben, oder ist das eine
ausführlich getestete Library?
// LCD-Funktion: Gibt eine positive double-Zahl auf dem LCD Display aus
// - Parameter dbl_value: auszugebende Zahl
// - Parameter u8_lenght: Größe des LCD Feldes (Zahl wird rechtsbündig
im Feld ausgegeben)
// - Paramter u8_decimals: Anzahl der anzuzeigenden Nachkommastellen
// - Funktion dürfen nur positive Zahlen übergeben werden
// - Funktion sichert sich nicht gegen zu große Zahlen und unplausbile
Werte ab !!!
Die LCD-Funktionen hab ich übernommen, das hatte ich nur mit eurer Hilfe
auf meinen Controller angepasst.
Problem des gesamten programmes ist auch noch, dass es viele daten
hintereinander nicht verarbeiten kann da kommt ein data overrun und
nichts geht mehr, aus diesem Grund shcicke ich die Daten momentan auch
einzeln, damit dieser Fehler nicht auftritt, da ich noch nicht weiß wie
ich das overrun verhindern kann.
Tom schrieb:> Die Ausgabe funktioniert auch jedoch wiederum nur wenn ich eine der> beiden werte verarbeite, sobald ich den zweiten hinzuschalte erhalte ich> wieder den HardFault_Handler.
Dann ist der Fehler wohl woanders...
> sobald ich den zweiten hinzuschalte erhalte ich> wieder den HardFault_Handler.
Was heißt dazuschalten?
Das verdreht mir ja das Auge. Wieviele Einsen sind das denn?
km=((data[6]>>8)&0b11111111111111111111);
Ich würde es so schreiben:
km=((data[6]>>8)&0xFFFFF);
Da sehe ich schneller: 5 x 4 Einsen.
Das ist bedenklich:
volatile uint32_t kmph = 0; // Variable Stundenkilometer
kmph=(((data[3]>>14))&0b1111111111)*0.32;
Hier muß der Compiler etliche implizite Konvertierungen durchführen, um
vom int32 über einen float wieder auf einen int32 zu kommen...
dazuschalten heißt in meinem Fall ich kommentiere eine aus und hab nur
noch eine der beiden stehen, hab aber gemerkt, dass es nen Fehler war,
dass der Fehler dann nicht mehr auftritt, er kommt nur später hinzu ...
hm okay das war mir nicht bewusst, dass dies zu kompliziert ist, kannst
du mir helfen und sagen wie es einfacher geht?
also das ganze funktioniert nur zuverlässig, wenn ich einfach nur die
festen sachen (linien feste werte) ausgebe und nichts von den
empfangenen Nachrichten als string versuche auszugeben.
so also mit sprintf funktioniert das programm nur solange, solange
sprintf nur einmal aufgerufen wird
mit der ersatzfunktion funktioniert es selbst wenn sie nur einmal
aufgerufen wird nur eine zeit lang und dann nicht mehr.
Tom schrieb:> dazuschalten heißt in meinem Fall ich kommentiere eine aus und hab nur> noch eine der beiden stehen, hab aber gemerkt, dass es nen Fehler war,> dass der Fehler dann nicht mehr auftritt, er kommt nur später hinzu ...
???????...????
Tom schrieb:> also das ganze funktioniert nur zuverlässig, wenn ich einfach nur die> festen sachen (linien feste werte) ausgebe und nichts von den> empfangenen Nachrichten als string versuche auszugeben.
Auch eine Zeichenkette ist ein statischer Wert. Nur scheint mir, du
probierst da mal alle funktionen isrgendwie durch und hoffst, dass sich
was ändert.
Ich tippe auf einen Stack-Overflow (wobei das bei 64k RAM eher
unwahrscheilich ist) oder einen amoklaufenden Pointer...
1
:
2
CAN_MSGMsgBuf_TX1,MsgBuf_TX2;/* TX and RX Buffers for CAN message */
3
CAN_MSGMsgBuf_RX1,MsgBuf_RX2;/* TX and RX Buffers for CAN message */
so zu meinem Problem mit dem Empfangen der Nachrichten nocheinmal zurück
ich werd langsam wahnsinnig
hier ist der Beispielcode von der NXP-Homepage (Sample Code Bundle for
LPC17xx Peripherals using Keil's MDK-ARM V1.02 )
ich habe für meine Zwecke den Empfang auf den CAN1 umgeschrieben (da
CAN2 bei mir nicht angeschlossen ist) den Wakeup teil weggenommne
(benötige ich nicht) sowie die Lookuptable vereinfacht und die Taktrate
geändert.
Sieht jemand so was daran nciht funktionieren könnte? wie gesagt ich
kann Daten nur empfangen wenn sie sehr sehr langsam kommen, sobald dies
schneller ist (bei einer Sekunde schon) wird ein Data overrun ausgelöst.
Mein CPU Takt beträgt 96MHz und der Peripherietakt 48MHz
* Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
> hier ist der Beispielcode von der NXP-Homepage (Sample Code Bundle for> LPC17xx Peripherals using Keil's MDK-ARM V1.02 )
Schöner Code. Und was ist damit?
okay sorry
ähm ich habe diesen Code benutzt und ein paar änderungen vorgenommen wie
oben im letzten Teil beschrieben, und es wird jedes mal wenn ich
nachrichten hintereinander Sende auch wenn dies eine sekunde
auseinanderliegt ein Dataoverrun erzeugt.
Daher wollte ich mal fragen, ob sich jemand das mal ansehen könnte ob
eine meiner Änderungen schuld daran ist.
1. Beitrag "Re: sprintf mehrfach" ist noch offen
2.
> Die Ausgabe funktioniert auch jedoch wiederum nur wenn ich eine der> beiden werte verarbeite, sobald ich den zweiten hinzuschalte erhalte ich> wieder den HardFault_Handler.
Wie sieht der Code aus, wenn der HardFault_Handler nicht angesprungen
wird und wie wenn er angesprungen wird. Gut lesbar wäre ein Listing im
Anhang mit einem #if DIES_ERGIBT_FEHLER #endif Konstrukt.
3.
> ähm ich habe diesen Code benutzt und ein paar änderungen vorgenommen wie> oben im letzten Teil beschrieben, und es wird jedes mal wenn ich
In einem übernommenen Code, den man ändert, sollte man die Änderungen
unbedingt kennzeichnen. Wenn es sich um größere Teile handelt auch mit
#if #else #endif, so dass man immer den Originalcode sehen und ggf. auch
zurückbauen kann. Die Chance ist hoch, dass sich der Fehler in den
Änderungen befindet.
so ich hab mich mal dran gesetzt und den originalcode zu meinen
gepackt, hab das immer so gekennzeichnet, dass der originale Code
auskommentiert ist und drüber /**********ORIGINAL****************/ steht
sorry ich geb mein bestes, und ich mache es mir auch nicht wirklich
leicht, da mittlerweile schon Wochen so ins Land gegangen sind und ich
nicht drauf komme was da falsch ist und ich halte euch alle für extrem
kompetent und hoffe einfach auf dem weg hilfe zu bekommen =)
Mein Tipp wäre, dass irgendwo ein Array überlaufen wird und du dir den
Stack ganz kräftig zerschiesst.
Was du mit dem sprintf siehst, sind die Symptome aber nicht die
eigentliche Ursache. Die liegt ganz woanders und daher hat es auch
keinen Sinn, da jetzt nach einer Alternative für den sprintf zu suchen.
Wenn ich den Code übernehmen müsste, dann würde ich
abspecken, abspecken, abspecken.
Die lcd Funktionen durchgehen, nach Buffer Overruns Ausschau halten und
die erst mal gründlichst testen.
Dann sukzessive den CAN Teil, so wie es eben möglich ist, ins Programm
wieder einbauen. Dabei wieder: den Teil den ich einbaue, kritisch unter
die Lupe nehmen. Wenn es gar nicht anders geht, dann müssen da
Sicherungen rein. Die Alarm schlagen, wenn Indizes zu hoch werden oder
Pointer ihren erlaubten Bereuich verlassen.
Wenn du, wie du sagst, schon Wochen an dem Problem sitzt, dann wärst du
schon 3 mal fertig geworden, wenn du mit einem neuen Pgm angefangen
hättest und dieses schön langsam hochgezogen hättest. Sukzessive immer
einen vorhandenen Baustein einbauen, gründlich unter die Lupe nehmen und
exzessiv testen.
Solche Rundumschlagdinger, ala ich kopiere mir da 200kB Code aus 25
verschiedenen Quellen zusammen, garniere das mit meinen eigenen Routinen
- so was funktioniert meistens nicht.
Tom schrieb:> Kannst du mir noch sagen wie du erkennst wann ein Array überläuft?
Oh, da gibt es einige Fehlerbilder:
Das Programm "stürzt" ab...
Irgendwas tut nicht mehr so wie es eigentlich soll...
Variable verändern ihre Werte selbständig...
Es werden die falschen Funktionen aufgerufen...
Der uC kommt nach einer Unterroutine nicht mehr "richtig" zurück...
Das Programm funktioniert nicht mehr, wenn irgendwo eine Zeile eingefügt
wird...
hm okay klingt nach meinem programm =) und woher weißt du um welches
array oder welchen pointer es sich dabei genau handelt? bzw wie gehts du
vor um das zu vermeiden?
soho ich hab neuigkeiten =)
Also ich hab in meiner Lookuptable den Beginn der FullCAN IDs auf 0
gesetzt gehabt (bzw im beispiel war dies auch so) jedoch ist es so, dass
sollte dieser wert 0 sein die FullCAN IDs disabled werden setzte ich das
ganze nun auf 1 also ungleich null so läuft es bisher durch ich kann
zyklische daten senden ohne unterberechungen drin zu haben