- LiFePO4 Speicher Test         
Ergebnis 1 bis 6 von 6

Thema: Im Rinfpuffer suchen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    25.05.2008
    Ort
    Korntal-Münchingen
    Alter
    42
    Beiträge
    15

    Im Rinfpuffer suchen

    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen,

    ich habe ein kleines Problemchen, okay, es sind zwei in einem.

    Und zwar, habe ich einen UART-Ringpuffer:

    Code:
    #define UART_BUF_SIZE	128
    
    char UART0_buffer[UART_BUF_SIZE];
    unsigned char in0_ptr;
    unsigned char out0_ptr;
    Der Ringpuffer wird von den Funktion (bzw. Interrupt) befüllt:

    Code:
    ISR(USART0_RXC_vect) {
    	UART0_buffer[in0_ptr] = UDR0;
    	in0_ptr++;
    	
    	if (in0_ptr == UART_BUF_SIZE){
    		in0_ptr = 0;
    	}
    }
    Soweit, so gut.

    Nun habe ich folgendes Problem: Wie kriege ich das hin, dass ich im Ringpuffer suchen kann?

    Angenommen, ich habe eine Nachricht, die so aussieht:

    Code:
    // Bremsbeläge
    char brake_pads_msg[] PROGMEM = {0x02, 0x04, 0x01, 0xC8, 0x3E, 0xF1};
    Wie kriege ich das hin, dass ich solche Nachrichten im Datenstrom finden kann?

    Das war das erste Halbproblem.

    Hier das zweite Halbproblem:

    Angenommen, ich habe eine Teilnachricht, die ich im Datenstrom suchen will. Diese sieht dann so aus:

    Code:
    // Verbrauch1:
    char consumption1_msg[] PROGMEM = {0x02, 0x05, 0x01, 0x92};
    Hier ist es etwas schwieriger. Die zweite Stelle dieser Nachricht, also 0x05 gibt die Länge der Nachricht an. Der Punkt ist, dass die Nachricht an sich sich ändert, nur dieser Header ist immer gleich. Das würde bedeuten, dass ich nach diesem Header suchen muss, wenn ich den Header gefunden habe, muss ich die ganze Nachricht extrahieren und dann auswerten.

    Hier ein Beispiel der vollständigen Nachricht:

    0x02, 0x05, 0x01, 0x92, 0x95, 0x83, 0x82

    0x02: Ist der Sender der Nachricht
    0x05: Ist wie gesagt die Länge der Nachricht ab dem nächsten Byte
    0x01: Ist der Empfänger
    0x92: Nummer der Funktion (ist uninteressant für dieses Beispiel)
    0x95 und 0x83 sind die Nutzdaten
    0x82: XOR CRC

    Die Länge wird ab dem dritten Byte bis CRC angegeben und sie ist wie gesagt immer gleich bei dieser Art der Nachrichten.

    Vielen Dank im Voraus.

    Achja, ganz vergessen, der Mikrocontroller ist ein AtMega162.

    Grüsse
    Heinrich

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    statt mit einem pointer das array zu befüllen wwürde ich mit 2 inizes arbeiten

    Code:
    int writecount;
    int readcount;
    
    ISR(){
       Buff[writecount++] = RxByte;
    }
    
    ...
       bytestoread = writecount - readcount;
       if (bytestoread < 0) bytestoread += buffsize;
       if (bytestoread > 1) { // mehr als 2 bytes empfangen (also auch das längebyte)
          if ((bytestoread > buff[readcount+1]+2)   // ausreichend bytes anhand der länge im paket ?
             && (getCRC(&buff[readcount]) == buff[buff[readcount+1]+2])) { // crc nachrechnen und mit der im paket vergleichen
                 doyourwork();
          }
       }
    ACHTUNG dieser code kann rechenfehler beinhalten, aber so ungefähr habe ich das gelöst

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    09.02.2006
    Beiträge
    57
    Hi!

    @Ceos: Wieso pointer? Er füllt den Empfangsbuffer doch auch über einen Index.

    Gruß
    Jonas
    Gruß
    Jonas

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.01.2007
    Beiträge
    134
    Naja also nach Nachrichten suchen ist doch nicht so schwer:
    Mit ner for-Schleife alle Elemente abgehen, jedesmal prüfen ob brake_pads_msg[i] drinsteht, falls ja prüfen ob brake_pads_msg[i+1] dahintersteht usw.
    Mit variablen dann halt etwas spezieller schreiben und die Prüfung für Pufferüberlauf nicht vergessen bzw. am Anfang weitersuchen.

    Grüsse, Stefan

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    25.05.2008
    Ort
    Korntal-Münchingen
    Alter
    42
    Beiträge
    15
    Hallo Leute,

    vielen Dank für die Ratschläge.

    Ihr meint sowas, oder:

    Code:
    	while (out0_ptr < in0_ptr) {
    		out0_ptr++;
    		if (uart0_buffer[out0_ptr]== brake_pads_msg[0]) {
    			if (uart0_buffer[out0_ptr+1]== brake_pads_msg[1]) {
    				if (uart0_buffer[out0_ptr+2]== brake_pads_msg[2]){
    					if (uart0_buffer[out0_ptr+3] == brake_pads_msg[3]) {
    						printf("BrakePads gefunden\n");
    					}
    				}
    			}
    		}
    	}
    Grüssle
    Heinrich

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.01.2007
    Beiträge
    134
    Jo fast nur dass [out0_ptr+1] halt doch mal auf das letzte Element zeigen kann und mit +1 wäre das dann undefinierter Speicher, also lieber vorher prüfen z.B. so:
    Code:
    while (out0_ptr < in0_ptr)
    {
        uint8_t i = ++out0_ptr;
        if (uart0_buffer[i++]== brake_pads_msg[0])
        {
            if (i >= UART_BUF_SIZE)
    			i = 0;
            if (uart0_buffer[i++]== brake_pads_msg[1])
            {
    			if (i >= UART_BUF_SIZE)
    				i = 0;
                if (uart0_buffer[i++]== brake_pads_msg[2])
                {
    				if (i >= UART_BUF_SIZE)
    					i = 0;
                    if (uart0_buffer[i++] == brake_pads_msg[3])
                    {
                        printf("BrakePads gefunden\n");
                    }
                }
            }
        }
    }

    Blöde Frage aber kann das überhaupt funktionieren mit dem Ringpuffer bei
    (out0_ptr < in0_ptr), wenn out0_ptr z.B. knapp UART_BUF_SIZE ist und in0_ptr z.B. 0 oder 1 ist? Nach der ISR oben is das zumindest möglich.

    Grüsse, Stefan

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress