📄 flash.c
字号:
/*******************************************************************************\
*
* Copyright (c) 2002, KTWORTH BROADBAND TECH. CO. LTD. PROPERTY.
*
* Filename : flash.c
* Author : fuxs
* Creation Date : 09-08-2002
* Description : flash相关函数
* Subsystem :
*
\*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ktcable.h>
#include <ostime.h>
#include "flash.h"
#include "stflashd.h"
#define BLOCKSIZE_LYQ (0x10000) /*64Kbytes*/
unsigned char Tembuf[BLOCKSIZE_LYQ];/*5.23 add by kt,pls compare with original*/
STATUS Init(sk_Flash *flash)
{
return STATUS_OK;
}
STATUS ID(sk_Flash *flash, u32 *id)
{
return STATUS_OK;
}
STATUS Size(sk_Flash *flash, u32 *size)
{
if (size == NULL)
{
return STATUS_ERR;
}
*size = 1024 * 1024 * 4;
return STATUS_OK;
}
STATUS BlockSize(sk_Flash *flash, i32 *blksize, i32 nBlock)
{
if (blksize == NULL)
{
return STATUS_ERR;
}
*blksize = 0;
if (nBlock <= 62)
{
*blksize = 0x10000;
}
else
{
*blksize = 0x2000;
}
return STATUS_OK;
}
/*
从flash中读取数据
输入参数:
startOffset 起始地址,注意应为相对地址
size 欲读取的字节数
buf 保存读取数据的缓冲区
返回值:
STATUS_OK 成功读取
STATUS_ERR 传送的参数错误,如buf为空等
*/
STATUS Read(sk_Flash *flash, u32 startOffset, i32 size, u8 *buf)
{
unsigned int flash_addr;
if (startOffset > (FLASH_TOTAL_SIZE - size) || size < 0 || buf == NULL)
{
return STATUS_ERR;
}
flash_addr = FLASH_START_ADDR + startOffset;
memcpy((void *) buf, (const void *) flash_addr, size);
return STATUS_OK;
}
/*---------------------------------------------------------------
将缓冲区中的内容写入flash中
输入参数:
startOffset 起始地址,注意应是相对地址
size 写入的字节数
buf 数据缓冲区地址
返回值:
STATUS_OK 成功写入
STATUS_ERR 发生错误
-----------------------------------------------------------------*/
STATUS Write(sk_Flash *flash, u32 startOffset, i32 size, u8 *buf)
{
int i, k, len, needcopy, havecopy, startOffset1, result, flag, flash_addr;
unsigned char * sourcedata;
if ((startOffset > (FLASH_TOTAL_SIZE - size)) || (size < 0) || (buf == NULL))
{
return STATUS_ERR;
}
sourcedata = buf;
flag = 0;
if (startOffset % BLOCKSIZE_LYQ != 0)
{
startOffset1 = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
needcopy = startOffset - startOffset1;
havecopy = BLOCKSIZE_LYQ - needcopy;
if (havecopy >= size)
{
havecopy = size;
flag = 1;
}
Read(sysFlash, startOffset1, BLOCKSIZE_LYQ, Tembuf);
memcpy((void *) (&Tembuf[needcopy]), sourcedata, havecopy);
result = EraseBlock((unsigned short *) (FLASH_START_ADDR + startOffset1));
if (!result)
{
return STATUS_ERR;
}
if (FLASH_START_ADDR + startOffset1 >= 0x7fff0000)
{
result = EarseBootBlock();
if (!result)
{
return STATUS_ERR;
}
}
result = ProgramFlashMiCo(FLASH_START_ADDR
+ (unsigned long int) startOffset1,
Tembuf,
BLOCKSIZE_LYQ);
if (!result)
{
return STATUS_ERR;
}
if (flag == 1)
{
return STATUS_OK;
}
sourcedata += havecopy;
size -= havecopy;
startOffset = startOffset1 + BLOCKSIZE_LYQ;
}
k = size / BLOCKSIZE_LYQ;
if (size % BLOCKSIZE_LYQ != 0)
{
k++;
}
flash_addr = FLASH_START_ADDR + startOffset;
for (i = 0; i < k; i++)
{
if ((i == (k - 1)) && (size % BLOCKSIZE_LYQ))
{
len = size % BLOCKSIZE_LYQ;
}
else
{
len = BLOCKSIZE_LYQ;
}
memcpy((void *) Tembuf, (const void *) sourcedata, len);
if (len != BLOCKSIZE_LYQ)
{
needcopy = BLOCKSIZE_LYQ - len;
memcpy((void *) (&Tembuf[len]),
(const void *) (flash_addr + len),
needcopy);
}
result = EraseBlock((unsigned short *) flash_addr);
if (!result)
{
return STATUS_ERR;
}
if (flash_addr >= 0x7fff0000)
{
result = EarseBootBlock();
if (!result)
{
return STATUS_ERR;
}
}
result = ProgramFlashMiCo((unsigned long int) flash_addr,
Tembuf,
BLOCKSIZE_LYQ);
if (!result)
{
print("Write flash error when call ProgramFlashMiCo.\n");
return STATUS_ERR;
}
if (flash_addr == 0x7fff0000)
{
break;
}
flash_addr += BLOCKSIZE_LYQ;
sourcedata += BLOCKSIZE_LYQ;
}
return STATUS_OK;
}
STATUS Erase(sk_Flash *flash, u32 startOffset)
{
int i, result;
unsigned int flash_addr;
if (startOffset >= FLASH_TOTAL_SIZE)
{
return STATUS_ERR;
}
startOffset = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
for (i = 0; i < 100; i++)
{
flash_addr = FLASH_START_ADDR + startOffset + i * BLOCKSIZE_LYQ;
result = EraseBlock((unsigned short *) flash_addr);
if (!result)
{
return STATUS_ERR;
}
if (flash_addr == 0x7fff0000)
{
result = EarseBootBlock();
if (!result)
{
return STATUS_ERR;
}
return STATUS_OK;
}
}
return STATUS_OK;
}
STATUS Protect(sk_Flash *flash, Bool on)
{
return STATUS_OK;
}
STATUS BlockWrite(sk_Flash *flash,
i32 blockSize,
u32 startOffset,
i32 size,
u8 *buf)
{
int result;
unsigned long int flash_addr;
if (startOffset >= BLOCKSIZE_LYQ || buf == NULL)
{
return STATUS_ERR;
}
startOffset = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
flash_addr = FLASH_START_ADDR + (unsigned long int) startOffset;
result = EraseBlock((unsigned short *) flash_addr);
if (!result)
{
return STATUS_ERR;
}
result = ProgramFlashMiCo(flash_addr, buf, blockSize);
return !result;
}
STATUS BlockErase(sk_Flash *flash, i32 blockSize, u32 startOffset)
{
int result;
u32 flash_addr;
if (startOffset >= FLASH_TOTAL_SIZE)
{
return STATUS_ERR;
}
startOffset = startOffset / BLOCKSIZE_LYQ * BLOCKSIZE_LYQ;
flash_addr = FLASH_START_ADDR + startOffset;
result = EraseBlock((unsigned short *) flash_addr);
return !result;
}
STATUS Term(sk_Flash *flash)
{
return STATUS_OK;
}
STATUS Close(sk_Flash *flash)
{
return STATUS_OK;
}
STATUS Img2Int(unsigned char *str, int *result)
{
int i, j, k, x, y, z;
if (str == NULL)
{
return STATUS_ERR;
}
x = 0;
k = 0;
for (i = 0; i < 4; i++)
{
y = (int) str[i];
z = 1;
for (j = 0; j < k; j++)
{
z *= 0x100;
}
x += y * z;
k++;
}
*result = x;
return STATUS_OK;
}
/*---------------------------------------------------------------
将bin形式的数据写入flash中,注意:如果写入的长度超过1.5M,
最好分开写
bin文件由一至多个数据块组成,每个块的格式如下:
{
地址(int型,4字节)+数据长度(int型,4字节)+数据区
}
数据以0xFFFFFFFF结束,最后跟一个 unsigned long int 型的crc校验码,
四个字节宽
输入参数:
buffer 欲写入的数据缓冲区
length 缓冲区长度
返回值:
STATUS_OK 成功写入
STATUS_ERR 发生错误,可能为bin文件的数据错误或者写入flash时发生错误
-----------------------------------------------------------------*/
STATUS Burn2Flash(sk_Flash *flash, unsigned char *buffer, int length)
{
int k, len, flash_addr, result;
if (buffer == NULL || length < 0)
{
print("Parameter error, please check.\n");
return STATUS_ERR;
}
k = 0;
for (; ;)
{
Img2Int(&buffer[k], &flash_addr);
if (flash_addr == 0xffffffff)
{
break;
}
flash_addr -= FLASH_START_ADDR;
k += 4;
Img2Int(&buffer[k], &len);
k += 4;
if (len > length)
{
len = length;
}
result = flash->Write(flash, flash_addr, len, buffer + k);
if (result != STATUS_OK)
{
print("Write to flash error.\n");
return STATUS_ERR;
}
k += len;
if (k >= length)
{
break;
}
}
return STATUS_OK;
}
int CAMODULE_Flash_Write(unsigned char *pbBuffer,
unsigned int uDest,
unsigned int uLength)
{
int result;
result = sysFlash->Write(sysFlash,
(unsigned int) (uDest - FLASH_START_ADDR),
(unsigned int) uLength,
(unsigned char *) pbBuffer);
if (result == STATUS_OK)
{
return 0;
}
else
{
return -1;
}
}
int CAMODULE_Flash_Read(unsigned char *pbBuffer,
unsigned int uDest,
unsigned int uLength)
{
sysFlash->Read(sysFlash,
(unsigned int) (uDest - FLASH_START_ADDR),
uLength,
pbBuffer);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -