金牌会员
 
- 积分
- 2099
- 金钱
- 2099
- 注册时间
- 2017-2-11
- 在线时间
- 306 小时
|
本帖最后由 jiangyy 于 2020-9-29 14:13 编辑
HAL库也是目前比较流行的MDK开发包,但很多朋友一直在用KEIL5软件,但是后续使用HAL库开发,编译速度大大降低,好处是大家用习惯了,很上手。但是意法半导体后期主打STM32CUBEIDE软件,面向图形界面开发编程,一键生成代码,减小开发周期和开发难度,大大缩小项目开发成本和时间,而且还有一点是,HAL库对代码的严谨性特别强,这点是编程工作者不能忽略的。今天特意在这里说一下关于图形化生成FATFS文件系统,挂载SD卡。我的软件版本是STM32CubeIDE Version: 1.4.2,库包版本是STM32CubeIDE FW_F4 V1.25.1,应该算是最新的了。目前基本上已调通(这里好多坑,填补了不少),只是有一个地方出问题,就是FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); 获取剩余容量和总容量错误。我把bsp_fatfs.c代码贴出来- /*
- * bsp_fatfs.c
- *
- * Created on: Sep 26, 2020
- * Author: jiangyuanyuan
- */
- #include "bsp_fatfs.h"
- FATFS fs; //工作空间
- FIL fil; // 文件项目
- uint32_t byteswritten; // 写文件计数
- uint32_t bytesread; // 读文件计数
- uint8_t wtext[] = "This is a 8G Card!!!"; // 写的内容
- uint8_t rtext[1024]; // 读取的buff
- char filename[] = "FATFS.txt"; // 文件名
- //得到磁盘剩余容量
- //drv:磁盘编号("0:"/"1:")
- //total:总容量 (单位KB)
- //free:剩余容量 (单位KB)
- //返回值:0,正常.其他,错误代码
- vu8 exf_getfree(u8 *drv,u32 *total,u32 *free)
- {
- FATFS *fs1;
- vu8 res;
- u32 fre_clust=0, fre_sect=0, tot_sect=0;
- //得到磁盘信息及空闲簇数量
- res = f_getfree((const TCHAR*)drv, (DWORD*)&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;
- }
- //通过串口打印SD卡相关信息
- void show_sdcard_info(void)
- {
- int sdcard_status = 0;
- HAL_SD_CardCIDTypeDef SDCard_CID;
- uint64_t CardCap; //SD卡容量
- HAL_SD_GetCardCID(&hsd,&SDCard_CID); //获取CID
- sdcard_status = HAL_SD_GetCardState(&hsd);
- switch(hsd.SdCard.CardType)
- {
- case CARD_SDSC:
- {
- if(hsd.SdCard.CardVersion == CARD_V1_X)
- printf("Card Type:SDSC V1\r\n");
- else if(hsd.SdCard.CardVersion == CARD_V2_X)
- printf("Card Type:SDSC V2\r\n");
- }
- break;
- case CARD_SDHC_SDXC:printf("Card Type:SDHC\r\n");break;
- }
- if(sdcard_status == HAL_SD_CARD_TRANSFER)
- {
- //打印SD卡基本信息
- CardCap = (uint64_t)hsd.SdCard.BlockSize*(uint64_t)hsd.SdCard.BlockNbr; //计算SD卡容量
- printf("CardCapacity: %ld MB\r\n",(uint64_t)(hsd.SdCard.BlockSize*hsd.SdCard.BlockNbr)); //显示容量
- printf("Card ManufacturerID:%ld \r\n",(u32)SDCard_CID.ManufacturerID); //制造商ID
- printf("Card RCA:%ld \r\n",hsd.SdCard.RelCardAdd); //卡相对地址
- printf("LogBlockNbr:%ld \r\n",hsd.SdCard.LogBlockNbr); //显示逻辑块数量
- printf("LogBlockSize:%ld \r\n",hsd.SdCard.LogBlockSize); //显示逻辑块大小
- printf("Card Capacity:%ld MB\r\n",(u32)(CardCap>>20)); //显示容量
- printf("Card BlockSize: %ld \r\n",hsd.SdCard.BlockSize); //显示块大小
- }
- else
- {
- printf("SD card init fail!\r\n" );
- }
- }
- void SD_Auto_NewFolder(void)
- {
- unsigned long total,free;
- vu8 err;
- // u8 paddr[18]; //存放P Addr:+p地址的ASCII值
- // BYTE *work=0;/* Work area (larger is better for process time) */
- printf("\r\n ****** FATFS SYSTEM ******\r\n\r\n");
- /*-1- 格式化SD卡*/
- // work = mymalloc(SRAMEX,_MAX_LEN);//外部内存池申请
- // if(work!=NULL)
- // {
- // sprintf((char*)paddr,"0X%08X",(u32)work);
- // printf("%s\r\n",paddr);
- // }
- //
- // err=f_mkfs("0:", FM_FAT32, 0, work, _MAX_LEN);
- // if(err==0)
- // {
- //// f_setlabel((const TCHAR*)"0:JAYMIE");//设置Flash磁盘的名字为:ALIENTEK
- // printf("Flash Disk Format Finish\r\n"); //格式化完成
- // }else printf("Flash Disk Format Error\r\n"); //格式化失败
- //
- // myfree(SRAMEX,work);//释放外部内存池内存
- // work = 0; //指向空地址
- /*-2- 挂载文件系统*/
- retSD = f_mount(&fs, "0:", 0);
- if(retSD)
- {
- printf(" mount error : %d \r\n",retSD);
- Error_Handler();
- }
- else
- printf(" mount sucess!!! \r\n");
- /*-3-获取SD卡容量和信息*/
- err = exf_getfree("0:",&total,&free);
- if(err)
- printf("SD Card Fatfs Error:%d!\r\n",err);
- printf("total:%ld MB,free:%ld MB\r\n",total>>10,free>>10);//显示SD卡总容量 MB,剩余容量 MB
- show_sdcard_info();
- /*-4-创建新的文件并写入数据*/
- retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE); //打开文件,权限包括创建、写(如果没有该文件,会创建该文件)
- if(retSD) //返回值不为0(出现问题)
- printf(" open file error : %d\r\n",retSD); //打印问题代码
- else
- printf(" open file sucess!!! \r\n");
- /*-5- 在txt文件中写入数据*/
- retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten); //在文件内写入wtext内的内容
- if(retSD) //返回值不为0(出现问题)
- printf(" write file error : %d\r\n",retSD); //打印问题代码
- else
- {
- printf(" write file sucess!!! \r\n");
- printf(" write Data : %s\r\n",wtext); //打印写入的内容
- }
- /*-6- 关闭txt文件*/
- retSD = f_close(&fil); //关闭该文件
- if(retSD) //返回值不为0(出现问题)
- printf(" close error : %d\r\n",retSD); //打印问题代码
- else
- printf(" close sucess!!! \r\n");
- /*-7- 打开文件读取数据*/
- retSD = f_open(&fil, filename, FA_READ); //打开文件,权限为只读
- if(retSD) //返回值不为0(出现问题)
- printf(" open file error : %d\r\n",retSD); //打印问题代码
- else
- printf(" open file sucess!!! \r\n");
- /*-8- 读取txt文件数据*/
- retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread); //读取文件内容放到rtext中
- if(retSD) //返回值不为0(出现问题)
- printf(" read error!!! %d\r\n",retSD); //打印问题代码
- else
- {
- printf(" read sucess!!! \r\n");
- printf(" read Data : %s\r\n",rtext); //打印读取到的数据
- }
- /*-9- 关闭文件*/
- retSD = f_close(&fil); //关闭该文件
- if(retSD) //返回值不为0(出现问题)
- printf(" close error!!! %d\r\n",retSD); //打印问题代码
- else
- printf(" close sucess!!! \r\n");
- /*-10- 读写一致性检测*/
- if(bytesread == byteswritten) //如果读写位数一致
- {
- printf(" FatFs is working well!!!\r\n"); //打印文件系统工作正常
- }
- }
复制代码
上面是应用层.c文件,在/*-3-获取SD卡容量和信息*/ 这个地方,exf_getfree("0:",&total,&free);的内容是错误的,我也不知道是公式的问题,还是这个底层的问题,还是文件系统中间件的问题,反正我研究了很长时间,没搞出来,后面我继续优化一下。对了,这里移植正点原子的内存池管理这章节,也是废了不少时间移植成功(涉及到内存的映射和启动文件.ld的修改),网上的涉及到.ld的修改文章很少,有的虽然修改成功了,但是生成的.bin和.hex文件超级大,后面经过一个贴友的帮助,总算修改好了启动文件。先把启动文件.ld代码贴出来,自己可以看看新增的地方。
- /**
- ******************************************************************************
- * @file LinkerScript.ld
- * @author Auto-generated by STM32CubeIDE
- * @brief Linker script for STM32F407ZGTx Device from STM32F4 series
- * 1024Kbytes FLASH
- * 64Kbytes CCMRAM
- * 128Kbytes RAM
- *
- * Set heap size, stack size and stack location according
- * to application requirements.
- *
- * Set memory bank area and size if external memory is used
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2020 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
- /* Entry Point */
- ENTRY(Reset_Handler)
- /* Highest address of the user mode stack */
- _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
- _Min_Heap_Size = 0x200 ; /* required amount of heap */
- _Min_Stack_Size = 0x1000 ; /* required amount of stack */
- /* Memories definition */
- MEMORY
- {
- CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
- RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
- FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
- SRAM (rx) : ORIGIN = 0x68000000, LENGTH = 1024K
- }
- /* Sections */
- SECTIONS
- {
- /* The startup code into "FLASH" Rom type memory */
- .isr_vector :
- {
- . = ALIGN(4);
- KEEP(*(.isr_vector)) /* Startup code */
- . = ALIGN(4);
- } >FLASH
- /* The program code and other data into "FLASH" Rom type memory */
- .text :
- {
- . = ALIGN(4);
- *(.text) /* .text sections (code) */
- *(.text*) /* .text* sections (code) */
- *(.glue_7) /* glue arm to thumb code */
- *(.glue_7t) /* glue thumb to arm code */
- *(.eh_frame)
- KEEP (*(.init))
- KEEP (*(.fini))
- . = ALIGN(4);
- _etext = .; /* define a global symbols at end of code */
- } >FLASH
- /* Constant data into "FLASH" Rom type memory */
- .rodata :
- {
- . = ALIGN(4);
- *(.rodata) /* .rodata sections (constants, strings, etc.) */
- *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
- . = ALIGN(4);
- } >FLASH
- .ARM.extab : {
- . = ALIGN(4);
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- . = ALIGN(4);
- } >FLASH
-
- .ARM : {
- . = ALIGN(4);
- __exidx_start = .;
- *(.ARM.exidx*)
- __exidx_end = .;
- . = ALIGN(4);
- } >FLASH
- .preinit_array :
- {
- . = ALIGN(4);
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array*))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- . = ALIGN(4);
- } >FLASH
-
- .init_array :
- {
- . = ALIGN(4);
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array*))
- PROVIDE_HIDDEN (__init_array_end = .);
- . = ALIGN(4);
- } >FLASH
-
- .fini_array :
- {
- . = ALIGN(4);
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(SORT(.fini_array.*)))
- KEEP (*(.fini_array*))
- PROVIDE_HIDDEN (__fini_array_end = .);
- . = ALIGN(4);
- } >FLASH
-
- /* Used by the startup to initialize data */
- _sidata = LOADADDR(.data);
- /* Initialized data sections into "RAM" Ram type memory */
- .data :
- {
- . = ALIGN(4);
- _sdata = .; /* create a global symbol at data start */
- *(.data) /* .data sections */
- *(.data*) /* .data* sections */
- . = ALIGN(4);
- _edata = .; /* define a global symbol at data end */
-
- } >RAM AT> FLASH
- /* Uninitialized data section into "RAM" Ram type memory */
- .ccmram(NOLOAD) :
- {
- . = ALIGN(4);
- _sccmram = .; /* create a global symbol at ccmram start */
- *(.ccmram)
- *(.ccmram*)
-
- . = ALIGN(4);
- _eccmram = .; /* create a global symbol at ccmram end */
- } >CCMRAM AT> FLASH /*新增*/
-
- . = ALIGN(4);
- .bss :
- {
- /* This is used by the startup in order to initialize the .bss section */
- _sbss = .; /* define a global symbol at bss start */
- __bss_start__ = _sbss;
- *(.bss)
- *(.bss*)
- *(COMMON)
- . = ALIGN(4);
- _ebss = .; /* define a global symbol at bss end */
- __bss_end__ = _ebss;
- } >RAM
- /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
- ._user_heap_stack :
- {
- . = ALIGN(8);
- PROVIDE ( end = . );
- PROVIDE ( _end = . );
- . = . + _Min_Heap_Size;
- . = . + _Min_Stack_Size;
- . = ALIGN(8);
- } >RAM
- .sram(NOLOAD) :
- {
- . = ALIGN(4);
- _SRAM_SYMBOLS = .; /* create a global symbol at data start */
- *(.sram) /* .data sections */
- *(.sram*) /* .data* sections */
- . = ALIGN(4);
- _ESRAM_SYMBOLS = .; /* define a global symbol at data end */
-
- } >SRAM /*新增*/
- /* Remove information from the compiler libraries */
- /DISCARD/ :
- {
- libc.a ( * )
- libm.a ( * )
- libgcc.a ( * )
- }
- .ARM.attributes 0 : { *(.ARM.attributes) }
- }
复制代码
内存池管理文件.c和.h
- /*
- * bsp_malloc.c
- *
- * Created on: Sep 24, 2020
- * Author: jiangyuanyuan
- */
- #include "bsp_malloc.h"
- //内存池(32字节对齐)
- __attribute__ ((aligned (32))) u8 mem1base[MEM1_MAX_SIZE]; //内部SRAM内存池
- __attribute__ ((aligned (32))) u8 mem2base[MEM2_MAX_SIZE] __attribute__((section(".sram"))); //外部SRAM内存池
- __attribute__ ((aligned (32))) u8 mem3base[MEM3_MAX_SIZE] __attribute__((section(".ccmram"))); //内部CCM内存池
- //内存管理表
- u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
- u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((section(".sram"))); //外部SRAM内存池MAP
- u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((section(".ccmram"))); //内部CCM内存池MAP
- //内存管理参数
- const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE}; //内存表大小
- const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE}; //内存分块大小
- const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE}; //内存总大小
- //内存管理控制器
- struct _m_mallco_dev mallco_dev=
- {
- my_mem_init, //内存初始化
- my_mem_perused, //内存使用率
- mem1base,mem2base,mem3base, //内存池
- mem1mapbase,mem2mapbase,mem3mapbase,//内存管理状态表
- 0,0,0, //内存管理未就绪
- };
- //复制内存
- //*des:目的地址
- //*src:源地址
- //n:需要复制的内存长度(字节为单位)
- void mymemcpy(void *des,void *src,u32 n)
- {
- u8 *xdes=des;
- u8 *xsrc=src;
- while(n--)*xdes++=*xsrc++;
- }
- //设置内存
- //*s:内存首地址
- //c :要设置的值
- //count:需要设置的内存大小(字节为单位)
- void mymemset(void *s,u8 c,u32 count)
- {
- u8 *xs = s;
- while(count--)*xs++=c;
- }
- //内存管理初始化
- //memx:所属内存块
- void my_mem_init(u8 memx)
- {
- mymemset(mallco_dev.memmap[memx], 0,memtblsize[memx]*2);//内存状态表数据清零
- mymemset(mallco_dev.membase[memx], 0,memsize[memx]); //内存池所有数据清零
- mallco_dev.memrdy[memx]=1; //内存管理初始化OK
- }
- //获取内存使用率
- //memx:所属内存块
- //返回值:使用率(0~100)
- u8 my_mem_perused(u8 memx)
- {
- u32 used=0;
- u32 i;
- for(i=0;i<memtblsize[memx];i++)
- {
- if(mallco_dev.memmap[memx][i])used++;
- }
- return (used*100)/(memtblsize[memx]);
- }
- //内存分配(内部调用)
- //memx:所属内存块
- //size:要分配的内存大小(字节)
- //返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
- u32 my_mem_malloc(u8 memx,u32 size)
- {
- signed long offset=0;
- u32 nmemb; //需要的内存块数
- u32 cmemb=0;//连续空内存块数
- u32 i;
- if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先执行初始化
- if(size==0)return 0XFFFFFFFF;//不需要分配
- nmemb=size/memblksize[memx]; //获取需要分配的连续内存块数
- if(size%memblksize[memx])nmemb++;
- for(offset=memtblsize[memx]-1;offset>=0;offset--)//搜索整个内存控制区
- {
- if(!mallco_dev.memmap[memx][offset])cmemb++;//连续空内存块数增加
- else cmemb=0; //连续内存块清零
- if(cmemb==nmemb) //找到了连续nmemb个空内存块
- {
- for(i=0;i<nmemb;i++) //标注内存块非空
- {
- mallco_dev.memmap[memx][offset+i]=nmemb;
- }
- return (offset*memblksize[memx]);//返回偏移地址
- }
- }
- return 0XFFFFFFFF;//未找到符合分配条件的内存块
- }
- //释放内存(内部调用)
- //memx:所属内存块
- //offset:内存地址偏移
- //返回值:0,释放成功;1,释放失败;
- u8 my_mem_free(u8 memx,u32 offset)
- {
- int i;
- if(!mallco_dev.memrdy[memx])//未初始化,先执行初始化
- {
- mallco_dev.init(memx);
- return 1;//未初始化
- }
- if(offset<memsize[memx])//偏移在内存池内.
- {
- int index=offset/memblksize[memx]; //偏移所在内存块号码
- int nmemb=mallco_dev.memmap[memx][index]; //内存块数量
- for(i=0;i<nmemb;i++) //内存块清零
- {
- mallco_dev.memmap[memx][index+i]=0;
- }
- return 0;
- }else return 2;//偏移超区了.
- }
- //释放内存(外部调用)
- //memx:所属内存块
- //ptr:内存首地址
- void myfree(u8 memx,void *ptr)
- {
- u32 offset;
- if(ptr==NULL)return;//地址为0.
- offset=(u32)ptr-(u32)mallco_dev.membase[memx];
- my_mem_free(memx,offset); //释放内存
- }
- //分配内存(外部调用)
- //memx:所属内存块
- //size:内存大小(字节)
- //返回值:分配到的内存首地址.
- void *mymalloc(u8 memx,u32 size)
- {
- u32 offset;
- offset=my_mem_malloc(memx,size);
- if(offset==0XFFFFFFFF)return NULL;
- else return (void*)((u32)mallco_dev.membase[memx]+offset);
- }
- //重新分配内存(外部调用)
- //memx:所属内存块
- //*ptr:旧内存首地址
- //size:要分配的内存大小(字节)
- //返回值:新分配到的内存首地址.
- void *myrealloc(u8 memx,void *ptr,u32 size)
- {
- u32 offset;
- offset=my_mem_malloc(memx,size);
- if(offset==0XFFFFFFFF)return NULL;
- else
- {
- mymemcpy((void*)((u32)mallco_dev.membase[memx]+offset),ptr,size); //拷贝旧内存内容到新内存
- myfree(memx,ptr); //释放旧内存
- return (void*)((u32)mallco_dev.membase[memx]+offset); //返回新内存首地址
- }
- }
- void Malloc_Test(void)
- {
- u8 *p=0;
- u8 *tp=0;
- u8 paddr[18]; //存放P Addr:+p地址的ASCII值
- #ifndef __USE_SRAM
- p=mymalloc(SRAMIN,2048);//内部内存池申请2K字节
- if(p!=NULL)
- {
- tp=p;
- sprintf((char*)paddr,"0X%08X",(u32)tp);
- sprintf((char*)p,"Memory SRAMIN ADDR:");//向p写入一些内容
- printf("%s",p);
- printf("%s\r\n",paddr);
- }
- myfree(SRAMIN,p);//释放内部内存池内存
- p=0; //指向空地址
- p=mymalloc(SRAMCCM,2048);//CCM内存池申请2K字节
- if(p!=NULL)
- {
- tp=p;
- sprintf((char*)paddr,"0X%08X",(u32)tp);
- sprintf((char*)p,"Memory SRAMCCM ADDR:");//向p写入一些内容
- printf("%s",p);
- printf("%s\r\n",paddr);
- }
- myfree(SRAMCCM,p);//释放CCM内存池内存
- p=0; //指向空地址
- #endif
- p=mymalloc(SRAMEX,2048);//外部内存池申请2K字节
- if(p!=NULL)
- {
- tp=p;
- sprintf((char*)paddr,"0X%08X",(u32)tp);
- sprintf((char*)p,"Memory SRAMEX ADDR:");//向p写入一些内容
- printf("%s",p);
- printf("%s\r\n",paddr);
- }
- myfree(SRAMEX,p);//释放外部内存池内存
- p=0; //指向空地址
- }
复制代码- /*
- * bsp_malloc.h
- *
- * Created on: Sep 24, 2020
- * Author: jiangyuanyuan
- */
- #ifndef INC_BSP_MALLOC_H_
- #define INC_BSP_MALLOC_H_
- #include "stm32f4xx_hal.h"
- #include "bsp_sys.h"
- #include "stdio.h"
- #define __USE_SRAM
- //定义三个内存池
- #define SRAMIN 0 //内部内存池
- #define SRAMEX 1 //外部内存池
- #define SRAMCCM 2 //CCM内存池(此部分SRAM仅仅CPU可以访问!!!)
- #define SRAMBANK 3 //定义支持的SRAM块数.
- #ifdef __USE_SRAM
- //mem1内存参数设定.mem1完全处于内部SRAM里面.
- #define MEM1_BLOCK_SIZE 32 //内存块大小为32字节
- #define MEM1_MAX_SIZE 0 //最大管理内存 0K
- #define MEM1_ALLOC_TABLE_SIZE 0 //内存表大小
- //mem3内存参数设定.mem3处于CCM,用于管理CCM(特别注意,这部分SRAM,仅CPU可以访问!!)
- #define MEM3_BLOCK_SIZE 32 //内存块大小为32字节
- #define MEM3_MAX_SIZE 0 //最大管理内存0K
- #define MEM3_ALLOC_TABLE_SIZE 0 //内存表大小
- #else
- //mem1内存参数设定.mem1完全处于内部SRAM里面.
- #define MEM1_BLOCK_SIZE 32 //内存块大小为32字节
- #define MEM1_MAX_SIZE 100*1024 //最大管理内存 100K
- #define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE //内存表大小
- //mem3内存参数设定.mem3处于CCM,用于管理CCM(特别注意,这部分SRAM,仅CPU可以访问!!)
- #define MEM3_BLOCK_SIZE 32 //内存块大小为32字节
- #define MEM3_MAX_SIZE 60 *1024 //最大管理内存60K
- #define MEM3_ALLOC_TABLE_SIZE MEM3_MAX_SIZE/MEM3_BLOCK_SIZE //内存表大小
- #endif
- //mem2内存参数设定.mem2的内存池处于外部SRAM里面
- #define MEM2_BLOCK_SIZE 32 //内存块大小为32字节
- #define MEM2_MAX_SIZE 960 *1024 //最大管理内存960K
- #define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE //内存表大小
- //内存管理控制器
- struct _m_mallco_dev
- {
- void (*init)(u8); //初始化
- u8 (*perused)(u8); //内存使用率
- u8 *membase[SRAMBANK]; //内存池 管理SRAMBANK个区域的内存
- u16 *memmap[SRAMBANK]; //内存管理状态表
- u8 memrdy[SRAMBANK]; //内存管理是否就绪
- };
- extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义
- void mymemset(void *s,u8 c,u32 count); //设置内存
- void mymemcpy(void *des,void *src,u32 n);//复制内存
- void my_mem_init(u8 memx); //内存管理初始化函数(外/内部调用)
- u32 my_mem_malloc(u8 memx,u32 size); //内存分配(内部调用)
- u8 my_mem_free(u8 memx,u32 offset); //内存释放(内部调用)
- u8 my_mem_perused(u8 memx); //获得内存使用率(外/内部调用)
- ////////////////////////////////////////////////////////////////////////////////
- //用户调用函数
- void myfree(u8 memx,void *ptr); //内存释放(外部调用)
- void *mymalloc(u8 memx,u32 size); //内存分配(外部调用)
- void *myrealloc(u8 memx,void *ptr,u32 size);//重新分配内存(外部调用)
- void Malloc_Test(void);
- #endif /* INC_BSP_MALLOC_H_ */
复制代码 上面因为我只用到外部SRAM的使用,所以没用到内部内存池和内部RAM的申请,所以头文件加了一个条件编译。以下是我SD卡打印的信息:
- sram:1024kb
- Memory SRAMEX ADDR:0X680EF800
- ****** FATFS SYSTEM ******
- 0X680E8000
- Flash Disk Format Finish
- mount sucess!!!
- total:722900 MB,free:38131 MB
- Card Type:SDHC
- CardCapacity: 512 MB
- Card ManufacturerID:3
- Card RCA:43690
- LogBlockNbr:15523840
- LogBlockSize:512
- Card Capacity:7580 MB
- Card BlockSize: 512
- open file sucess!!!
- write file sucess!!!
- write Data : This is a 8G Card!!!
- close sucess!!!
- open file sucess!!!
- read sucess!!!
- read Data : This is a 8G Card!!!
- close sucess!!!
- FatFs is working well!!!
复制代码 从串口打印数据,可以看到total:722900 MB,free:38131 MB是错误的,但是HAL_SD_CardCIDTypeDef SDCard_CID 结构体成员的信息是对的
有贴友知道err = exf_getfree("0:",&total,&free);获取错误的问题,请留言,谢谢。
|
|