cancel
Showing results for 
Search instead for 
Did you mean: 

IAP over GSM: UART and Flash programming

gmate1
Associate II
Posted on January 07, 2016 at 16:29

Hi,

I'm developing an IAP application for firmware upgrade over GSM network. I've a SIM800H module connected to STM32 over UART interface and I'm able to establish GSM connection, setup HTTP GET request and on wire (I'm listening on SIM800-STM32 UART tx/rx lines) I see that HTTP GET works fine (I see that the data matches the firmware hosted on server). I would like to write this hex format firmware image into main flash memory, starting from an area reserved for application firmware and to do so, In my IAP driver code, I unlock the flash and start programming the flash memory by using APIs from STM32 library, however there is a mismatch between data (firmware hex file) received over UART and what's actually written in the memory. Please advice. More information below:

Snip from UART IRQ handler: file1:: uart.c
-----------------------------------------
volatile 
int
start_capture = 0;
void
process_reception(uint16_t data)
{
static
volatile 
int
rx_index = 0;
static
volatile uint8_t rx_buffer[4];
volatile uint32_t val = 0;
static
volatile uint32_t flashaddress = 0x08004000;
static
volatile 
int
seen = 0;
/* Special case for firmware hex file download */
if
(start_capture) 
/* this flag is set after successful response for HTTPREAD execute command */
{
/* Though we are told to start capturing the firmware hex file,
* we should wait until a particular character arrives
*/
if
(data == 0x3A) 
/* hex format firmware starts with this character */
seen = 1;
if
(seen)
{
if
(rx_index == 3)
{
/* ***: Since the programming is done either a word basis or
* half word basis by the STM API, Is it correct way of
* using the API ? */
val = (rx_buffer[0] << 24) + (rx_buffer[1] << 16) + (rx_buffer[2] << 8) + (rx_buffer[3]);
if
((FLASH_ProgramWord(flashaddress, val) == FLASH_COMPLETE))
{
flashaddress += 4;
}
rx_index = 0;
}
else
{
rx_buffer[rx_index++] = data;
}
}
else
{
; 
/* do nothing, wait for the special character */
}
} 
/* end of start capture */
/* some more code here, not relevant here */
}
void
USART1_IRQHandler(
void
)
{
/*
* some code for TX, not relevant here
*/
if
(USART_GetITStatus(peripheral->USARTx, USART_IT_RXNE) != RESET)
{
process_reception((
char
) USART_ReceiveData(USART1);
}
}

void
uart_init(
void
)
{
USART_InitTypeDef USART_InitStructure;
/* Restore UART to it's default state */
USART_DeInit(USART1);
/* configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
Initiating the firmare capture from a different routine (file2:: app.c)
-----------------------------------------------------------------------------------
extern
volatile 
int
start_capture;
void
foo(
void
)
{
/*
* checking the response after sending AT+HTTPREAD execute command
*/
if
(strncmp(rsp, 
''+HTTPREAD:''
, 10) == 0)
{
start_capture = 1;
}
}

snip from AT+Command logs ------------------------------------ +HTTPACTION: 0,200,4437 AT+HTTPREAD +HTTPREAD: 4437 :020000040800F2 :1040000070060020D5400008F5410008D1410008A5 :1040100000000000000000000000000000000000A0 /*goes on */ ............... OK AT+HTTPTERM OK #stm32 #stm32 #usart #iap #iap #flash #flash #stm32f0 #solved
13 REPLIES 13
gmate1
Associate II
Posted on January 13, 2016 at 19:21

That seem to be the only option left. I opened the bin file in a hex editor and found that there are consecutive occurrence of CR and LF in the firmware data also. So blindly parsing based on CR and LF will not work

As you have suggested, I'm thinking of collecting the data stream in the ISR in a little bigger buffer than the payload size returned from GSM, then parse it somewhere else to produce a final buffer that will be ultimately written into memory.

gmate1
Associate II
Posted on January 19, 2016 at 14:34

Got it working :)

With a 2kB receive buffer (had to change the default stack size in system startup file), baud rate of 115200, it took about 90 seconds to download and program the application firmware of about 23kB (binary file) in size. Many thanks to Clive1 and now I plan to add some failover, Firmware validation and security checks and will probably open a different thread to discuss and get some ideas on these topics.

Hi gmate,

Am also trying to develop FOTA using GSM http ,am also getting same problem that gsm module responses are also getting stored when am reading bin file. please help me out in solving this issue. that how to remove the http command responses .

regards

shreyas

Be conscious that this thread is 3 years old, and removing HTTP responses seems like a pretty basic stream parsing task. If the STM32/ARM aspect adds complexity perhaps try implementing a Berkeley Sockets (nee WinSock) version on a PC and test/analyze the task there first.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..