Hallo,
ich habe ein Problem mit der Kommunikation meines ATMega mit einer
Z80-PIO. Aus irgendwelchen Gründen komme ich in der Kommunikation mit
der PIO aus dem Trab und bleibe unter gewissen Bedingungen in einer
Endlosschleife hängen in der Hoffnung ein Signalwechsel der PIO zu
erleben welcher aber nie eintritt.
Mein Problem ist nun, das ich gerne die Endlosschleife finden würde in
der er hängen bleibt das genaue Signal zu erfahren auf was er wartet und
wo er
genau im Programmablauf stecken bleibt.
Leider ist die Kommunikation mit der PIO vom Timing her so das ich
extrem limitiert bin mit dem was ich so "dazwischen" noch machen kann.
Ausgaben über UART fallen z.B. komplett flach.
Da auch alle Ports belegt sind, habe ich kein JTAG o.ä. zur Verfügung
sondern ausschliesslich ISP und mein AVR Dragon.
Ich habe in meiner Signal-Warteschleife einen counter eingebaut und bei
Überlauf des Counters gebe ich den letzten Wert einer Variable aus dem
"Hauptprogramm" aus - in der Hoffnung zu erkennen an welcher Stelle er
auf das Signal wartet.
Problem ist nun, das uint8_t zu wenig Wartezeit bietet. uint16_t auch,
und uint32_t scheint irgendwie nie in den Überlauffall reinzulaufen
(kann ich mir eigentlich nicht vorstellen). Konkrete Überprüfungen der
Werte der Überlaufvariablen sind zeitlich auch nicht möglich (ich kann
also nicht checken ob uint32_t i > 20.000.000 ist). Ich kann lediglich
darauf prüfen ob der Counter 0 ist. Ich habe mir also mit einem
Überlaufzähler beholfen. Leider ist die dadurch zur Verfügung stehende
Zeit auch nicht ausreichen. Ein weiterer Überlaufzähler für den
Überlaufzähler ist zeitlich schon wieder nicht möglich....
Hier mal der aktuelle Stand meiner "Warteroutine mit
Endlosschleifenerkennung"
1 | static inline void wait_until_ardy_asserted (uint16_t err)
|
2 | {
|
3 | uint8_t i,a;
|
4 |
|
5 | i=0;a=1;
|
6 | do {
|
7 | if ( !info_wardy_is_high() && !info_wardy_is_high() ) {
|
8 | return;
|
9 | }
|
10 | i++;
|
11 | if(i == 0) a++;
|
12 | if(a == 0) {
|
13 | uart_putstring(PSTR("ardy assert fehler: "),false);
|
14 | uart_putw_dec(err);
|
15 | }
|
16 | } while ( true );
|
17 | }
|
"err" wird vom Hauptprogramm mitgegeben und gibt mir einen Hinweis auf
die Codestelle im Hauptprogramm. Noch ein uint8_t geht nicht.
JTAG-Debugging geht nicht (hab ich auch noch nie gemacht). Wie gesagt -
irgendwelche uart-Ausgaben ohne das der Fehlerfall eingetreten ist geht
auch nicht.
Hat noch einer eine Idee wie ich rausfinden kann in welcher Zeile des
generierten ASM Codes der AVR bis zum Sankt Nimmerleinstag wartet (dank
inline habe ich dann die Stelle des Hauptprogramms...)
Ich kann ca. sagen was eine einzelne Datenkommunikation an Zeit dauern
müsste. Kann ich vor jeder Kommunikation einen Timer konfigurieren und
diesen einen Interrupt auslösen lassen? Wenn ich dann die notwendigen
Variablen um die Codestelle zu identifizieren global mache kann ich dann
auf diese in der Interruptroutine zugreifen und diese dann dort
ausgeben. Wenn die Datenkommunikation erfolgreich durchläuft, stoppe ich
den Timer einfach (damit kein IRQ ausgelöst wird).... Klingt irgendwie
durchs Knie ins Auge? Ist das so möglich oder gibt es noch bessere
Wege?
Bevor jemand auf die Idee kommt - ja ich habe einen LA, aber der kann
weder Life-View noch hat er Pre-Trigger-Möglichkeiten - und der Fehler
tritt teilweise erst nach einer Stunde permanenter Kommunikation auf...
Keine Chance mit meinem LA da per Zufall genau diesen Mißstand zu
erwischen.