Проблема с PROGMEM
- Войдите на сайт для отправки комментариев
Ср, 19/03/2014 - 06:49
Привет, ребят!
Ситуация такая: использую Arduino 2.0.5r2 на виндовс 7, запихал библиотеку для des шифрования, при компиляции предупреждает:
warning: only initialized variables can be placed into program memory area
Ругается на все строчки такого типа:
const uint8_t sbox[256] PROGMEM = ... //ну и там массив
В итоге при попытке зашифровать что-либо мега328 уходит в бесконечный ребут. Недавно перешел на винду, на убунте ардуина 2.0.5 компилила все без ошибок. В чем проблема и как решить?
P.S. замена PROGMEM на
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))
результата не дало!
Спасибо!
http://arduino.cc/en/Main/Software#.UykmE_l_s00
тут нет такой версии. откуда взяли?
я бы написал так
P.S. замена PROGMEM на
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))
результата не дало!
Спасибо!
Вы просто не умеете его готовить.... :)
Попробуйте вот-таки вверху файла сделать:
#include <avr/pgmspace.h> #undef PROGMEM #define PROGMEM __attribute__(( section(".progmem.data") ))Ну или, если хотите раз и навсегда (что-бы в других библиотеках не ругалось), то в файле WString.h, после #include <avr/pgmspace.h>, вставить эти два #undef/#define
Ну и, что-бы два раза не вставать, и тип prog_uchar было бы более уместно тут.
Arduino - PROGMEM
Some cryptic bugs are generated by using ordinary datatypes for program memory calls.
Это про возможную причину зависания.
P.S. Это warning, а не error - с этим можно жить :)
P.S.S. Это не ваша ошибка, а баг. Только не Arduino, а компилятора gcc (который используется ардуинойIDE).
у меня вроде и так работает
#include <avr/pgmspace.h> static const char mass[64] PROGMEM ={....проблемм пока не было. появились когда засунул туда 2байтные значения (тип данных менял), а чтение производил старой командой
ну это был сам виноват
Таки я так его и готовлю.
const uint8_t e_permtab[] PROGMEM = { 4, 6, /* 4 bytes in 6 bytes out*/ 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 };Вот пример массива, я думаю укладывается все как надо по размерности. И да, не помогает, потому что предупреждений нет, а девайс все равно уходит в ребут.
И да, я установил самую самую новую ардуину - проблема осталась, потом перенес туда AVR-GCC 4.7 и стало более или менее норм, правда ответы от сервера стали порой битыми приходить, из-за чего пришлось немного фиксить все. То есть это костыль, вероятно не самый надежный. Но ведь на бубунде оно работало вообще без каких-либо проблем! Почему?
Таки я так его и готовлю.
Во первых "готовите", отсносилось к "костылю" #undef/#define.
Я вам предолжил, не только добавить его в начало скетча, но и еще одну строку туда воткнуть. #include <avr/pgmspace.h>
В скетче мне это помогло (но продолжало ругаться варингами на библиотеку tone).
А есть рецепт "как поправить что-бы в каждый скетч" не пихать. В файле WString.h. После этого у меня этот тип варнингов исчез полностью.
Оба рецепта я проверил на себе. На винде. Про убунту - не знаю. А вы проверили?
Это по поводу варнинга.
Жалуетесь, на "зависоны", я вам дал ссылочку на документацию, и даже жирным выделил. Где сказанно что подобное использование типов часто является "причиной критических ошибок". Почему в вашем примере по прежнему
uint8_tвидно?Я не знаю, может и не из-за этого зависоны. Но даже обсуждать чо-то другое, пока не исправлена рекомендация из документации - не вижу смысла.Нет, изменив на char вообще работать перестало шифрование, хоть и не уходило в ребут. На убунте у меня не было никаких предупреждений и все работало как следует.
Здесь проблема более или менее решилась только новой версией GCC-AVR 4.7 + новая Arduino с поддержкой Due. И все работает без ругательств и ребутов.
<avr/pgmspace.h> было добавлено к слову вместе с редефайном. Сейчас все стандартными процедурами без переопределения макроса PROGMEM работает
Нет, изменив на char вообще работать перестало
Хм... А почему вы пытались изменить именно на char? Почему вы решили что char это более правильно чем uint8_t?
я предлагал не просто char а
а предлагал потому что у меня это работает стабильно в нескольких проектах
вот например в одном проекте куча использований. и все прекрасно работает
//цифры размером 16х32 пикселей static const char mass16x32[10][64] PROGMEM ={ { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //0 0x3F, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x3F, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0xF8, //1 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x1F}, { 0x00, 0x00, 0x02, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //2 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F, 0xFE, 0xFF, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x40, 0x00, 0x00}, { 0x00, 0x00, 0x02, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //3 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}, { 0xF8, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0xF8, //4 0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x1F}, { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x02, 0x00, 0x00, //5 0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}, { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x02, 0x00, 0x00, //6 0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE, 0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}, { 0x00, 0x00, 0x02, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x1F}, { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //8 0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F, 0xFE, 0xFF, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE, 0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}, { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //9 0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}}; //цифры размером 10х16 пикселей static const char mass10x16[10][20] PROGMEM ={ {0x7E, 0x3D, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3D, 0x7E, // 0 0x7F, 0xBE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBE, 0x7F}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE, // 1 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE}, {0x00, 0x81, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E, // 2 0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x80, 0x00}, {0x00, 0x81, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E, // 3 0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F}, {0x7E, 0xBC, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBC, 0x7E, // 4 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x3E, 0x7F}, {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x81, 0x00, // 5 0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F}, {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x81, 0x00, // 6 0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F}, {0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3D, 0x7E, // 7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x7F}, {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E, // 8 0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F}, {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E, // 9 0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F} }; //картинка линия под которой написано m/s static const char image[48] PROGMEM ={ 0x00, 0x04, 0xE4, 0xC4, 0x84, 0x04, 0x84, 0xC4, 0xE4, 0x04, 0x04, 0x04, 0x04, 0x84, 0xE4, 0x04, 0xC4, 0x64, 0x24, 0x24, 0x64, 0xC4, 0x04, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x01, 0x03, 0x01, 0x00, 0xFF, 0x00, 0xE0, 0x38, 0x0E, 0x03, 0x00, 0x00, 0x61, 0xC3, 0x82, 0x86, 0xCC, 0x78, 0x00, 0x00}; //индикатор батареи static const char batt[4] PROGMEM ={ 0x3C, //+ вывод 0xFF, //вертикальная линия 0x81, //пустая батарейка 0xBD}; //полная батарейка //Заставка static const char zastavka[2][85] PROGMEM = { { 0xFC, 0xFE, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x04, 0xFC, 0xC4, 0x20, 0x20, 0xC0, 0x00, 0xE0, 0xE0, 0x20, 0x20, 0xC0, 0x00, 0xC0, 0xE0, 0x20, 0xC0, 0x00, 0xE0, 0xE0, 0x40, 0x20, 0xE0, 0x00, 0xC0, 0xE0, 0x20, 0xC0, 0x00, 0xC0, 0xE0, 0x20, 0xC0, 0x00, 0xE0, 0xE0, 0x20, 0x20, 0xC0, 0x00, 0xC0, 0xE0, 0x20, 0xE0, 0x00, 0x00, 0xE0, 0xE0, 0x20, 0x20, 0xC0, 0x04, 0xFC, 0xC4, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0xC0, 0x00, 0xE0, 0xA0, 0xA0, 0x20, 0x00, 0x00, 0x00, 0xE0, 0xA0, 0xA0, 0x20}, { 0x03, 0x07, 0x08, 0x08, 0x08, 0x0C, 0x04, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x0F, 0x03, 0x05, 0x08, 0x00, 0x07, 0x0F, 0x08, 0x07, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x07, 0x0F, 0x08, 0x07, 0x00, 0x07, 0x4F, 0x68, 0x3F, 0x00, 0x0F, 0x0F, 0x03, 0x05, 0x08, 0x00, 0x07, 0x0F, 0x08, 0x07, 0x08, 0x00, 0x7F, 0x7F, 0x08, 0x08, 0x07, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x08, 0x07, 0x00, 0x08, 0x08, 0x08, 0x07, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x07}};версия иде 1.0.4 правда, а не самая последняя бета версия
я предлагал не просто char а
Я видел что вы предлагали, я спрашивал топикстартера почему он взял char. И ответ "потому что предложил jeka_tm" - не самый правильный (или я предложил...).
Давайте перефразирую: а какие типы рекомендует использовать документация? Есть в списке "рекомендуемых" char, uint_8 и т.п.?
P.S. А то что "работало...", дык это лично меня не убеждает. И при выходе за границы массива, и забывая volatile в обработчиках прерывания можно долго говорить "у меня все замечательно работает". А потом, при совершенно безобидном изменении скетча получить абсолютно невменяемое поведение. Или даже без изменении, просто вышла новая версия IDE которая по умолчанию использует другие флаги оптимизации... А потом утром бежать покупать новую клавиатуру (так как у старой обгрызены края :)
P.S.S. И еще не известно, как топикстартер читает эти байты. Раз в доку заглядывать не торопимся. Поэтому "все более менее решилось" - меня совершенно не убеждает. Возможно это лечение язвы стаканом водки с солью.
const uint8_t twhr[12][31] PROGMEM={ {17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17}, {17,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18}, {18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19}, {19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}, {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21}, {21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21}, {21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,20,20}, {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,19,19,19}, {19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,18,18,18,18,18,18,18,18}, {18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,17,17,17,17}, {17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17}, {17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17} };Выводится циклами i=1..12, j=1..31 в сериал. Из сериала приходит это:
WTF? Баловство с pgmspace.h, #undef PROGMEM результатов не дало.
Про мышей и кактус. Какой ещё есть способ точно убедиться что массив окажется во флеше, а не в ОЗУ?
ну вообще надо 0-11 и 0-30
i=1;i<=12;i++;
Жалко подчеркнутого шрифта нет, т. к. болдом <= не особенно выделяется. Но думаю понятно. Так что тут всё правильно.
Кастовать строку Serial.print(String(twhr[i][j],DEC)); не помогает. Как мне точно выяснить, что инфа в массиве не искажена?
Каст в десятичный номер (+48) с делением (/ на десятках, % на единицах) и вывод через Serial.write() помогает. Результаты следующие:
- PROGMEM есть - массив безобразный. Одни нули и кое-где мусор типа G, @ и т. п.
- нету - чудовищный расход оперативы, но всё видно. С багами.
Во-первых цифры больше на единицу. То есть вместо 17 идет 18 и т. д.
Во-вторых, конец массива покоцан. Нули, мусор, НЁХ.
как считываешь из массива? так?
это неправильно!!!
надо
еще раз повторяю
0-11 и 0-30
почитай про массивы
О, ахринеть! ни за что бы в голову не пришло. Теперь правильно :)
ну вот. а ты сразу ругать либу, и только потому что не умел ей пользоваться
Незаметная она, эта фраза. В предыдущих постах.
дя меня вот не понятно, а что - #include <avr/pgmspace.h> - после проверки компиляции никак не влияет на размер занимаемой памяти? Почему так?
Потому что не должно.