Я не уверен, что понял вашу проблему, и у меня нет желания тратить время на это. Если вы пришлёте мне свой проект, может быть, я разберусь. Пока что я могу лишь предположить, что вы невнимательно читали статью. Я же написал, что pgm_get_far_address не умеет работать с элементом массива, вычисляемым во время работы; ей нужно подать определённый при компиляции указатель (другими словами, сам массив), а смещение делать вручную (через арифметику указателей. Вам знаком этот термин?). При этом я не понимаю, почему у вас работает pgm_read_dword_near; вы уверены, что данные расположены после 64 КБ?
О проблеме 0x1FFFF + 1 = 0x10000 слышу впервые; похоже, кто-то (кто? Компилятор GCC? Какая-то конструкция библиотеки AVR-libc? Отладчик Студии?) производит сложение по модулю 0x10000 (64 К) в младших 16 битах, но при этом сохраняет старшие (или всегда производит смещение на 0x10000). Также стоит помнить о том, что в микроконтроллерах AVR одни и те же вещи (например, адреса флеша) в одних местах исчисляются в байтах, а в других — в словах. Ещё я не понял, почему ваша проблема может быть решена прибавлением 4. Почему именно 4, откуда такая константа?
Понятия не имею, у какого микроконтроллера есть 8 МБ флеша. В серии ATmega, насколько я знаю, максимум 256 КБ; ATxmega — 392 КБ. В статье речь не о размере флеша микроконтроллера, а об адресном пространстве, выбранном разработчиками адаптированного для архитектуры AVR компилятора GCC. С практической точки зрения важно, что существую микроконтроллеры с более, чем 32 КБ флеша, а не существуют ли с 8 МБ.
Вот теперь ваша мысль ясна. Я же в самом начале статьи написал, какому именно компилятору она посвящена. Ваша ветвь комментариев — точно такой же оффтоп, как и те, где рекомендуют сменить МК.
Вся эта статья возникла из-за чтения мануалов. Читаю главу 5, делаю как написано. До 32 КБ работает, потом нет. Вот что я, по-вашему, должен был делать в таком случае? Какие именно мануалы читать, если не те, что я и читал? Как не думать о 32-битной адресации, если нужные данные лежать за пределами 16-битного адресного пространства? При чём тут вообще прерывания? Откуда я мог взять смещение, которое нужно положить в «рампз»?
Что вы подразумеваете под «ни разу не атомарной операцией»? Что LPM, что ELPM выполняются 3 такта. Как вы перед этим заполняете регистры — другой вопрос. И почему бы вам не привести пример другого, короткого и простого макроса?
Об этом и речь. До тех пор, пока вам достаточно 2 Б (в ассемблере это регистр Z и инструкция LPM — Load Program Memory), всё хорошо. Чтобы выйти за 64 КБ (а по факту за 32), приходится использовать 3-Б аппаратные регистры, а именно RAMPZ:Z и инструкцию ELPM (Extended Load Program Memory). И вся проблема в том, что в главе 5 мануала AVR Libc об этом ни слова, хотя сам модуль pgmspace содержит всё нужное.
Прежде, чем затирать загрузчик, было бы полезно сохранить его (и фьюз-биты), чтобы можно было вернуть всё как было. Мне, например, не удалось заставить работать китайский клон с официальным загрузчиком.
Но наличие такой корреляции совершенно не говорит о том, что есть причина, а что следствие. Вполне логично, что проблема ожирения приводит к поиску путей её решения, то есть возрастанию количества фитнес-клубов и организованного спорта. И логично, что это не приводит к полному решению проблемы ожирения, ведь первоначальная причина не в недостаточном количестве фитнес-клубов.
Надо смотреть на вторую производную. Уменьшилась ли скорость роста ожирения после увеличения количества фитнес-клубов? Такую статистику не приводят.
Другими словами, вы признаёте, что сами выдумали существование гена сопротивления кожи?
И что вы думаете о многократной зависимости сопротивления конкретного человека от его сытости, настроения, влажности...? Об этом, в отличие от генов, пишут во всех инструкциях по электробезопасности.
Я не уверен, что понял вашу проблему, и у меня нет желания тратить время на это. Если вы пришлёте мне свой проект, может быть, я разберусь. Пока что я могу лишь предположить, что вы невнимательно читали статью. Я же написал, что pgm_get_far_address не умеет работать с элементом массива, вычисляемым во время работы; ей нужно подать определённый при компиляции указатель (другими словами, сам массив), а смещение делать вручную (через арифметику указателей. Вам знаком этот термин?). При этом я не понимаю, почему у вас работает pgm_read_dword_near; вы уверены, что данные расположены после 64 КБ?
О проблеме 0x1FFFF + 1 = 0x10000 слышу впервые; похоже, кто-то (кто? Компилятор GCC? Какая-то конструкция библиотеки AVR-libc? Отладчик Студии?) производит сложение по модулю 0x10000 (64 К) в младших 16 битах, но при этом сохраняет старшие (или всегда производит смещение на 0x10000). Также стоит помнить о том, что в микроконтроллерах AVR одни и те же вещи (например, адреса флеша) в одних местах исчисляются в байтах, а в других — в словах. Ещё я не понял, почему ваша проблема может быть решена прибавлением 4. Почему именно 4, откуда такая константа?
Понятия не имею, у какого микроконтроллера есть 8 МБ флеша. В серии ATmega, насколько я знаю, максимум 256 КБ; ATxmega — 392 КБ. В статье речь не о размере флеша микроконтроллера, а об адресном пространстве, выбранном разработчиками адаптированного для архитектуры AVR компилятора GCC. С практической точки зрения важно, что существую микроконтроллеры с более, чем 32 КБ флеша, а не существуют ли с 8 МБ.
Надо смотреть на вторую производную. Уменьшилась ли скорость роста ожирения после увеличения количества фитнес-клубов? Такую статистику не приводят.
Автор той статьи начал с опровержения этого мифа. Миф выдумали продавцы АКБ для ИБП, чтобы продавать их втридорога.
И что вы думаете о многократной зависимости сопротивления конкретного человека от его сытости, настроения, влажности...? Об этом, в отличие от генов, пишут во всех инструкциях по электробезопасности.
А есть ли вообще ген, отвечающий за сопротивление кожи? Впервые слышу.