Комментарии 20
Интересно, а стандартные функции и библиотеки Arduino умеют пользоваться данными, размещёнными за пределами первых 32к? Например, snprintf_P и перегрузка Stream.print(const __FlashStringHelper*)
Пробовали offsetof (костыль получше)?

typedef struct {
    unsigned char array2d[2][3];
} x_t;
...
const x_t  v PROGMEM = {...};
...
unsigned char a = pgm_read_byte_far(pgm_get_far_address(v) + offsetof(x_t, array2d[i][j]));

Надо переходить на ARM, где единное 32 битное адресное пространство (если не перешли).
Вот именно, я не вижу смысла в AVR, кроме как в формате восьминогих тараканов типа ATTiny, дешевле и проще поставить STM32F0/F1, или L серию, если надо ещё и по питанию экономию полную сделать. Есть конечно запущенные случаи, где сигнальные уровни 5V, но там можно и преобразователей уровня поставить.
Вот из-за таких костылей в коде я и пересел на STM32 — никаких раздельных адресных пространств, все указатели 32 бита…
Возможно появление массивов больше 32К в 8-битном решении намекает на необходимость использования для проекта более мощного МК?
Обработка такого большого массива на 8-и битном МК возможно (зависит от Т.З.) занимает много времени. Поэтому возможно имеет смысл посмотреть в сторону увеличения разрядности.
а еще это может быть развитая менюшка, или набор констант читаемых раз в жизни, или… много всяких или. было у меня семейство приборов на сопровождении. мега2560 с почти полной пзу, а производительности хватало.
НЛО прилетело и опубликовало эту надпись здесь
Что вы подразумеваете под «ни разу не атомарной операцией»? Что LPM, что ELPM выполняются 3 такта. Как вы перед этим заполняете регистры — другой вопрос. И почему бы вам не привести пример другого, короткого и простого макроса?
НЛО прилетело и опубликовало эту надпись здесь
Вся эта статья возникла из-за чтения мануалов. Читаю главу 5, делаю как написано. До 32 КБ работает, потом нет. Вот что я, по-вашему, должен был делать в таком случае? Какие именно мануалы читать, если не те, что я и читал? Как не думать о 32-битной адресации, если нужные данные лежать за пределами 16-битного адресного пространства? При чём тут вообще прерывания? Откуда я мог взять смещение, которое нужно положить в «рампз»?
НЛО прилетело и опубликовало эту надпись здесь
Вот теперь ваша мысль ясна. Я же в самом начале статьи написал, какому именно компилятору она посвящена. Ваша ветвь комментариев — точно такой же оффтоп, как и те, где рекомендуют сменить МК.
«ни разу не атомарная операция», означает в данном контексте, что для получения адреса за пределами смещения в 32к (ограниченных 15 битами регистровой пары Z), необходимо изменять RAMPZ, потому что адресация ELPM использует пару RAMPZ:Z
Аппаратные регистровые указатели у AVR — двухбайтные, X, Y, Z.
Об этом и речь. До тех пор, пока вам достаточно 2 Б (в ассемблере это регистр Z и инструкция LPM — Load Program Memory), всё хорошо. Чтобы выйти за 64 КБ (а по факту за 32), приходится использовать 3-Б аппаратные регистры, а именно RAMPZ:Z и инструкцию ELPM (Extended Load Program Memory). И вся проблема в том, что в главе 5 мануала AVR Libc об этом ни слова, хотя сам модуль pgmspace содержит всё нужное.
Об этом и речь.

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

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