-
- Тебе ниже про OVERLAY всё расписали. - fk0(13.12.2020 16:07, ссылка)
- Добрались руки попробовать - всё получилось. - POV_(21.12.2020 23:44, )
- Т.к. в 51-й архитектуре нет эффективных инструкций для работы с ОЗУ
по относительным адресам, то для размещения локальных переменных по
абсолютным адресам компилятор-линкер C51 от кейл использует
механизм Data Overlay. il-2(484 знак., 13.12.2020 13:51)
- Колбек типизированный. Всё компилятор знает чего вызывает. - POV_(13.12.2020 13:59, )
- Ничего он не знает и типы совершенно никакого отношения не имеют. В
Keil C51 нужно делать специальный линкер-скрипт и с помощью
директивы OVERLAY перечислять для функции, из которой может быть
вызван callback, все возможные функции используемые в качестве
callback-функции. Нашёл свой старый проект -- там именно так. - fk0(13.12.2020 16:05)
- Ну, хоть какое-то решение. Но вообще неудобно. Неужто это реально
только такой путь? - POV_(13.12.2020 22:18, )
- Я ж говорю -- не пользоваться указателями на функции, делать через
enum. Это несколько более прямолинейный путь для архитектур вроде
x51 и PIC16/18. Правда архитектурно плохо получается, без
указателей. Для PIC18 там вообще пляски с бубном: - fk0(13.12.2020 22:58, ссылка)
- Не вариант, не будет у свитч-кейса знаний о вызываемых функциях... POV_(335 знак., 13.12.2020 23:14, )
- Что значит "не будет"? Оно есть. Если его нет -- у тебя программа
никогда не заработает ни на x51, ни на pic18. На обоих архитектурах
ВЫЧИСЛЯЕМЫЙ адрес функции невозможен. Только из набора жёстко
заданных. А это тот же switch-case. Преимущество switch-case -- не
нужно морочиться с OVERLAY. Но если у тебя кросс-платформенность и
switch-case не удобен, то мучайся с OVERLAY. Я в своё время
предпочёл OVERLAY и FNCALL (в PICC18), чем switch-case (ибо
архитектурно жутко неудобно) fk0(1 знак., 13.12.2020 23:24)
- Тот код, где вызывает колбэк - это неизменяемый код. Типа,
библиотека низкого уровня. Она не может и не должна знать о новых
фичах прошивки... POV_(510 знак., 14.12.2020 00:03, )
- Так или иначе, но знать она БУДЕТ. Либо непосредственно (в switch-case). Либо в скрипте линкера (OVERLAY). По-другому в принципе не сделаешь. Если у тебя коллбек устанавливается ровно один раз на старте -- можешь имя функции коллбэка передавать при компиляции макросом, например. Ну или как "зарезервированное имя внешней функции". Но суть одна -- компилятор должен непосредственно знать, что будет вызываться. Скомпилировать такой код, когда компилятор вызывает неизвестную fk0(541 знак., 14.12.2020 01:34)
- Тот код, где вызывает колбэк - это неизменяемый код. Типа,
библиотека низкого уровня. Она не может и не должна знать о новых
фичах прошивки... POV_(510 знак., 14.12.2020 00:03, )
- Что значит "не будет"? Оно есть. Если его нет -- у тебя программа
никогда не заработает ни на x51, ни на pic18. На обоих архитектурах
ВЫЧИСЛЯЕМЫЙ адрес функции невозможен. Только из набора жёстко
заданных. А это тот же switch-case. Преимущество switch-case -- не
нужно морочиться с OVERLAY. Но если у тебя кросс-платформенность и
switch-case не удобен, то мучайся с OVERLAY. Я в своё время
предпочёл OVERLAY и FNCALL (в PICC18), чем switch-case (ибо
архитектурно жутко неудобно) fk0(1 знак., 13.12.2020 23:24)
- на PIC18 у меня вообще не получились указатели на функции, сносило куда-то совсем не туда.. - Aleksey_75(13.12.2020 23:01)
- Не вариант, не будет у свитч-кейса знаний о вызываемых функциях... POV_(335 знак., 13.12.2020 23:14, )
- Я ж говорю -- не пользоваться указателями на функции, делать через
enum. Это несколько более прямолинейный путь для архитектур вроде
x51 и PIC16/18. Правда архитектурно плохо получается, без
указателей. Для PIC18 там вообще пляски с бубном: - fk0(13.12.2020 22:58, ссылка)
- Ну, хоть какое-то решение. Но вообще неудобно. Неужто это реально
только такой путь? - POV_(13.12.2020 22:18, )
- Это современные компиляторы умные. С51 не из них. Запросто может игнорировать такое знание. - SciFi(13.12.2020 14:12)
- Ничего он не знает и типы совершенно никакого отношения не имеют. В
Keil C51 нужно делать специальный линкер-скрипт и с помощью
директивы OVERLAY перечислять для функции, из которой может быть
вызван callback, все возможные функции используемые в качестве
callback-функции. Нашёл свой старый проект -- там именно так. - fk0(13.12.2020 16:05)
- Колбек типизированный. Всё компилятор знает чего вызывает. - POV_(13.12.2020 13:59, )
- ХЗ. Где и как вызываются колбеки. Однако Вещественная Арифметика вполне может быть не реентерабельной. - Zoro(13.12.2020 13:46)
- А при чём тут C99? Ни при чём. Ну и си для 8051 — это же недоси.
Можно ли там вызывать колбеки, не делая дополнительных
телодвижений? Возможно, их нужно объявить реентерабельными? - SciFi(13.12.2020 13:41, ссылка)
- Да, именно оно. С reentrant всё заработало как надо. - POV_(13.12.2020 14:04, )
- reentrant функции нужны для другого, для случаев когда функции
могут вызываться из биглупа и из прерываний одновременно, например.
Делать все функции подряд reentrant из-за коллбэков не стоит, т.к.
reentrant функции используют симулированный стек, который ограничен
в размерах, работают медленно, генерируется большой объём кода и
т.п. И вызов любой не-reentrant функции из reentrant функции
вызывает рекурсивно те же проблемы. А всё подряд reentrant не
сделаешь. reentrant это fk0(140 знак., 13.12.2020 16:12, ссылка)
- Ну я вот реентрантными сделал 5 колбеков. Все вызываются из прерываний... POV_(198 знак., 13.12.2020 21:19, )
- А теперь отвечай - почему? - il-2(13.12.2020 14:11)
- Проще говоря - компилятор не знал что это - колбэк, который будет
вызван из прерывания. Потому локальные переменные перекрывались с
другими функциями, якобы по причине невозможности их перекрестного
вызова. - POV_(13.12.2020 14:44, )
- У тебя набор слов, как у студента, который сдает зачет и "плавает" в теме. Непонятно только, кто препод, и для кого строятся эти словесные нагромождения. il-2(882 знак., 13.12.2020 16:02)
- Потому как адрес локальной переменной был жестко задан на этапе
компиляции. И перекрывался с чем не надо. Так видимо. - POV_(13.12.2020 14:23, )
- Не морочь голову. Список функций в директиве OVERLAY ничем не лучше
switch-case прямо в коде. На который и нужно заменить указатели на
функции. И всё само и волшебно заработает оптимальным образом.
Просто вместо установки указателя, ты в переменной, где был раньше
указатель, должен будешь держать enum позволяющий выбор из одного
из N вариантов. А в обработчике прерываний сделать switch
(enum-var) { case Variant1: f1(); break; case Variant2: f2();
break... }... - fk0(13.12.2020 16:15)
- Нет, эти колбеки могут быть перезначены. - POV_(13.12.2020 16:18, )
- Ну вот вместо адреса функции для коллбэка будешь менять число в enum'е. Разницы никакой. - fk0(13.12.2020 16:19)
- Нет, эти колбеки могут быть перезначены. - POV_(13.12.2020 16:18, )
- Не морочь голову. Список функций в директиве OVERLAY ничем не лучше
switch-case прямо в коде. На который и нужно заменить указатели на
функции. И всё само и волшебно заработает оптимальным образом.
Просто вместо установки указателя, ты в переменной, где был раньше
указатель, должен будешь держать enum позволяющий выбор из одного
из N вариантов. А в обработчике прерываний сделать switch
(enum-var) { case Variant1: f1(); break; case Variant2: f2();
break... }... - fk0(13.12.2020 16:15)
- Проще говоря - компилятор не знал что это - колбэк, который будет
вызван из прерывания. Потому локальные переменные перекрывались с
другими функциями, якобы по причине невозможности их перекрестного
вызова. - POV_(13.12.2020 14:44, )
- reentrant функции нужны для другого, для случаев когда функции
могут вызываться из биглупа и из прерываний одновременно, например.
Делать все функции подряд reentrant из-за коллбэков не стоит, т.к.
reentrant функции используют симулированный стек, который ограничен
в размерах, работают медленно, генерируется большой объём кода и
т.п. И вызов любой не-reentrant функции из reentrant функции
вызывает рекурсивно те же проблемы. А всё подряд reentrant не
сделаешь. reentrant это fk0(140 знак., 13.12.2020 16:12, ссылка)
- Да, именно оно. С reentrant всё заработало как надо. - POV_(13.12.2020 14:04, )
- Тебе ниже про OVERLAY всё расписали. - fk0(13.12.2020 16:07, ссылка)