Mega2560 чтение одного байта из eeprom с адреса > 255

Тема в разделе "Arduino & Shields", создана пользователем Vovka, 8 ноя 2020.

Метки:
  1. parovoZZ

    parovoZZ Гуру

    Данный код не вызывается в прерывании. А если даже и так, то инструкции sei и cli там попросту не нужны - все обеспечит ядро аппаратно.
     
  2. parovoZZ

    parovoZZ Гуру

    Почему же? Если вся работа программы построена на прерываниях, то из них и не будем вылезать. Правда, архитектура самой AVR не предназначена для этого.
     
  3. AlexU

    AlexU Гуру

    Что вы так к этим прерываниям привязались. Дело не в прерываниях, а в неявном поведении функции.
    Функция записи в EEPROM зачем-то активирует прерывания. Зачем она это делает? Без активации прерывания нельзя завершить операцию записи в EEPROM?
    Это лишняя операция, которую она делать не должна. Запись данных в EEPROM не должна менять состояние "системы".

    Кому не понятно:
    в основном коде программы (не в обработчике прерывания) я запретил прерывания, разрешать буду в определённый момент, мне так нужно, иначе нарушится логика работы моей программы. И тут вдруг при попытке обновить данные в EEPROM прерывания разрешаются. С какого .....? Далее смотрим на вопросы в начале сообщения -- зачем?

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

    Вот и встаёт вопрос -- зачем таким кодом хвастаться?
     
  4. a1000

    a1000 Гуру

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

     
    akl нравится это.
  5. AlexU

    AlexU Гуру

    Это был пример.
    Дело не в алгоритме, а в том, что функция должна делать только то, для чего предназначена. Запись в EEPROM -- только запись в EEPROM, без изменения "внешнего мира".
    Только в этом случае использование функции становится безопасным.
    А, если функция начинает "чудить", то это может привести к непредсказуемым эффектам, которые могут стать причиной трудноотловимых ошибок в работе программы.

    Вы в своём коде на ASM, вызывая подпрограммы (посредством инструкции call и подобных), используете регистры как хотите, не задумываясь о сохранении их состояния, например, в стеке и последующем восстановлении перед выходом из подпрограммы (инструкции push/pop)? Правильно?
     
  6. a1000

    a1000 Гуру

    Дело в том, что подпрограммы вызываются зряче и осознанно. Поэтому можно проконтролировать какие РОН на момент вызова свободны и могут безболезненно использоваться в теле подпрограмы. Вообще использовать РОН для хранения данных это моветон. По этому, если писать грамотно, нужное количество свободных РОН обычно под рукой и ничего бросать в стек при входе в подпрограмму не приходится.
    Другое дело прерывания. В какой момент мы туда свалимся неизвестно. А значит, что и в каких РОН будет в момент входа в обработчик не сможет спрогнозировать ни кто. Поэтому в начале обработчика в стек бросаются все используемые в нём РОН и обязательно SREG. Перед выходом всё востанавливается в первоначальный вид. Главное забрать из стека ровно столько сколько положили, ибо в стеке так-же сохраняется адрес возврата из прерывания. Если начудить, то по инструкции reti можно улететь в неизвестном направлении.:)
     
  7. akl

    akl Гуру

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

    Asper Daffy Иксперд

    Почему? Во вполне известном.
     
  9. AlexU

    AlexU Гуру

    Есть заранее написанная подпрограмма 'XXX', которая делает очень сложную работу и использует регистры R6, R7, R8, R9, R10, R11.
    В текущий момент Вы пишете программу и понимаете, что программа должна выполнить действия, которые уже реализованы в подпрограмме 'XXX', функционал сложный и было бы разумным решением просто переиспользовать готовую подпрограмму (зачем изобретать новый велосипед?). Но вот проблема в Вашей программе в текущий момент уже используются регистры R6, R8, R11. Что будете делать? Переписывать основную программу, что бы освободить нужные регистры? Или переписывать подпрограмму?
    А потом будете сочинять новую программу и опять понадобится подпрограмма 'XXX' и опять выяснится, что регистры заняты -- правда другие: R7, R8, R9.
    Опять будете переписывать? Что будете переписывать -- программу или подпрограмму? Если подпрограмму, то как быть с первой программой, которая использовала регистры R6, R8, R11? Если основную программу, то может выясниться, что для освобождения регистров R7, R8 понадобится переписать не малую часть кода этой программы.

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

    Про хранение речи не было -- вот только работать с данными можно только после загрузки в РОН. Есть вариант воспользоваться всего парой РОН, но каждая загрузка/выгрузка РОН из памяти или в память это два такта процессора. Но это малая проблема -- данные-то где-то надо хранить. И тут либо распределение РОН по всей программе и используемым библиотекам (которые могут быть написанными давным-давно), либо распределение памяти, опять же с учетом библиотек (которые могут быть .......).
     
  10. a1000

    a1000 Гуру

    Как объяснил преподаватель в ролике - при записи прерывания запрещать нужно. Ибо если прерывание вклинится между установкой бита EEMWE и бита EEWE - запись не произойдет. Такой баг может не произойти при наладке а вылезти через некоторое время работы уже готового устройства. При чтении запрет прерываний не нужен. Главное не попортить регистры с адресом, а между инструкциями может быть любое число тактов.
     
    Daniil нравится это.
  11. a1000

    a1000 Гуру

    По использованию РОН - каждый решает сам. На первый взгляд их дофига - аж 32. (рассматриваем ATmega8/168/32). Но младшие, до R15, не всегда можно использовать, не все инструкции поддерживают. В оставшихся, если ещё использовать регистровые пары для индексных переходов, не так пного ресурсов остаётся. Ну и по самому алгоритму смотреть надо. По возможности не лезть в подпрограмму когда в РОН висит куча промежуточных результатов. Но я ни в коем случае не утверждаю, что нельзя использовать предложенный вами вариант сохранения регистров на входе в подпрограмму.
    Использовать предыдущие наработки не только можно, но и нужно. Но на мой взгляд оформлять их нужно в виде макросов. Тогда при их вставке можно выбирать используемые РОН.