Вопрос.LPC2468+Keil. Подгружаемый участок кода.

Ну вот понимаю что можно так сделать, но как-то гложут сомнения в исполнении данной задачи. Вторую неделю бьюс.
Вводная: система построена на базе МК LPC2468. Рабочая программа, проверенна, отлажена.Система должна иметь возможность переключаться между двумя режимами работы. Но дело все в том что исполняемый код данных режимов также будет меняться. В чем встал вопрос: «загрузка поточного кода Userовской программы выполнения во внутреннее ОЗУ и исполнение ее там». Посредством внешнего интерфейса данных (в данном случае Ethernet) загружается данный участок кода в ОЗУ и передается управление данной программе.
Расположить участок кода в ОЗУ при компиляции не составляет труда, но вот как расположить его в процессе работающей программы. Думал так:
— Выделить участок памяти в ОЗУ, прописать пустую функцию(без тела)
— принимаемый код программы располагать в участке зарезервированной функции
— индицировать прием и запись программы и передать ей управление
Расположить участок кода можно путем резервирования места в файле "..Obj\*.sct"

;*************************************************************
;*** Scatter-Loading Description File generated by uVision ***
;*************************************************************

LR_IROM1 0x00000000 0x00080000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00080000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x40000000 0x00000FFF  {  ; RW data
   .ANY (+RW +ZI)
   }

  RW_IRAM2 0x4001000  0x0000F001{      ; место для подгружаемой программы
   User_Prog.o(+RW +ZI)
  }

}


Буду рад любому совету и ответу.
P.S. Может стоит создать Ветку «Ищу Ответ» или «Вопросы»?
  • 0
  • 14 июля 2011, 15:00
  • Zov

Комментарии (15)

RSS свернуть / развернуть
А указатель на функцию? Не?
Выделить буффер в памяти, записать в него код функции, инициализировать указатель адресом буффера и вызвать вынкцию по этому указателю. Если заставить компилятор генерировать перемещаемый код (position independent code PIC) — GCC это умеет, для загружаемой функции, то даже неважно будет фактическое расположение буффера в памяти. Надо будет только о выравнивании позаботится.
+1
Указатель всегда один и тот же. Память жестко выделена.
Что-т проясняется уже.
То есть по сути выполняется обычная запись массива данных(код функции) в ОЗУ, после которой передается указатель на эту функцию и можно ее вызывать с того места?
P.S.RealView MDK-ARM V.:4.00
0
// максимальный размер функции в байтах
const int maxFuncSize = 200;
// буффер для хранения кода функции
// uint32_t - для того, чтоб буфер был выровнен по границе двойного слова
uint32_t func_buffer[maxFuncSize / 4];
// тип указателя на функцию
typedef void (*func_ptr_t)(void);
// объявляем указатель на функцию
func_ptr_t func_ptr;
...
// записываем в буффер код функции откуда надо
memcpy(func_buffer, source_buffer, size_of_func);
...
// присваиваем указателю адрес начала буфура
func_ptr = (func_ptr_t)func_buffer;
// вызываем функцию по указателю
func_ptr();

Как-то так.
При таком подходе надо помнить, что загружаемая функция должна быть позиционо независимой.
В справке Кейла есть раздел «Position independence qualifiers»
+1
Ну ты магёшь! Оперативно, Спасибо.
Так, будем пробовать, о результатах напишу.
0
У тебя получилось?
У меня сходная задача. Сделала, как написал neiver, пробовала указывать в линкере разные квалификаторы --apcs — не работает. Как сделать функцию позиционно независимой?
0
За это, как ни странно, отвечает не линкер, а компилятор. У gcc это ключ -fpic, если мне память не изменяет.
0
Используешь Keil?
0
Нет. Но код в любом случае генерит компилятор, линкер по определению это «редактор связей», то есть он только располагает код на свои места и, поскольку именно в этот момент становится однозначной связь между именем объекта и его адресом, проставляет адреса вместо символов. Если код сгенеренный компилятором, использует символьные ссылки (например, адреса меток), то он будет позиционно-зависимым, если же используется адресация относительно какого-то регистра (обычно относительно счетчика команд), то код будет позиционно-независимым. Как-то так.
0
я спрашивал kozavgolfah, ну да ладно).
Я опробовал два способа реализации через Keil. Непосредственно через указатель на функции (как писал neiver), и используя встроенные средства Кейла — возможность распределения памяти — указав что 1 область ОЗУ под «все», а «2» непосредственно для подгружаемой программы.Это в двух словах.
0
Сорри, проглядел, что вопрос был не мне.
0
да, я поняла
не сообразила сразу, спасибо, что поправили
0
да, Keil
0
Так разобрались? Вопрос отпал?
0
да, спасибо
0
Я подозреваю, что она будет вполне нормально работать и в том случае, если она будет позиционно зависимой, но слинкованой в точности на адрес буфера. Ну и буфер можно расположить в памяти по фиксированному адресу.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.