Jump to content

    
Sign in to follow this  
zuuuuk

Использование своих секций при компиляции

Recommended Posts

Доброго времени суток.

Я применяю ARM freescale.

и в моем проекте я располагаю несколько функций в отдельной секции.

uint8_t fn_ld () __attribute__ ((section(".name1")));
uint8_t fn_md () __attribute__ ((section(".name1")));
uint8_t fn_init () __attribute__ ((section(".name1")));

linker script

..............
    .name1 :
    {
     . = ALIGN(4);
    *(.name1)
    . = ALIGN(4);
    } > m_name1
.............

 

Подскажите, а возможно расположить в одной секции несколько функций и переменную?

вот так

uint8_t var __attribute__ ((section(".name1")));
uint8_t fn_ld () __attribute__ ((section(".name1")));
uint8_t fn_md () __attribute__ ((section(".name1")));
uint8_t fn_init () __attribute__ ((section(".name1")));

 

что для этого нужно поправить в коде или линковочном скрипте?

 

 

 

 

attribute_electronix.zip

Share this post


Link to post
Share on other sites
Подскажите, а возможно расположить в одной секции несколько функций и переменную?
Можно. Если эта секция в ОЗУ или переменная константная и статическая.

что для этого нужно поправить в коде или линковочном скрипте?
Ничего не нужно править - достаточно того, что вы написали. Но есть один нюанс:

 

Наверняка ваша программа компилируется с ключами -function-sections и -fdata-sections, тогда ваш скрипт надо поправить вот так:

    *(.name1)
    *(.name1.*)

а переменные раскладывать в секции с разными именами, начинающимися на ".name1.":

uint8_t fn_ld () __attribute__ ((section(".name1.ld")));

uint8_t fn_md () __attribute__ ((section(".name1.md")));

uint8_t fn_init () __attribute__ ((section(".name1.init")));

 

Объясняю: с этими ключами компилятор выделает под каждую функцию (-function-sections) и переменную (-fdata-sections) свою секцию - .text.func1, .data.var1, .bss.var3 и т.д. Это позволяет линкеру по ключу -gc-sections удалять из выходного файла те секции, на которые нет ссылок, т.е. удалять неиспользуемые в программе переменные и функции. *(.name1.*) как раз и говорит линкеру "класть из всех файлов секции, начинающиеся на .name1." А размещение каждой вашей функции/переменной в отдельной секции позволит линкеру выкинуть все лишнее.

 

Тем не менее, очень интересно - что за задача заставляет вас вот так шаманить с секциями? Подозреваю, что написание загрузчика. В таком случае это делается совсем иначе. Если версия с загрузчиком подтвердится - распишу.

Share this post


Link to post
Share on other sites

дело в том, что передо мной стоит задача обновления устройства на базе ARM freescale.

 

Но канал для обновления медленный. Поэтому принято решение обновлять частично.

Я хочу создать программный модуль.

вот map файл

.mod1           0x0000cc60       0x7c
                0x0000cc60                . = ALIGN (0x4)
*(.name1.all)
.name1.all     0x0000cc60       0x14 ./Sources/mod1.o
                0x0000cc60                fn_all
*(.name1.*)
.name1.var     0x0000cc74        0x1 ./Sources/mod1.o
*fill*         0x0000cc75        0x3 
.name1.init    0x0000cc78       0x1c ./Sources/mod1.o
                0x0000cc78                fn_init
.name1.ld      0x0000cc94       0x24 ./Sources/mod1.o
                0x0000cc94                fn_ld
.name1.md      0x0000ccb8       0x24 ./Sources/mod1.o
                0x0000ccb8                fn_md
*(.name1)
                0x0000ccdc                . = ALIGN (0x4)

 

где функция fn_all () имеет фиксированный адрес и она вызывается из основной программы.

а все остальные функции могут меняться .

uint8_t fn_all () {
  fn_ld ();
  fn_md ();
  return 0;
}

 

такой модуль будет меньше чем вся программа.

и замену производить только этого модуля.

вот примерно так..

 

 

 

 

Share this post


Link to post
Share on other sites
а все остальные функции могут меняться .
Но ведь если изменится функция - изменится ее длина и изменится адрес следующей функции. Тогда надо делать таблицу с точками входа во все эти функции и все функции вызывать через эту таблицу и таблицу обновлять при замене любой функции. Но ведь кроме вашего кода существуют еще и библиотечные функции, без которых ваш код работать не сможет и которые компилятор пихает в секцию .text и каждый раз в разном порядке.

А обновляемые функции у вас меняются по одной в случайное время или все скопом?

Share this post


Link to post
Share on other sites

Есть вариант - внешние функции на внешней памяти запускаемые по внешнему событию (буквально). В этом случае каталог функций можно разместить на внешней памяти, будет одна точка входа. Определение номера внешней функции для запуска - универсальное, описывается как изменяемое внешним процессом, в этом случае gcc не оптимизирует этот код до нуля. Ну и естественно варианты: исполнять код по месту хранения, или предварительно копировать в память - от этого зависит способ компиляции.

Чем дальше в лес, тем больше дров можно наломать. Часто проще менять всю прошивку, даже если она весит гигабайты.

Share this post


Link to post
Share on other sites

То что вы описали, использует сименс в своих контроллерах S7-300.

Там реализовано это всё очень сложно. То что перечислили AVI-crak и Сергей Борщ, это тоже не всё.

Например новая функция может память по разному использовать. Например ей понадобится больше или меньше.

Я доподлинно не знаю, озвучу только то, что вычислил косвенно.

1. Подмену осуществляет ОС. И ОС не меняется сама.

2. Подмена осуществляется вначале прохода.

3. Меняется блок. В нём может быть как 1 так и несколько ф-ций. Каждый блок имеет свою секцию памяти. Абсолютно независимую.

4. Блок, который можно поменять в нашем embedded понимании - задача ОС. ОС вылизана так, что может запускать 1000 задач. То есть не совсем так как с МК принято.

5. Любая задача может обращаться к памяти (секции) другой задачи. Но это уже чисто на совести программиста. Контроля нет. Ты уже непосредственно по адресу обращаешься.

6. В момент подмены создаётся 2 копии задачи и 2 копии данных. Есть механизм передачи данных. Но если есть существенная разница - всё равно крах наступает. То есть всё это тоже на программиста возлагается.

 

Почему функции поменять сложно? Ну давайте представим, что у вас ОС. Она ведь остановится не на начале ф-ции. Она может прервать исполнение где угодно. Как её поменять? Как вообще узнать где идёт исполнение? Тут только через ОС и задачи. Тогда ещё как-то реализуемо. В некоторый момент, останавливаете старую задачу. Потом завершаете её и запускаете новую задачу.

В этом случае, естественно надо сборщик мусора и следить за дефрагментацией флэши.

===

По моему есть более простое решение. Поставить флэшку какую-нибудь типа at25, благо они сейчас недорогие, загружать постепенно всю прошивку. Когда загрузилась, обновиться.

Share this post


Link to post
Share on other sites

1000 запущенных активных задач - это уже перебор. Мне удалось запустить примерно 320 копий с двойным падением производительности, 600 копий теоретически дадут падение в 7 раз, а тысяча - уже в 20-50 раз замедление. На вытесняющей ос такое количество задач просто невозможно запустить. Но смысла в диком количестве работающих задач - нет.

 

Сама ос должна висеть в кеше, так-же как и почти все аппаратные прерывания, у каждого мк свои варианты - ускорится всегда можно. Но есно ос одноразовая и единственная, работает от старта мк и до ресета, обновлению не подлежит.

Весь низкий уровень обновлению не подлежит, это всё что работает с периферией. Очень желательно ассоциативный слой тоже сделать постоянным, иначе будет маленький ужас.

 

И того, меняться может математика в чистом виде, графика, и наборы инструкций во всех смысловых вариантах. Всё это очень много весит.

 

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

 

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

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

 

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

 

Совместное использование памяти имеет свои ограничения, по сути - это обмен сообщениями, всегда однонаправленный. В одном ограниченном блоке памяти первая задача пишет и может читать, вторая и остальные задачи - только читать.

Есть исключение для операции - занять ресурс, или что-то подобное. Цель - вписать свое имя, имеется поддержка на уровне команд асмы, ограничение - uint32_t размер, выше нет смысла, ниже - просто глупо.

 

В любом случае общение задач выполняется через выделенную память по веткам структуры стандартного вида (размер резиновый). Вид структуры задаётся один раз, на этапе написания ос. Но не является стандартом для всех проектов без исключения, скорее наоборот - для каждого проекта - своя уникальная структура связи.

 

Использование внешней памяти позволяет дописывать новые функции на свободное непрерывное место. Удалять сами функции уже не получится, но когда размер флешки большой - можно устроить глобальную перегрузку девайса с удалением и дефрагментацией.

 

В любом случае система получается очень близкой по функционалу к домашнему настольному компу. В некоторых случаях проще использовать жирные макетки от интел или нечто арм-овское на андроеде. Особенно если у вас реально 1000 активных задач.

Мне-бы хотелось взглянуть на подобного монстра, а ещё больше интересует склочная команда поддержки из многоэтажного центра управления. Иным способом штамповать обновления просто невозможно.

 

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

Share this post


Link to post
Share on other sites
В любом случае система получается очень близкой по функционалу к домашнему настольному компу. В некоторых случаях проще использовать жирные макетки от интел или нечто арм-овское на андроеде. Особенно если у вас реально 1000 активных задач.

Мне-бы хотелось взглянуть на подобного монстра, а ещё больше интересует склочная команда поддержки из многоэтажного центра управления. Иным способом штамповать обновления просто невозможно.

Система, я так понимаю, значительно сложнее чем настольная ОС. Там даже файловая система с дублированием. Там ARM проц. Типа ARM9, наверное. И речь не обо мне. Речь о S7-300.

Зачем всё это сделано? Там можно заменить блок на горячую. Как аппаратный блок так и программный. Можно подключится к производственной линии, и править программу прямо во время её работы. Она при этом занимается производственным выпуском. Я лично это делал причём многократно. Понимаете, одно дело, когда разрабатываешь устройство. Ты можешь отладить его. Постепенно развивать потенциал. А в старых устройствах обновлять ПО. Другое дело одна производственная линия. И больше таких нет. И стоимость её например 100 тысяч $ и более с учётом монтажа. Завод заинтересован в его окупаемости. Но какой бы сильный программист вы не были, без ошибок сделать сложно. Кроме того, по результатам эксплуатации порой что-то изменить требуется. Но для тебя линию никто останавливать не будет. Это объективная реальность.

Взглянуть - да пожалуйста. Можно почитать 2-ух томник Бергера. Но там больше по программированию. Из этого сложно общий вывод сделать. Надо понять идеологию построения. Короче надо что-либо написать... запустить.

Там не вытесняющая многозадачность. Там очень много существенных отличий.

Share this post


Link to post
Share on other sites
Зачем всё это сделано? Там можно заменить блок на горячую. Как аппаратный блок так и программный. Можно подключится к производственной линии, и править программу прямо во время её работы. Она при этом занимается производственным выпуском.

 

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

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

 

Грохнуть программу в рабочем режиме - ну никак нельзя. В случае дублирования - невозможно грохнуть сравнивающий узел. И уж никак нельзя грохнуть или исправить саму ос.

 

Но если подобный садомазо режим существует - я требую детального объяснения его алгоритма работы. С наскальными рисунками - выполненные кровью убитых мамонтов.

Share this post


Link to post
Share on other sites
В этом случае оперативно правится не сама программа - а только последовательность команд управления.

Непереводимая игра слов. :biggrin: Да нет. Там всё по честному - компилится и заливается.

Грохнуть программу в рабочем режиме - ну никак нельзя. В случае дублирования - невозможно грохнуть сравнивающий узел. И уж никак нельзя грохнуть или исправить саму ос.

 

Но если подобный садомазо режим существует - я требую детального объяснения его алгоритма работы. С наскальными рисунками - выполненные кровью убитых мамонтов.

К ОСи ты не имеешь отношения. Там даже функций нет и вызовов. Она как бы не существует.

Грохнуть можно. При несовпадении блока переменных. У тебя сразу линия клац. ))

В моём случае десятки ампер в фазе. )) Очень шумно. При этом сразу брак. ))

Собственно мы ушли от темы.

 

Предложение топикстартеру - Поставить внешнюю флэшку. Подгружать прошивку пусть медленно, как 100% загружено рестартовать с заливкой новой прошивки.

Share this post


Link to post
Share on other sites
Непереводимая игра слов. :biggrin: Да нет. Там всё по честному - компилится и заливается.

 

Реальность, китайский автономный чпу станок, работает совершенно автономно, без постоянной связи с компьютером, по "программе" записанной на флешке.

Дык вот, G код на флешке - это откомпилированная программа или всё-же набор управляющих команд?

Share this post


Link to post
Share on other sites
Дык вот, G код на флешке - это откомпилированная программа или всё-же набор управляющих команд?

Теоретически можно сделать и так и так. В одном случае будет компилятор во втором интерпретатор. Но при любом раскладе - прога это прога. Ошибку можно в любом случае сделать, что приведёт к ошибке и в конечном счёте к падению. Ну бэйсик класический взять?

На сименсе компилятор.

Share this post


Link to post
Share on other sites
Реальность, китайский автономный чпу станок, работает совершенно автономно, без постоянной связи с компьютером, по "программе" записанной на флешке.

Прошивка лежит в самой ЧПУ, а управляющая программа обработки (последовательность G-кодов) может подгружаться с компа, читаться с флэшки/sd-карты или тянутся из сетки или по вайфаю.

В более крутых станках еще отдельным файлом идет электроавтоматика станка (тоже программа, но в другом виде), чтобы одну и ту же чпу можно было подключать к разным станкам с разным функционалом.

Нет никакого смысла обновлять тока часть прошивки - в противном случае это чревато адским геморроем с совершенном непонятным профитом ...

 

Вот пример простой относительно бюджетной чпу: http://smoothieware.org/smoothieboard

Прошивка обновляется прямо с sd-карты при подаче питания (если она есть на карте), после обновления файл переименовывается и при следующем старте соотв. прошивка уже не будет обновляться.

Загрузчик поддерживает fat32 (возможно урезанный) и работу с sd-картой.

Сам загрузчик тоже можно обновить, но через отладочный порт и или usb (используется заводской железно зашитый в МК загрузчик), у каждого производителя МК своя метода.

Кстати, проект, что по ссылке, опенсорс!

 

зы. китайцы уже освоили бюджетную версию этой платы (полностью совместима по софту):

https://...2384368763.html

 

В моем 3Д принтере стоит эта плата, я доволен ))

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this