赞
踩
开发环境为STM32F407VET6 和STM32F105RCT6两个DEMO board,USB Host 在U盘实现FATFS, SPI Flash上FATFS,当插入U盘后,将SPI Flash 上的文件拷贝至U盘。
这个要求不为过吧,翻烂了CSDN,都找不到一篇详细的教程,大家都是重复的说来说去,却在关键的点上,都闭口不言。让我想起我读高中时期,有一个数学老师,一旦遇到简单的问题就说的特别详细,一旦有难度,就说交给大家了,让大家自行想办法解决问题。
经过一段时间的尝试,请大家跟着我的脚步一起完成它。如果你还有问题,你可以在我的CSDN上留言,我会及时的回复,我上CSDN的频率一天为2-4次。
大家都会,不废话,要的是干货。
大家都会,不废话,要的是干货。
USB-OTG-FS 选择host only,FS是full speed 的意思,HS需要额外的时钟电路,我没有尝试过。
注意选择步骤3,如果这个值默认是128 ,被卡在这儿的概率就很高了,建议用512个words,即2K字节。
步骤3大家也都没有问题。
步骤4:千万注意,volumes必须选择2个以上,要实现2个文件系统在两个外设上。MAX Sector Size 和Min Sector Size 分别是4096和512。Flash是4096 ,U盘和Sd卡是512 。
步骤5:本文最大的干货,必须关闭重入功能,否则,你会卡死在一个信号量的释放上,ST的FAE也不打算解决这个问题。在操作系统的环境下,如果MAX_Secotor Size !=MIN Sector Size,就会卡在一个信号量的释放上。
SPI Flash的MAX sector size 和MIN sector size必须配置为4096才能正常使用f_mout f_open函数,而U盘却的MAX sector size 和MIN sector size必须配置为512才能正常使用f_mout f_open函数。
ST的Fae说未来逐渐摆脱FreeRTOS,会切换到Thread-X。
堆栈调大一点
以上步骤可以确保你一路顺利了,接下来,我会附上我的部分代码。
很多人抄来抄去,从来没有人说明这个函数的具体内容。
- FRESULT f_open (
- FIL* fp, /* [OUT] Pointer to the file object structure */
- const TCHAR* path, /* [IN] File name */
- BYTE mode /* [IN] Mode flags */
- );
第一个和第3个参数大家都很清楚,第二个参数很少有人详细的说清楚,都是抄来抄去的重复内容。
STM32CubeMX学习笔记(25)——FatFs文件系统使用(操作SPI Flash)_fa_open_always_Leung_ManWah的博客-CSDN博客
这篇文章,很多人都在看,但是呢,对特别关键的f_open函数并没有说的很清楚,一旦遇到我们有2个逻辑驱动区的时候,就傻眼了,你发现永远也写不到第二个里面。
上图的表里说的很清楚,必须指定逻辑分区。所以正确的f_open 函数应该这样写:
f_open (&fs,"0:/test.txt",FA_READ);
0:/是非常关键的信息,它指的是逻辑分区,当只有一个逻辑分区的时候,是可以省略,但是当有2个以上的时候,就绝对不能省略。
- void MX_FATFS_Init(void)
- {
- /*## FatFS: Link the USBH driver ###########################*/
- retUSBH = FATFS_LinkDriver(&USBH_Driver, USBHPath);
- /*## FatFS: Link the USER driver ###########################*/
- retUSER = FATFS_LinkDriver(&USER_Driver, USERPath);
-
- /* USER CODE BEGIN Init */
- /* additional user code for init */
- /* USER CODE END Init */
- }
-
这两句话意义上挂载两个逻辑分区,逻辑分区分别是0:/和1:/
先执行的就是逻辑分区0 ,后执行的就是逻辑分区1 。
所以要想写逻辑分区0的文件,必须用f_open(&fs,0:/test.txt,FA_WRITE);
所以要想写逻辑分区1的文件,必须用f_open(&fs,1:/test.txt,FA_WRITE);
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file fatfs.c
- * @brief Code for fatfs applications
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2023 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
- #include "fatfs.h"
-
- uint8_t retUSBH; /* Return value for USBH */
- char USBHPath[4]; /* USBH logical drive path */
- FATFS USBHFatFS; /* File system object for USBH logical drive */
- FIL USBHFile; /* File object for USBH */
- uint8_t retUSER; /* Return value for USER */
- char USERPath[4]; /* USER logical drive path */
- FATFS USERFatFS; /* File system object for USER logical drive */
- FIL USERFile; /* File object for USER */
-
- /* USER CODE BEGIN Variables */
- #include "userDebugCom.h"
- extern osMutexId falshMutexHandle;
- extern struct systemTime_t sysTime;
- static UINT fnum;
- static BYTE ReadBuffer[20] = {0}; /* 读缓冲区 */
- static BYTE WriteBuffer_Title[] = "This Is File Test\r\n"; /* 写缓冲区*/
- static uint8_t flashFlag = 0;
- static uint8_t fileSPIWriteFlag = 0;
- /* USER CODE END Variables */
-
- void MX_FATFS_Init(void)
- {
- /*## FatFS: Link the USBH driver ###########################*/
- retUSBH = FATFS_LinkDriver(&USBH_Driver, USBHPath);
- /*## FatFS: Link the USER driver ###########################*/
- retUSER = FATFS_LinkDriver(&USER_Driver, USERPath);
-
- /* USER CODE BEGIN Init */
- /* additional user code for init */
- /* USER CODE END Init */
- }
-
- /**
- * @brief Gets Time from RTC
- * @param None
- * @retval Time in DWORD
- */
- DWORD get_fattime(void)
- {
- /* USER CODE BEGIN get_fattime */
- #if 1
- return ((sysTime.year - 1980) << 25) /* Year = 2010 */
- | (sysTime.month << 21) /* Month = 11 */
- | (sysTime.day << 16) /* Day = 2 */
- | (sysTime.hour << 11) /* Hour = 15 */
- | (sysTime.minute << 5) /* Min = 0 */
- | (sysTime.second >> 1) /* Sec = 0 */
- ;
- #endif
- return 0;
- /* USER CODE END get_fattime */
- }
-
- /* USER CODE BEGIN Application */
- /**
- * @brief 测试fatfs在SPIFlash是否正常工作
- *
- */
- void InitFatFs_SPI_FLASH(void)
- {
-
- osMutexWait(falshMutexHandle,osWaitForever);
- retUSER = f_mount(&USERFatFS, USERPath, 1);
- if (retUSER != FR_OK)
- {
- Debug_Printf("SPI Flash is not formatted\r\n");
- retUSER = f_mkfs(USERPath, 1, 4096); // flash 要格式化1次,不然文件系统记录的不正确
- // 千万注意,f_mkfs函数耗时极长,可能到10分钟左右,和SD卡的容量相关?
- if (retUSER == FR_OK)
- {
- Debug_Printf("The FLASH formats the file system successfully\r\n");
- retUSER = f_mount(NULL, (TCHAR const *)USERPath, 1);
- retUSER = f_mount(&USERFatFS, (TCHAR const *)USERPath, 1);
- }
- else
- {
- Debug_Printf("Formatting failure\r\n");
- }
- }
- if (retUSER == FR_OK)
- {
- Debug_Printf("Fmout OK!\r\n");
- uint32_t total;
- uint32_t free;
- if (exf_getfree((uint8_t *)USERPath, &total, &free) == FR_OK)
- {
- Debug_Printf("Total=%d KB,Free=%d KB\r\n", total, free);
- }
- else
- {
- Debug_Printf("Disk Space Error\r\n");
- }
- flashFlag = 1;
- }
- osMutexRelease(falshMutexHandle);
- }
-
- void spiFlashSoundPromt(void)
- {
- if (memcmp(ReadBuffer, WriteBuffer_Title, sizeof(WriteBuffer_Title)) == 0)
- {
- for (int i = 0; i < 3; i++)
- {
- HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET);
- osDelay(50);
- HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET);
- osDelay(50);
- }
- }
- }
- /**
- * @brief 读写测试文件系统
- *
- */
- void FileReadWriteTest(void)
- {
- if (flashFlag > 0)
- {
- osMutexWait(falshMutexHandle,osWaitForever);
- Debug_Printf("File Write Test\n");
- #if 1
- retUSER = f_open(&USERFile, "1:/test.txt", FA_OPEN_ALWAYS | FA_WRITE);
- fileSPIWriteFlag = 1;
- // f_res = f_lseek(&SDFile, f_size(&SDFile));
- if (retUSER == FR_OK)
- {
- Debug_Printf("Write To file\n");
- retUSER = f_write(&USERFile, WriteBuffer_Title, sizeof(WriteBuffer_Title), &fnum);
- if (retUSER == FR_OK)
- {
- Debug_Printf("Write Len=%d\n", fnum);
- Debug_Printf("Write Data:\n%s\n", WriteBuffer_Title);
- }
- else
- {
- Debug_Printf("Write Fail,Error Code(%d)\n", retUSER);
- }
- f_close(&USERFile);
- fileSPIWriteFlag = 0;
- }
- else
- {
- Debug_Printf("打开/创建文件失败。\n");
- }
-
- /*------------------- 文件系统测试:读测试 ------------------------------------*/
- Debug_Printf("File Read Test\n");
- // HAL_IWDG_Refresh(&hiwdg);
- retUSER = f_open(&USERFile, "1:/test.txt", FA_OPEN_EXISTING | FA_READ);
- fileSPIWriteFlag = 1;
- // f_res = f_lseek(&SDFile, 2);
- if (retUSER == FR_OK)
- {
- Debug_Printf("File Opend\r\n");
-
- retUSER = f_read(&USERFile, ReadBuffer, sizeof(ReadBuffer), &fnum);
- if (retUSER == FR_OK)
- {
- Debug_Printf("Read Len=%d\n", fnum);
- Debug_Printf("Read Data:\n%s \n", ReadBuffer);
- }
- else
- {
- Debug_Printf("Read Fail,Error Code(%d)\n", retUSER);
- }
- }
- else
- {
- Debug_Printf("File Open Failed\n");
- }
- f_close(&USERFile);
- fileSPIWriteFlag = 0;
- #endif
- osMutexRelease(falshMutexHandle);
- }
- }
- /**
- * @brief 得到磁盘剩余容量
- *
- * @param drv 磁盘编号("0:"/"1:")
- * @param total total capacity (KB)
- * @param free free capacity (KB)
- * @return uint8_t get status
- */
- uint8_t exf_getfree(uint8_t *drv, uint32_t *total, uint32_t *free)
- {
- FATFS *fs1;
- uint8_t res;
- DWORD fre_clust = 0;
- uint32_t fre_sect = 0, tot_sect = 0;
- // 得到磁盘信息及空闲簇数量
- res = f_getfree((const TCHAR *)drv, &fre_clust, &fs1);
- if (res == 0)
- {
- tot_sect = (fs1->n_fatent - 2) * fs1->csize; // 得到总扇区数
- fre_sect = fre_clust * fs1->csize; // 得到空闲扇区????
- #if _MAX_SS != 512 // 扇区大小不是512字节,则转换为512字节
- tot_sect *= fs1->ssize / 512;
- fre_sect *= fs1->ssize / 512;
- #endif
- *total = tot_sect >> 1; // 单位为KB
- *free = fre_sect >> 1; // 单位为KB
- }
- return res;
- }
-
-
- /* USER CODE END Application */
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file user_diskio.c
- * @brief This file includes a diskio driver skeleton to be completed by the user.
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2023 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
-
- #ifdef USE_OBSOLETE_USER_CODE_SECTION_0
- /*
- * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
- * To be suppressed in the future.
- * Kept to ensure backward compatibility with previous CubeMx versions when
- * migrating projects.
- * User code previously added there should be copied in the new user sections before
- * the section contents can be deleted.
- */
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- #endif
-
- /* USER CODE BEGIN DECL */
-
- /* Includes ------------------------------------------------------------------*/
- #include <string.h>
- #include "ff_gen_drv.h"
- #include "w25qxx.h"
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
-
- /* Private variables ---------------------------------------------------------*/
- /* Disk status */
- static volatile DSTATUS Stat = STA_NOINIT;
-
- /* USER CODE END DECL */
-
- /* Private function prototypes -----------------------------------------------*/
- DSTATUS USER_initialize (BYTE pdrv);
- DSTATUS USER_status (BYTE pdrv);
- DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
- #if _USE_WRITE == 1
- DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
- #endif /* _USE_WRITE == 1 */
- #if _USE_IOCTL == 1
- DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
- #endif /* _USE_IOCTL == 1 */
-
- Diskio_drvTypeDef USER_Driver =
- {
- USER_initialize,
- USER_status,
- USER_read,
- #if _USE_WRITE
- USER_write,
- #endif /* _USE_WRITE == 1 */
- #if _USE_IOCTL == 1
- USER_ioctl,
- #endif /* _USE_IOCTL == 1 */
- };
-
- /* Private functions ---------------------------------------------------------*/
-
- /**
- * @brief Initializes a Drive
- * @param pdrv: Physical drive number (0..)
- * @retval DSTATUS: Operation status
- */
- DSTATUS USER_initialize (
- BYTE pdrv /* Physical drive nmuber to identify the drive */
- )
- {
- /* USER CODE BEGIN INIT */
- Stat = STA_NOINIT;
- if(W25QXX_Init() == 0)
- {
- Stat &= ~STA_NOINIT;
- }
- return Stat;
- /* USER CODE END INIT */
- }
-
- /**
- * @brief Gets Disk Status
- * @param pdrv: Physical drive number (0..)
- * @retval DSTATUS: Operation status
- */
- DSTATUS USER_status (
- BYTE pdrv /* Physical drive number to identify the drive */
- )
- {
- /* USER CODE BEGIN STATUS */
- Stat = STA_NOINIT;
- if(W25QXX_Get_State() == W25Q_OK)
- {
- Stat &= ~STA_NOINIT;
- }
- return Stat;
- /* USER CODE END STATUS */
- }
-
- /**
- * @brief Reads Sector(s)
- * @param pdrv: Physical drive number (0..)
- * @param *buff: Data buffer to store read data
- * @param sector: Sector address (LBA)
- * @param count: Number of sectors to read (1..128)
- * @retval DRESULT: Operation result
- */
- DRESULT USER_read (
- BYTE pdrv, /* Physical drive nmuber to identify the drive */
- BYTE *buff, /* Data buffer to store read data */
- DWORD sector, /* Sector address in LBA */
- UINT count /* Number of sectors to read */
- )
- {
- /* USER CODE BEGIN READ */
- sector+=1;
- W25QXX_Read(buff, sector <<12, count<<12);
- return RES_OK;
- /* USER CODE END READ */
- }
-
- /**
- * @brief Writes Sector(s)
- * @param pdrv: Physical drive number (0..)
- * @param *buff: Data to be written
- * @param sector: Sector address (LBA)
- * @param count: Number of sectors to write (1..128)
- * @retval DRESULT: Operation result
- */
- #if _USE_WRITE == 1
- DRESULT USER_write (
- BYTE pdrv, /* Physical drive nmuber to identify the drive */
- const BYTE *buff, /* Data to be written */
- DWORD sector, /* Sector address in LBA */
- UINT count /* Number of sectors to write */
- )
- {
- /* USER CODE BEGIN WRITE */
- /* USER CODE HERE */
- sector+=1;
- W25QXX_Write((void *)(buff),sector<<12,count<<12 );
- return RES_OK;
- /* USER CODE END WRITE */
- }
- #endif /* _USE_WRITE == 1 */
-
- /**
- * @brief I/O control operation
- * @param pdrv: Physical drive number (0..)
- * @param cmd: Control code
- * @param *buff: Buffer to send/receive control data
- * @retval DRESULT: Operation result
- */
- #if _USE_IOCTL == 1
- DRESULT USER_ioctl (
- BYTE pdrv, /* Physical drive nmuber (0..) */
- BYTE cmd, /* Control code */
- void *buff /* Buffer to send/receive control data */
- )
- {
- /* USER CODE BEGIN IOCTL */
- DRESULT res = RES_OK;
- switch(cmd){
- case GET_SECTOR_COUNT:
- *(DWORD *)buff = 4095;
- break;
- case GET_SECTOR_SIZE:
- *(DWORD *)buff = 4096;
- break;
- case GET_BLOCK_SIZE:
- *(DWORD *)buff = 1;
- break;
- }
- return res;
- /* USER CODE END IOCTL */
- }
- #endif /* _USE_IOCTL == 1 */
-
2.4 usb_host.c
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : usb_host.c
- * @version : v2.0_Cube
- * @brief : This file implements the USB Host
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2023 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
-
- /* Includes ------------------------------------------------------------------*/
-
- #include "usb_host.h"
- #include "usbh_core.h"
- #include "usbh_msc.h"
-
- /* USER CODE BEGIN Includes */
- #include "usart.h"
- #include "usb_host.h"
- #include "fatfs.h"
- #include "userDebugCom.h"
- /* USER CODE END Includes */
-
- /* USER CODE BEGIN PV */
- /* Private variables ---------------------------------------------------------*/
- static uint8_t status = 0;
- static char FileWriteBuff[] = "Hello,This is U-Disk\r\n";
- static char FileReadBuff[23] = "";
- static UINT bw;
- static uint8_t fileWriteFlag = 0;
- /* USER CODE END PV */
-
- /* USER CODE BEGIN PFP */
- /* Private function prototypes -----------------------------------------------*/
-
- /* USER CODE END PFP */
-
- /* USB Host core handle declaration */
- USBH_HandleTypeDef hUsbHostFS;
- ApplicationTypeDef Appli_state = APPLICATION_IDLE;
-
- /*
- * -- Insert your variables declaration here --
- */
- /* USER CODE BEGIN 0 */
-
- /* USER CODE END 0 */
-
- /*
- * user callback declaration
- */
- static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id);
-
- /*
- * -- Insert your external function declaration here --
- */
- /* USER CODE BEGIN 1 */
- /**
- * @brief USB 文件测试
- *
- */
- void UdiskBeginTest(void)
- {
- if (Appli_state == APPLICATION_READY) // U盘已经加轿
- {
- if (status == 0)
- {
- status = 1;
- fileWriteFlag = 0;
- memset(FileReadBuff, 0x00, sizeof(FileReadBuff));
- retUSBH = f_mount(NULL, (TCHAR const *)USBHPath, 1);
- retUSBH = f_mount(&USBHFatFS, (TCHAR const *)USBHPath, 1);
- if (retUSBH == FR_OK)
- {
- osDelay(100);
- f_close(&USBHFile);
- if (retUSBH == FR_OK)
- {
- Debug_Printf("Closed OK\r\n");
- }
- Debug_Printf("Udisk fmount OK\r\n");
- #if 1
- uint32_t total;
- uint32_t free;
- if (exf_getfree((uint8_t *)USBHPath, &total, &free) == FR_OK)
- {
- Debug_Printf("Total=%d MB,Free=%d MB\r\n", total / 1024, free / 1024);
- }
- else
- {
- Debug_Printf("Udisk fmount error\r\n");
- }
- #endif
- //USBHFile.fs=&USBHFatFS;
- retUSBH = f_open(&USBHFile, (const char *)"0:/testUdisk.txt", FA_OPEN_ALWAYS | FA_WRITE);
- if (retUSBH == FR_OK)
- {
- Debug_Printf("Opened OK\r\n");
- retUSBH = f_write(&USBHFile, FileWriteBuff, sizeof(FileWriteBuff), &bw);
- if (retUSBH == FR_OK)
- {
- Debug_Printf("Writed Udisk Test File OK\r\n");
- retUSBH = f_close(&USBHFile);
- }
- }
- retUSBH = f_open(&USBHFile, "0:/testUdisk.txt", FA_OPEN_EXISTING | FA_READ);
- // f_res = f_lseek(&SDFile, 2);
- if (retUSBH == FR_OK)
- {
- Debug_Printf("Udisk File Opend\r\n");
-
- retUSBH = f_read(&USBHFile, FileReadBuff, sizeof(FileReadBuff), &bw);
- if (retUSBH == FR_OK)
- {
- Debug_Printf("Udisk Read Len=%d\n", bw);
- Debug_Printf("Udisk Read Data:\n%s \n", FileReadBuff);
- }
- else
- {
- Debug_Printf("Udisk Read Fail,Error Code(%d)\n", retUSER);
- }
- }
- else
- {
- Debug_Printf("Udisk File Open Failed\n");
- }
- f_close(&USBHFile);
- }
- udiskSoundPromt();
- }
- }
- }
- /**
- * @brief 测试U盘提示音
- *
- */
- void udiskSoundPromt(void)
- {
- if (memcmp(FileReadBuff, FileWriteBuff, sizeof(FileWriteBuff)) == 0)
- {
- for (int i = 0; i < 2; i++)
- {
- HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET);
- osDelay(50);
- HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET);
- osDelay(50);
- }
- fileWriteFlag = 1;
- //sendQueenToCopyFiles();
- }
- }
-
- /* USER CODE END 1 */
-
- /**
- * Init USB host library, add supported class and start the library
- * @retval None
- */
- void MX_USB_HOST_Init(void)
- {
- /* USER CODE BEGIN USB_HOST_Init_PreTreatment */
-
- /* USER CODE END USB_HOST_Init_PreTreatment */
-
- /* Init host Library, add supported class and start the library. */
- if (USBH_Init(&hUsbHostFS, USBH_UserProcess, HOST_FS) != USBH_OK)
- {
- Error_Handler();
- }
- if (USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS) != USBH_OK)
- {
- Error_Handler();
- }
- if (USBH_Start(&hUsbHostFS) != USBH_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN USB_HOST_Init_PostTreatment */
-
- /* USER CODE END USB_HOST_Init_PostTreatment */
- }
-
- /*
- * user callback definition
- */
- static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
- {
- /* USER CODE BEGIN CALL_BACK_1 */
- switch(id)
- {
- case HOST_USER_SELECT_CONFIGURATION:
- break;
-
- case HOST_USER_DISCONNECTION:
- Appli_state = APPLICATION_DISCONNECT;
- status=0;
- break;
-
- case HOST_USER_CLASS_ACTIVE:
- Appli_state = APPLICATION_READY;
- break;
-
- case HOST_USER_CONNECTION:
- Appli_state = APPLICATION_START;
- break;
-
- default:
- break;
- }
- /* USER CODE END CALL_BACK_1 */
- }
-
- /**
- * @}
- */
- /**
- * @}
- */
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * File Name : freertos.c
- * Description : Code for freertos applications
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2023 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- */
- /* USER CODE END Header */
-
- /* Includes ------------------------------------------------------------------*/
- #include "FreeRTOS.h"
- #include "task.h"
- #include "main.h"
- #include "cmsis_os.h"
-
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include "usb_host.h"
- #include "fatfs.h"
- #include "iwdg.h"
- /* USER CODE END Includes */
-
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
-
- /* USER CODE END PTD */
-
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
-
- /* USER CODE END PD */
-
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
-
- /* USER CODE END PM */
-
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN Variables */
- extern struct systemTime_t sysTime;
- /* USER CODE END Variables */
- osThreadId fileRecordHandle;
- osThreadId readRTCHandle;
- osThreadId lcdDisplayHandle;
- osThreadId keyTaskHandle;
- osTimerId softwareTimerHandle;
- osMutexId usart1PrintHandle;
- osMutexId SetingParameterHandle;
- osMutexId falshMutexHandle;
- osSemaphoreId TenSecTimeupHandle;
-
- /* Private function prototypes -----------------------------------------------*/
- /* USER CODE BEGIN FunctionPrototypes */
-
- /* USER CODE END FunctionPrototypes */
-
- void StartFileRecordTask(void const * argument);
- extern void StartReadRTCTask(void const * argument);
- extern void StartTasklcdDisplay(void const * argument);
- extern void StartkeyTask(void const * argument);
- extern void Callback01(void const * argument);
-
- extern void MX_USB_HOST_Init(void);
- void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
-
- /**
- * @brief FreeRTOS initialization
- * @param None
- * @retval None
- */
- void MX_FREERTOS_Init(void) {
- /* USER CODE BEGIN Init */
-
- /* USER CODE END Init */
- /* Create the mutex(es) */
- /* definition and creation of usart1Print */
- osMutexDef(usart1Print);
- usart1PrintHandle = osMutexCreate(osMutex(usart1Print));
-
- /* definition and creation of SetingParameter */
- osMutexDef(SetingParameter);
- SetingParameterHandle = osMutexCreate(osMutex(SetingParameter));
-
- /* definition and creation of falshMutex */
- osMutexDef(falshMutex);
- falshMutexHandle = osMutexCreate(osMutex(falshMutex));
-
- /* USER CODE BEGIN RTOS_MUTEX */
- /* add mutexes, ... */
- /* USER CODE END RTOS_MUTEX */
-
- /* Create the semaphores(s) */
- /* definition and creation of TenSecTimeup */
- osSemaphoreDef(TenSecTimeup);
- TenSecTimeupHandle = osSemaphoreCreate(osSemaphore(TenSecTimeup), 1);
-
- /* USER CODE BEGIN RTOS_SEMAPHORES */
- /* add semaphores, ... */
- /* USER CODE END RTOS_SEMAPHORES */
-
- /* Create the timer(s) */
- /* definition and creation of softwareTimer */
- osTimerDef(softwareTimer, Callback01);
- softwareTimerHandle = osTimerCreate(osTimer(softwareTimer), osTimerOnce, NULL);
-
- /* USER CODE BEGIN RTOS_TIMERS */
- /* start timers, add new ones, ... */
- /* USER CODE END RTOS_TIMERS */
-
- /* USER CODE BEGIN RTOS_QUEUES */
- /* add queues, ... */
- /* USER CODE END RTOS_QUEUES */
-
- /* Create the thread(s) */
- /* definition and creation of fileRecord */
- osThreadDef(fileRecord, StartFileRecordTask, osPriorityNormal, 0, 1536);
- fileRecordHandle = osThreadCreate(osThread(fileRecord), NULL);
-
- /* definition and creation of readRTC */
- osThreadDef(readRTC, StartReadRTCTask, osPriorityIdle, 0, 256);
- readRTCHandle = osThreadCreate(osThread(readRTC), NULL);
-
- /* definition and creation of lcdDisplay */
- osThreadDef(lcdDisplay, StartTasklcdDisplay, osPriorityLow, 0, 256);
- lcdDisplayHandle = osThreadCreate(osThread(lcdDisplay), NULL);
-
- /* definition and creation of keyTask */
- osThreadDef(keyTask, StartkeyTask, osPriorityLow, 0, 256);
- keyTaskHandle = osThreadCreate(osThread(keyTask), NULL);
-
- /* USER CODE BEGIN RTOS_THREADS */
- /* add threads, ... */
- /* USER CODE END RTOS_THREADS */
-
- }
-
- /* USER CODE BEGIN Header_StartFileRecordTask */
- /**
- * @brief Function implementing the fileRecord thread.
- * @param argument: Not used
- * @retval None
- */
- /* USER CODE END Header_StartFileRecordTask */
- void StartFileRecordTask(void const * argument)
- {
- /* init code for USB_HOST */
-
- /* USER CODE BEGIN StartFileRecordTask */
- osDelay(100);
- InitFatFs_SPI_FLASH();
- osDelay(100);
- FileReadWriteTest();
- spiFlashSoundPromt();
- osDelay(1000);
- MX_USB_HOST_Init();
- /* Infinite loop */
- for(;;)
- {
- osDelay(10);
- UdiskBeginTest();
- HAL_IWDG_Refresh(&hiwdg);
- }
- /* USER CODE END StartFileRecordTask */
- }
-
- /* Private application code --------------------------------------------------*/
- /* USER CODE BEGIN Application */
-
- /* USER CODE END Application */
2.6 user_Debug.c
- #include "userDebugCom.h"
- #include <stdarg.h>
- #include "fatfs.h"
-
- extern osMutexId usart1PrintHandle;
-
- #ifdef __cplusplus
- extern "C"
- {
- #endif
-
- #ifdef __GNUC__
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
- #else
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
- #endif
- PUTCHAR_PROTOTYPE
- {
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
- return ch;
- }
- #ifdef __cplusplus
- }
- #endif
-
- /**
- * @brief 重写printf函数,加上互斥锁
- *
- * @param format
- * @param ...
- */
- void Debug_Printf(char *format, ...)
- {
- char buf_str[128];
- va_list v_args;
-
- va_start(v_args, format);
- (void)vsnprintf((char *)&buf_str[0],
- (size_t)sizeof(buf_str),
- (char const *)format,
- v_args);
- va_end(v_args);
-
- /* 互斥信号量 */
- osMutexWait(usart1PrintHandle, osWaitForever);
- printf("%s", buf_str);
- osMutexRelease(usart1PrintHandle);
- }
- #define CPU_FREQUENCY_MHZ 72 // STM32时钟主频
- void delay_us(__IO uint32_t delay)
- {
- int last, curr, val;
- int temp;
-
- while (delay != 0)
- {
- temp = delay > 900 ? 900 : delay;
- last = SysTick->VAL;
- curr = last - CPU_FREQUENCY_MHZ * temp;
- if (curr >= 0)
- {
- do
- {
- val = SysTick->VAL;
- } while ((val < last) && (val >= curr));
- }
- else
- {
- curr += CPU_FREQUENCY_MHZ * 1000;
- do
- {
- val = SysTick->VAL;
- } while ((val <= last) || (val > curr));
- }
- delay -= temp;
- }
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。