реклама на сайте
подробности

 
 
> как работать с IAP?
cornflyer
сообщение Jan 28 2009, 14:26
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



Кто-нибудь научился работать с флеш-памятью LPC2148 через IAP?
Пока я лучше и проще выхода не нашел как поставить внешний i2c eeprom....
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 55)
zltigo
сообщение Jan 28 2009, 15:10
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(cornflyer @ Jan 28 2009, 17:26) *
Кто-нибудь научился работать...

 нашел как поставить внешний i2c eeprom....


A, что, кто-нибудь это (после чтения документации и многочисленных обсуждений на форуме ) не умеет smile.gif. А вообще смотря для чего, у меня I2C EEPROM почти всегда, не смотря на то, что и во FLASH многое что пишется (приложения, прошивки FPGA,.....).


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
cornflyer
сообщение Jan 29 2009, 12:47
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



на форуме нет внятного описания как работать с IAP, нет рабочего кода, только какие-то танцы с бубном smile.gif
пробовал код с форума - то пишет, то не пишет... непонятно почему
в самой документации на lpc2148 - только пару строк
хотя я все делал как требуется:
выключал прерывания
вызывал функцию подготовки флеша
потом писал туда массив байт из RAM'а
выложи свой рабочий код, который пишет и читает внутреннюю FLASH через IAP smile.gif
Go to the top of the page
 
+Quote Post
Nixon
сообщение Jan 29 2009, 13:14
Сообщение #4


Гуру
******

Группа: Админы
Сообщений: 2 736
Регистрация: 17-06-04
Из: Киев
Пользователь №: 48



Кроме документации существует еще и application note. Там и описание и код, все есть.


--------------------
Вам помочь или не мешать?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 29 2009, 15:31
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(cornflyer @ Jan 29 2009, 14:47) *
выложи свой рабочий код, который пишет и читает внутреннюю FLASH через IAP smile.gif
Тут принято несколько иначе - вы выложите свой код, а мы покажем, что в нем не так. Уж для чтения-то зачем IAP???


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
cornflyer
сообщение Jan 30 2009, 06:51
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



да, я читал application note AN10256
компилятор Keil, target опция USE THUMB MODE включена....

CODE
/*
* IAP In-System Application Programming
*/

#include <LPC21xx.H>

// Clock Frequency
#define XTAL 12000000 // Oscillator Frequency

#ifdef BYPASS_IAP
#define CPUCLK XTAL // CPU Clock without PLL
#else
#define CPUCLK (XTAL*4) // CPU Clock with PLL
#endif

#define CCLK (XTAL / 1000) // CPU Clock without PLL in kHz

// Phase Locked Loop (PLL) definitions
#define PLL_BASE 0xE01FC080 // PLL Base Address
#define PLLCON_OFS 0x00 // PLL Control Offset
#define PLLSTAT_OFS 0x08 // PLL Status Offset
#define PLLFEED_OFS 0x0C // PLL Feed Offset
#define PLLCON_PLLE 0x01 // PLL Enable
#define PLLCON_PLLD 0x00 // PLL Disable
#define PLLCON_PLLC 0x03 // PLL Connect(0x02) | PLL Enable
#define PLLSTAT_PLOCK 0x0400 //1<<10 // PLL Lock Status


struct iap_in {
unsigned int cmd;
unsigned int par[4];
};

typedef void (*IAP)(struct iap_in *in, unsigned int *result);
#define iap_entry ((IAP) 0x7FFFFFF1) // IAP entry point


/* Default Interrupt Function: may be called when interrupts are disabled */
void def_isr (void) __irq {
;
}


#ifdef BYPASS_IAP
/*
* Switch CPU to PLL clock
*/
void start_pll (void) {
__asm {
LDR R0, =PLL_BASE
MOV R1, #0xAA
MOV R2, #0x55

// Enable PLL
MOV R3, #PLLCON_PLLE
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]

// Wait until PLL Locked
LDR R2, =PLLSTAT_PLOCK
PLL_Loop:
LDR R3, [R0, #PLLSTAT_OFS]
CMP R3, R2
BEQ PLL_Loop

// Switch to PLL Clock
MOV R2, #0x55
MOV R3, #PLLCON_PLLC
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
}
}


/*
* Switch CPU to standard XTAL
*/
void stop_pll(void) __arm {
__asm {
LDR R0, =PLL_BASE
MOV R1, #0xAA
MOV R2, #0x55

// Disable PLL
MOV R3, #PLLCON_PLLD
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
}
}

#endif

/*
* Convert 'addr' to sector number
*/
unsigned int get_secnum (void *addr) {
unsigned int n;

n = ((unsigned int) addr >> 13) & 0x1F; // pseudo sector number

if (n >= (0x30000 >> 13)) {
n -= 14; // high small 8kB Sectors (
}
else if (n >= (0x10000 >> 13)) {
n = 7 + (n >> 3); // large 64kB Sectors
}
return (n); // sector number
}


/*
* Erase Sector between 'start' and 'end'
* Return: IAP error code (0 when OK)
* NOTES: start needs to be a 256 byte boundary
* size should be 256, 512, 1024 or 4089
*/
unsigned int erase (void* start, void* end) {
struct iap_in iap; // IAP input parameters
unsigned int result[16]; // IAP results
unsigned int save_VicInt; // for saving of interrupt enable register

save_VicInt = VICIntEnable; // save interrupt enable status
VICIntEnClr = 0xFFFFFFFF; // disable all interrupts

#ifdef BYPASS_IAP
stop_pll(); // IAP requires to run without PLL
#endif

iap.cmd = 50; // IAP Command: Prepare Sectors for Write
iap.par[0] = get_secnum (start); // start sector
iap.par[1] = get_secnum (end); // end sector
iap_entry (&iap, result); // call IAP function
if (result[0]) goto exit; // an error occured?

iap.cmd = 52; // IAP command: Erase Flash
iap.par[0] = get_secnum (start); // start sector
iap.par[1] = get_secnum (end); // end sector
iap.par[2] = CCLK; // CPU clock
iap_entry (&iap, result); // call IAP function

exit:

#ifdef BYPASS_IAP
start_pll(); // start PLL
#endif

VICIntEnable = save_VicInt; // enable interrupts
return (result[0]);
}


/*
* Program *data to flash_addr. number of bytes specified by size
* Return: IAP error code (0 when OK)
* Note:
*/
unsigned int program (void *flash_addr, void *data, unsigned int size) {
struct iap_in iap; // IAP input parameters
unsigned int result[16]; // IAP results
unsigned int save_VicInt; // for saving of interrupt enable register

save_VicInt = VICIntEnable; // save interrupt enable status
VICIntEnClr = 0xFFFFFFFF; // disable all interrupts

#ifdef BYPASS_IAP
stop_pll(); // IAP requires to run without PLL
#endif

iap.cmd = 50; // IAP Command: Prepare Sectors for Write
iap.par[0] = get_secnum (flash_addr); // start sector
iap.par[1] = iap.par[0]; // end Sektor
iap_entry (&iap, result); // call IAP function
if (result[0]) goto exit; // an error occured?

iap.cmd = 51; // IAP Command: Copy RAM to Flash
iap.par[0] = (unsigned int) flash_addr; // destination-addr
iap.par[1] = (unsigned int) data; // source-addr
iap.par[2] = size; // number of bytes
iap.par[3] = CCLK; // CPU clock
iap_entry (&iap, result); // call IAP function

exit:

#ifdef BYPASS_IAP
start_pll(); // start PLL
#endif

VICIntEnable = save_VicInt; // enable interrupts
return (result[0]);
}



unsigned char vals[512];


void main (void) {
unsigned int i;

unsigned int volatile start;

for (start = 0; start < 1000000; start++) {
; // wait for debugger connection (about 0.3 sec)
}

VICDefVectAddr = (unsigned int) def_isr; // for spurious interrupts

for (i = 0; i < sizeof (vals); i++) {
vals[i] = (unsigned char) i;
}

program (0x30000, vals, sizeof (vals));
program (0x31000, vals, sizeof (vals));
program (0x32000, vals, sizeof (vals));
erase (0x30000, 0x31FFF);
erase (0x32000, 0x33FFF);

while (1);
}


Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 30 2009, 08:48
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(cornflyer @ Jan 29 2009, 15:47) *
на форуме нет внятного описания как работать с IAP, нет рабочего кода, только какие-то танцы с бубном smile.gif



Никаких танцев при шатном использовании.

Цитата
..непонятно почему


На вопрос "почему" отвечает сам IAP возвращая коды ошибок, только вот Вы их анализировать не считаете нужным sad.gif. Начните с этого

Цитата
в самой документации на lpc2148 - только пару строк


Вообще-то там целый раздел...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
segment
сообщение Jan 31 2009, 16:32
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 352
Регистрация: 10-08-06
Из: Санкт-Петербург
Пользователь №: 19 471



Кстати да, интересная тема. Может ктонибудь объяснит или напишет небольшой РАБОЧИЙ, самое главное РАБОЧИЙ, код для работы с flash.
А так же интересует вопрос - как чтолибо сохранить во flash, то есть как определяем свободные диапазоны адресов? и что они не будут заняты в будущем?

Просто мысль была сохранять данные, чтобы при выключении они сохранялись. В АВРках было проще, там почти везде был еепром
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 31 2009, 16:36
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Сега @ Jan 31 2009, 18:32) *
то есть как определяем свободные диапазоны адресов? и что они не будут заняты в будущем?
Резервируем нужную область в скрипте линкера. Он будет ругаться, если в будущем будет попытка ее занять чем-то другим.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
cornflyer
сообщение Feb 2 2009, 07:21
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



внутренний flash стоит использовать для хранения редкоменяющейся инфы...
часто писать во внутренний flash - плохой стиль
у него ресурс всего 100000 циклов записи....
запись через IAP занимает время, причем проц не обрабатывает прерывания....
если 100 раз в сутки приходица сохранять инфу - лучше писать во внешний eeprom
у него ресурс 1000000 циклов
вот например можно поставить i2c eeprom M24C64
код для чтения/записи приведен ниже:
Код
#include "lpc214x.h"
/*-------------------------------------------------------------------------*/
#define SDA_BIT    (1<<3)//for olimex board
#define SCL_BIT    (1<<2)//for olimex board
#define I2C_ADDR (0x50)//I2C Slave Address
/*-------------------------------------------------------------------------*/
void I2C_DELAY(void){
    volatile z=1000;
    while(z) z--;
}
/*-------------------------------------------------------------------------*/
unsigned char I2C_SDA(void){
    return (IOPIN0&SDA_BIT);    
}
/*-------------------------------------------------------------------------*/
void I2C_SDA_HIGH(void){
    IODIR0 &=~ SDA_BIT;//input    
}
/* -------------------------------------------------------------------------*/
void I2C_SDA_LOW(void){
    IOCLR0 = SDA_BIT;
    IODIR0 |= SDA_BIT;//output low
}
/*-------------------------------------------------------------------------*/
void I2C_SCL_HIGH(void){
    IODIR0 &=~ SCL_BIT;//input
}
/*-------------------------------------------------------------------------*/
void I2C_SCL_LOW(void){
    IOCLR0 = SCL_BIT;
    IODIR0 |= SCL_BIT;//output low
}
/*-------------------------------------------------------------------------*/
unsigned char i2c_send_byte(unsigned char b){
    unsigned char result = 0;
    unsigned int i = 0;
    for(i=0;i<8;i++){
        //Set Data
        if(b&0x80){// == 1000 0000
            I2C_SDA_HIGH();
        }else{
            I2C_SDA_LOW();
        }
        b = b<<1;//shift left by one position
        I2C_DELAY();
        I2C_SCL_HIGH();//make clock pulse
        I2C_DELAY();
        I2C_SCL_LOW();
        I2C_DELAY();    
    }
    //Acknowledge
    I2C_SDA_HIGH();
    I2C_DELAY();
    I2C_SCL_HIGH();//make clock pulse
    I2C_DELAY();
    if(I2C_SDA()){//check i2c slave acknowledge
        result = 1;
    }else{
        result = 0;
    }
    I2C_SCL_LOW();
    I2C_DELAY();
    return result;
}
/*-------------------------------------------------------------------------*/
unsigned char i2c_write(unsigned int addr,unsigned char b){
    unsigned char result = 0;
    //Initial state (stop condition)
    I2C_SCL_HIGH();
    I2C_DELAY();
    I2C_SDA_HIGH();
    I2C_DELAY();
    //Start (start condition)
    I2C_SDA_LOW();
    I2C_DELAY();
    I2C_SCL_LOW();
    I2C_DELAY();
    //Send i2c address
    if(i2c_send_byte(I2C_ADDR<<1)){//RW=0
        result = 1;
    }else{
        if(i2c_send_byte(addr>>8))result = 1;//high addr
        if(i2c_send_byte(addr))result = 1;//low addr
        if(i2c_send_byte(b))result = 1;
    }
    //Stop (stop condition)
    I2C_SDA_LOW();
    I2C_DELAY();
    I2C_SCL_HIGH();
    I2C_DELAY();
    I2C_SDA_HIGH();
    I2C_DELAY();
    return result;
}
/*-------------------------------------------------------------------------*/
void i2c_write_byte(unsigned int addr, unsigned char b){
    unsigned char result = 1;
    while(result)result = i2c_write(addr,b);
}
/*-------------------------------------------------------------------------*/
void i2c_read_page(unsigned int addr, unsigned char *page_buff, unsigned int page_length){
    unsigned char data_byte = 0;
    int b;
    //Initial state
    I2C_SCL_HIGH();
    I2C_DELAY();
    I2C_SDA_HIGH();
    I2C_DELAY();
    //Start (start condition)
    I2C_SDA_LOW();
    I2C_DELAY();
    I2C_SCL_LOW();
    I2C_DELAY();
    //Send address
    i2c_send_byte(I2C_ADDR<<1);//RW=0
    i2c_send_byte(addr>>8);//high addr
    i2c_send_byte(addr);//low addr
    //Start (start condition)
    I2C_SCL_HIGH();
    I2C_DELAY();
    I2C_SDA_LOW();
    I2C_DELAY();
    I2C_SCL_LOW();
    I2C_DELAY();
    i2c_send_byte((I2C_ADDR<<1)|0x01);//RW = 1
    while(page_length){//read page    
        I2C_SDA_HIGH();
        for(b=8;b--;){
            I2C_DELAY;
            I2C_SCL_HIGH();
            I2C_DELAY();
            data_byte = (data_byte<<1)|((I2C_SDA())?0x01:0x00);
            I2C_DELAY();
            I2C_SCL_LOW();
            I2C_DELAY();
        }
        *page_buff = data_byte;
        page_buff++;
        data_byte = 0;
        page_length--;
        //Acknowledge
        if(page_length) I2C_SDA_LOW(); else I2C_SDA_HIGH();
        I2C_DELAY();
        I2C_SCL_HIGH();
        I2C_DELAY();
        I2C_DELAY();
        I2C_SCL_LOW();
        I2C_DELAY();
    }
    //Stop (stop condition)
    I2C_SDA_LOW();
    I2C_DELAY();
    I2C_SCL_HIGH();
    I2C_DELAY();
    I2C_SDA_HIGH();
    I2C_DELAY();
}
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Feb 2 2009, 07:46
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(cornflyer @ Feb 2 2009, 10:21) *
вот например можно поставить i2c eeprom M24C64
код для чтения/записи приведен ниже:

А почему софтовый I2C???
Go to the top of the page
 
+Quote Post
yuri_t
сообщение Feb 2 2009, 08:22
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 24-08-05
Пользователь №: 7 937



По поводу IAP можно посмотреть здесь:

http://www.tnkernel.com/usb_fw_upgrader.html
(usb-fwu-1-0-1-lpc214x.zip -> fwu_asm.s)

По поводу I2C - здесь:
Прикрепленные файлы
Прикрепленный файл  LPC2xx_I2Clib.zip ( 9.04 килобайт ) Кол-во скачиваний: 88
 
Go to the top of the page
 
+Quote Post
cornflyer
сообщение Feb 2 2009, 11:17
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



преимущества софтового i2c :
- софтовый i2c меньше занимает, работает без глюков wink.gif (смотри еррату на lpc2148)
- SDA и SCL можно на любые ноги повесить

мой личный опыт показывает что код, написанный на все случаи жизни - работает медленно, глючит и
много жрет ресурсов....
поэтому я стараюсь кодить только то, что нужно для решения поставленной задачи
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 2 2009, 12:48
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(cornflyer @ Feb 2 2009, 14:17) *
софтовый i2c меньше занимает, работает без глюков wink.gif (смотри еррату на lpc2148)



Смотреть нечего - уже ДЕСЯТКИ лет I2C на любых Филипсовских контролерах никаких errata и глюков не имеет, является отлитым в бронзе стандартом. И, как Вам показалось, заработавший copy-paste  из интернету софтового I2C не повод изрекать глупости про "глюки", "ресурсы" и "медленность".

 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
cornflyer
сообщение Feb 3 2009, 07:47
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



согласен.
перечитал еррату - действительно с i2с в lpc2148 проблем нет. похоже я перепутал с другим камнем.
i2c контроллер нужен если на шине много устройств
а если всего один eeprom и к тому же накосячил с разводкой - тут поможет только софтверный i2c.
скоро буду разводить новую плату под ecos - вот тут мне понадовица i2c контроллер

P.S. кстати, нашел в ecos'е пару багов - неправильно было определено адресное смещение - должно быть 0x10000000
из-за этого код больше 1Mb не работал...
и еще там не включена опция кэширования.....
в итоге после фиксов все заработало в 10 раз (!!!!) быстрее!
Go to the top of the page
 
+Quote Post
bigarmer
сообщение Feb 7 2009, 07:32
Сообщение #16


Участник
*

Группа: Новичок
Сообщений: 52
Регистрация: 5-12-08
Пользователь №: 42 221



CODE


===========IAP.C=============



#include "IAP.h"

#define IAP_CLK Fcclk

#define IAP_LOCATION 0x7FFFFFF1
#define iap_entry(a, cool.gif ((void (*)())(IAP_LOCATION))(a, cool.gif

unsigned long command[5] = {0,0,0,0,0};
unsigned long result[3]= {0,0,0};


/*************************************************************************
* Function Name: IAP_PrepareSec
* Parameters: unsigned long StartSecNum -- Start Sector Number
* unsigned long EndSecNum -- End Sector Number
* Return: unsigned long -- Status Code
*
* Description: This command must be executed before executing "Copy RAM to Flash" or
* "Erase Sector(s)" command.
*
*************************************************************************/
unsigned long IAP_PrepareSec (unsigned long StartSecNum, unsigned long EndSecNum)
{
if (EndSecNum < StartSecNum)
return IAP_STA_INVALD_PARAM;

command[0] = IAP_CMD_PrepareSec;
command[1] = StartSecNum;
command[2] = EndSecNum;
iap_entry(command, result);

return result[0];
}

/*************************************************************************
* Function Name: IAP_CopyRAMToFlash
* Parameters: unsigned long dst -- Destination Flash address, should be a 256 byte boundary.
* unsigned long src -- Source RAM address, should be a word boundary
* unsigned long number -- 256 | 512 |1024 |4096
* Return: unsigned long -- Status Code
*
* Description: This command is used to program the flash memory.
*
*************************************************************************/
unsigned long IAP_CopyRAMToFlash (unsigned long dst, unsigned long src,
unsigned long number)
{
command[0] = IAP_CMD_CopyRAMToFlash;
command[1] = dst;
command[2] = src;
command[3] = number;
command[4] = IAP_CLK / 1000; // Fcclk in KHz
iap_entry(command, result);

return result[0];
}


/*************************************************************************
* Function Name: IAP_EraseSec
* Parameters: unsigned long StartSecNum -- Start Sector Number
* unsigned long EndSecNum -- End Sector Number
* Return: unsigned long -- Status Code
*
* Description: This command is used to erase a sector or multiple sectors of on-chip Flash
* memory.
*
*************************************************************************/
unsigned long IAP_EraseSec (unsigned long StartSecNum, unsigned long EndSecNum)
{
if (EndSecNum < StartSecNum)
return IAP_STA_INVALD_PARAM;

command[0] = IAP_CMD_EraseSec;
command[1] = StartSecNum;
command[2] = EndSecNum;
command[3] = IAP_CLK / 1000;
iap_entry(command, result);

return result[0];
}

/*************************************************************************
* Function Name: IAP_BlankChkSec
* Parameters: unsigned long StartSecNum -- Start Sector Number
* unsigned long EndSecNum -- End Sector Number
* Return: unsigned long -- Status Code
*
* Description: This command is used to blank check a sector or mutilple sectors of on-chip
* Flash memory.
*
*************************************************************************/
unsigned long IAP_BlankChkSec (unsigned long StartSecNum, unsigned long EndSecNum,
unsigned long * pResult)
{
if (EndSecNum < StartSecNum)
return IAP_STA_INVALD_PARAM;

command[0] = IAP_CMD_BlankChkSec;
command[1] = StartSecNum;
command[2] = EndSecNum;

iap_entry(command, result);

if (result[0] == IAP_STA_SECTOR_NOT_BLANK)
{
*pResult = result[0];
*(pResult+1) = result[1];
}

return result[0];
}

/*************************************************************************
* Function Name: IAP_ReadParID
* Parameters: unsigned long * PartID
* Return: unsigned long -- Status Code
*
* Description: This command is used to read the part identification number.
*
*************************************************************************/
unsigned long IAP_ReadParID (unsigned long * PartID)
{

command[0] = IAP_CMD_ReadParID;
iap_entry(command, result);
*PartID = result[1];

return result[0];
}

/*************************************************************************
* Function Name: IAP_ReadBootVer
* Parameters: char * MajorVer
* char * MinorVer
* Return: unsigned long -- Status Code
*
* Description: This command is used to read the boot code version number.
*
*************************************************************************/
unsigned long IAP_ReadBootVer (unsigned long * MajorVer, unsigned long * MinorVer)
{
command[0] = IAP_CMD_ReadBootVer;
iap_entry(command, result);
*MajorVer = (result[1] & 0xff00)>>8;
*MinorVer = result[1] & 0xff;

return result[0];
}

/*************************************************************************
* Function Name: IAP_Compare
* Parameters: unsigned long dst -- Destination Flash address
* unsigned long src -- Source RAM address
* unsigned long number -- Should be in mutilple of 4
* Return: unsigned long -- Status Code
*
* Description: This command is used to compary the memory contents at two locations.
*
* NOTE: Compary result may not be correct when source or destination address contains
* any of the first 64 bytes starting from address zero. First 64 bytes can be re-mapped
* to RAM.
*
*************************************************************************/
unsigned long IAP_Compare (unsigned long dst, unsigned long src,
unsigned long number, unsigned long *offset)
{
command[0] = IAP_CMD_Compare;
command[1] = dst;
command[2] = src;
command[3] = number;
iap_entry(command, result);

if (result[0] == IAP_STA_COMPARE_ERROR)
*offset = result[1];

return result[0];
}

void IAP_ReinvokeISP(void)
{
command[0] = IAP_CMD_REINVOKEISP;
iap_entry(command, result);;
}

=====================================
===========IAP.H=============
#ifndef __IAP_H
#define __IAP_H

/* IAP Command */
#define IAP_CMD_PrepareSec 50 //select sector
#define IAP_CMD_CopyRAMToFlash 51 //copy data from ram to flash
#define IAP_CMD_EraseSec 52 //erase sector
#define IAP_CMD_BlankChkSec 53 //check if sector is blank
#define IAP_CMD_ReadParID 54 //read chip ID
#define IAP_CMD_ReadBootVer 55 //read BOOT version
#define IAP_CMD_Compare 56 //compare
#define IAP_CMD_REINVOKEISP 57 //reinvoke ISP command

/* IAP Status Codes */
#define IAP_STA_CMD_SUCCESS 0
#define IAP_STA_INVALID_COMMAND 1
#define IAP_STA_SRC_ADDR_ERROR 2
#define IAP_STA_DST_ADDR_ERROR 3
#define IAP_STA_SRC_ADDR_NOT_MAPPED 4
#define IAP_STA_DST_ADDR_NOT_MAPPED 5
#define IAP_STA_COUNT_ERROR 6
#define IAP_STA_INVALID_SECTOR 7
#define IAP_STA_SECTOR_NOT_BLANK 8
#define IAP_STA_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9
#define IAP_STA_COMPARE_ERROR 10
#define IAP_STA_BUSY 11

#define IAP_STA_INVALD_PARAM 12

extern unsigned long IAP_PrepareSec (unsigned long, unsigned long);
extern unsigned long IAP_CopyRAMToFlash (unsigned long dst, unsigned long src,
unsigned long number);
extern unsigned long IAP_EraseSec (unsigned long StartSecNum, unsigned long EndSecNum);
extern unsigned long IAP_BlankChkSec (unsigned long StartSecNum, unsigned long EndSecNum,
unsigned long * pResult);
extern unsigned long IAP_ReadParID (unsigned long * PartID);
extern unsigned long IAP_ReadBootVer (unsigned long * MajorVer, unsigned long * MinorVer);
extern unsigned long IAP_Compare (unsigned long dst, unsigned long src,
unsigned long number, unsigned long *offset);
extern void IAP_ReinvokeISP(void);


#endif

Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 18 2009, 12:27
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Позвольте задать вопрос в этой теме касаемо IAP. В мануале на LPC2378, который использую, написанно чёрным по-нерусски: "Up to 512 kB on-chip Flash Program Memory with In-System Programming (ISP) and In-Application Programming (IAP) capabilities. Single Flash sector or full-chip erase in 400 ms and 256 bytes programming in 1 ms". То есть для стирания !одного! или !всех! секторов без разницы надо 400 мс, а для записи 4кб=256*16=16мс? а сколько надо для подготовки сектора к записи и стиранию, и сравнения двух секторов? по этим операциям временных рамок не нашёл.


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 18 2009, 18:16
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(TanT @ Feb 18 2009, 15:27) *
а сколько надо для подготовки сектора к записи и стиранию
D
В миллисекундном измерении приблизительно "нисколько".
Цитата
, и сравнения двух секторов?

А это вообще бесполезность - сами можете сравнить - за сколько сравните, за столько и будет.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 19 2009, 05:49
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Я так и думал smile.gif . А касаемо стирания одного сектора? "Single Flash sector or full-chip erase in 400 ms "
И вообще имеет смысл каждый раз чистить сектор перед употреблением? То есть, не правильно выразился, какова вероятность ошибочной записи сектора без его предворительного стирания?


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Feb 19 2009, 06:06
Сообщение #20


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(TanT @ Feb 19 2009, 08:49) *
И вообще имеет смысл каждый раз чистить сектор перед употреблением? То есть, не правильно выразился, какова вероятность ошибочной записи сектора без его предворительного стирания?

Такя же, как и вероятность записи единицы на место записанного ранее нуля. То есть, не так выразился, записать можно только ноль на месте единицы, для обратной записи нужно стирание


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 19 2009, 06:45
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Цитата
(TanT @ Feb 19 2009, 08:49)
И вообще имеет смысл каждый раз чистить сектор перед употреблением? То есть, не правильно выразился, какова вероятность ошибочной записи сектора без его предворительного стирания?

Глупый вопрос, blush.gif Следующий раз буду внимательнее слушать старших товарищей.

Однако, всё таки кто-нибудь сможет ответить на вопрос: сколько требуется времени для стирания одного сектора по IAP для LPC2378?


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
MikePic
сообщение Feb 19 2009, 07:11
Сообщение #22


Участник
*

Группа: Новичок
Сообщений: 57
Регистрация: 7-11-06
Пользователь №: 22 054



TanT
Цитата
Однако, всё таки кто-нибудь сможет ответить на вопрос: сколько требуется времени для стирания одного сектора по IAP для LPC2378?

А просто взять и измерить?
1. Таймером - считать значение до входа в процедуру стирания, считать значение после выхода, вывести в UART разницу
2. Осциллом - установить пин из 0 в 1 до входа, из 1 в 0 после выхода
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 19 2009, 09:59
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(MikePic @ Feb 19 2009, 10:11) *
А просто взять и измерить?

Зачем? Получить некое конкретное зачение для данного чипа в данный момент времени? Что будет у другого экземпляра? Что будет после 1000 стираний? Производитель документирует 400 - их и нужно придерживаться.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 19 2009, 10:04
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Цитата
Производитель документирует 400 - их и нужно придерживаться.


Игорь, простите, конечно, настырность, но эти милисекунды очень критичны. Развейте наконец мои сомнения. Сколько времени требуется для стирания одного сектора? А десяти?


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 19 2009, 10:33
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(TanT @ Feb 19 2009, 13:04) *
Сколько времени требуется для стирания одного сектора? А десяти?

Столько, сколько Вы прочитали в документации - любое стирание хоть чипа, хоть одного сектора 400ms. Десять секторов последовательно - в десять раз больше одного сектора. Любые надежды на ускорение и из последствия на Вашей совести. Когда-то давно давно еще на LPC2114 измерения делал - результаты где-то в глубинах форума должны быть. Время стирания помнится много меньше 400ms ну и что? Хотите занятся радиолюбительством? - Измеряйте и занимайтесь sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 19 2009, 11:22
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Спасибо большое, именно это хотел услышать.
А радиолюбительством я вроде и не собирался заниматься, не тот случай. wink.gif


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Feb 19 2009, 11:41
Сообщение #27


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Если уж хочется что-то поделать пока идет стирание, можно разместить функцию в RAM. Если нужны прерывания - мапировать векторы в RAM и разместить в RAM обработчики. У меня так сбрасывается внешний вочдог пока идет стирание.
Go to the top of the page
 
+Quote Post
Denisvak
сообщение Feb 24 2009, 14:18
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 141
Регистрация: 7-03-06
Из: Санкт-Петербург
Пользователь №: 15 038



Позвольте задать вопрос в этой же теме дабы не создавать новой.
Собираюсь писать свой загрузчик под LPC21хх через модуль IAP.
Состоит из программы ПК и программы для контроллер. ПО на ПК будет принимать прошивку в в виде hex файла и отправлять контроллеру через хх интерфейс, допусти 232. Надо ли мне как-то преобразовывать в другой формат прежде чем писать прошивку во флеш, или хватит просто класть по нужным адресам?

Ещё вопрос по созданию проектов в IAR
Бутлодер должен висеть в самом начале флеша(первые 4кб), и запускаться первым затем передавать управление основной программе функцией ((void (*)())0x1000)();
Основная программа расположена с адреса 0x1000. Как в данном случае должна происходить работа прерываний для этих разный областей.
Go to the top of the page
 
+Quote Post
etoja
сообщение Feb 24 2009, 15:18
Сообщение #29


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Прилагаю подробную инструкцию по IAP для использования с компилятором Crossworks.
Извиняюсь перед автором этого документа, что не записал его адрес в интернете.
Прикрепленные файлы
Прикрепленный файл  IAP.zip ( 4.03 килобайт ) Кол-во скачиваний: 110
 
Go to the top of the page
 
+Quote Post
Denisvak
сообщение Feb 24 2009, 16:26
Сообщение #30


Частый гость
**

Группа: Участник
Сообщений: 141
Регистрация: 7-03-06
Из: Санкт-Петербург
Пользователь №: 15 038



Цитата(etoja @ Feb 24 2009, 18:18) *
Прилагаю подробную инструкцию по IAP для использования с компилятором Crossworks.
Извиняюсь перед автором этого документа, что не записал его адрес в интернете.

Спасибо за пример, разбираюсь smile.gif

Вопрос по прерываниям в основной программой. Если я линкеру укажу файлик "LPC2148_flash.xcl" в котором ручками поправлю начало флеш
Код
-DROMSTART=00001000
вместо
Код
-DROMSTART=00000040
и прерывания
Код
-Z(CODE)INTVEC=00001000-0000103f
вместо
Код
-Z(CODE)INTVEC=00000000-0000003f
будут ли корректно работать прерывания? Камешек lpc2148
Всем спасибо.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 24 2009, 18:32
Сообщение #31


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Denisvak @ Feb 24 2009, 18:26) *
будут ли корректно работать прерывания?
При возникновении исключения процессор переходит на адреса 0-0x3f. Куда вы положите вектора - ему все равно. Он будет переходить по заложенным в него железно адресам 0...0x3f. Один из возможных вариантов решения вашей проблемы - remap. Читайте про него в документации на ARM7 и ищите по форуму.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 26 2009, 05:05
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Вопрос в продолжении темы IAP: команда 56 - сравнение секторов. насколько быстро и надёжно всё это происходит, например, для сектора в 4кб? Вообще, в принципе какая вероятность записать с ошибкой сектор по IAP?


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
etoja
сообщение Feb 26 2009, 07:21
Сообщение #33


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Цитата(TanT @ Feb 26 2009, 08:05) *
Вопрос в продолжении темы IAP: команда 56 - сравнение секторов. насколько быстро и надёжно всё это происходит, например, для сектора в 4кб? Вообще, в принципе какая вероятность записать с ошибкой сектор по IAP?


Записывайте в конец сектора свою 32-битную контрольную сумму.
Go to the top of the page
 
+Quote Post
TanT
сообщение Feb 26 2009, 07:52
Сообщение #34


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Если сравнение гарантирует 100% выявление ошибок, то за чем лишнии действия? Однако, кто ответит что быстрее и надёжнее - вычисление 32-битной(16-битной) контрольной суммы или стандартная операция сравнения IAP?


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 26 2009, 11:05
Сообщение #35


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(TanT @ Feb 26 2009, 10:52) *
Если сравнение гарантирует 100% выявление ошибок, то за чем лишнии действия? Однако, кто ответит что быстрее и надёжнее - вычисление 32-битной(16-битной) контрольной суммы или стандартная операция сравнения IAP?

а у IAP есть операция сравнения? Сравнивать надо самим, благо весь флеш доступен на чтение.
Контрольную сумму вычислять вообще смысла нет! Потому что все равно надо будет считывать все данные, чем производить с ними операции проще сравнить с оригиналом. Да и скорость обработки данных не сопоставима со скоростью их передачи для прошивки и временем прошивки.
Go to the top of the page
 
+Quote Post
etoja
сообщение Feb 26 2009, 16:12
Сообщение #36


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Контрольная сумма нужна обязательно, поскольку в момент программирования может выключиться питание прибора.
Но это - для профессионального оборудования.
Go to the top of the page
 
+Quote Post
Denisvak
сообщение Feb 26 2009, 17:02
Сообщение #37


Частый гость
**

Группа: Участник
Сообщений: 141
Регистрация: 7-03-06
Из: Санкт-Петербург
Пользователь №: 15 038



Цитата(TanT @ Feb 26 2009, 10:52) *
Если сравнение гарантирует 100% выявление ошибок, то за чем лишнии действия? Однако, кто ответит что быстрее и надёжнее - вычисление 32-битной(16-битной) контрольной суммы или стандартная операция сравнения IAP?


Какая-то у вас тяга к быстрым вычислениям smile.gif Для чего?
Go to the top of the page
 
+Quote Post
TanT
сообщение Mar 2 2009, 06:16
Сообщение #38


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Цитата
Контрольная сумма нужна обязательно, поскольку в момент программирования может выключиться питание прибора.
Но это - для профессионального оборудования.

контрольная сумма будет обязательно будет, точнее она есть (16). И данные будут записываться уже достоверные, то есть требуется сличить записанные и записываемые данные. Совет KRS я считаю правильным и не пременно им воспользуюсь. Уцепился сразу за эту команду сравнения IAP, казалось что специально написанная функция должна быть оптимизированна и прочее smile.gif

Цитата
Какая-то у вас тяга к быстрым вычислениям Для чего?

Кроме записи по IAP много чего ещё должно работать, и запись далеко не приоритетная задача, и чем меньше времени она будет крутиться тем лучше. Вообще запись данных требуется проводить не заметно для остальных процессов, что сильно затрудняет обязательное требование запрета прерываний. Поэтому и стараюсь точно определить все временные рамки и по возможности их минимизировать, в частности на проверку данных. Большие трудности создаёт возможность неудачной записи (вероятность ошибки, думаю, никому неизвестна) 400 мс для стирания и повторной записи у меня нет.


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
etoja
сообщение Mar 2 2009, 08:04
Сообщение #39


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Цитата(TanT @ Mar 2 2009, 09:16) *
Большие трудности создаёт возможность неудачной записи (вероятность ошибки, думаю, никому неизвестна) 400 мс для стирания и повторной записи у меня нет.


Неудачная запись по вине процессора никогда не встречалась.
По вине пропадания питания в момент записи - возможна.
Запись во внутреннюю память процессора - монопольный процесс. Если это не устраивает - используйте внешнюю FRAM.
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Mar 2 2009, 09:56
Сообщение #40


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(TanT @ Mar 2 2009, 08:16) *
Вообще запись данных требуется проводить не заметно для остальных процессов, что сильно затрудняет обязательное требование запрета прерываний.

Запрет прерываний - требование не обязательное. Обязательное требование - отсутствие доступа к Flash. Прерывания могут спокойно работать в RAM.
Цитата
The on-chip flash memory is not accessible during erase/write operations. When the user
application code starts executing the interrupt vectors from the user flash area are active.
The user should either disable interrupts, or ensure that user interrupt vectors are active in
RAM and that the interrupt handlers reside in RAM, before making a flash erase/write IAP
call. The IAP code does not use or disable interrupts.
Go to the top of the page
 
+Quote Post
TanT
сообщение Mar 2 2009, 12:23
Сообщение #41


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Цитата
Запрет прерываний - требование не обязательное. Обязательное требование - отсутствие доступа к Flash. Прерывания могут спокойно работать в RAM.
угу, читал. для меня обязательное unsure.gif


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
Denisvak
сообщение Mar 3 2009, 20:15
Сообщение #42


Частый гость
**

Группа: Участник
Сообщений: 141
Регистрация: 7-03-06
Из: Санкт-Петербург
Пользователь №: 15 038



Сергей Борщ и etoja
Спасибо Вам за помощь все работает smile.gif
Go to the top of the page
 
+Quote Post
vesago
сообщение Mar 15 2009, 17:31
Сообщение #43


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Прошу совета по сабжу. Я использую LPC2214. C 0 по 0x1FFF расположен загрузчик, с 0x2000 приложение. Все работате отлично. Решил я написать приложение, которое будет обновлять загрузчик. То есть образ нового загрузчика расположен по адресу 0x6000. После заливки, это приложение через IAP должно стереть сектор где расположен старый загрузчик, т.е. сектор 0 и скопировать туда образ нового загрузчика с адреса 0x6000. При отладке я пробовал копировать в область с адресом 0x8000 - проблем не было. В боевом варианте после стирания сектора 0 система зависает. Если посмотреть память флэш меджиком, видно что сектор 0 стерт. Почему система отваливается, ума не приложу. Вроде все сконфигурировано правильно - в опциях кейла и стартапе задал, что прошивка начинается с адреса 0x2000. Может есть какие-то особенности IAP - типа клинит соседний сектор? JTAG смотрел - показалось, что коллапс наступает после восстановления прерываний.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 15 2009, 18:02
Сообщение #44


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Ну дык если стёрли нулевой сектор, то стёрли и вектора прерываний по адресам 00-3f. Либо делайте ремап на ОЗУ (заполнив вектора 0x40000000-0x4000001f) и уже потом разрешайте прерывания, либо не разрешайте прерывания вообще до окончательной перезаписи нулевого сектора.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
vesago
сообщение Mar 15 2009, 18:10
Сообщение #45


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Я думал, что если начало прошивки сконфигурировано с адреса 0x2000, то и вектора там же. А как же она работает в обычном режиме? Там же сидит загрузчик как отдельное приложение. Получается для ремапа, мне нужно в начало рамы копирнуть область векторов с 0 флеши и задать ремап?
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Mar 15 2009, 19:23
Сообщение #46


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(vesago @ Mar 15 2009, 20:10) *
Я думал, что если начало прошивки сконфигурировано с адреса 0x2000, то и вектора там же. А как же она работает в обычном режиме? Там же сидит загрузчик как отдельное приложение. Получается для ремапа, мне нужно в начало рамы копирнуть область векторов с 0 флеши и задать ремап?

Да, этого достаточно.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Mar 15 2009, 19:34
Сообщение #47


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(vesago @ Mar 15 2009, 23:10) *
А как же она работает в обычном режиме? Там же сидит загрузчик как отдельное приложение.

В векторах программ чаще всего используется IRQ. Если по адресу 0x18 в нулевом секторе (загрузчике) стоит команда LDR PC,[PC,#-0xFF0], то этого достаточно чтобы IRQ прикладной программы нормально действовали. Для FIQ тоже можно сделать похожим образом. Ну а остальные вестора исключительных ситуаций обычно не возникают и для большинства программ не имеют значения. Обычно там вообще стоят заглушки типа зависона.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
vesago
сообщение Mar 15 2009, 19:53
Сообщение #48


Тутэйшы
****

Группа: Свой
Сообщений: 708
Регистрация: 30-11-04
Пользователь №: 1 263



Спасибо, все понятно.
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Mar 16 2009, 02:31
Сообщение #49


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(cornflyer @ Jan 29 2009, 07:47) *
на форуме нет внятного описания как работать с IAP, нет рабочего кода, только какие-то танцы с бубном smile.gif
пробовал код с форума - то пишет, то не пишет... непонятно почему
в самой документации на lpc2148 - только пару строк
хотя я все делал как требуется:
выключал прерывания
вызывал функцию подготовки флеша
потом писал туда массив байт из RAM'а
выложи свой рабочий код, который пишет и читает внутреннюю FLASH через IAP smile.gif

Может вы не ту доку читали? Я пользовался LPC2478, в доке все внятно прописано более менее. Не пара строк. За пару часов запись удалось осуществить.
Go to the top of the page
 
+Quote Post
TanT
сообщение Mar 17 2009, 06:19
Сообщение #50


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



Вопрос к etoja по поводу записи, точнее верификации.
Пишу себе спокойно по IAP, проверяю двумя способами: в лоб по рекомендации KRS и IAPовским сравнением. И нет такого момента, чтобы без ошибок обошлось на 32 кб записи 2-3 ошибки в среднем. Ну это ещё полбеды. Смотрю где ошибка - записанно всё что требуется (покрайней мере в том месте куда указывают функции сравнения). Ладно, думаю, по не опытности накосячил где-нить с указателями и не то сравниваю, однако, прошивка не запускается. Но стоит повторить целиком запись прошивки "поверх" старой, и - о чудо - всё работает и ошибок проверки не возникает. Чем это может быть обоснованно? Как всё таки достоверно сравнивать данные из ОЗУ и флеш?

P.S. Записывал массив одинаковых символов, смотрел глазками что вышло, всё в идеале, хотя ошибки всё равно лезут.
Прерывания естественно все отключены, даже пробовал модуль акселератора памяти отключать (МАМ), думалось может при обращении к флеш не-то читается - не помогло в общем.


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Mar 17 2009, 11:42
Сообщение #51


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



Цитата(TanT @ Mar 17 2009, 01:19) *
Вопрос к etoja по поводу записи, точнее верификации.
Пишу себе спокойно по IAP, проверяю двумя способами: в лоб по рекомендации KRS и IAPовским сравнением. И нет такого момента, чтобы без ошибок обошлось на 32 кб записи 2-3 ошибки в среднем. Ну это ещё полбеды. Смотрю где ошибка - записанно всё что требуется (покрайней мере в том месте

Не ту частоту передаете параметром в IAP. Flash не успевает прописаться надежно.
Go to the top of the page
 
+Quote Post
TanT
сообщение Mar 17 2009, 12:14
Сообщение #52


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 22-11-05
Из: Россия->Омск
Пользователь №: 11 210



а вы правы, ar__systems. частота стояла из старого проекта в 4 раза меньше требуемой.
Для надёжного прописывания флеш сколько времени требуется - то есть после записи, требуется провести проверку, что же там написанно. Паузы не требуется между записью блока и проверкой?


--------------------
Если вы не можете объяснить что-то шестилетнему ребенку, значит, вы сами этого не понимаете.
Альберт Эйнштейн
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Mar 17 2009, 12:16
Сообщение #53


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(TanT @ Mar 17 2009, 14:14) *
а вы правы, ar__systems. частота стояла из старого проекта в 4 раза меньше требуемой.
Для надёжного прописывания флеш сколько времени требуется - то есть после записи, требуется провести проверку, что же там написанно. Паузы не требуется между записью блока и проверкой?

Паузы не требуется. Я вообще проверяю целиком всю записанную информацию - считаю CRC. Ни разу не было проблем с записью (только при пропадании питания мусор естественно).
Go to the top of the page
 
+Quote Post
KRS
сообщение Mar 17 2009, 12:17
Сообщение #54


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(TanT @ Mar 17 2009, 15:14) *
Паузы не требуется между записью блока и проверкой?

Не требуются, из IAP возвращается после того как запись полностью произойдет и флешь полностью можно исплоьзовать
Go to the top of the page
 
+Quote Post
Wano
сообщение Aug 3 2009, 09:32
Сообщение #55


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Подскажите всё ли правильно делаю,чтобы зашить в LPC2134 число:
1) в кейле Options for Target задаю два раздела IROM1 от 0х0 до 0x17FFF IROM2 от 0х18000 до 0x20000, тоесть планирую писать в последний сектор,для этого создаю раздел IROM2.
2) в прогу определяю переменную как const unsigned int i __attribute__((at(0x18000)));
3) следующей функцией стираю последний сектор и записываю туда какой-то массив, в первом элементе которого хранится будущее значение i

Код
typedef void (*IAP)(unsigned int *in, unsigned int *result);
#define iap_entry ((IAP) 0x7FFFFFF1)

unsigned int program (unsigned int * data)  {
  unsigned int command[5];
  unsigned int result[5];
  unsigned int save_VicInt;                

  save_VicInt = VICIntEnable;              
  VICIntEnClr = 0xFFFFFFFF; //запрет прерываний            

  command[0] = 50;//подготовка                            
  command[1] = 10;                                             
  command[2] = 10;                                           
  iap_entry (command, result);                    
  if (result[0])goto exit;

  command[0] = 52;//стирание                            
  command[1] = 10; // начало
  command[2] = 10;// конец
  command[3] = 60000;// частота проца
  iap_entry (command, result);
  if (result[0])goto exit;

  command[0] = 50;//подготовка
  command[1] = 10;
  command[2] = 10;                                     
  iap_entry (command, result);
  if (result[0])goto exit;

  command[0] = 51;//запись
  command[1] = (unsigned int) 0x0018000;  // куда пишется
  command[2] = (unsigned int) data;//что пишется              
  command[3] = 256;// число байт
  command[4] = 60000;
  iap_entry (command, result);
  if (result[0])goto exit;

exit:

  VICIntEnable = save_VicInt;
  return (result[0]);
}


Проблема состоит в том, что в таком случае на команде стирания проц вылетает в PAbt_Handler. Если не объявлять раздел IROM2,тогда всё нормально проходит,но тогда как проконтролировать не залезет ли прога в область,где предполагается перезапись.
Go to the top of the page
 
+Quote Post
IgorMarx
сообщение Aug 27 2009, 19:57
Сообщение #56


Участник
*

Группа: Участник
Сообщений: 61
Регистрация: 5-10-05
Из: Зеленоград
Пользователь №: 9 268



Цитата(GetSmart @ Mar 15 2009, 23:34) *
В векторах программ чаще всего используется IRQ. Если по адресу 0x18 в нулевом секторе (загрузчике) стоит команда LDR PC,[PC,#-0xFF0], то этого достаточно чтобы IRQ прикладной программы нормально действовали. Для FIQ тоже можно сделать похожим образом. Ну а остальные вестора исключительных ситуаций обычно не возникают и для большинства программ не имеют значения. Обычно там вообще стоят заглушки типа зависона.


Это отличное решение для IRQ (главное не забыть запрограммировать VICDefVectAddr, иначе при spurious interrupt поимеем переход на нулевой адрес). Но я не уверен что для FIQ такой номер прокатит. Если мне не изменяет память, то инструкция LDR PC,[PC,#-0xFF0] загружает в PC значение, считанное по адресу PC,#-0xFF0, то есть VICVectAddr, и это хорошо подходит для векторных прерываний. FIQ к ним не относится. Могу ошибаться, поправьте, если я не прав (сам не пробовал). Но вряд ли FIQ понадобятся самому бутлоадеру, можно сделать обычный переход в нужную страницу.
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th June 2025 - 22:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.02151 секунд с 7
ELECTRONIX ©2004-2016