Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 09:36:20

Друзья, есть вопрос. Пишу свой алгоритм программирования внешней флеши, по шаблону, который имеется в keil. Код грузится в ОЗУ, откуда и выполняется. Так вот в этом коде мне нужно задействовать systick, соответственно, нужны прерывания. Не сразу вспомнил, что вектор таблицы прерываний нужно переносить (делал это один раз и давно, когда писал бутлодер).
Так вот собственно, вопрос - по какому адресу его переносить? Как это понять? В начало ОЗУ, по адресу 0х20000000? Вроде бы по этому адресу грузится сам код. Или же мне его переносить в любую свободную область за пределами программы? Под программу у меня выделено 0х8000 байт. Значит нужно указать любой адрес повыше этогого?

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 09:43:53

Читаем даташит на соответствующий МК.
У каждого семейства свои правила.
В большинстве случаев области размещения таблиц векторов прерываний имеют заранее предопределенные области адресов ПЗУ.
8)

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 09:47:45

Так вот собственно, вопрос - по какому адресу его переносить? Как это понять? В начало ОЗУ, по адресу 0х20000000? Вроде бы по этому адресу грузится сам код. Или же мне его переносить в любую свободную область за пределами программы? Под программу у меня выделено 0х8000 байт. Значит нужно указать любой адрес повыше этогого?

Проще всего в начало RAM переносить, по любому адресу нельзя, нужно выравнивание которое разное для разных серий.

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 09:58:00

Если весь код выполняется из ОЗУ, таблицу логично расположить в начале.

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 10:00:36

Ну хорошо, вот в даташите на мой контроллер stm32f746 значится, что systick имеет адрес 0х0000003с.

Что из этого следует? Это ведь не абсюлютный адрес, а смещение? То есть по факту он расположен по адресу 0х8000003с. Что мне с этой информацией делать?
Спрошу по-другому. Когда я писал бутлодер, то есть переносил основной код программы выше по адресу, я с таблицей делал вот что
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8004000); //
А если я хочу в ОЗУ? 8 заменить на 2, а 4000 на значение выше чем размер моего кода?
Попробовать сейчас не могу, я на работе, но мысли гложут, вот и роюсь с сети и на форумах, хочу домой приехать с пониманием.

Добавлено after 2 minutes 35 seconds:
Если весь код выполняется из ОЗУ, таблицу логично расположить в начале.

То есть SCB->VTOR=0х20000000 ?

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 10:01:47

Вы можете перенести всю таблицу, а не указатели на отдельные обработчики.
В файле линкера (это для GCC, смотрите особенности кейла) указывайте чтобы секция таблицы прерываний оказалась первой.
Дальше функции NVIC_SetVectorTable передаете адрес начала ОЗУ.

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 10:10:07

Про выравнивание я узнал - должно быть кратным 0х200 Ну да ладно, помещу в начало.
Тогда такой вопрос... проект необычный, он генерирует файл FLM, шаблон создавал и настраивал не я. Создатель шаблона мог не расчитывать на то, что я буду переносить таблицу векторов прерываний. Где в коде или в настройках можно убедиться, что сама программа не будет грузиться по адресу 0х20000000, а то, боюсь, будет конфликт.

Добавлено after 5 minutes 47 seconds:
Ух ты.... в файле system_stm32f7xx.c нашел такие строки:
Uncomment the following line if you need to relocate your vector table in internal SRAM
/* #define VECT_TABLE_SRAM */

Интересно, этого будет достаточно, чтобы линкер все правильно собрал....

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 10:16:04

MementoMori писал(а):Интересно, этого будет достаточно, чтобы линкер все правильно собрал
Нет конечно же.
Он не анализирует код. Ему нужно во первых, задать адрес выполнения кода. Во вторых задать адрес расположения секции таблицы прерываний. Проще всего расположить ее первой и тогда она окажется в начале памяти, а поскольку началом нужно задать ОЗУ, то окажется в начале ОЗУ.
Поищите метод отладки в ОЗУ для кейла.

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 10:27:25

Обычно таблица векторов отрабатывается аппаратно.
Это задано железом МК. У АВРок - соответствующие флаг-биты конфигурации тем управляют.
Как у АРМ - не особо ведаю.
А вот... относительно программы исполняемой из ОЗУ при фиксированной аппаратной области таблицы векторов прерываний...
К примеру для МСS51 при подобной ситуации (базовый участок фиксирован во флеш, а исполняемый - в "верхней половине" ВПД/ВПП - модифицируемый)...
Можно в штатной таблице векторов поставить указатели на любую область.
А там уже или выполнять прерывания или делать переадресацию.
Единственно - потеря времени на дополнительные переходы.
8)

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 10:56:53

MementoMori писал(а):Интересно, этого будет достаточно, чтобы линкер все правильно собрал
Нет конечно же.
Он не анализирует код. Ему нужно во первых, задать адрес выполнения кода. Во вторых задать адрес расположения секции таблицы прерываний. Проще всего расположить ее первой и тогда она окажется в начале памяти, а поскольку началом нужно задать ОЗУ, то окажется в начале ОЗУ.
Поищите метод отладки в ОЗУ для кейла.


Ну адрес выполнения кода где-то задан в проекте, код то у меня выполняется из ОЗУ, только с прерываниями проблемы. Я к тому, что эта проблема уже решена за меня создателями шаблона.
Я пошерстил код ниже. Там есть строка, которая задает адрес таблицы векторов. Если строка define VECT_TABLE_SRAM раскомментирована, то указывается один адрес. Если закомментирована - то адрес начала флеш.
Так что если проект в целом в ОЗУ грузится и работает (молитвами тех, кто создал этот пррект-шаблон), то мне остается только раскомментировать эту строку. Что ж, проверю.
А отладить этот проект не получится, он не отлаживаемый. Он компилируется, а потом запускается во время прошивания флеш. Только если UART прицепить. Пока я тупо моргал диодом где надо - этого хватило чтобы понять, что не работает систик, а потом понять, что дело в прерываниях.
Спасибо за оперативные советы, пока не ломайте голову себе, я вечером попробую поколдовать с таблицей, не выйдет, буду дальше вопрошать)

Добавлено after 27 minutes 1 second:

Нет конечно же.
Он не анализирует код


Это я выразился неправильно. Линкер у меня код собирает адекватно - программа то запускается и работает. Просто в ходе работы не там ищет прерывания.

Хм... крамольная мысль - а нет ли у кого случайно алгоритма (с исходником) для прошивания кейлом qspi флешки w25q128a?

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 15:05:26

Я же вам на электрониксе уже писал, что флэшлоадер это не обычная прошивка. Можно, конечно, добавить таблицу векторов прерываний, разместить её через скаттер-файл в начале, прописать vtor в функции инит. Но всего этого даром не надо во флэшлоадере, он прекрасно без прерываний работает.

Добавлено after 4 minutes 18 seconds:
Как у АРМ - не особо ведаю.
И чего тогда лезть в обсуждение? Тут конкретный вопрос, про конкретный камень, а не про вообще.

Добавлено after 12 minutes 54 seconds:
Там даже задержку не надо делать, она задаётся в структуре FlashDevice и IDE сама её сделает.

Добавлено after 6 minutes 22 seconds:
И ещё, не забывайте, что флэшлоадер компилируется как Position Independed Code. Вы заранее не знаете с какого адреса она будет загружен. Это так, для понимания как делать не надо.

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 17:02:29

Уважаемый Владислав. У вас может быть написание прошивки и займет 15 минут - у меня нет. У вас больше опыта - у меня его мало. Работая с QSPI я потратил день на то, чтобы библиотеку под n25Q128, которая работает, адаптировать под W25Q128 - не вышло. Может быть я и дурак, но только после того как я выложил дефайны на электрониксе на обе микросхемы - никто не дал ответа в чем может быть проблема и какое такое коренное отличие имеется у двух микросхем, которое не позволяет стандартной в общем-то библиотеке написанной под одну микросхему, работать с другой.
Как вы думаете, охота ли мне писать код на регистрах, с нуля, если у меня есть хоть и написанная в ненавидимом всеми HAL, но РАБОТАЮЩАЯ, понимаете, РАБОТАЮЩАЯ библиотека? И что-то мне подсказывает, что и в алгоритме эта библиотека заработает, несмотря на громоздкость кода. А для того, чтобы она заработала в алгоритме, не хватает самой малости - включить прерывания, с чем у меня почему-то проблемы. И именно этой проблеме я посвятил тему на ЭТОМ форуме. Я хочу здесь услышать не как мне работать с QSPI, а как мне включить прерывания.
Но вы упорно советуете то, что может быть является пустяком для вас, но является сложным для меня.

Мне осталось из 100 км проехать один метр, но у меня проколото колесо - я спрашиваю как его поменять - а вы мне говорите - зачем тебе автомобиль, возьми доски, пилу, гвозди, сооруди телегу, автомобиль - это слишком сложно для такой простой задачи как проехать 3 метра.

Вы можете меня не плотницкому делу учить, а сказать, как открутить болт на ступице колеса?

https://cloud.mail.ru/public/3Tfg/3TsZhTnuP
Если можете - то буду вам благодарен.
Если у меня заморгает светодиодик, но прошивальщик так и не заработает - я вам клянусь, что брошу все и пойду учить как QSPI работает на регистрах, без всяких оберток.

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 17:20:09

Чтобы преодолеть последний метр вам надо перелезть стену. Проще её обойти.

Понимаешь, разработчики IDE сделали всё, чтобы флэшлоадер был как можно проще. IDE сама порежет образ на страницы, сотрёт их предварительно, сделает паузы между записями. Тебе надо лишь сказать ей параметры чипа и реализовать подпрограммы стирания и записи страницы.

Чем отличаются n25Q128 и W25Q128 так сложно сравнением двух даташитов определить?

Re: Перенос таблицы векторов прерываний в ОЗУ

Пт фев 07, 2020 17:37:49

Чтобы преодолеть последний метр вам надо перелезть стену. Проще её обойти.

Понимаешь, разработчики IDE сделали всё, чтобы флэшлоадер был как можно проще. IDE сама порежет образ на страницы, сотрёт их предварительно, сделает паузы между записями. Тебе надо лишь сказать ей параметры чипа и реализовать подпрограммы стирания и записи страницы.

Чем отличаются n25Q128 и W25Q128 так сложно сравнением двух даташитов определить?

Структура идентична, принципы работы идентичны. Отличаются номерами регистров, но те, которые задействованы в моем коде - идентичны. Еще отличаются числом DummyCycle - я подправил в дефайнах - не помогло. В интернете, в том числе и в забугорном поисковик находит кучу тем, посвященных этой микросхеме. Но темы эти о том, что, мол, сделал по мануалу, или переделал из n25q128 - не работает, помогите. И результат всегда один - после одной двух страниц обсуждения тема глохнет без результата.

Что ж... попробую без прерываний
Код:
static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag,
                                                        FlagStatus State, uint32_t tickstart, uint32_t Timeout)
{
  /* Wait until flag is in expected state */   
  while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State)
  {
    /* Check for the Timeout */
    if (Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
      {
        hqspi->State     = HAL_QSPI_STATE_ERROR;
        hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT;
       
        return HAL_ERROR;
      }
    }
  }
  return HAL_OK;
}

Эта (и остальные подобные) функции проскакивают за одну итерацию, так как tickstart всегда равен HAL_GetTick(). Попробую добавлением пустых операций довести время выполнения этой функции до таймаута....

Re: Перенос таблицы векторов прерываний в ОЗУ

Сб фев 08, 2020 19:29:29

ОК! Я последовал Вашему совету. Выкинул нафиг HAL, взял шаблон, пустой, скомпилировал, подключил - функции вызываются (видно что KEIL перебирает адреса, не выдавая сообщений об ошибке, ведь функции возвращают 0).

Только добавляю в функцию init включение тактирования QSPI (чистые регистры, безо всяких калокубов, таймеров, прерываний)
RCC->AHB3ENR |= RCC_AHB3ENR_QSPIEN;
как все встает колом. Функция EraseSector не вызывается, Keil ждет таймаута и ругается.

Что-то не так с шаблоном. Я честно все сделал по мануалу (а он не предполагает изменения настроек шаблона).
Ну что с ним не так?
Я прошу, глянуть проект - это шаблон кейловский, без изменений (кроме FlashDevice), в него добавлена всего лишь одна строка.
https://cloud.mail.ru/public/5Ghh/3Hv6gbCb1
Ответить