Re: Übertragung von großen Datenblöcken Kategorie: Programmierung (von Detlef Bäthke - 19.04.2005 17:09) | ||
Als Antwort auf Übertragung von großen Datenblöcken von Epp - 19.04.2005 10:18 | ||
| ||
Hallo, ich sende immer 2 bis 8 Kbyte an das CC2. Bei solchen Datenmengen sollte man aber ein Protokoll verwenden, damit �bertragungsfehler abgefangen werden. Ich würde die Daten in ein Bytearray verpacken. Mit mem.getfloat kann man die Werte auf der CC2 Seite wieder aus dem Bytearry auslesen. Hier sind mal einige Auszüge aus meiner Anwendung. Botschaftsaufbau Senden: Alle Daten zwischen dem Tester und dem CC2 sind Hexadezimalzahlen . byte 4 Byte Header #1 Command #2 Header CS #3 Data CS #4 Data length Header CS = byte #1 + byte #3 + byte #4 Data CS = byte #5 + ... + byte #n Botschaftsaufbau Empfangen: Alle Befehle, die vom Tester zum CC2 gesendet werden , werden quittiert. Positive Quittung: Befehlscode wird wiederholt. Negative Quittung: Statt dem Befehlscode wird der Errorcode gesendet. byte 4 Byte Header #1 Command / Errorcode #2 Header CS #3 Data CS #4 Data length ByteArray_Write Befehlsbyte: 07 hex Daten vom Tester in das Bytearray des CC2 übertragen. Tester * CC2 byte 4 Byte Header + n Bytes #1 Command #2 Header CS #3 Data CS #4 Data length #5 start address MSB #6 start address LSB #7 Byte #1 Word #1 MSB #8 Byte #2 Word #1 LSB : Byte #n CC2 * Tester Byte 4 Byte Header + 5 Bytes #1 Command #2 Header CS #3 Data CS #4 Data length #5 start address MSB #6 start address LSB #7 length #8 max address MSB #9 max address LSB -----CC2 ----------------------------------------- // Programmierung 24C16, 93C86 und 25C640 //---------------------------------------- byte EEDataWrite[0x2000]; // Solldaten für das Eeprom byte EEDataRead[0x2000]; // Istdaten des Eeproms für Verify int Error; // Fehlercode long ee242593_Error; // Fehlercode EE93C86 Routinen byte HWcombuf[150]; // Puffer für HWCOM byte RXDbuf[160]; // Speicher für empfangene Daten HWCOM byte TXDbuf[160]; // Speicher für zu sendende Daten HWCOM byte TXDdata[160]; // Speicher für zu sendende Daten byte command; // Befehlscode byte HeaderCS; // Header-Checksumme byte DataCS; // Datenchecksumme byte Datalen; // Datenlänge byte TXDdatalen; // Länge der zu sendenden Daten byte CFG_bck12; // Barcodekopf Stelle 1,2 byte CFG_bck34; // Barcodekopf Stelle 3,4 int CFG_end_address; // Konfiguration: Endadresse EEprom int CFG_end_address_byte; // Konfiguration: Endadresse Bytearray byte CFG_org; // 1 = 8 Bit, 2 = 16 Bit byte CFG_eetyp; // 1 = 93C86 2 = 24C16 3 = 25C640 byte CFG_init_value; // Konfiguration: 00 oder FF Defaultwert für EEpromdaten long CFG_checksum; // Checksumme EEDaten byte CFG_status; // Konfiguration: 0 = nicht durchgeführt byte EETXDdata[16]; // Fehlermeldung der EEprom Routinen byte EETXDdatalen; // Länge der Fehlermeldung byte EETask; // Merker, ob Eeprom Task gestartet wurde -1 = ja //---------------------------------- inline function IncInbuffercnt () //---------------------------------- { inline 0x144; // Load Immediate Bytevalue "1" inline vmcodes.VM_LOAD_ABSOLUTE_INT; inline 0xF962; inline 0x45; // ADD inline vmcodes.VM_STORE_ABSOLUTE_INT; inline 0xF962; } //----------------------------- function Parameter_Tester2Buf() //----------------------------- // Befehl 07: Eepromdaten von Tester in das Bytearray übertragen { int k; int Startaddress; int Length; EETask = 0; if CFG_status == 0 Error = 0x88; else { Startaddress = mem.getint(RXDbuf,0); Length = Datalen -2; mem.putint(TXDdata,0, Startaddress); TXDdata[2]= Length / CFG_org; mem.putint(TXDdata,3, CFG_end_address); TXDdatalen = 5; if ((Startaddress * CFG_org) + Length - CFG_org) > (CFG_end_address * CFG_org) { Error = 0x87; } else { mem.copypos ( EEDataWrite, (Startaddress * CFG_org), RXDbuf,2, Length ); } } } // Ende Parameter_Tester2Buf //------------------------------- function TXDQuittung(byte TXDcmd) //------------------------------- // Quittung senden { byte k; string s; DataCS = 0; Datalen = TXDdatalen; if Datalen > 0 { for k = 0 ... (Datalen -1) { DataCS = DataCS + TXDdata[k]; TXDbuf[k+4]= TXDdata[k]; } } TXDbuf[0] = TXDcmd; TXDbuf[2] = DataCS; TXDbuf[3] = Datalen; TXDbuf[1] = TXDbuf[0] + TXDbuf[2] + TXDbuf[3]; hwcom.send(TXDbuf,Datalen + 4); wait hwcom.ready(); } // Ende TXDQuittung //----------- thread main //----------- { int i; byte cs; string s; byte cmd_reset; //Variablen initialisieren CFG_bck12 = 0; CFG_bck34 = 0; CFG_end_address = 0; CFG_init_value = 0; CFG_checksum = 0; CFG_status = 0; CFG_org = 0; CFG_eetyp = 0; EETask = 0; cap.init(); hwcom.init (); // Init hwcom.setspeed(hwcom.SPEED_19200); // Baudrate setzen //hwcom.set_S0CON (hwcom.set8N1); // 8Bit, no parity, 1 stop bit hwcom.setbuf(HWcombuf,150); // standard buffer hat nur 64 byte // lcd.init(); //lcd.clear(); // wait lcd.ready(); // Ports auf Ausgang und Low schalten ports.set( 0,0); ports.set( 1,0); ports.set( 2,0); do // endlosschleife { Error = 0; cmd_reset = 0; command = 0; DataCS = 0; Datalen = 0; TXDdatalen = 0; hwcom.flush(); //Buffer löschen; wait hwcom.rxd(); // Wartet auf Daten. Gibt -1 zurück, sobald Daten im Puffer i = hwcom.receive (RXDbuf, 4, 25); // die ersten 4 byte einlesen if i != 4 Error = 0x8A; //Fehler, kein 4 Byte Header if Error == 0 { HeaderCS = RXDbuf[0] + RXDbuf[2] + RXDbuf[3]; if HeaderCS != RXDbuf[1] Error = 0x81; // Fehler HeaderCS if Error == 0 { command = RXDbuf[0]; DataCS = RXDbuf[2]; Datalen = RXDbuf[3]; if Datalen > 0 // restliche Daten abholen { i = hwcom.receive (RXDbuf, Datalen, Datalen ); if i != Datalen // zu wenige Daten { if i == (Datalen - 1) // ein Byte fehlt { IncInbuffercnt (); // Fehler in OSOPT V3.0 // sporadisch fehlt ein Byte RXDbuf[Datalen-1] = hwcom.get(); } else { Error = 0x85; TXDdata[0]= i; TXDdata[1]= Datalen; TXDdatalen = 2; // mem.copypos(TXDdata, 2, HWcombuf, 0, 150); // TXDdatalen = 152; } } if Error == 0 { cs = 0; for i = 0 ... (Datalen - 1) cs = cs + RXDbuf[i]; if DataCS != cs Error = 0x82; // Fehler DatenCS } } } if Error == 0 { if (command > 0) and (command < 0xF) // Befehl bekannt ? { if (command == 3) // Reset-Befehl { cmd_reset = -1; } else { if (cap.Get(1)== 0) // Eeprom Prozess aktiv? { if (command != 0xB) Error = 0x89; // nur Status Befehl erlaubt else ee242593_Status(); } else { if (command == 1) Software_Version(); if (command == 2) Error = 0x83; // change Baudrate if (command == 4) Config_Write(); if (command == 5) Config_Read(0); if (command == 6) Parameter_Buf2Tester(); if (command == 7) Parameter_Tester2Buf(); if (command == 8) ee242593_Write(); if (command == 9) ee242593_Verify(); if (command == 0xA) ee242593_Task(); if (command == 0xB) ee242593_Status(); if (command == 0xC) ee242593_Read_Direct(); if (command == 0xD) ee242593_Write_Direct(); if (command == 0xE) Config_Read(-1); } } } else { Error = 0x83; // unbekannter Befehl } } } if Error != 0 // Fehler oder normale Quittung { TXDQuittung(Error); } else { TXDQuittung(command); } } while cmd_reset == 0; // bei Reset Befehl Schleife beenden quit -1; } //main ------------ Visual Basic --------------- Private Sub CMD_WriteAll_Click() Dim TXDstr As String Dim k As Integer Dim L As Integer Dim TXRXtime As Long Dim Paketsize As Integer Dim pa_word As Long TXRXtime = GetTickCount() Select Case CC2_eeprom_typ Case Else CC2.Parameter_24C16 Paketsize = &H80 For k = 0 To CC2_CFG_end_address Step Paketsize TXDstr = Chr$(k 256) & Chr$(k Mod 256) For L = 0 To (Paketsize - 1) If k + L > CC2_CFG_end_address Then Exit For TXDstr = TXDstr & Chr$(CC2_PA(k + L)) Next L If Len(TXDstr) <> (2 + Paketsize) Then Form_Main!List_Messages.AddItem "Paketsize: " & Hex$(Len(TXDstr)) Form_Main!List_Messages.Selected(Form_Main!List_Messages.ListCount - 1) = True DoEvents Call CC2_LOGTXRX(TXDstr, "") End If CC2_Status = CC2_TXRX(&H7, TXDstr) If CC2_Status > 0 Then Exit For End If Next k End Select Form_Main!List_Messages.AddItem "TXRXTime: " & Format(GetTickCount() - TXRXtime) & " ms" Form_Main!List_Messages.Selected(Form_Main!List_Messages.ListCount - 1) = True DoEvents End Sub Gru� Detlef | ||
Antwort schreiben Antworten: Re: Übertragung von großen Datenblöcken (von Epp - 21.04.2005 17:50) |