Serielle Übertragung führt zu Programmabsturz

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Serielle Übertragung führt zu Programmabsturz

      Hallo Kolleginnen und Kollegen,


      ich habe ein gravierendes Problem mit einer seriellen Übertragung und hoffe, dass Ihr mir evtl weiterhelfen könnt.

      Ob ich hier im Forum richtig bin, weiss ich nicht genau. Vielleicht werde ich das Problem auch auf einem Raspberry oder Python Forum posten….


      Hier die oberflächliche Problembeschreibung (weiter Infos gibt es unten):

      Ich übertrage seriell Daten von einem atxmega128 zu einem Raspberry 4, der diese Daten empfängt und ggfs. dann auf einen USB-Stick schreiben soll.

      Dazu läuft auf dem Raspberry ein kleiner Python Script im Autostart.

      Sobald dieser Script beendet wird (vermutlich durch einen Fehler), friert mein Bascom-Programm komplett ein.


      Hier der Aufbau:

      Der Raspberry 4 ist über die beiden Pins 8 und 10 mit meinem xmega128a4u Pin 26 und 27 verbunden (Com4)

      Der Python-Script läuft als systemd Service (vorher via Eintrag unter rc.local)


      Hier der Python-Script:

      Source Code

      1. #!/usr/bin/python
      2. #coding: utf8
      3. #!/usr/bin/env python
      4. import time
      5. import serial
      6. import subprocess
      7. import os.path
      8. ser = serial.Serial("/dev/ttyS0")
      9. ser.baudrate = 19200
      10. x = 0
      11. while 1:
      12. try:
      13. i=ser.readline()
      14. print i
      15. if ("record stop" in i):
      16. print "record stop"
      17. x = 0
      18. if ("record start" in i):
      19. print "record start"
      20. x = 1
      21. if ("umount" in i):
      22. cmd = "sudo umount -l /media/usb"
      23. os.system(cmd)
      24. if (x == 1):
      25. try:
      26. if os.path.ismount("/media/usb/"):
      27. File_Obj = open("/media/usb/reading.txt", "a")
      28. File_Obj.write(i)
      29. File_Obj.close
      30. ser.write("O")
      31. else:
      32. ser.write("F")
      33. except:
      34. print("error write usb")
      35. except:
      36. continue
      Display All


      Hier noch der Bascom-Code:


      Source Code

      1. '##### Konfigurations-Gedöns ##############################
      2. $regfile = "xm128a4udef.dat"
      3. $crystal = 32000000
      4. $hwstack = 64
      5. $swstack = 40
      6. $framesize = 40
      7. '##### mehr Gedöns ########################################
      8. $lib "xmega.lib"
      9. $lib "i2c_TWI.Lbx"
      10. $external _xmegafix_clear
      11. $external _xmegafix_rol_r1014
      12. '##### Echtzeit Gedöns ###################################
      13. Config Osc = Enabled , 32mhzosc = Enabled , 32khzosc = Enabled
      14. Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
      15. Config Clock = Soft , Rtc = 1khz_int32khz_rcosc , Gosub = Sectic
      16. Config Priority = Static , Vector = Application , Lo = Enabled ' the RTC uses LO priority interrupts so these must be enabled !!!
      17. Enable Interrupts
      18. '##### EEPROM Gedöns ######################################
      19. Config Eeprom = Mapped
      20. '##### LCD Gedöns #########################################
      21. $lib "glcdeadogm128x6.lib" ' specify the used lib
      22. Config Vport0 = D
      23. Config Graphlcd = 128 * 64eadogm , Cs1 = Port0.5 , A0 = Port0.3 , Si = Port0.1 , Sclk = Port0.2 , Rst = Port0.4
      24. '##### Debounce konfigurieren ##########################
      25. Config Debounce = 15
      26. '### Konfigurationsgedöns des Analog-Digital Wandlers #########################
      27. Config Adca = Single , Convmode = Unsigned , Resolution = 12bit , Dma = Off , _
      28. Reference = Intvcc , Event_mode = None , Prescaler = 32 , _
      29. Ch0_gain = 1 , Ch0_inp = Single_ended , Mux0 = &B00000000
      30. '###### Kalibrierung ADC - Version 3
      31. Dim Calibration_word As Word
      32. Dim Adca_byte_0 As Byte At Calibration_word Overlay
      33. Dim Adca_byte_1 As Byte At Calibration_word + 1 Overlay
      34. 'First we read the Calibration bytes form Signature Row (to get the real 12-Bit)
      35. Adca_byte_0 = Readsig(&H20)
      36. Adca_byte_1 = Readsig(&H21)
      37. 'Write factory calibration values to calibration register
      38. Adca_call = Adca_byte_0
      39. Adca_calh = Adca_byte_1
      40. '##### Konfig für die serielle Schnitstelle ###############
      41. Config Com5 = 9600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Terminal
      42. Config Com1 = 9600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'LCD
      43. Config Com4 = 19200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 'Raspberry
      44. 'Config Serialout5 = Buffered , Size = 20 'Terminal
      45. Config Serialout1 = Buffered , Size = 20 'LCD
      46. 'Config Serialout4 = Buffered , Size = 20 'Raspberry
      47. Open "COM5:" For Binary As #1 'Terminal
      48. 'Open "COM1:" For Binary As #3 'LCD
      49. 'Open "COM4:" For Binary As #4 'Raspberry
      50. '##### I2C starten ###############
      51. Dim Twi_start As Byte 'This Variable is used by the I2C functions
      52. Open "twie" For Binary As #2
      53. I2cinit 'set i2c pins to right state , open collector , pull up activated
      54. Config Twie = 100000 'Set TWI Baud Rate and Enable TWI Master
      55. '############## Variablendeklarationen ##############################
      56. 'Dim ca. 100 Variable as Igendwas
      57. 'Declare ca. 40 Subs
      58. '###### Die Main-Loop
      59. Do
      60. Open "COM1:" For Binary As #3 'Nextion
      61. Open "COM4:" For Binary As #4 'Raspberry
      62. 'Ich habe hier mal alles rausgeschmissen, damit es ein bisschen übersichtlicher ist (siehe Unterprogramme)
      63. Loop
      64. '##### Unterprogramme #########################################################
      65. 'Hier stehen nochmal 40 Unterprogramme und 4000 Zeilen Code
      66. End
      67. Sectic:
      68. If Per_ist = Per_soll Then
      69. Per_ist = 1
      70. Print #4 , "Day: " ; _day ; " Time: " ; Time$ ; " Value: " ; Lw ; " " ; Einheitanz ; " " ; ";"
      71. Else
      72. Incr Per_ist
      73. End If
      74. 'Clear Serialout4
      75. Close #4
      76. Return
      Display All



      Alles sehr verkürzt, aber an sich ist das alles keine Raketenwissenschaft.

      Der Pythonscript läuft und empfängt die Daten. Er reagiert auf die Steuerbefehle „record start“ und „record stop“ und zeichnet dann auch auf USB auf.

      Leider friert das System reproduzierbar ein.

      Mal nach wenigen Sekunden, mal nach mehreren Stunden (Rekord waren bisher 28 Stunden).

      Ich habe natürlich schon einiges versucht: Baudraten geändert. Serielle Verbindung in der Schleife beendet und wieder aufgebaut.

      Ich habe das ganze System ein zweites mal aufgebaut (mit Rasperry 2). Alles mit dem gleichen Ergebnis…

      Das einzige was ich herausgefunden habe und was überhaupt Hinweise liefert ist folgendes:

      Wenn der Python-Script im Raspberry unter /etc /rc.local eingetragen ist, dann sieht man ihn ja laufen, wenn man sich mit dem Befehl „top“ die Liste der laufenden Prozesse anschaut.

      Solange der Script dort erscheint ist alles OK.

      Aus einem nicht ersichtlichen Grund verschwindet er aber irgendwann dort und dann bleibt sofort mein Bascom-Programm stehen.

      Ich bin jetzt langsam mit meinem Latein am Ende und bin für jeden erdenklichen Hinweis dankbar.

      Ich vermute mal, dass es kein Bascom-Problem ist, aber sicher bin ich mir nicht.

      Also falls Ihr irgendwelche Ideen, Vorschläge, Geistesblitze habt, wäre ich Euch sehr dankbar!
    • Was mir auffällt, dass Du die Schnittstellen in der Main-Loop dauernd öffnest und wieder schließt.
      Ich verwende das "open" nur einmal bei der Konfiguration der Schnittelle(n) und das wars.
      In der Hilfe steht: "For the UART, SPI or other devices, you do not need to close the device"
      Des Weiteren verwendest Du einen gepufferten UART. Gibt es einen speziellen Grund dafür?
      Hast Du anstelle des Raspberry mal nen PC mit nem Terminal-Programm versucht?
    • Vielen Dank für die Antworten, Infos und die Unterstützung!
      Ich kann momentan wirklich jede Hilfe gebrauchen…

      Dass man in einer ISR nie einen Print ausgeben sollte, das wusste ich nicht.
      Wenn ich es richtig verstehe, dann macht man das also ungefähr so:

      Source Code

      1. Do
      2. If Flag = 1 then
      3. Print irgendwas
      4. Flag=0
      5. End if
      6. Loop
      7. Sectic
      8. Flag = 1
      9. Return
      Was das Öffnen, Schließen und Puffern der UART angeht, das sind alles verzweifelte Versuche.
      Ursprünglich habe ich die 3 Verbindungen bei Programmstart geöffnet, nicht geschlossen und auch nicht gepuffert.
      Ich habe auch schon mit der Baudrate experimentiert…

      Die anderen beiden seriellen Verbindungen, zum Display und zum PC (via FT232) funktionieren ja auch problemlos.
      Es ist ja auch nicht so, dass die Verbindung zu Raspberry nicht funktioniert. An sich geht sie ja, aber eben nicht zuverlässig.

      Ich verstehe einfach den Zusammenhang zwischen dem vermutlich abstürzenden Python Script auf dem Raspberry und dem einfrierendem Bascom Programm auf dem Xmega nicht.
      Über alle 3 Verbindungen wird ja lediglich ein Messwert ausgegeben und auf der anderen Seite wird dieser eingelesen.
      Wenn ich die Kabel vom Display abziehe, dann friert ja auch mein Bascom Programm nicht ein…
      Für mein Verständnis muss es da irgendeine Art der „Rückkopplung“ geben, die meinen Xmega zum Absturz bringt.
      Aber da ist guter Rat teuer…

      Also falls Ihr noch Ideen oder Änderungsvorschläge habt, gerne her damit.
      Ich stehe programmiertechnisch mit dem Rücken zur Wand und kann jede Hilfe brauchen….
      Tausend Dank vorab!
    • Da muss ich aber noch einmal nachfragen...
      Zu Beginn sagst du, das:

      lendl wrote:

      friert mein Bascom-Programm komplett ein.
      jetzt sagst du, das

      lendl wrote:

      die meinen Xmega zum Absturz bringt
      was passiert denn genau?
      Resettet der Xmega oder bleibt er einfach in "hängen" und das Programm läuft nicht weiter?
      Hast du den watchdog eingeschaltet?

      Duesentrieb72 wrote:

      Hast Du anstelle des Raspberry mal nen PC mit nem Terminal-Programm versucht?
    • Super! Danke für Eure Antworten!

      @six1
      Ein Optokoppler ist auf alle Fälle einen Versuch wert. Das ist ne gute Idee!
      Kannst Du mir zufällig einen empfehlen?

      @Duesentrieb72
      Er bleibt einfach hängen:
      Ich lese mir Messwerte eines I2C AD-Wandlers mit meinem Bascom Programm ein und gebe diese Messwerte kontinuierlich über die COM5 an den PC, über die COM1 an ein Nextion LCD und über die COM4 an den Raspberry aus und kann mir die da anschauen.
      In dem Moment, wenn auf dem Raspberry das Python-Script "abstürzt", friert die ganze Sache ein, d.h. auf meinem Display bleibt einfach der letzte Wert stehen und auf dem PC hört die Ausgabe der Werte (im Putty Fenster) einfach auf.

      Den Watchdog habe ich nicht eingeschaltet, weil beim starten die Messwerte manuell tariert werden müssen und das beim unbeaufsichtigten Reset ja nicht passieren würde. Folglich würden dann falsche Werte dargestellt werden.

      @alle
      Diese Schaltung und das Bascom Programm laufen schon länger und es gab nie Probleme.
      Neu an der ganzen Angelegenheit ist der Raspberry. Ich vermute hier ja auch den Fehler, aber ich kann keinen Zusammenhang finden.
      Falls Ihr also noch irgendwelche Ideen habt, wie und wo ich suchen kann, her damit, ich bin für jeden Vorschlag dankbar!