2016-04-14 10:16 PM
Hi,
I am using STM32L4xx MCU to interface micro SD card of 2GB over SDMMC1 interface. The FatFs and FreeRTOS is also integrated with the firmware. There are other peripherals interfaced over SPI and I2C.Scenario:FatFs, SD card and the peripherals are initialized successfully in the beginning. The peripheral over SPI (Peripheral &sharp1) generates external interrupt at every 4 ms and the peripheral over I2C (Peripheral &sharp2) generates external interrupt at every 10ms. I am using DMA to write data on SD card.Now, firmware reads 11 bytes of data and put it into the circular buffer in the ISR of Peripheral &sharp1. There is a thread, which reads these data from the circular buffer and writes it on the SD card. The thread creates new file at every 30 seconds. Firmware reads 12 bytes of data at every 10ms in the ISR of Peripheral &sharp2, but currently these data is unused.External interrupt priority of Peripheral &sharp1 is 4 and of Peripheral &sharp2 is 5. The SDMMC interrupt priority is 6 and SD card DMA channels priority is 7.Problem:The f_open() and f_write() function calls fail randomly and once it goes into this state it never comes out of it. This thing works perfectly fine when the peripheral interrupts are disabled during the SD card operation in the thread!! But I can't keep the interrupts disabled, as it'll leads to data loss and I can't afford to lose the data.I also tried to keep the interrupt priority equal to the priority of SDMMC interrupt, but that didn't work.Please help me to resolve this issue.Appreciate your quick help.Thanks,Dhaval #stm32l4 #hal #fatfs #microsd2016-04-19 12:48 AM
Someone, please help me here. This is really a critical issue for me.
2016-04-19 02:41 AM
Hi, Dhaval
The problem is not due to the processor. SD cards have write latency, which can reach tens of ms. There is a controller in it with unpredicted behaviour. Therefore my advice is: write incoming data in a temporary buffer and store it to SD card every 100ms. Regards, Serafim Merkulov2016-04-19 04:41 AM
Hi Merkulov,
Thanks for your reply.Actually currently also, I am accumulating data of 32 ms and then write it on to the SD card. And I can increase that time to 100ms too. But the my question is, still do I need to disable the peripheral interrupts while SD card write operation?If yes, then is there any way to resolve it? Because as I said before, I can't disable the interrupts.Thanks,Dhaval2016-04-19 05:13 AM
I'd use buffers that are coherent with the blocking sizes of the media, rather than time.
No real reason interrupts should be an issue, unless they are doing excessive amounts of work and blocking execution. If you have one critical to operation, it should pre-empt. What exactly is the SD interrupt doing? Most of the SD criticality is supplying data rapidly during the data phase. The interrupt needs to ensure that the DMA, FIFO, and controller have completed so the next command can start. Not looking to wade into L4/HAL issues.2016-04-19 05:33 AM
Hi Clive,
Thanks for your reply.I used the buffers related to time to quickly check test the data writing on SD card along with on-board peripheral. But does it lead to this kind of problem? Do you want me to try with the buffer size coherent to the media block size?In peripheral ISR, firmware is reading data from peripheral over SPI and putting it into the circular buffer, nothing else. So that should not hamper the SD card write operation. Also, I tried to set the peripheral interrupt priority to higher, lesser and equal to the priority of SDMMC/DMA, but none of them worked!The SDMMC ISR is as it is in the HAL driver of SD card, I haven't modified it. I think it is verifying the data transfer is complete through DMA and sets appropriate bit. This bit is checked by the DMA transfer complete callback. And that's how the DMA write completes.Please help.Thanks,Dhaval2016-04-19 06:05 AM
The size of the writes will have a significant impact on the time spent writing in the SD card. I don't see this as the issue here.
Be careful with ''Priority'' it orders how it transitions from one interrupt to the next. If you want to break into another interrupt, you need ''Preemption'' The HAL has some hidden delays/loops, you'll have to dig into these to understand the internal mechanics, I'm not doing that. The ticker interrupt needs to preempt everything. The most probable issue is that the SD interrupt is occurring before you are expecting it, due to delays introduced by other code.2016-04-20 01:09 AM
Hi Clive,
I am writing only peripheral #1 data to the SD card. And reading that data over SPI in ISR of that peripheral.Let me explain the interrupt priorities here, that I tried:1. Periperhal #1 = 4, Peripheral #2 = 5, SDMMC1 = 6 and DMA = 72. Periperhal #1 = 6, Peripheral #2 = 7, SDMMC1 = 4 and DMA = 53. Periperhal #1 = 5, Peripheral #2 = Disabled, SDMMC1 = 4 and DMA = 54. Periperhal #1 = 4, Peripheral #2 = Disabled, SDMMC1 = 4 and DMA = 5But in all cases the write was failed after some time. Would you please suggest any other priority, that I should try?I also tried to write 512 bytes in each write , a media block size, but still no luck!I am also using FreeRTOS, so the SysTick is used by FreeRTOS. It's priority is set to 15 (Lowest). And I am using Timer 1 as Time Base and it's interrupt priority is set to 0 (Highest).I am not able to understand this ''SD interrupt is occurring before you are expecting it, due to delays introduced by other code''. Please help me to understand it. Thanks,Dhaval2016-04-20 03:39 AM
It is akin to waiting for a bus you have already missed. You must recognize that it already passed.
I'm not sure how premption is handled in your system.2016-06-06 10:46 PM
Hi Clive,
Sorry for delayed response.As you suggested, I have tried to write on the card in the chunks of 512 bytes. But still the issue persists. So to debug it further, I disabled all the peripherals and their respective interrupts. Just writing dummy data to the SD card and enables Timer to generate interrupt at same frequency as the peripheral interrupt. Then everything works fine!!Now, I enable the peripheral, connected over SPI1,. It generates interrupt at every 4ms. As I explained before, in that ISR I am reading data from peripheral over SPI. When I kept this interrupt enabled and disables the SPI operations everything works fine.So I thought SPI is playing spoil sport here. So I implement DMA for SPI1 too. But even after that issue persist. I am not able to understand what is wrong here.I would appreciate if you can help me here. Let me know if you need any other information.Regards,Dhaval