Миландр

Ключевым подразделением нашей компании
является Центр Проектирования интегральных микросхем
Текущее время: 2020-май-28 11:19

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 14 сообщений ] 
Автор Сообщение
 Заголовок сообщения: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 08:59 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Добрый день! Возникла проблема с записью данных в EEPROM.
Написан кусок программы (с использованием SPL) для записи данных в eeprom.
Открыть main.c
#include "MDR1986VE1T.h"
#include "MDR32F9Qx_eeprom.h"
#include "main.h"
#define EEPROM_PAGE_SIZE             (4*1024)
#define MAIN_EEPAGE                  29
int8_t data = 0;
int main()
{	
           EEPROM_config();
           Address = 0x00000000 + MAIN_EEPAGE * EEPROM_PAGE_SIZE;
	BankSelector = EEPROM_Main_Bank_Select;
	
	data = EEPROM_ReadByte(Address, BankSelector);
           while(1);

}

void EEPROM_config(){
	RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
}
Закрыть
Открыть system_MDR1986VE1T.c
void SystemCoreClockUpdate (void)
{
MDR_RST_CLK->PER_CLOCK |= (1<<4);				// RST_CLK clock enable
MDR_RST_CLK->HS_CONTROL = 0x00000005;		       // HSE On, HSE2 on, Oscillator mode;
while((MDR_RST_CLK->CLOCK_STATUS&0x0c)!=0x0c);	            // Wait until HSE not ready
MDR_RST_CLK->CPU_CLOCK = 0x00000002;			 // CPU_C1 = HSE (8MHz)
MDR_RST_CLK->PLL_CONTROL=(1<<2)|(11<<8);		            // CPU PLL On, PLL_MULL =11 	
while((MDR_RST_CLK->CLOCK_STATUS&0x02)!=0x02);	            // Wait until PLL not ready
MDR_RST_CLK->PER_CLOCK |= (1<<3);				 // EEPROM_CTRL clock enable
MDR_EEPROM->CMD |= (3<<3);
MDR_RST_CLK->PER_CLOCK&=(~0x08);				 // EEPROM_CTRL clock disable
MDR_RST_CLK->CPU_CLOCK = 0x00000106;			 // HCLK = PLL clock (96MHz)
}
void SystemInit (void)
{
  /* Reset all clock but RST_CLK & BKP_CLC bits */
  MDR_RST_CLK->PER_CLOCK   = (uint32_t)0x8000010;
  /* Reset CPU_CLOCK bits */
  MDR_RST_CLK->CPU_CLOCK   &= (uint32_t)0x00000000;
  /* Reset PLL_CONTROL bits */
  MDR_RST_CLK->PLL_CONTROL &= (uint32_t)0x00000000;
  /* Reset HSEON and HSEBYP bits */
  MDR_RST_CLK->HS_CONTROL  &= (uint32_t)0x00000000;
  /* Reset USB_CLOCK bits */
  MDR_RST_CLK->USB_CLOCK   &= (uint32_t)0x00000000;
  /* Reset ADC_MCO_CLOCK bits */
  MDR_RST_CLK->ADC_MCO_CLOCK   &= (uint32_t)0x00000000;
  SystemCoreClockUpdate();
}
Закрыть
Проблема заключается в следующем: когда программа начинает выполнять функцию «EEPROM_ReadByte» она сразу же перескакивает на выполнения прерывания «HardFault_Handler» и все зависает.
Кроме EEPROM все остальное не инициализируется, прерывания не включаются.
Функции из «MDR32F9Qx_eeprom.h» размешены и выполняются из ОЗУ микроконтроллера.
Прошу помочь решить данную проблему.
Спасибо за внимание!


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 10:52 
Не в сети

Зарегистрирован: 2010-июл-08 08:50
Сообщения: 734
Откуда: АО "ПКК Миландр"
AlexChas писал(а):
Функции из «MDR32F9Qx_eeprom.h» размешены и выполняются из ОЗУ микроконтроллера.
Куда конкретно размещаются функции?
Код, исполняемый из ОЗУ, можно размещать, начиная с адреса 0x2010_0000 до 0x2010_3FFF.
На время работы с Flash-памятью, как с периферийным блоком, необходимо запрещать прерывания, так как вектора обработчиков прерываний находятся во Flash и их нельзя перемещать.


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 11:16 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-авг-07 09:58
Сообщения: 132
AlexChas писал(а):
Добрый день! Возникла проблема с записью данных в EEPROM.
Написан кусок программы (с использованием SPL) для записи данных в eeprom.
Для правильного размещения функций в памяти МК необходимо использовать нужный файл линкера (keil: MDR1986VE1T.sct; IAR: MDR1986VE1T.icf).


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 11:32 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Цитата:
Куда конкретно размещаются функции?
Ниже скрин из Keil
Цитата:
Код, исполняемый из ОЗУ, можно размещать, начиная с адреса 0x2010_0000 до 0x2010_3FFF.
Интересно, этого я не знал. Из скрина ниже видно, что этот адреса начинаются с 0х2000_0000. Напрашивается вопрос, как задать правильный адрес? Попробую предположить что можно изменить адреса в 2 местах. Первое это скатер файл, что, по-моему, трогать не нужно. Второе это в настройках проекта вкладка target окно Read_write memory areas изменить адрес на выше сказанный.
Цитата:

На время работы с Flash-памятью, как с периферийным блоком, необходимо запрещать прерывания, так как вектора обработчиков прерываний находятся во Flash и их нельзя перемещать.
Это мне известно, и я специально написал программу без включения прерываний
Спасибо!


Вложения:
Комментарий к файлу: Скрин
[ attachment ]
Безымянный.JPG [ 87.67 КБ | 9838 просмотров ]
Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 11:49 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Перечитал спецификацию, увидел интересную таблицу: 0х20000000-0х200FFFFF Область памяти шины DTCM для данных. Доступ за инструкцией в эту область приводит к ошибке. 0x20100000-0x3FFFFFFF Область памяти внешней системной шины для кода программы и данных. Моя ошибка, не дочитал.
Как я понимаю скатер файл генерируется исходя из настроек проекта. Я прав или нет?
Спасибо!


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 12:16 
Не в сети

Зарегистрирован: 2013-сен-26 08:21
Сообщения: 4
Разобрался. Переписал Scatter файл. Заработало. Буду тестировать дальше.
LR_IROM1 0x00000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00007FFF  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00003FFF  {
    MDR32F9Qx_eeprom.o (+RO)
   .ANY (+RW +ZI)
  }
}
Спасибо за внимания.


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2013-сен-26 12:28 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-авг-07 09:58
Сообщения: 132
AlexChas писал(а):
Разобрался. Переписал Scatter файл. Заработало. Буду тестировать дальше.
Зачем его переписывать?
MDR1986VE1T.sct уже написан и прилагается к библиотеке.
LR_IROM1 0x00000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20100000 0x00004000  {
   *.o (EXECUTABLE_MEMORY_SECTION) 
	.ANY (+RW +ZI)
  }
}


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2015-июл-27 10:55 
Не в сети

Зарегистрирован: 2015-апр-10 22:42
Сообщения: 18
Добрый день форумчане.
У меня функция
EEPROM_ReadWord()
вычитывает нули,
а функция
EEPROM_ProgramWord()
ничего не меняет.
Повторное вычитывание после записи снова возвращает нули.
Вот код:
int main(void)
{
	UART_Init();

	   RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
	  uint32_t data = EEPROM_ReadWord(0x00000000, EEPROM_Main_Bank_Select);
	  printf("before: %x ", data);
	  EEPROM_ProgramWord(0x00000000, EEPROM_Main_Bank_Select, 0x55);
	  data = EEPROM_ReadWord(0x00000000, EEPROM_Main_Bank_Select);
	  printf("after: %x ", data);

	while(1);
  return 0;
}
Программа крутится в пространстве начиная с адреса 0x2010_0000 - и MAP-файл и пошаговое выполнение программы утилитой
JLink.exe
это подтверждают. USART шлет данные как нужно. Но флеш не перезаписывается и даже не вычитывается. Проверил код используемых функций чтения и записи во флеш - они соответсвуют требуемой последовательности работы с EEPROM в спецификации на камень. В чем может быть проблема?


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2015-июл-31 11:48 
Не в сети

Зарегистрирован: 2010-июл-08 08:50
Сообщения: 734
Откуда: АО "ПКК Миландр"
посмотрите пример отсюда


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-02 18:28 
Не в сети

Зарегистрирован: 2015-авг-26 16:21
Сообщения: 10
Откуда: г. Москва, "Экспериментальная лаборатория Наукасофт"
Здравствуйте.
Не хочу создавать новую тему по тому же самому вопросу, поэтому пишу сюда.
Использую МК 1986ВЕ92 + отладочную плату, среду Keil 5. На Кейл поставил SPL + SP и радостно все это полгода использую. Но появилась необходимость работать с EEPROM.
Для начала воспользовался готовым примером, из тех, что шли в комплекте с библиотеками (обозначен как "code in RAM"). Указал, чтобы MDR32F9Qx_eeprom.c запускался из RAM (скрин прилагаю), откомпилировал, запустил... и все.
Стал выполнять программу построчно, увидел, что все стопорится на строке
MDR_EEPROM->ADR = Address + Offset; 
(строка 230 в MDR32F9Qx_eeprom.c, функция EEPROM_ErasePage).
Далее отбросил готовые библиотеки и начал писать свое. Подробно, построчно, выполняя действия, указанные на страницах 44-47 описания моего МК.
Написал main.c, лежащий в основной памяти, добавил eeprom.c, указав, что его код должен запускаться из RAM, в него положил функцию для очистки одной страницы информационной памяти.
Выяснил, что после перевода памяти в режим программирования, когда устанавливается бит CON регистра MDR_EEPROM->CMD, микроконтроллер перестает реагировать.
Получается, что программа не выполняется из RAM? Или я не отключил прерывания (я использовал __disable_irq() )?
Буду благодарен любым комментариям.

П.С. Искал примеры, пробовал примеры с этого форума, но запустить не смог.
П.П.С. На скрине кейловская настройка запуска из RAMа. Ниже мой код, который слизан с описания МК и, опять же, виснет при установке CON.
Открыть
        MDR_EEPROM->KEY = 0x8AAA5551; //вводим ключ на старт	
	MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 9); //работу с информационной памятью IFREN = 1
	MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 0); //переводим в режим программирования CON = 1
	MDR_EEPROM->ADR = 0x08000000;	//выставляем адрес страницы (ВОТ ТУТ УЖЕ ВИСИТ)
	//биты EEPROM_ADR оставляем 00, соответствует работе с сектором A
	MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 6); //XE в единицу
	MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 10); //ERASE в единицу
  ProgramDelay(40);	//ждем 5мкс
	MDR_EEPROM->CMD = MDR_EEPROM->CMD | (1 << 13); //ставим NVSTR в единицу - команда на стирание
  ProgramDelay(320); //ждем 40мкс
	MDR_EEPROM->CMD = MDR_EEPROM->CMD & (~(1 << 10));	//очищаем ERASE
  ProgramDelay(40);	//ждем 5мкс
	MDR_EEPROM->CMD = MDR_EEPROM->CMD & (~(1 << 6)); //XE в нуль
	MDR_EEPROM->CMD = MDR_EEPROM->CMD & (~(1 << 13)); //NVSTR в нуль
  ProgramDelay(8); //ждем 1мкс
Закрыть


Вложения:
[ attachment ]
1.jpg [ 29.02 КБ | 7609 просмотров ]
Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 08:55 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 537
Вот это, часом, не забыли?
MDR_RST_CLK->PER_CLOCK |= (1 << 3); // вкл. тактирование EEPROM


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 09:12 
Не в сети

Зарегистрирован: 2015-авг-26 16:21
Сообщения: 10
Откуда: г. Москва, "Экспериментальная лаборатория Наукасофт"
Нет, тактирование включил. Вот код:
RST_CLK_DeInit();
  RST_CLK_HSEconfig(RST_CLK_HSE_ON);
	RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTF, ENABLE);
	RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
	RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);


Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 12:49 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 537
Ну тогда методом сравнения. На форуме есть рабочие примеры работы с flash/eeprom, да и функции из SPL по виду :) похожи на рабочие.
Например, здесь viewtopic.php?p=893#p893
Ниже "наш" код, но для info-flash
//================================================================================
// API чтения/записи/стирания банков информационной страницы FLASH-памяти
// В странице четыре банка с начальными адресами FLASH_START, FLASH_START+4, 
//  FLASH_START+8, FLASH_START+12, т.е. между соседними словами одного банка 
// разница в 16 байт (или 4 слова)
// Каждый из банков содержит 256 слов по 32 бита
// Внимание!
// 	Все функции должны запускаться из ОЗУ, для ВЕ1,3 в области IRAM2
//  Функция настройки DWT таймера DelayConfig() должна быть вызвана из preinit()
//  Для корректного отсчёта задержек задать параметр SYSCLK равный частоте ядра
//================================================================================
#if defined(USE_MDR1986VE9x) || defined(USE_MDR1986VE94)
	//-------------------------------------------------------------------------------
	// Задержка полингом по DWT таймеру, вх. параметр в микросекундах
	//-------------------------------------------------------------------------------
	#pragma inline
void Sleep(u32 cnt)
	{	  
	DWT->CYCCNT = 0;
	while (DWT->CYCCNT < (cnt * SYSCLK_MHZ));
	}

	//-------------------------------------------------------------------------------
	//-------------------------------------------------------------------------------
void DelayConfig()
	{
	CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;	// включение модуля DWT
	DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
	DWT->CYCCNT = 0;
	}
	
#elif defined(USE_MDR1986VE1T) || defined(USE_MDR1986VE3)
	//------------------------------------------------------------------------------------------------
	// Задержка полингом по SysTick таймеру, вх. параметр в микросекундах
	// SysTick в ВЕ1 все равно глючный при работе из Flash (см. errata), для других целей не подходит
	//------------------------------------------------------------------------------------------------
#define SYS_TICK_MAX	(u32)0x00FFFFFF	// не более ~130 мс при SYSCLK_MHZ = 128
void Sleep(u32 cnt)
	{
	cnt *= SYSCLK_MHZ;
	if( cnt > SYS_TICK_MAX )
		cnt = SYS_TICK_MAX;
	SysTick->LOAD = cnt;
	SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
	while( (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0 );
	}
	
#endif

#if defined(USE_MDR1986VE9x) || defined(USE_MDR1986VE94)
	#include "flash.h"
#elif defined(USE_MDR1986VE1T) || defined(USE_MDR1986VE3)
	#include "flash_BE1.h"
#endif

#define	EEPROM_KEY	(uint32_t)0x8AAA5551

//-------------------------------------------------------------------------------
// Очистка одного банка Flash
//-------------------------------------------------------------------------------
void ErasePage(u32 Addr) 
{ 
MDR_EEPROM->ADR = Addr; 
MDR_EEPROM->CMD |= EEPROM_CMD_XE;
MDR_EEPROM->CMD |= EEPROM_CMD_ERASE;
Sleep(6);// 5.5us 
MDR_EEPROM->CMD |= EEPROM_CMD_NVSTR;
Sleep(46000);// 46ms 
MDR_EEPROM->CMD &= ~EEPROM_CMD_ERASE;
Sleep(6);// 5.5us 
MDR_EEPROM->CMD &= ~EEPROM_CMD_XE;
MDR_EEPROM->CMD &= ~EEPROM_CMD_NVSTR;
Sleep(2); // 1.8us 
} 

//-------------------------------------------------------------------------------
// Установка сигналов программирования flash
//-------------------------------------------------------------------------------
void ProgramSignalsOn(void) 
{ 
MDR_EEPROM->CMD |= EEPROM_CMD_XE;
MDR_EEPROM->CMD |= EEPROM_CMD_PROG;
Sleep(6);	// 5.5us 
MDR_EEPROM->CMD |= EEPROM_CMD_NVSTR;
Sleep(11);	// 10.6us 
} 

//-------------------------------------------------------------------------------
// Сброс сигналов программирования flash
//-------------------------------------------------------------------------------
void ProgramSignalsOff(void) 
{ 
MDR_EEPROM->CMD &= ~EEPROM_CMD_PROG;
Sleep(6);	// 5.5us 
MDR_EEPROM->CMD &= ~EEPROM_CMD_XE;
MDR_EEPROM->CMD &= ~EEPROM_CMD_NVSTR;
Sleep(2); // 1.8us 
} 

//-------------------------------------------------------------------------------
// Запись 32 бит слова по адресу 
//-------------------------------------------------------------------------------
void WriteFlash(u32 Addr, u32 Data) 
{ 
MDR_EEPROM->ADR = Addr; 
MDR_EEPROM->DI = Data; 

Sleep(1);	// 0.3us 
MDR_EEPROM->CMD |= EEPROM_CMD_YE;	// YE=1 
Sleep(46);	// 46us 
MDR_EEPROM->CMD &= ~EEPROM_CMD_YE;	// YE=0 
Sleep(1);	// 0.3us 
} 

//-------------------------------------------------------------------------------
// Чтение из ОДНОГО БАНКА информационной страницы Flash 
// Входные параметры:
// - указатель на буфер-приёмник
// - смещение первого считываемого слова от начала информационной страницы
// - число 32-бит слов, которые нужно считать
// Возвращаемое значение : нет 
//-------------------------------------------------------------------------------
void InfPageRead(u32 *buff, int offs, int len)
{
int i;

int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;	// перевод в режим программирования

MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos); // установка режима информационной памяти

MDR_EEPROM->CMD |= ((1 << EEPROM_CMD_XE_Pos) | (1 << EEPROM_CMD_YE_Pos) | (1 << EEPROM_CMD_SE_Pos));

for (i=0; i < len; i++)
	{
	MDR_EEPROM->ADR = (u32)FLASH_START + offs*4 + i*16;
	Sleep(2);
	buff[i] = MDR_EEPROM->DO;
	}

MDR_EEPROM->CMD &= ~((1 << EEPROM_CMD_XE_Pos) | (1 << EEPROM_CMD_YE_Pos) | (1 << EEPROM_CMD_SE_Pos));
MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;	// выход из режима программирования
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
	__enable_irq();
}

//-------------------------------------------------------------------------------
// Стирание информационной страницы Flash (все 4 банка), требуется 225 мс
//-------------------------------------------------------------------------------
void InfPageErase()
{
int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;
MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos);

// Чтобы очистить страницу целиком, надо очистить все четыре банка
ErasePage(FLASH_START + 0x00); 
ErasePage(FLASH_START + 0x04); 
ErasePage(FLASH_START + 0x08); 
ErasePage(FLASH_START + 0x0C);
 
MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;// CON=0
MDR_EEPROM->KEY = 0;
 
if(!irq_was_masked)
	__enable_irq();
}

//-------------------------------------------------------------------------------
// Стирание одного банка Flash
//-------------------------------------------------------------------------------
void InfBankErase(u8 bank)
{
int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;	// CON=1 
MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos);

ErasePage(FLASH_START + bank * 4); 

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;	// CON=0 
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
	__enable_irq();
}

//-------------------------------------------------------------------------------
// Запись массива 32 бит слов в ОДИН БАНК информационной страницы Flash
// Входные параметры:
// - указатель на источник данных
// - смещение от начала страницы
// - число 32 бит слов, которые нужно записать
// Возвращаемое значение : нет
// Внимание, писать можно только по чистым ячейкам
//-------------------------------------------------------------------------------
void InfPageWrite(u32 *buff, int beg, int len) 
{ 
int j;

int irq_was_masked = __disable_irq();

MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;
MDR_EEPROM->CMD |= (1 << EEPROM_CMD_IFREN_Pos);

ProgramSignalsOn(); 

for(j = 0; j < len; j++) 
	WriteFlash((u32)FLASH_START + j * 16 + beg * 4, buff[j]);

ProgramSignalsOff(); 

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;
MDR_EEPROM->KEY = 0;
 
if(!irq_was_masked)
	__enable_irq();
} 	 

//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
/*
void MainPageWrite(u32 Addr, u32 Data)
{
int irq_was_masked = __disable_irq();
 
MDR_EEPROM->KEY = EEPROM_KEY;
MDR_EEPROM->CMD |= EEPROM_CMD_CON;
MDR_EEPROM->CMD &= ~(1 << EEPROM_CMD_IFREN_Pos);

ProgramSignalsOn(); 
WriteFlash(Addr, Data);
ProgramSignalsOff();  

MDR_EEPROM->CMD &= ~EEPROM_CMD_CON;
MDR_EEPROM->KEY = 0;

if(!irq_was_masked)
	__enable_irq();
}
*/



Вернуться к началу
 Заголовок сообщения: Re: Работа с внутреней FLASH и RAM
СообщениеДобавлено: 2016-авг-03 19:29 
Не в сети

Зарегистрирован: 2015-авг-26 16:21
Сообщения: 10
Откуда: г. Москва, "Экспериментальная лаборатория Наукасофт"
Проблему решил.
Проблема оказалась в том, что код выполнялся не из ОЗУ. Причины:
1). Keil в Evaluation версии не дает выполнять код из ОЗУ, при этом не выводится никаких предупреждений. Смена на MDK-ARM Professional исправила причину.
2). __RAMFUNC в Keil не работает. Пришлось городить конструкцию вида __attribute__((section("EXECUTABLE_MEMORY_SECTION"))); после объявления функции и добавлять Scatter-файл. Код Scatter'а прилагаю, вдруг кому понадобится.
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
  *.o (EXECUTABLE_MEMORY_SECTION) 
   .ANY (+RW +ZI)
  }
}
Спасибо за помощь!


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 14 сообщений ] 

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 6 гостей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти: 

Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB