Решил данный вопрос задать в отдельной теме, ответвив от темы про стартовый загрузчик
http://electronix.ru/forum/index.php?showt...15&start=15Там подсказали насчёт организации записи флеш из пользовательской программы. Сделал по мануалу, т.к. примеров пока не видел. Получилось вот так:
Код
#include "iolpc1778.h"
#include "LPC17xx.h"
#define IAP_LOCATION 0x1fff1ff1 //точка входа в IAP (страница 896 мануала)
unsigned long *command;
unsigned long *result;
unsigned int *test;
typedef void (*IAP)(unsigned int*, unsigned int*);
void main(void)
{
{ //INIT
SCS |= 0x20; //подключение осциллятора 12МГц
while(!( SCS & 0x40 )) {} //ожидание запуска
PLL0CON |= 0x01; //включение PLL0
PLL0CFG |= 0x09; //умножение частоты тактирования на (1+9) - 120МГц
PLL0FEED = 0xAA; //
PLL0FEED = 0x55; //
CCLKSEL |= 0x100; //тактирование CPU от PLL0
}
test = (unsigned int*)0x20001004; //записал контрольный байт в копируемую область RAM
*test = 0xAA;
IAP iap_entry; //так в мануале написано
iap_entry = (IAP) IAP_LOCATION; //---//---
//_______СТЕРЕТЬ СЕКТОР_______//
{
result = (unsigned long*)0x20006100; //адрес расположения таблицы результатов
command = (unsigned long*)0x20006000; //адрес таблицы параметров
*command = 52; //код команды
*command++;
*command = 4; //начальный номер сектора
*command++;
*command = 4; //конечный номер сектора
*command++;
*command = 120000; //системная тактовая частота в кГц
asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта
asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц
asm ("mov r1, #0x6100");
asm ("movt r1, #0x2000");
iap_entry (command, result);
}
//_______СТЁРЛИ СЕКТОР______//
//_______ПОДГОТОВИТЬ СЕКТОР К ЗАПИСИ_______//
{
result = (unsigned long*)0x20006100; //адрес расположения таблицы результатов
command = (unsigned long*)0x20006000; //адрес таблицы параметров
*command = 50; //код команды
*command++;
*command = 4; //начальный номер сектора
*command++;
*command = 4; //конечный номер сектора
asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта
asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц
asm ("mov r1, #0x6100");
asm ("movt r1, #0x2000");
iap_entry (command, result);
}
//_______ПОДГОТОВИЛИ СЕКТОР К ЗАПИСИ______//
//_______КОПИРОВАТЬ ОПЕРАТИВНУЮ ПАМЯТЬ ВО ФЛЕШ_______//
{
result = (unsigned long*)0x20006100; //адрес расположения таблицы результатов
command = (unsigned long*)0x20006000; //адрес таблицы параметров
*command = 51; //код команды
*command++;
*command = 0x4000; //начальный адрес перезаписываемой флеш
*command++;
*command = 0x20001000; //начальный адрес оперативной памяти, откуда нужно копировать
*command++;
*command = 512; //число байт для копирования
*command++;
*command = 120000; //системная тактовая частота в кГц
asm ("mov r0, #0x6000"); //Запись в регистры отдельно младшие 2 байта
asm ("movt r0, #0x2000"); //и старшие два байта адресов таблиц
asm ("mov r1, #0x6100");
asm ("movt r1, #0x2000");
iap_entry (command, result);
}
//_______СКОПИРОВАЛИ СЕКТОР______//
while(1)
{
test = (unsigned int*)0x4004; //для просмотра ячейки в отладчике в пошаговом режиме.
}
}
Работать почему-то не хочет - как было во флеш FFFFFFFFFFFF, так и остались. Ещё в мануале написано, что содержимое регистров r0 и r1 остаётся постоянным во время работы с флеш-памятью, но у меня в пошаговом режиме видно, что после функции
iap_entry (command, result); они меняются. Так же там написано, что в регистры r0 и r1 записываются начальные адреса таблиц параметров и результатов. Можно ли в моём коде избавиться от ассемблерных вставок, т.к. каждый раз вручную назначать адреса таблиц в памяти неудобно и нежелательно. Ещё там написано, что верхние 32 байта RAM не должны использоваться пользовательской программой, но как программе запретить пользоваться этими байтами?
UP1: добавил файл проекта в IAR
Сообщение отредактировал ДЕЙЛ - Oct 2 2014, 11:24