📄 fl.c
字号:
/*
* File: flash.c
* Purpose: Core dBUG Flash Utilities
*
* Notes:
*
* Modifications:
*
*/
#include "src/include/dbug.h"
#include "src/uif/uif.h"
/********************************************************************/
/*
* Table for storing Flash device information
*/
static FLASH_INFO
device[MAX_FLASH_DEVICES];
/*
* Constant strings
*/
static const char FLASH_ADDRESS_ERROR[] = \
"Invalid Flash address range\n";
static const char FLASH_ERASE_WARNING[] = \
"Must erase complete sectors (%#08X to %#08X)\nContinue? ";
static const char FLASH_ERASE_ERROR[] = \
"Flash Erase error: %#X bytes of %#X erased\n";
static const char FLASH_ERASE_SUCCESS[] = \
"Flash Erase complete. %#X bytes erased\n";
static const char FLASH_PROGRAM_ERROR[] = \
"Flash Write error: %#X bytes of %#X written\n";
static const char FLASH_PROGRAM_SUCCESS[] = \
"Flash Write complete. %#X bytes written\n";
static const char FLASH_BYTE_ERROR[] = \
"Flash Write error: byte count must be divisible by %d\n";
static const char FLASH_WRITE_ERROR[] = \
"Flash Write error: source and destination in same device\n";
/********************************************************************/
void
flash_init(void)
{
int index;
for (index = 0; index < MAX_FLASH_DEVICES; index++)
{
device[index].size = 0;
}
}
/********************************************************************/
int
flash_dlio_vda(ADDRESS addr)
{
int index;
for (index = 0; index < MAX_FLASH_DEVICES; index++)
{
if ((device[index].size) &&
(device[index].base <= addr) &&
(addr <= (ADDRESS)(device[index].base + (device[index].size - 1))))
{
if ((device[index].protect_start <= addr) &&
(addr <= device[index].protect_start +
(device[index].protect_size - 1)))
{
/* Address is protected */
return 0;
}
else
{
return index+1;
}
}
}
/*
* Address was not found within a registered Flash device
*/
return 0;
}
/********************************************************************/
void
flash_display_info(void)
{
int i, j, size, ssize, displayed;
ADDRESS start, end;
printf("Flash Device Information:\n\n");
for (i = 0; i < MAX_FLASH_DEVICES; i++)
{
if (!device[i].size)
continue;
printf(" Device %d: %s\n",i,device[i].name);
printf(" Total Size: %#X ",device[i].size);
if (device[i].size>>10 > 1024)
printf("(%dM) bytes\n", device[i].size>>20);
else
printf("(%dK) bytes\n", device[i].size>>10);
printf(" Address Range: %#08X->%#08X\n",device[i].base,
device[i].base + device[i].size - 1);
printf(" Protected Range: %#08X->%#08X\n",device[i].protect_start,
device[i].protect_start + (device[i].protect_size - 1));
printf(" Access Size: %d byte(s)\n", device[i].mask + 1);
size = 0;
displayed = 11;
for (j = 0; size < device[i].size; j++)
{
start = device[i].sector_start(device[i].base + size);
end = device[i].sector_end(device[i].base + size);
ssize = (end - start) + 1;
size += ssize;
printf(" Sector %2d: %#08X->%#08X (%3dK)\n", j, start, end,
ssize>>10);
if (pause(&displayed))
return;
}
printf("\n");
}
}
/********************************************************************/
void
flash_usage(void)
{
printf("Flash Utility Usage:\n\n");
printf(" (fl)ash (e)rase addr bytes\n");
printf(" (fl)ash (w)rite dest src bytes\n\n");
}
/********************************************************************/
int
flash_register_device (FLASH_INFO *fl_info)
{
int index;
for (index = 0; index < MAX_FLASH_DEVICES; index++)
{
if (device[index].size == 0)
{
strcpy(device[index].name,fl_info->name);
device[index].base = fl_info->base;
device[index].size = fl_info->size;
device[index].mask = fl_info->mask;
device[index].erase = fl_info->erase;
device[index].program = fl_info->program;
device[index].sector_start = fl_info->sector_start;
device[index].sector_end = fl_info->sector_end;
device[index].putchar = fl_info->putchar;
device[index].protect_start = fl_info->protect_start;
device[index].protect_size = fl_info->protect_size;
return TRUE;
}
}
/*
* Table was full
*/
return FALSE;
}
/********************************************************************/
int
flash_erase(ADDRESS start, int bytes, int index)
{
int ebytes, temp;
char answer[UIF_MAX_LINE];
ADDRESS s_start, s_end;
int i = index - 1;
if ((i < 0) || i >= MAX_FLASH_DEVICES)
return FALSE;
/*
* Verify erase operation with user
*/
s_start = device[i].sector_start(start);
s_end = device[i].sector_end(start + bytes - 1);
if ((s_start != start) || (s_end != (start + bytes - 1)))
{
printf(FLASH_ERASE_WARNING, s_start, s_end);
get_line(answer);
if (strncasecmp("yes",answer,1) != 0)
return 0;
}
/*
* Call device specific erase routine
*/
temp = (s_end - s_start) + 1;
ebytes = device[i].erase(s_start, temp, device[i].putchar);
if (ebytes != temp)
{
printf(FLASH_ERASE_ERROR, ebytes, temp);
return FALSE;
}
else
{
printf(FLASH_ERASE_SUCCESS, ebytes);
return TRUE;
}
}
/********************************************************************/
int
flash_program(ADDRESS dest, ADDRESS src, int bytes, int index, int er, int pc)
{
/*
* er - if TRUE, then flash will be erased before programmed
* pc - if TRUE, then driver will output characters as progress indicator
*/
int i = index - 1;
if ((i < 0) || i >= MAX_FLASH_DEVICES)
return 0;
if (pc)
return device[i].program(dest, src, bytes, er, 0, device[i].putchar);
else
return device[i].program(dest, src, bytes, er, 0, 0);
}
/********************************************************************/
void
uif_cmd_fl (int argc, char **argv)
{
ADDRESS addr1, addr2;
int success, bytes, i, j;
char answer[20];
ADDRESS s_start, s_end;
if (argc == 1)
{
flash_usage();
flash_display_info();
}
else if (strncasecmp(argv[1],"erase",1) == 0)
{
if (argc != 4)
{
flash_usage();
return;
}
/*
* Get start address
*/
addr1 = get_value(argv[2],&success,BASE);
if (success == 0)
{
printf(INVALUE,argv[2]);
return;
}
/*
* Get (minimum) number of bytes to erase
*/
bytes = get_value(argv[3],&success,BASE);
if (success == 0)
{
printf(INVALUE,argv[3]);
return;
}
/*
* Verify that start and end are valid addresses
* within same device
*/
i = flash_dlio_vda(addr1);
j = flash_dlio_vda(addr1 + bytes);
if (!(i && j && (i == j)))
{
printf(FLASH_ADDRESS_ERROR);
flash_display_info();
return;
}
/*
* Call Flash erase routine
*/
flash_erase(addr1, bytes, i);
}
else if (strncasecmp(argv[1],"write",1) == 0)
{
if (argc != 5)
{
flash_usage();
return;
}
/*
* Get destination address
*/
addr1 = get_value(argv[2],&success,BASE);
if (success == 0)
{
printf(INVALUE,argv[2]);
return;
}
/*
* Get source address
*/
addr2 = get_value(argv[3],&success,BASE);
if (success == 0)
{
printf(INVALUE,argv[3]);
return;
}
/*
* Get number of bytes to copy
*/
bytes = get_value(argv[4],&success,BASE);
if (success == 0)
{
printf(INVALUE,argv[4]);
return;
}
/*
* Verify that start and end are valid addresses
* within same device
*/
i = flash_dlio_vda(addr1);
j = flash_dlio_vda(addr1 + bytes);
if (!(i && j && (i == j)))
{
printf(FLASH_ADDRESS_ERROR);
flash_display_info();
return;
}
/*
* Verify bytes count is divisible by min. port size
*/
if (bytes & device[i].mask)
{
printf(FLASH_BYTE_ERROR,(device[i].mask + 1));
flash_display_info();
return;
}
/*
* Don't allow source and destination in same Flash device
*/
if (flash_dlio_vda(addr2) == i)
{
printf(FLASH_WRITE_ERROR);
return;
}
/*
* Verify erase operation with user
*/
s_start = device[i-1].sector_start(addr1);
s_end = device[i-1].sector_end(addr1 + bytes - 1);
if ((s_start != addr1) || (s_end != (addr1 + bytes - 1)))
{
printf(FLASH_ERASE_WARNING, s_start, s_end);
get_line(answer);
if (strncasecmp("yes",answer,1) != 0)
return;
}
/*
* Erase and program
*/
j = flash_program(addr1, addr2, bytes, i, TRUE, TRUE);
if (j != bytes)
{
printf(FLASH_PROGRAM_ERROR, j, bytes);
}
else
{
printf(FLASH_PROGRAM_SUCCESS, j);
}
}
else
{
flash_usage();
}
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -