ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
21 февраля
974721 Топик полностью
Связанные сообщения
Dynamic LinkingДинамическое СвязываниеPlcHal
Подскажите, нужно ли обязательно нормализовать, приводить все параметры участвующие в регулировании PID к 100% и как это правиль...2024-10-17
Стыдно вопрошать, ну да ладно. кто-то на птичьих языках (ПЛК) программируеть? есть ПЛК Митсубиши с севшей батарейкой и стертой п...2024-05-19
LL vs Registers - стоит ли заморачиваться LL? Посмотрел на LL примеры для stm32, он дает достаточно длинный и сложный на первый ...2024-05-04
Хочу задать здесь вопрос по теме написания программного ядра (основной программы с нуля и пользовательской подгружаемой) специал...2024-03-26
Кто как защищает вход контроллера 4...20 мА? Есть спец. микруха MAX14626, но её крайне сложно достать. Чтобы такое несложное на ...2022-07-20
Ух ты! 2016 год. Вторая ссылка. Прошло достаточно времени чтобы "увидеть истинный вектор движения".2022-04-03
господа эмбеддера, рынок плк пуст, практически, занимайте свои ниши.2022-04-01
У кого как с ПЛК и пром. автоматикой? Производителей подводит отсутствие готового товара на складах. Всё как ранее описывал С...2022-03-20
ПРограммируемы логические контроллеры - чтоб почитать?2022-02-19
Подскажите как сейчас правильно организовать в микроконтроллере программные таймеры?2020-10-23
Демонстрация проблемы по ссылке. Дело не в линкере, а ещё в компиляторе. При задании опций -mpic-register=r10 -msingle-pic-base ...2020-09-16
Не надо прибивать адреса. Верней надо, но ровно один адрес одной функции. Нужно лишь сделать самодельный недо-COM. Где эта одна ...2020-09-16
Не понял что ты хочешь. Ты не знаешь по какому адресу в итоге будет размещаться программа? Для этого существуют релокации и пози...2020-09-14
[Универсальная проводная шина для задач "распределенный PLC"]. Одна витая пара, дуплекс, до 100 Кбит/сек, гальваническ...2020-05-03
На сахаре несколько раз всплывала тема данных в питании. Наиболее адекватная идея -- отвязать питание через дроссель (фильтр НЧ)...2020-04-03
При наличии полноценного компилятора не при чём (не хуже чем 16 бит). Но как правило с этим проблемы. Для всех кроме AVR у многи...2020-02-28
С отладкой некоторые сложности, потому, что имеем два ELF-файла и каждый со своим набором отладочной информации. Если отладчик н...2020-01-30
Выводы контроллера всегда управляются в контексте управления каким-либо более крупным аппаратным ресурсом. I2C-шиной, например. ...2019-12-17
Железо нужно симулировать не на уровне битов и фронтов сигналов, а на уровне высокоуровневых операций (например, чтение-запись б...2019-11-07
От проекта зависит. Насколько чётко выделена аппаратно-зависимая часть и насколько абстракции используемые в старом проекте реал...2019-05-24
Собственно можно код запускать в эмуляторе процессора (qemu), которому привязать симуляцию нужной аппаратуры, или заменить HAL н...2019-02-06
Когда ПО прибора запускается на обычном ПК. Для этого обычно ПО разделяется на два слоя, как минимум: платформо-независимый (бол...2018-05-23
[IEC 61131-3 часть 2.3] Отечественные фирмы, производящие ПЛК "вокруг да около" стандартных языков.2017-06-21
[IEC 61131-3 часть 2.2] Среды для работы с языками. GPL, проприетарные.2017-06-21
[IEC 61131-3 часть 2] Кто какие знает ресурсы по теме? Делимся, обсуждаем.2017-06-21
[Фундаментальная размышлизма.] Опенсорц, С++ и победа прогрессивного человечества.2016-12-13
Вспомнинается, тут давали интересную идею: использовать IRDA-трансивер/приёмник (только электрический, без оптики). Идея в том, ...2016-01-23
Одни абстракции заменяются на другие, которые тоже нужно учить, документировать и запоминать, учитывать возможные побочные эффек...2015-07-23
Передача информации по проводам. Тут давали интересную идею (см. ссылку). Мол многие МК сейчас имеют IRDA и ежели развязать тран...2014-04-15
Жалкая паделка финских студентов написана на 100% на C, из ассемблера только вектора прерываний, crt и ещё мелочи, в C30 v3.31. ...2014-04-10
Да, трэш угар и содомия. Иногда абстракции через край, поэтому я имею такое мнение, что иногда и не грех в исходники прямо вписа...2013-12-29
Не совсем. Над HAL может быть ещё один слой, уже нужный для совмещения разных программных интерфейсов. Т.е. есть модуль A, котор...2013-10-25
Полезны аж 3 прослойки (ассемблеристам дальше лучше не читать):2011-10-13
Есть ли здесь люди, которые разрабатывали свой PLC и софт для него? Как обычно реализуют интерпретатор логики унутре PLC? Как я ...2010-03-17
fk0легенда (30.01.2020 02:23 - 11:47, просмотров: 842) ответил Chum_A на Требуются идеи по реализации нечто, типа BIOS для МК. Исходные данные: имеется железо - МК Cortex-M0 и физические драйверы CAN, RS-485, SPI... Для этого железа написан и отлажен (давно) HAL, диспетчер очереди событий, программные таймеры и т.п.
Тебе нужна динамическая компоновка (функций ОС к прикладной программе). Фактически это то, чем занимается ОС при загрузке процесса. Поэтому идея взять готовую ОС не самая глупая. Но в принципе не обязательно. Фактически, ты хочешь, чтоб у тебя часть кода (HAL) собиралась и компилировалась отдельно, часть кода отдельно (основная программа). При этом видимо HAL в исходниках будет не доступен (да и не нужен). В принципе сделать такое достаточно легко: для разных частей (HAL и основная программа) можно иметь разные линкер-скрипты кладующие код в разные части памяти. Трудность возникает с тем, что основной программе откуда-то нужно узнать адреса функций HAL. Это опять же легко реализуется путём передачи списка функций с адресами в линкер скрипте, но это плохая идея: при выпуске новой версии HAL на окажется несовместима с программами откомпилированными с адресами для старой версии HAL. Т.е. проблему можно сформулировать так, что нужен способ экспорта адресов HAL в таком виде, чтоб было возможно обновление HAL. Что можно реализовать: 1) с помощью функции с фиксированным адресом, принимающей код настоящей функции (а-ля INT21 в досе); 2) с помощью таблицы переходов (а-ля функции BIOS в CP/M -- серия вызовов "JMP xxx" располагающаяся по известному адресу); 3) наконец с помощью PLT/GOT как это делается с динамическими библиотеками на PC (когда та самая таблица "JMP xxx" размещается фактически в ОЗУ загружаемой программы, а адреса исправляются на нужные); 4) наконец с помощью релокаций (когда загружается файл в специальном формате, например ELF, и он имеет список релокаций, как нужно исправить саму загружаемую программу, где адреса функций вшиты прямо в код). Последний вариант обычно делает линкер при компиляции, а в рантайме это не делают -- дороговато (много патчить). На самом деле при ручной реализации (нет поддержки ОС, линкера, загрузчика...) удобней будет некоторая комбинация вариантов 2 и 3. Что для этого нужно: во-первых код загружаемой программы должен как-то запускаться, следовательно не только загружаемая программа должна узнать адреса функций HAL, но и сам HAL должен знать адрес по-меньшей мере одной функции загружаемой программы. Программа, положим, всегда загружается по фиксированному адресу (иначе там должен быть позиционно-независимый код, или опять релокации -- этот вариант рассматривать не будем). И допустим, HAL просто передаёт управление на адрес первого байта загруженной программы. Можно считать, что этот адрес -- на самом деле функция принимающая какие-то аргументы и одним из аргументов может быть адрес таблицы функций HAL. Т.е. где-то в хедере HAL'а, доступном так же для загружаемой программы (это интерфейс между программой и HAL) пишется что-то вроде следующего: struct HAL_API { void (*Hal_func1)(int); int (*Hal_func2)(const char*); ... }; И при этом единственная точка входа загружаемой программы реализуется примерно так: const struct HAL_API *_hal; void main(const struct HAL_API *hal) { _hal = hal; ... } Т.е. программа принимает адрес таблицы списка функций HAL и запоминает в своей глобальной переменной. Потом, чтобы использовать функции HAL и не писать выражения вида "_hal->func1(x)" реализуется, в коде загружаемой программы, примерно следующая прослойка (она просто заимствуется из кода HAL, в виде исходника на C): void Hal_func1(int x) { return _hal->Hal_func1(x); } int Hal_func2(const char *p) { return _hal->Hal_func2(p); } ... Теперь функции HAL можно вызывать просто по имени. Осталось правильно экспортировать таблицу функций HAL в коде самого HAL: void Hal_func1(int x) { ... imlementation ... } int Hal_func2(const char *p) { ... implementation .... return ... } ... static const struct HAL_API hal_table = { Hal_func1, Hal_func2, ... }; Вот и всё. Вроде понятно. Разумеется на практике в таблицу функций самым первым пунктом неплохо бы добавить функцию возвращающую версию API: тогда можно потом "const struct HAL_API*" преобразовать, например, к "const struct HAL_API2*", если понятно, что данная версия HAL имеет больше функций. А если не имеет то прослойки должны видеть, что HAL_API2 это NULL и возвращать ошибку вместо вызова функции которой нет. Как-то так.
[ZX]