cancel
Showing results for 
Search instead for 
Did you mean: 

Write into flash while USART interrupt executed

Clemens Ehm
Associate II
Posted on October 23, 2017 at 12:33

Hello,

I have some trouble to write into the flash of my stm32f I can send via usart a lot of commands to the µC, interprete and execute them finally. One command is to write some data into the flash but if I write and the usart is still receiving data, the communication is totally dead - only mcu reset helps.

The only 'solution' which doesn't crash the communication is to deactivate the usart with USART1->CR1 &= ~USART_CR1_UE; before I write into flash and re-enable it after the flash operation - but that's not a real solution cause I will lose data/commands.

What I tried:

- Moving the vector table into SRAM

- Disable the usart interrupt (NVIC_DisableIRQ(USART1_IRQn);)

-

__disable_irq

(

)

;

before the flash operation

Without any effect. The linker script has the following settings:

MEMORY

{

FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K

UNUSED (rx) : ORIGIN = 0x8020000, LENGTH = 128K

RAM (xrw) : ORIGIN = 0x200000C0, LENGTH = 32K - 0xC0

}

I always write into the UNUSED section, not the FLASH where the running firmware is stored.

The best solution would be to disable the interrupt for the flash-write-time, the mcu buffering all incoming packages for the moment and after re-enabling the interrupt I receive the buffered data. Is that somehow possible or you have any other useful hints for me?

Thanks

Note: this post was migrated and contained many threaded conversations, some content may be missing.
19 REPLIES 19
Posted on October 25, 2017 at 11:59

Is the DMA buffer large enough to hold all the data you expect during flash write?

Posted on October 25, 2017 at 13:14

Some library or function is likely touching FLASH, code needs to be very carefully crafted to be entirely functional from RAM.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 26, 2017 at 08:56

No the buffer is not large enough

🙂

I dont know a good solution for the interrupt execution condition. The DMA Interrupt is called after every received byte. The input can be very different. It's possible I receive over 1000 Byte but also possible I receive only 5 Byte for example. 

Posted on October 26, 2017 at 11:57

At what baudrate comes data from the serial line? Provide a buffer that can keep serial data for 40 ms (page erase time) and break up flash code to yield after at perhaps 20 ms. Do not erase multiple pages without intermediate yield. ' The DMA Interrupt is called after every received byte' also sounds strange . DMA should only provide interrupt when a full buffer was received.

Posted on October 26, 2017 at 15:51

115200 baud... that's 14400 bytes in one second. For 40ms I would need a buffer with a size of 576 bytes. I totally agree it's strange (or I would call it stupid

🙂

) to use DMA for only one byte. But again: I don't know the count of incoming data. It's possible I receive only 50 Bytes and then 30 seconds nothing. I guess I need some dma buffer timeout but is that possible and how?
Posted on October 26, 2017 at 16:06

You can query the DMA count register to see how many characters arrived, or better how many characters still miss from the required size.

Posted on October 26, 2017 at 16:41

Okay I didn't know that I will try to handle it with a bigger buffer and use the DMA_GetCurrDataCounter. Thanks for your help

Posted on October 26, 2017 at 17:23

Okay I have to ask you again something.

If I define the Buffer with 100 Bytes and nothing is inside, the function DMA_GetCurrDataCounter return the value

If I received 5 Bytes now, the return value is Now what's a save way to extract the 5 Bytes from the buffer without disturb a possible current usart communication and losing incoming packages?

Posted on October 26, 2017 at 18:25

I'm still confused by the merits of '

USART1->CR1 &= ~USART_CR1_UE or RE', it doesn't stop the pins banging up and down, or the host continuing to send data, and opens the window to synchronization and framing issues.

Important to understand what state the USART gets into that requires a reset. Please post peripheral registers from cases where it gets into this state.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 26, 2017 at 18:27

>>

115200 baud... that's 14400 bytes in one second.

Likely to be less than 11520 with framing and inter-symbol

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