Миландр

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

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




Начать новую тему  Ответить на тему  [ 35 сообщений ]  На страницу « 1 2 3 »
Автор Сообщение
СообщениеДобавлено: 2019-янв-10 11:09 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-май-05 08:45
Сообщения: 31
Откуда: Москва
А насколько сложно в следующей ревизии чипа пустить сигналы контроллера внешней шины наружу через общий коммутатор? Чтобы была возможность их переназначать. Вроде бы изменения мизерные, а функционал заметно возрастет.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-10 12:50 
Не в сети

Зарегистрирован: 2017-фев-14 11:21
Сообщения: 132
Организация: АО ПКК Миландр
Откуда: АО "ПКК Миландр"
Новых ревизий 1986ВЕ1Т не планируется. Проект закрыт. Пожелание разработчикам передам (для новых разработок).

_________________
Отдел технической поддержки support@milandr.ru


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-10 13:44 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 456
Организация: Milandr
Откуда: ПКК "Миландр"
При ресете, когда ITСMLAEN = 0, защелкивается внешняя память с 0-го адреса в адр. пространстве, настраивается контроллер шины и выводы. Все это происходит аппаратно.
Далее настройку выводов на контроллер шины удерживает сигнал ITСMLAEN = 0. Если его переключить на ITСMLAEN = 1, то аппаратное подключение выводов к контроллеру внешней шины отключается.

Есть предложение попробовать следующее:
1 - Вывод ITСMLAEN подтянуть к 0, чтобы при ресете всегда происходил старт с внешней памяти.
2 - В ПО продублировать настройку выводов в функции шины.
3 - Переключить программно ITСMLAEN = 1 перетянув подтягивающий резистор. Это можно сделать каким-нибудь свободным выводом GPIO заведенным на вход ITСMLAEN . При этом аппаратное назначение выводов на шину отключится, а текущее назначение подхватит программная настройка. Т.е. выводы продолжат выполнять функцию шины.
4 - Использовать аналоговые выводы по назначению.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-10 16:23 
Не в сети

Зарегистрирован: 2010-сен-21 12:57
Сообщения: 722
Откуда: г. Санкт-Петербург
Vasiliy писал(а):
Есть предложение попробовать следующее:...
Наверно все это лучше делать, выполняя код из внутренней SRAM 0x20100000- 0x20103fff.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 11:35 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-май-05 08:45
Сообщения: 31
Откуда: Москва
Ekaterina писал(а):
Новых ревизий 1986ВЕ1Т не планируется. Проект закрыт. Пожелание разработчикам передам (для новых разработок).
Проект закрыт в смысле, что не будет новых ревизий или в смысле, что вообще 1986ВЕ1Т скоро будет недоступен для закупки?


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 11:42 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-май-05 08:45
Сообщения: 31
Откуда: Москва
Vasiliy писал(а):
При ресете, когда ITСMLAEN = 0, защелкивается внешняя память с 0-го адреса в адр. пространстве, настраивается контроллер шины и выводы. Все это происходит аппаратно.
Далее настройку выводов на контроллер шины удерживает сигнал ITСMLAEN = 0. Если его переключить на ITСMLAEN = 1, то аппаратное подключение выводов к контроллеру внешней шины отключается.

Есть предложение попробовать следующее:
1 - Вывод ITСMLAEN подтянуть к 0, чтобы при ресете всегда происходил старт с внешней памяти.
2 - В ПО продублировать настройку выводов в функции шины.
3 - Переключить программно ITСMLAEN = 1 перетянув подтягивающий резистор. Это можно сделать каким-нибудь свободным выводом GPIO заведенным на вход ITСMLAEN . При этом аппаратное назначение выводов на шину отключится, а текущее назначение подхватит программная настройка. Т.е. выводы продолжат выполнять функцию шины.
4 - Использовать аналоговые выводы по назначению.
Да, я тоже об этом думал. У меня в схеме даже предусмотрена RC-цепочка на входе itcmlaen, предполагалось задавать пином gpio нужный логический уровень и затем делать аппаратный сброс. А конденсатор для того, чтобы напряжение на входе itcmlaen не менялось за время сброса. Это планировалось для других целей, но сейчас пин, заведенный на itcmpaen через rc-цепочку, позволит сделать то, что Вы выше описали. Попробую так сделать. Если изменится логический уровень на itcmlaen в процессе выполнения кода из внешней памяти, то при правильно программно настроенных пинах, отвечающих за внешнюю шину, зависания произойти ведь не должно?


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 12:35 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1390
Откуда: Тула
koe писал(а):
Ekaterina писал(а):
Новых ревизий 1986ВЕ1Т не планируется.
Проект закрыт в смысле, что не будет новых ревизий !

_________________
сочувствующий…


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 13:04 
Не в сети

Зарегистрирован: 2009-май-22 09:01
Сообщения: 1299
Откуда: АО "ПКК Миландр"
koe писал(а):
зависания произойти ведь не должно?
По нашим внутренним обсуждениям не должно быть проблем, но на железе не проверяли. Но на случай их возникновения можно воспользоваться рекомендацией vasili
vasili писал(а):
Наверно все это лучше делать, выполняя код из внутренней SRAM 0x20100000- 0x20103fff.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 13:52 
Не в сети
Аватара пользователя

Зарегистрирован: 2012-май-05 08:45
Сообщения: 31
Откуда: Москва
Сходу не получилось, очевидно, из-за того, что при передергивании itcmlaen следующий код операции извлекается из диапазона адресов 0x00000000, а шина мэппится в диапазон 0x00100000. Даже если дернуть ногой itcmlaen из ОЗУ, все равно в стеке будет адрес возврата в диапазоне 0x00000000. Попробую в ПЗУ склеить 2 программы. Одна скопирует себя в ОЗУ, настроит шины, дернет ногой itcmlaen, потом сделает безусловный переход назад в ПЗУ уже по правильному адресу.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 18:06 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 456
Организация: Milandr
Откуда: ПКК "Миландр"
Да, действительно, вариант оказался не рабочий.

Проверил на демо плате, если переключаться с основной памяти на внешнюю, то исполнение продолжается из внутренней без проблем - внутренняя защелкнулась и не портится.
А с внешней так не получается, при переключении с ITCMLAEN = 0 на 1, внешняя память с 0-го адреса портится. При этом в диапазоне внешней шины данные остаются правильные - т.е. контроллер внешней шины работает и читает внешнюю программу правильно.

В качестве выхода попытался скомпилировать программу сразу во внешнюю память начиная с адреса 0х0010_0000, чтобы все вектора и код расположились там. Тогда стартуя с 0-го адреса, считав указатель стека и адрес ResetHandle исполнение должно было уйти на адреса внешнего кода и спокойно там исполняться несмотря на состояние ITCMLAEN. Т.е. ну пусть память с 0-х адресов портится, исполнение при ресете уходит по вектору ResetHandle куда-то в адреса 0х0010_0000 и в 0-е адреса не вернется. НО оказалось, что исполнение остается в 0-х адресах.

Ядро не может сделать такой длинный прыжок с 0-го адреса по вектору в 0х0010_0000. Поэтому необходимо оставить в 0-х адресах функцию с длинным переходом на исходный ResetHandle.
__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     Reset_Handler_Jump  ; ЗАМЕНА вектора НА функцию дальнего прыжка !!!
; Функция с прыжком
Reset_Handler_Jump   PROC
                LDR     R0,=Reset_Handler
				BX      R0
                ENDP

; Reset Handler - ИСХОДНЫЙ обработчик
Reset_Handler   PROC
                EXPORT  Reset_Handler			[WEAK]
                IMPORT  __main
                LDR     R0,=__main
				BX      R0
                ENDP
На демо проекте успешно переключиться удалось под самый конец дня. Могу быть в чем-то не прав, поскольку сильно спешил. В понедельник исправлю, если накосячил.
Изложил содержимое на случай, если кто-то работает по выходным.


Вложения:
Комментарий к файлу: пример
ITCMLAEN_Hack.zip [2.28 КБ]
107 скачиваний
Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-11 18:18 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 456
Организация: Milandr
Откуда: ПКК "Миландр"
С векторами похоже перемудрил, в адреса 0х0010_0000 все-таки и так допрыгивает. Файл startup_MDR1986VE1T.s править не нужно.
Достаточно собрать программу начиная с адреса IROM1 = 0x0010_0000.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-14 08:54 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 456
Организация: Milandr
Откуда: ПКК "Миландр"
Забыл, что вектора прерываний остались в 0-й памяти и сломаются вместе с содержимым памяти. А таблицу прерываний в этом МК не перенести.
Вариант с программой в адресах 0x0010_0000 отпадает.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-16 14:10 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 456
Организация: Milandr
Откуда: ПКК "Миландр"
Посмотрели подробнее логику работы ITCMLAEN. При переключении ITCMLAEN = 1 не будет формироваться сигнал выбора внешней шины для адресного пространства 0x00000000-0x000FFFFF. Все что можно сделать - это запускать программу с адресов внешней шины, но тогда теряются вектора прерываний.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-янв-16 15:15 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 121
Может быть такая идея поможет решить проблему.
Для МК с ядрами Cortex M0 и M1, не имеющими перемещаемой таблицы векторов прерываний, размещение проекта по произвольному адресу выполняю так (пример заточен под 1986ВЕ4У):
1. Создаю основной проект, в котором для всех используемых прерываний формирую функцию-обработчик и функцию, реализующую обработку. Функция-обработчик вызывает функцию, реализующую обработку, с помощью указателя на функцию, расположенному в ОЗУ по фиксированному адресу:
// **** Модуль MDR32F9Qx_it.c основного проекта ****

// Таблица указателей на функции, реализующие обработчики прерываний
// В каждом из проектов, имеющихся на камне, эта таблица лежит по одному и тому же адресу
void  (* IT_Table [128])(void) __attribute__((at(0x20003000))); 

// Обработчик для прерывания от DMA
void DMA_IRQHandler (void)
{
	// Вызов функции, реализующей обработчик
	(*IT_Table[IT_DMA_IRQ_HANDLER_IDX])();	
}

void DMA_IRQHandler_Implement (void)
{
	// Требуемый код
	// ...
}
2. В функции main основного проекта в самом начале заполняю массив указателей на функции, реализующую обработку:
// **** Модуль MDR32F9Qx_it.c основного проекта ****
// Индексы функций-обработчиков
enum
{
  IT_UART1_IRQ_HANDLER_IDX = 0,
  IT_DMA_IRQ_HANDLER_IDX,
  IT_TIMER1_IRQ_HANDLER_IDX,

  IT_IRQ_HANDLER_COUNT
};

// Инициализация таблицы векторов-прерываний
void IT_Init (void)
{
	// Сопоставление функций, реализующих обработчики прерываний 
	IT_Table[IT_UART1_IRQ_HANDLER_IDX]    = UART1_IRQHandler_Implement;
	IT_Table[IT_DMA_IRQ_HANDLER_IDX]      = DMA_IRQHandler_Implement;
	IT_Table[IT_TIMER1_IRQ_HANDLER_IDX]   = TIMER1_IRQHandler_Implement;
	// ...
}


// **** Модуль main.c основного проекта ****
// Точка входа
int main (void)
{
  // Инициализация таблицы векторов-прерываний
  IT_Init ();

  // Все, что нужно в проекте
  // ...
}
3. Формирую в основном проекте scatter-файл, позволяющий разместить секцию кода по требуемому адресу. В данном случае - по адресу 0x0000c000:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x0000C000 0x0000C000  {    ; load region size_region
  ER_IROM1 0x0000C000   {  ; load address = execution address

  *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00003c00  {  ; RW data
   .ANY (+RW +ZI)
  }
}
4. Заливаю проект. Но работать он пока не будет!
5. Формирую вспомогательный проект. В нем также создаю массив указателей на функции, реализующие обработчики прерываний, и требуемые обработчики прерываний:
// **** Модуль MDR32F9Qx_it.c вспомогательного проекта ****

// Таблица указателей на функции, реализующие обработчики прерываний
// В каждом из проектов, имеющихся на камне, эта таблица лежит по одному и тому же адресу
void  (* IT_Table [128])(void) __attribute__((at(0x20003000))); 

// Индексы функций-обработчиков
enum
{
  IT_UART1_IRQ_HANDLER_IDX = 0,
  IT_DMA_IRQ_HANDLER_IDX,
  IT_TIMER1_IRQ_HANDLER_IDX,

  IT_IRQ_HANDLER_COUNT
};

// Обработчик для прерывания от DMA
void DMA_IRQHandler (void)
{
	// Вызов функции, реализующей обработчик
	(*IT_Table[IT_DMA_IRQ_HANDLER_IDX])();	
}

6. Функция main вспомогательного проекта будет фиктивной:
// **** Модуль main.c вспомогательного проекта ****
// Этот код никогда не выполнится
int main (void)
{
  while (1) 
  {}
}
7. В модуле system_MDR1986ВЕ4.c вспомогательного проекта делаем вызов Reset_Handler основного проекта:
// **** Модуль system_MDR1986ВЕ4.c вспомогательного проекта ****
void SystemInit (void)
{
	// Указатель на функцию для вызова основного проекта
	void (*Main_Project) (void); 
	volatile uint32_t* addr;
	volatile uint32_t value;		

	// Начальный адрес основного проекта
  uint32_t Main_Project_Start_Addr = 0x0000C000;	

	// Это все было изначально
	/* Reset the RST clock configuration to the default reset state */
  /* Reset all clock but RST_CLK & BKP_CLC bits */
  MDR_RST_CLK->PER1_CLOCK   = (uint32_t)0x30;
  MDR_RST_CLK->PER2_CLOCK   = (uint32_t)0x1010;

  /* 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 ADC_MCO_CLOCK bits */
  MDR_RST_CLK->ADC_MCO_CLOCK   &= (uint32_t)0x00000000;

  SystemCoreClockUpdate();
	
	
	// В начале прошивки основного проекта располагается стандартная таблица векторов прерываний __Vectors  (определена в startup_MDR1986ВЕ4.s)
	// В ее 1-м элементе располагается адрес функции-обработчика Reset_Handler, с которой начинается выполнение программы
	addr = (uint32_t*)Main_Project_Start_Addr; addr++;
	Main_Project = (void (*)(void)) (*addr);
	
	value = *addr;			

        // Запустить программу основного проекта, если она есть, вызвав ее Reset_Handler
	if (value != 0xFFFFFFFF && 
			value != 0x00000000 && 
			value != 0xAAAAAAAA
		 )
	{
		(*Main_Project)();

		// Сюда уже не попадем
	}

	// Подвиснем тут, если основного проекта нет
  while (1)
	{
	
	}		
}
Отсюда и начнется выполнение основного проекта, а вспомогательный проект так и не запустит свою функцию main.
Когда возникнет прерывание, сработает функция-обработчик из вспомогательного проекта и вызовет функцию, реализующую обработчик прерываний, из основного проекта. Конечно, обработка прерываний несколько замедлится из-за дополнительного вызова функции и возврата из нее. Но это всё равно лучше, чем ничего.
8. Заливаем вспомогательный проект в МК, предварительно выключив полное стирание Flash-памяти МК, и основной проект заработает.
При таком подходе не получится использовать режим отладки основного проекта. Но можно сначала его отладить, разместив по 0-му адресу, а потом уже отлаженный заливать по иному адресу.
Этот же подход можно с успехом применять для размещения нескольких проектов в одном камне, что я обычно и делаю.
PS:
Не забудьте сделать копию файла system_MDR1986ВЕ4.c, поместив ее в каталог с остальными исходниками проекта вспомогательного проекта. Иначе внесенные в этот файл изменения задействуются в других проектах.


Вынести предупреждение
Вернуться к началу
СообщениеДобавлено: 2019-май-14 08:34 
Не в сети
Аватара пользователя

Зарегистрирован: 2019-янв-15 10:14
Сообщения: 34
Организация: ООО "НПП "АСТРОН ЭЛЕКТРОНИКА"
Откуда: г. Орел
Не проще ли ram функции использовать для этого, если функция находится по фиксируемому адресу в ОЗУ?
Секцию определить в ОЗУ для ram функций и принудительно их там размещать. Компилятор в таблицу векторов нужный адрес встроит. Или же нужно налету менять вектор?...


Вынести предупреждение
Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 35 сообщений ]  На страницу « 1 2 3 »

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


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

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


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

Перейти: 

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