This article is a supplement to the original http://blog.csdn.net/flydream0/article/details/52777923.
The original text does not consider the SD card unplugged problem, and Sdio does not use DMA, this article as a supplement, the example how to improve these two aspects of the problem.
1 SD card Plug and Socket detection
The Fatfs file system was initialized with the following modifications:
void MX_FATFS_Init(void) { /*## FatFS: Link the SD driver ###########################*/ retSD = FATFS_LinkDriver(&SD_Driver, SD_Path); /* USER CODE BEGIN Init */ /* additional user code for init */ /* USER CODE END Init */}
That is, keep cubemx automatically generated as it is, and there is no need to add any additional content.
The key is to detect the SD card unplugged in the while loop in main:
while(1) {/* user code END while */* user code BEGIN3*/Cursdcardstatus =bsp_sd_isdetected ();if(Cursdcardstatus!=presdcardstatus) {switch (cursdcardstatus) { CaseSd_present:bsp_sd_init (); Mountfat32filesystemimmeditely (); Break; CaseSd_not_present:unmountfilesystem (); Fatfs_unlinkdriver ("0:/"); Break; } presdcardstatus =cursdcardstatus; }//Hal_gpio_togglepinch(led1_gpio_port,led1_pinch);//Hal_gpio_togglepinch(led2_gpio_port,led2_pinch);//Hal_gpio_togglepinch(led3_gpio_port,led3_pinch);//Hal_gpio_togglepinch(led4_gpio_port,led4_pinch);//Hal_delay ( $); }
As the code above, the loop detects the insertion state of the SD card and, once the status has been detected, the corresponding operation, such as mounting the file system, or uninstalling the file system.
Mount File System
Static intMountfat32filesystem (void) {fresult ret; RET =f_mount (&sdfatfs,"0:/",0);if(ret!= FR_OK) {if(Ret ==fr_disk_err) {//if (F_MKFS ((TCHAR const*) sd_path, 0, 0)! = FR_OK)//format The sdcard with FAT32 filesystem// {///* FatFs Format Error *///Error_Handler ();// }}Else{Error_Handler (); } }return 0;}
function F_mount for the actual operation of the file system Mount function, there are 3 input parameters, the last parameter is 0, the first is not mounted, wait until fopen, then mount, for 1 o'clock, then immediately mount, in this function will use the CHECK_FS function to check whether the FAT32 file system, If it is, the mount succeeds, otherwise it fails.
Of course, it can be mounted immediately, but if you are constantly unplugged SD card, there is a certain probability will be unexpected, such as subsequent fopen failure. Therefore, the 3rd parameter here uses 0, does not mount immediately, but waits until the file is actually read to execute the Mount file system.
File System uninstallation
staticint UnmountFilesystem(void){ FRESULT ret; ret =f_mount(NULL"0:/"0); return ret;}
The 3rd parameter of F_mout is meaningless here, and it is ignored within this f_mount function.
File test
Compared to the previous code, the file test we changed it in the key callback function:
void Filetest (void) {Fresult res; uint32_t Byteswritten, Bytesread; /* FileWrite/ReadCounts */uint8_t wtext[] ="This was STM32 working with FatFs"; /* FileWriteBuffer */uint8_t rtext[ -];if(F_open (&myfile,"0:/stm32.txt", Fa_create_always | Fa_write)! = FR_OK) {/* ' STM32. TXT 'fileOpen for WriteError */Error_Handler (); }Else{res = F_write (&myfile, Wtext, sizeof (Wtext), (void *) &byteswritten);if(Byteswritten = =0) || (res! = FR_OK)) {/* ' STM32. TXT 'fileWriteorEOF Error */Error_Handler (); }Else{f_close (&myfile); /*##-7-open The text file object with Read access ###############*/ if(F_open (&myfile,"0:/stm32.txt", fa_read)! = FR_OK) {/* ' STM32. TXT 'fileOpen for ReadError */Error_Handler (); }Else{res = F_read (&myfile, Rtext, sizeof (Rtext), (uint*) &bytesread);if(Bytesread = =0) || (res! = FR_OK)) {/* ' STM32. TXT 'fileReadorEOF Error */Error_Handler (); }Else{f_close (&myfile); /*##-10-compare read data with the expected data ############*/ if((Bytesread! = Byteswritten)) {/* Read data isDifferent from theExpected data */Error_Handler (); }Else{/* Success of theDemo:noErrorOccurrence */Hal_gpio_togglepin (Led1_gpio_port, Led1_pin); }}}}}}void Hal_gpio_exti_callback (uint16_t gpio_pin) {if(Gpio_pin ==gpio_pin_15) {if(bsp_sd_isdetected () ==sd_present) {filetest (); } }}
2 SDIO use DMA to operate
To increase the DMA, you first have to increase the DMA for the Sdio TX and RX in CUBEMX, respectively:
Figure 1 DMA settings for Sdio
Second, it is important to note that the SDIO has several interrupt priority settings:
Figure 2 DMA settings for Sdio
The interrupt priority of SDIO global inerrupt cannot be higher than the DMA priority, otherwise the DMA callback death will occur.
The end is docking:
In the sd_diskio.c file, locate the Sd_read function and change the Bsp_sd_readblocks function to the BSP_SD_READBLOCKS_DMA function:
count){ DRESULT res = RES_OK; if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff, (uint64_t) (sector * BLOCK_SIZE), BLOCK_SIZE, count) != MSD_OK) { res = RES_ERROR; } return res;}
Similarly, write functions are modified accordingly, using a DMA function:
count){ DRESULT res = RES_OK; if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff, (uint64_t)(sector * BLOCK_SIZE), count) != MSD_OK) { res = RES_ERROR; } return res;}
It is important to note that sd_diskio.c this file will overwrite it every time Cubemx generates code, by default, by using non-DMA mode.
3 Conclusion:
The key here is that the interrupt priority, SDIO Global Interrupt (4) must be higher than the DMA interrupt priority (5), or the program will be stuck in the DMA interrupt.
Additional attached: http://download.csdn.net/detail/flydream0/9728000
How to use CUBEMX to make an SD card based file system Engineering (2)