|
发表于 2014-10-15 11:19:05
|
显示全部楼层
之前用楼主的代码,存在u盘不能格式化的问题,经过一番努力,改写了mass_mal.c文件。现在u盘正常了,代码分享如下:
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : mass_mal.c
* Author : MCD Application Team
* Version : V2.2.0
* Date : 06/13/2008
* Description : Medium Access Layer interface
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "mass_mal.h"
#include "disk_image.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define FLASH_START_ADDR 0x08020000 // Flash start address
#define FLASH_SIZE 0x40000
#define FLASH_PAGE_SIZE 0x800 // 2K per page
#define FLASH_WAIT_TIMEOUT 100000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u32 Mass_Memory_Size[2];
u32 Mass_Block_Size[2];
u32 Mass_Block_Count[2];
/*******************************************************************************
* Function Name : MAL_Init
* Description : Initializes the Media on the STM32
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t MAL_Init(uint8_t lun)
{
u16 status = MAL_OK;
switch (lun)
{
case 0:
FLASH_Unlock(); break;
default:
return MAL_FAIL;
}
return status;
}
/*******************************************************************************
* Function Name : MAL_Write
* Description : Write sectors
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
{
uint16_t i,lenBackup=0;
static uint32_t Readbuff[FLASH_PAGE_SIZE>>2];//一个uint32_t占4个字节;数组比较大,用static修饰放在静态区避免堆栈溢出
uint32_t PageAddr,StartWriteOffset,EndWriteOffset;//页起始地址,页内需要修改的起始偏移数,页内需要修改的结束偏移数
StartWriteOffset=(FLASH_START_ADDR + Memory_Offset)%FLASH_PAGE_SIZE;
EndWriteOffset=FLASH_PAGE_SIZE;
PageAddr=FLASH_START_ADDR + Memory_Offset-StartWriteOffset;
if((lun!=0) && (lun!=1)) return MAL_FAIL;
while(PageAddr < FLASH_START_ADDR + Memory_Offset + Transfer_Length)
{
//printf("\r\n PageAddr:0x%08x PageAddr - FLASH_START_ADDR:0x%04x",PageAddr,PageAddr - FLASH_START_ADDR);
MAL_Read(0,PageAddr - FLASH_START_ADDR,Readbuff,FLASH_PAGE_SIZE);//读一页
// for(i=0; i < (FLASH_PAGE_SIZE>>2); i++) //显示修改前的数据
// printf("\r\n <-:0x%04x data:0x%08x",i<<2,Readbuff[i]);
if(PageAddr + FLASH_PAGE_SIZE > FLASH_START_ADDR+Memory_Offset+Transfer_Length) //计算是否最后一页
EndWriteOffset=(FLASH_START_ADDR + Memory_Offset + Transfer_Length)%FLASH_PAGE_SIZE;
//printf("\r\nStartWriteOffset:0x%x EndWriteOffset:0x%x",StartWriteOffset,EndWriteOffset);
for(i=StartWriteOffset; i<EndWriteOffset; i+=4 )//修改需要修改的数据
Readbuff[i>>2]=Writebuff[lenBackup++];
// for(i=0; i < (FLASH_PAGE_SIZE>>2); i++) //显示修改后的数据
// printf("\r\n ->:0x%04x data:0x%08x",i<<2,Readbuff[i]);
FLASH_ErasePage(PageAddr); //擦除
for(i=0; i<(FLASH_PAGE_SIZE>>2); i++)//写一页
{
if( FLASH_WaitForLastOperation(FLASH_WAIT_TIMEOUT) != FLASH_TIMEOUT )
{
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
}
if(Readbuff[i]!=0xffffffff)//0xffffffff说明原来就没有数据;这可以减少写flash的次数;
{
//printf("\r\n i:%04x wAddr:0x%08x wdata:0x%08x",i,PageAddr+(i<<2),Readbuff[i]);
FLASH_ProgramWord(PageAddr+(i<<2), Readbuff[i]);
}
}
// MAL_Read(0,PageAddr - FLASH_START_ADDR,Readbuff,FLASH_PAGE_SIZE);//读一页
// for(i = 0; i <FLASH_PAGE_SIZE; i+=4)//读显示
// printf("\r\n bias:0x%04x data:0x%08x",i,Readbuff[i>>2]);
PageAddr=PageAddr+FLASH_PAGE_SIZE;
StartWriteOffset=0;
}
return MAL_OK;
}
/*******************************************************************************
* Function Name : MAL_Read
* Description : Read sectors
* Input : None
* Output : None
* Return : Buffer pointer
*******************************************************************************/
uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)
{
uint16_t i;
switch (lun)
{
case 0:
for( i=0; i < Transfer_Length; i+=4 )
{
//printf("\r\nReadAddr:0x%08x ",FLASH_START_ADDR + Memory_Offset+i);
Readbuff[i>>2] = ((vu32*)(FLASH_START_ADDR + Memory_Offset))[i>>2];
// printf("data:0x%08x ",Readbuff[i>>2]);
}
break;
case 1:
break;
default:
return MAL_FAIL;
}
return MAL_OK;
}
/*******************************************************************************
* Function Name : MAL_GetStatus
* Description : Get status
* Input : None
* Output : None
* Return : None
*******************************************************************************/
uint16_t MAL_GetStatus (uint8_t lun)
{
if (lun == 0)
{
Mass_Block_Count[0] = FLASH_SIZE/FLASH_PAGE_SIZE;
Mass_Block_Size[0] = FLASH_PAGE_SIZE;
Mass_Memory_Size[0] = FLASH_SIZE;
return MAL_OK;
}
return MAL_FAIL;
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
|