Цитата(vesago @ Jan 22 2006, 12:22)

Спасибо, Kenat. Хотел еще спросить - существенно ли медленнее исполняется код из флеша? Стоит ли максимально грузить в рам или в большинстве случаев можно из флеши? И еще - можно как нибудь дистанционно запустить загрузку во флешь используя штатный загрузчик. Допустим прибор где нибудь в отдалении по 485 связан и надобно поменять прошивку? Я так понял 14 лапу сожают на землю только для того, чтоб после ресета камень перешел в область загрузчика.
скорость выполнения программ зависит от ваших требований. Только учтите, что скорость махание лапками ограничено аппаратной реализацией .
Для загрузки своего кода можно применить технологию IAP + преназначение области встроенной RAM на вектора прерыванией MEMMAP ..
код IAP прилагаю с примером.
iap.h
Код
#ifndef _IAP_H
#define _IAP_H
// Results from flashInit()
#define LPC256K 2
#define LPC128K 1
#define LPCUNKN -1
// (Philips) Status Codes
#define CMD_SUCCESS 0
#define INVALID_CMD 1
#define SRC_ADDR_ERROR 2
#define DST_ADDR_ERROR 3
#define SRC_ADDR_NOT_MAPPED 4
#define DST_ADDR_NOT_MAPPED 5
#define COUNT_ERROR 6
#define INVALID_SECTOR 7
#define SECTOR_NOT_BLANK 8
#define SECTOR_NOT_PREPARED 9
#define COMPARE_ERROR 10
#define BUSY 11
#define PARAM_ERROR 12
#define ADDR_ERROR 13
#define ADDR_NOT_MAPPED 14
#define CMD_LOCKED 15
#define INVALID_CODE 16
#define INVALID_BAUD_RATE 17
#define INVALID_STOP_BIT 18
#define CODE_READ_PROT_ENABLED 19
int flashBlank(int startSector, int endSector);
int flashErase(int startSector, int endSector);
int flashInit(void);
int flashWrite(void *dst, void *src, unsigned byteCount);
#endif
iap.c
Код
#include <intrinsic.h>
#include "string.h"
#include "iap.h"
#define IAP_LOCATION 0x7ffffff1
typedef void (*IAP)(unsigned long *,unsigned long *);
IAP iap_entry =(IAP) IAP_LOCATION;
static unsigned long flashParams[5],
flashResult[2];
static int lastSector;
#ifndef MIN
#define MIN(n,m) (((n) < (m)) ? (n) : (m))
#endif
int GetProcessorClockFreq(void);
int GetPeripheralClockFreq(void);
int flashBlank(int startSector, int endSector)
{
flashParams[0] = 53; // blank check
flashParams[1] = startSector; // start sector
flashParams[2] = endSector; // end sector
iap_entry(flashParams,flashResult);
return (int)flashResult[0];
}
int flashErase(int startSector, int endSector)
{
// unsigned long cpsr;
// unsigned char memmap;
__disable_interrupt();
// memmap = MEMMAP; // get current memory map
// MEMMAP = MEMMAP_FLASH; // map User Flash into low 64 bytes
flashParams[0] = 50; // prepare sector(s)
flashParams[1] = startSector; // start sector
flashParams[2] = endSector; // end sector
iap_entry(flashParams,flashResult);
if (flashResult[0] == CMD_SUCCESS)
{
flashParams[0] = 52; // erase sector(s)
flashParams[1] = startSector; // start sector
flashParams[2] = endSector; // end sector
flashParams[3] = GetProcessorClockFreq()/1000; // cpu clock freq in KHz
iap_entry(flashParams,flashResult);
}
//MEMMAP = memmap & 0x03; // restore the memory map
__enable_interrupt();
return (int)flashResult[0];
}
int flashInit(void)
{
lastSector = 0; // clear last usable sector #
switch (flashBlank(16, 16)) // check last sector of 256K parts
{
case CMD_SUCCESS:
case SECTOR_NOT_BLANK:
lastSector = 16; // store last usable sector #
return LPC256K;
case INVALID_SECTOR:
break;
default:
return LPCUNKN;
}
switch (flashBlank(14, 14)) // check last sector of 128K parts
{
case CMD_SUCCESS:
case SECTOR_NOT_BLANK:
lastSector = 14; // store last usable sector #
return LPC128K;
default:
break;
}
return LPCUNKN;
}
int flashWrite(void *dst, void *src, unsigned byteCount)
{
// unsigned char memmap;
unsigned long count; // cpsr,;
unsigned long buffer[512/sizeof (long)];
if ((lastSector == 0) &&
( flashInit() == LPCUNKN))
return BUSY;
while (byteCount) {
// cpsr = disableINTs(); // disable all interrupts
__disable_interrupt();
// memmap = MEMMAP; // get current memory map
// MEMMAP = MEMMAP_FLASH; // map User Flash into low 64 bytes
// prepare all sectors for programing
flashParams[0] = 50; // prepare sectors
flashParams[1] = 0; // start sector
flashParams[2] = lastSector; // last sector
iap_entry(flashParams,flashResult);
if (flashResult[0] != CMD_SUCCESS) {
// MEMMAP = memmap & 0x03; // restore the memory map
// restoreINTs(cpsr); // restore all interrupts
__enable_interrupt();
return flashResult[0];
}
// check if dst is on 512 byte boundary
if ((unsigned long)dst & 0x1FF) {
// no, copy 512 bytes from flash into buffer
memcpy(buffer, (void *)((unsigned long)dst & ~0x1FF), 512);
// copy src into buffer
count = MIN(byteCount, (512 - ((unsigned long)dst & 0x1FF)));
memcpy((char *)buffer + ((unsigned long)dst & 0x1FF), src, count);
flashParams[0] = 51; // copy RAM to Flash
flashParams[1] = (unsigned long)dst & ~0x1FF; // destination
flashParams[2] = (unsigned long)buffer; // source
flashParams[3] = 512; // byte count
flashParams[4] = GetProcessorClockFreq()/1000; // CCLK in KHz
iap_entry(flashParams,flashResult);
// MEMMAP = memmap & 0x03; // restore the memory map
// restoreINTs(cpsr); // restore all interrupts
__enable_interrupt();
if (flashResult[0] != CMD_SUCCESS)
return (int)flashResult[0];
dst = (char *)dst + count;
src = (char *)src + count;
byteCount -= count;
continue; // restart the loop to prepare sectors again
}
// dst is now aligned on a 512 byte boundary
// find the biggest chunk we can program at a time
if (byteCount >= 8192)
count = 8192;
else if (byteCount >= 4096)
count = 4096;
else if (byteCount >= 1024)
count = 1024;
else if (byteCount >= 512)
count = 512;
else
count = byteCount;
if (count < 512) {
memcpy(buffer, dst, 512); // copy current flash contents into buffer
memcpy(buffer, src, count); // update buffer with the new contents
flashParams[2] = (unsigned long)buffer; // source
flashParams[3] = 512; // byte count
} else {
flashParams[2] = (unsigned long)src;
flashParams[3] = count; // byte count
}
flashParams[0] = 51; // copy RAM to Flash
flashParams[1] = (unsigned long)dst; // destination
flashParams[4] = GetProcessorClockFreq()/1000; // CCLK in KHz
iap_entry(flashParams,flashResult);
// MEMMAP = memmap & 0x03; // restore the memory map
// restoreINTs(cpsr); // restore all interrupts
__enable_interrupt();
if (flashResult[0] != CMD_SUCCESS)
return (int)flashResult[0];
dst = (char *)dst + count;
src = (char *)src + count;
byteCount -= count;
}
return CMD_SUCCESS;
}
пример
Код
// 1 Erase 16 block
printf ("Erase calibration\r\n");
rslt = flashErase(16, 16);
printf ("Result = 0x%04X\r\n",rslt);
printf ("Write calibration\r\n");
rslt = flashWrite((int *)pCalibration, &ZerroREDOX, sizeof(int));
printf ("Result = 0x%04X\r\n",rslt);