Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Выполнение функции из RAM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > Keil
MiklPolikov
Пытаюсь выполнить функцию из RAM.
Попадаю в Hardfault.
Подскажите, что я делаю неправильно ?
STM32L151 Keil

Код
////////////////////////////
void function(void)
{
    
}

//////////////////////////
void Execute_Function_From_Ram(void)
{
     unsigned int func_ram_array[0x20];
    
    int i;
      unsigned char *p1;
      unsigned char *p2;
    void  (*p_function)(void)=&function;
    
    
      p_function(); ///вызов через указатель ОК

     //переписываем функцию в RAM
      p1=(unsigned char*)p_function;  
      p2=(unsigned char*)&func_ram_array[0];
      for(i=0;i<(0x20*4);i++)
      {
              p2[i]=p1[i];
        }
      
        //запускаем из RAM
        p_function=(void*)p2;
        p_function(); ///тут программа попадает в HardFault
    
}

aaarrr
Цитата(MiklPolikov @ Jul 16 2016, 03:40) *
Подскажите, что я делаю неправильно ?

Ну, как минимум нулевой бит в адресе вызываемой функции должен быть установлен в '1'.
Листинг нужно смотреть. А лучше разместить функцию в RAM штатными средствами.
x893
У них есть пример как это делать.
Ключевое слово __ramfunc
MiklPolikov
Цитата
Ну, как минимум нулевой бит в адресе вызываемой функции должен быть установлен в '1'.


Да, видел это в примерах. Всё равно не работает. Делал так :

Код
     //запускаем из RAM
     x=(unsigned int)p2;
     x|=1;  //увеличиваем 0й бит адреса на 1
     p_function=(void*)x;
     p_function(); ///тут программа попадает в HardFault



Цитата(x893 @ Jul 16 2016, 04:16) *
У них есть пример как это делать.
Ключевое слово __ramfunc


У меня Keil не понимает __ramfunc. В интернете везде пишут по-разному.
Покажите пожалуйста правильный пример.
x893
Посыпаю голову пеплом - __ramfunc это в IAR
В качестве компенсации прилагаю проект под Keil с тремя функциями из RAM.
Запускать можно под симулятором.

Нажмите для просмотра прикрепленного файла
jcxz
Цитата(MiklPolikov @ Jul 16 2016, 06:40) *
Подскажите, что я делаю неправильно ?

Нельзя так делать. Как Вы определяете размер функции? А вложенные вызовы функций из копируемой учитываете? А константы, адресуемые через PC, учитываете? А исполнение кода для этого участка ОЗУ в MPU разрешено? ....
Размещать функции в ОЗУ нужно штатными средствами компилятора и компоновщика.
MiklPolikov
Цитата(x893 @ Jul 16 2016, 11:41) *
прилагаю проект под Keil с тремя функциями из RAM.
Запускать можно под симулятором.
Нажмите для просмотра прикрепленного файла


Неужели всё так просто ? Одна настройка в опциях файла, и всё ?! И не нужно вписывать какую-нибудь секцию в Scatter файл, например ?
А каким образом под отладкой убедится, что выполняется на самом деле из RAM ?
aaarrr
Цитата(MiklPolikov @ Jul 16 2016, 18:45) *
И не нужно вписывать какую-нибудь секцию в Scatter файл, например ?

Среда возьмет на себя эту нелегкую задачу. Можете убедиться, заглянув в сгенерированный ею .scat

Цитата(MiklPolikov @ Jul 16 2016, 18:45) *
А каким образом под отладкой убедится, что выполняется на самом деле из RAM ?

Под отладкой посмотреть диапазон адресов, в котором происходит исполнение.
А вообще, лучше приучить себя пользоваться map-файлом для прояснения вопроса что и где лежит.
x893
Установить в Debug - Simulator и нажать Ctrl-F5
Можно конечно и через scatter - а смысл ?
scifi
Цитата(MiklPolikov @ Jul 16 2016, 18:45) *
Неужели всё так просто ? Одна настройка в опциях файла, и всё ?! И не нужно вписывать какую-нибудь секцию в Scatter файл, например ?
А каким образом под отладкой убедится, что выполняется на самом деле из RAM ?

Гораздо интереснее вопрос "а каким способом убедиться, что функция не вызывает ничего из того, что расположено не в RAM?" wacko.gif
jcxz
Цитата(scifi @ Jul 17 2016, 13:17) *
Гораздо интереснее вопрос "а каким способом убедиться, что функция не вызывает ничего из того, что расположено не в RAM?" wacko.gif

IAR, когда ему указываешь __ramfunc и, если функция лезет куда-то вне ОЗУ, выдаёт варнинг.
А иначе в общем случае - никак, потому что никто не мешает компилятору при оптимизации, вынести часть функции в отдельную функцию (так как в соседней функции есть подобный участок). И компилятор активно использует константы, адресумые через PC, располагая их рядом с телом функции, а может быть и не рядом.
Так что пользоваться надо штатными средствами, а не городить колхоз.
MiklPolikov
Вот почему в примере x893 в map файле видно что функция расположена в RAM , а в моём проекте, хотя я сделал всё то же самое, она в RAM не расположена ????
aaarrr
Смотрите сгенерированный .scat
MiklPolikov
Цитата(aaarrr @ Jul 17 2016, 16:02) *
Смотрите сгенерированный .scat

У меня нет такого файла. Может .sct , он же Scatter ? Вот он.
aaarrr
Как можно видеть, "не шработала" галочка в среде. Добавьте к RW_IRAM1 { flash_rom_ram.o (*) }
MiklPolikov
Цитата(aaarrr @ Jul 17 2016, 17:19) *
Как можно видеть, "не шработала" галочка в среде. Добавьте к RW_IRAM1 { flash_rom_ram.o (*) }


Разобрался ! Нужно поставить вот эту галочку.
Тогда и .sct сам изменяется, и в .map всё правильно.
aaarrr
OMG! Не надо ставить галочки, не надо позволять среде генерировать какую-то отсебятину. Надо:
1. Читать документацию. Проблема с размещением кода решается минут за 30 от силы.
2. По возможности использовать нормальные средства сборки, тот же make, например.
Прошу извинить за брюзжание.
pitt
Цитата(aaarrr @ Jul 17 2016, 11:30) *
По возможности использовать нормальные средства сборки, тот же make, например.

suum cuique pulchrum est biggrin.gif
x893
suum cuique
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.