c - How to design a function which identifies when "+IPD," is arrived from UART? -
i'm working tiva launchpad ek-tm4c123gxl , esp8266 wifi module.
when module gets wifi packet, sends microcontroller through uart port.
the format used esp8266 send packet (to uc via uart) is:
+ipd,n:xxxxx\r\nok\r\n
where:
n
length (in bytes) of data packet:
indicates next byte first data bytexxxxx
data packet\r\nok\r\n
6 bytes , useless me.
for example:
+ipd,5:hello\r\nok\r\n
here situation:
i'm working on existing project, can't change these 2 things:
1- uart module configured generate interrupt when receive fifo (of 16 bytes) half-full.
2- isr (interrupt service routine) handles interrupt:
reads 1 byte uartdr (uart data register)
saves variable
calls function (called rx_data()) handle byte.
now, have write function, called rx_data(), in c language.
so, message coming form esp8266 module passed function, rx_data(), 1 byte @ time, , function must able to:
identify header
+ipd,
read length
n
of data packetsave data packet
xxxxx
(which located after:
character , before first\r
character) bufferdiscard final bytes
\r\nok\r\n
(these 6 bytes useless me, but, anyway, must read them remove them receive fifo)
i think work step step, i' m reasoning on:
how identify +ipd,
, considering only 1 byte @ time passed function?
it's time make state machine. every time rx_data
called, update state of state machine, , @ point know have received string "+ipd,".
the simplest thing work this, assuming byte received uart passed argument rx_data
:
void rx_data(uint8_t byte) { static uint8_t state = 0; if (byte == '+') { state = 1; } else if (state == 1 && byte == 'i') { state = 2; } else if (state == 2 && byte == 'p') { state = 3; } else if (state == 3 && byte == 'd') { state = 4; } else if (state == 4 && byte == ',') { state = 0; handleipdmessage(); // received "+ipd," } else { state = 0; } }
you can see handleipdmessage()
called if , if last characters received "+ipd,".
however, should consider writing more general state machine operate on lines instead of looking 1 string. easier write , more robust. when complete line received, call function named handlelinereceived()
handle line. function have access buffer entire line, , parse in whatever way wants to. (just careful never write beyond end of buffer.)
by way, wouldn't putting logic in isr. it's best keep isrs simple , fast. if not doing already, store byte circular buffer in isr , read circular buffer in main loop, , every time read byte circular buffer call function rx_data
function described above process byte.