PROGMEM tricks

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

qwone пишет:

sadman41 пишет:
Простите, не понял вопроса. Приведите пример как "хорошо". Можно на JS или что Вы там под "языками для web" понимаете.

Тю . это легко и не очень. всего надо освоить это http://www.solarix.ru/for_developers/cpp/stl/stl.shtml
Но скорее всего данный камень это уже не потянет.


сплю уже... но ведь говорили не раз -- есть 100500 адаптаций стандартных темплейтов под АВР и ардуину.

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

Тю . это легко и не очень. всего надо освоить это http://www.solarix.ru/for_developers/cpp/stl/stl.shtml

Но скорее всего данный камень это уже не потянет.

Потянет. В простейшем виде это называется map. его к ардуино давно прикрутили,

std::map<char,int> first;

  first['a']=10;
  first['b']=30;
  first['c']=50;
  first['d']=70;

правда, чтобы сделать ключом map массив char* - надо прилично извратится и вроде как написать свои функции сравнения строк.

То есть в конечном итоге вся эта красота скрывает внутри теже самые функции поиска нужного значения в структуре путем перебора элементов, от которых Садман хотел бы избавится :)

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

sadman41 пишет:
хотелось бы получить удобный маппинг (в обе стороны)
тут можно долго спорить есть это в языке или нет, т.к. есть оно во внешней библиотеке STL (вроде как не в языке), но эта библиотека стандартизована в ISO-IEC 14882-2017 (нужные нам контейнеры - разд. 26.4, стр. 896).

Другая беда, что в поставке IDE (как и Atmel Studio) библиотеки STL нет. Она, конечно же есть для gnu'сного компилятора, но с этими продуктами не поставляется. Поставить можно. Я как-то ставил. Что-то там было непросто (может потому,  что я плохо знаю gcc) но в итоге поставилось и работало.

sadman41, Вы не из МГУ часом?

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

sadman41 пишет:
хотелось бы получить удобный маппинг (в обе стороны)
тут можно долго спорить есть это в языке или нет, т.к. есть оно во внешней библиотеке STL (вроде как не в языке),

...

Поставить можно. Я как-то ставил. Что-то там было непросто (может потому,  что я плохо знаю gcc) но в итоге поставилось и работало.

Непросто - это плохо, конечно. В опенсорц-прожект не выплеснешь исходник просто так... Что ж, раз волшебства нет, попробую заварить чаёк на шаблонах. 

ЕвгенийП пишет:
sadman41, Вы не из МГУ часом?

Бывало, конечно, мне льстили в жизни, но чтобы вот вот так - в первый раз. Про МГУ я знаю только то, что в районе Мехмата что ли... снег идёт вверх. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sadman41 пишет:

Бывало, конечно, мне льстили в жизни, но чтобы вот вот так - в первый раз.

Улыбнули с утра...производство...звонок с сообщением о неисправности ТПА...прихожу...слышу в свой адрес ..."самый умный мужчина Советского Союза"...в ответ - ну Вы и льстите...а по существу...работали исключительно матери-одиночки, зарплата от 350 до 400, надо только чтобы станки работали непрерывно )))
Извиняюсь за оффтоп
PS Видимо Евгений Петрович увидел ШКОЛУ ПРЕПОДАВАНИЯ, а УЧИТЕЛЯ встречаются везде )))
 

sadman41
Offline
Зарегистрирован: 19.10.2016

Нет, конечно уборщиком меня бы взяли, наверное, в МГУ... Однако, мои столкновения с высокими материями ограничиваются разовым  прохождением мимо незамерзающего пруда в ИТЭФе с последующим употребле... обменом опытом с коллегами и наблюдением за всклокоченными людьми в трико, которые в ночи черкали странные формулы на досках, развешенных по коридорам.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

[quote=ua6em увидел ШКОЛУ ПРЕПОДАВАНИЯ[/quote]Нет, я увидел (уже в нескольких местах) использование словечек и выражений, которые, хотя и являются общеизвестными, но почему-то чаще всего используются людьми учившимися или работающими в МГУ (может это только по моим знакомым так - не знаю)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

[quote=ua6em увидел ШКОЛУ ПРЕПОДАВАНИЯ

Нет, я увидел (уже в нескольких местах) использование словечек и выражений, которые, хотя и являются общеизвестными, но почему-то чаще всего используются людьми учившимися или работающими в МГУ (может это только по моим знакомым так - не знаю)

[/quote]

Мир тесен, может его учитель учился или тесно общался с выходцами МГУ )))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
void setup() {
  Serial.begin(9600);
  Serial.println("ffff");
  Serial.println(reinterpret_cast<const __FlashStringHelper *>PSTR("qwwhhhhhhhbbbbbbbbbbbbbbbbbbbhhhhhhhe"));
  Serial.println(reinterpret_cast<const __FlashStringHelper *>(__extension__({static const char __c[] PROGMEM = "qwwhhhhhhhbbbbbbbbbbbbbbbbbbbhhhhhhhe"; &__c[0];})));
}
void loop() {
}
Скетч компилируется и работает

 

lean_74
Offline
Зарегистрирован: 22.12.2015

qwone пишет:

Скетч компилируется и работает

да гошишь...

exit status 1
Ошибка компиляции для платы Arduino Pro or Pro Mini.
C:\Users\9D20~1\AppData\Local\Temp\ccVhdSDj.ltrans0.ltrans.o:(.rodata+0x6): undefined reference to `Print::write(unsigned char const*, unsigned int)'
 
c:/arduino/arduino-1.8.7/hardware/tools/avr/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr5/crtatmega328p.o:(.init9+0x0): undefined reference to `main'
 
collect2.exe: error: ld returned 1 exit status
 
exit status 1
Ошибка компиляции для платы Arduino Pro or Pro Mini.
 
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

у меня скомпилировался тоже, что я не так сделал )))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
void setup() {
  Serial.begin(9600);
  Serial.println("ffff");
  Serial.println(reinterpret_cast<const __FlashStringHelper *>PSTR("qwwhhhhhhhbbbbbbbbbbbbbbbbbbbhhhhhhhe"));
  Serial.println(reinterpret_cast<const __FlashStringHelper *>(__extension__({static const char __c[] PROGMEM = "qwwhhhhhhhbbbbbbbbbbbbbbbbbbbhhhhhhhe"; &__c[0];})));
}
void loop() {
}
/*Для Нано
  Скетч использует 1606 байт (5%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 190 байт (9%) динамической памяти, оставляя 1858 байт для локальных переменных. Максимум: 2048 байт.
*/
/* Результат
ffff
qwwhhhhhhhbbbbbbbbbbbbbbbbbbbhhhhhhhe
qwwhhhhhhhbbbbbbbbbbbbbbbbbbbhhhhhhhe
*/

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Чуть более извращённый генератор HTML-страницы, использующий шаблонные функции для доступа к однотипным массивам-"справочникам", расположенным в Program Space. Надеюсь, что совсем грубых ляпов в темплейтах не наделал. Но, если не справился, - напишите. 

//#pragma GCC optimize ("O0")
#include <avr/pgmspace.h>

// *** Strings ***
const char text_EMPTY_STRING[]       PROGMEM = "";
const char text_SUPERHERO_SCHEDULE[] PROGMEM = "Superhero's schedule";

const char name_DAY_MONDAY[]         PROGMEM = "Monday";
const char name_DAY_TUESDAY[]        PROGMEM = "Tuesday";
const char name_DAY_WEDNESDAY[]      PROGMEM = "Wednesday";
const char name_DAY_THURSDAY[]       PROGMEM = "Thursday";
const char name_DAY_FRIDAY[]         PROGMEM = "Friday";
const char name_DAY_SATURDAY[]       PROGMEM = "Saturday";
const char name_DAY_SUNDAY[]         PROGMEM = "Sunday";

const char name_COLOR_VIOLET[]       PROGMEM = "Violet";
const char name_COLOR_INDIGO[]       PROGMEM = "Indigo";
const char name_COLOR_BLUE[]         PROGMEM = "Blue";
const char name_COLOR_GREEN[]        PROGMEM = "Green";
const char name_COLOR_YELLOW[]       PROGMEM = "Yellow";
const char name_COLOR_ORANGE[]       PROGMEM = "Orange";
const char name_COLOR_RED[]          PROGMEM = "Red";

const char html_CLASS_DAY_WORK[]     PROGMEM = "dwrk";
const char html_CLASS_DAY_REST[]     PROGMEM = "drst";
const char html_CLASS_IS_TODAY[]     PROGMEM = "istd";

const char html_CLASS_COLOR_VIOLET[] PROGMEM = "cvi";
const char html_CLASS_COLOR_INDIGO[] PROGMEM = "cin";
const char html_CLASS_COLOR_BLUE[]   PROGMEM = "cbl";
const char html_CLASS_COLOR_GREEN[]  PROGMEM = "cgr";
const char html_CLASS_COLOR_YELLOW[] PROGMEM = "cye";
const char html_CLASS_COLOR_ORANGE[] PROGMEM = "cor";
const char html_CLASS_COLOR_RED[]    PROGMEM = "cre";

const char html_CSS_TABLE[]          PROGMEM = "\n<style>\n\
body,html{height:100%;background-color:#F0F0F0}\n\
table{width:100%}\n\
th{border-bottom:1px solid #999;padding:10px}\n\
td{margin:0;padding:0}\n\
.cvi{color:DarkViolet}\n\
.cin{color:Indigo}\n\
.cbl{color:DarkSlateBlue}\n\
.cgr{color:LimeGreen}\n\
.cye{color:Gold}\n\
.cor{color:Coral}\n\
.cre{color:IndianRed}\n\
.dwrk{background-color:MistyRose}\n\
.drst{background-color:LemonChiffon}\n\
.istd{font-weight:700}\n\
</style>\n\n";

// *** Enumes ***

typedef enum { diMonday = 1, diTuesday, diWednesday, diThursday, diFriday, diSaturday, diSunday } dayId_t;
typedef enum { ciViolet = 10, ciIndigo, ciBlue, ciGreen, ciYellow, ciOrange, ciRed } colorId_t;

// *** Structs ***
typedef struct {
  dayId_t id;
  PGM_P name;
  PGM_P htmlClass;
  colorId_t colorId;
} dayOfWeek_t;

typedef struct {
  colorId_t id;
  PGM_P name;
  PGM_P htmlClass;
} colorOfSocks_t;

// *** Data ***

const dayOfWeek_t daysOfWeek[]      PROGMEM = {
  { diMonday,    name_DAY_MONDAY,    html_CLASS_DAY_WORK, ciViolet },
  { diTuesday,   name_DAY_TUESDAY,   html_CLASS_DAY_WORK, ciIndigo },
  { diWednesday, name_DAY_WEDNESDAY, html_CLASS_DAY_WORK, ciBlue   },
  { diThursday,  name_DAY_THURSDAY,  html_CLASS_DAY_WORK, ciGreen  },
  { diFriday,    name_DAY_FRIDAY,    html_CLASS_DAY_WORK, ciYellow },
  { diSaturday,  name_DAY_SATURDAY,  html_CLASS_DAY_REST, ciOrange },
  { diSunday,    name_DAY_SUNDAY,    html_CLASS_DAY_REST, ciRed    }
};

const colorOfSocks_t colorsOfSocks[] PROGMEM = {
  { ciViolet, name_COLOR_VIOLET, html_CLASS_COLOR_VIOLET  },
  { ciIndigo, name_COLOR_INDIGO, html_CLASS_COLOR_INDIGO  },
  { ciBlue,   name_COLOR_BLUE,   html_CLASS_COLOR_BLUE    },
  { ciGreen,  name_COLOR_GREEN,  html_CLASS_COLOR_GREEN   },
  { ciYellow, name_COLOR_YELLOW, html_CLASS_COLOR_YELLOW  },
  { ciOrange, name_COLOR_ORANGE, html_CLASS_COLOR_ORANGE  },
  { ciRed,    name_COLOR_RED,    html_CLASS_COLOR_RED     }
};

// *** Helpers ***

#define arraySize(_array) ( sizeof(_array) / sizeof(*(_array)) )
#define FSH_P(p) (reinterpret_cast<const __FlashStringHelper *>(p))

// *** Templates ***

// structure.id => structure.htmlClass
template < typename ID_TYPE, typename ITEM_TYPE> PGM_P getHtmlClassById(const ID_TYPE _itemId, ITEM_TYPE * _refArray, size_t _refArraySize) {
  PGM_P ptrItemName = NULL;
  ID_TYPE currentItemId;
  for (size_t i = 0x00; i < _refArraySize; i++) {
    memcpy_P(&currentItemId, &(_refArray[i].id), sizeof(ID_TYPE));
    if (_itemId == currentItemId) {
      ptrItemName = pgm_read_word(&_refArray[i].htmlClass);
      break;
    }
  }
  return ptrItemName;
}

// structure.id => structure.name
template < typename ID_TYPE, typename ITEM_TYPE> PGM_P getNameById(const ID_TYPE _itemId, const ITEM_TYPE * _refArray, size_t _refArraySize) {
  PGM_P ptrItemName = NULL;
  ID_TYPE currentItemId;
  for (size_t i = 0x00; i < _refArraySize; i++) {
    memcpy_P(&currentItemId, &(_refArray[i].id), sizeof(ID_TYPE));
    if (_itemId == currentItemId) {
      ptrItemName = pgm_read_word(&_refArray[i].name);
      break;
    }
  }
  return ptrItemName;
}

// structure.name => structure.id
template <typename ID_TYPE, typename ITEM_TYPE> ID_TYPE getIdByName(char  *_itemName, const ITEM_TYPE * _refArray, size_t _refArraySize) {
  ID_TYPE itemId = NULL;
  for (size_t i = 0x00; i < _refArraySize; i++) {
    PGM_P ptrItemName = pgm_read_word(&_refArray[i].name);
    if (!strcmp_P(_itemName, ptrItemName)) {
      memcpy_P(&itemId, &( _refArray[i].id), sizeof(ID_TYPE));
      break;
    }
  }
  return itemId;
}

// *** Functions ***

// Web page printer
void printPage(Stream& _stream, const dayId_t todayId) {
  char buffer[100];
  dayId_t   someDayId;
  colorId_t someColorId;

  // Print the header of the page and table
  snprintf_P(buffer, sizeof(buffer), PSTR("<!DOCTYPE HTML><html><head><meta charset=\"utf-8\">\n<title>%S</title></head><body>\n<table>\n"), text_SUPERHERO_SCHEDULE);
  _stream.print(buffer);
  
  _stream.print(FSH_P(html_CSS_TABLE));

  snprintf_P(buffer, sizeof(buffer), PSTR("<h2>%S</h2>\n<tr><th>Day</th><th>Socks color</th><tr>\n"), text_SUPERHERO_SCHEDULE);
  _stream.print(buffer);

  for (uint8_t i = 0; i < arraySize(daysOfWeek); i++) {

    // Just take every Day and his color as enum from PROGMEM array of structures
    memcpy_P(&someDayId,   &(daysOfWeek[i].id),      sizeof(dayId_t));
    memcpy_P(&someColorId, &(daysOfWeek[i].colorId), sizeof(colorId_t));

    // Fetch day's data from PROGMEM store
    PGM_P someDayName = getNameById(someDayId, daysOfWeek, arraySize(daysOfWeek));
    PGM_P someDayHtmlClass = getHtmlClassById(someDayId, daysOfWeek, arraySize(daysOfWeek));
    PGM_P isTodayHtmlClass = (todayId == someDayId) ? html_CLASS_IS_TODAY : text_EMPTY_STRING;

    // Fetch color's info from PROGMEM store
    PGM_P socksColorName = getNameById(someColorId, colorsOfSocks, arraySize(colorsOfSocks));
    PGM_P socksColorHtmlClass = getHtmlClassById(someColorId, colorsOfSocks, arraySize(colorsOfSocks));

    // Print out the table row
    snprintf_P(buffer, sizeof(buffer), PSTR("<tr class=\"%S %S\"><td>%S</td><td class=\"%S\">%S</td><tr>\n"), someDayHtmlClass, isTodayHtmlClass, someDayName, socksColorHtmlClass, socksColorName);
    _stream.print(buffer);
  }

  // Print the footer of the page and table
  snprintf_P(buffer, sizeof(buffer), PSTR("</table>\n<body><html>\n") );
  _stream.print(buffer);
}

void setup() {
  char today[] = "Sunday";
  dayId_t todayId;

  Serial.begin(115200);
  Serial.println(F("PROGMEM: Superhero's schedule page generator\n\n"));

  // Take today's id
  todayId = getIdByName<dayId_t, dayOfWeek_t>(today, daysOfWeek, arraySize(daysOfWeek));
  // Make HTML page
  printPage(Serial, todayId);
}

void loop() { }

 

alexbmd
Offline
Зарегистрирован: 15.01.2016

попробовал три варианта sadman41  из 2 поста в 1,8,9. прагма оптимизатор почему то ни на что не влияет.

1 вариант 161 байт рам

2 вариант 197. тут получается строки в рам? но почему разница только 36 байт ? там строки явно больше занимают. даже с учетом одинаковых строк

3 вариант 161. самый красивый получается.  при этом и строки и указатели во флэш

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Пропробуй найти отличия, объясни себе разность между

const char *s;

char const *s;

const char const *s;

 Ну и наморщи мосх и скажи, что из этого можно пхать в PROGMEM.

Справишьса?

alexbmd
Offline
Зарегистрирован: 15.01.2016

первые два одно и тоже

третий  ошибка

из этого ничего. такое можно const char * const s[] или такое const char s[] ну или как sadman41 структуру ну и тд

но Дед Симэн какое это имеет отношение к моему вопросу ? :)

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

alexbmd, дед просто опечатался. Он имел в виду вот так.

const char *s1 = "1";
char * const s2 = "2";
const char * const s3 = "3";

Ответь на его вопрос, тогда поговорим.

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Ворота пишет:

дед просто опечатался. Он имел в виду вот так.

Да, спасибо, я просто с планшета писал, да в звёздочках запутался. :) 

sadman41
Offline
Зарегистрирован: 19.10.2016

Три варианта, но более доступно. Можно в STRING_OF_NUMBERS докидывать по символу и смотреть, как растёт потребление ресурса и какого именно.

Serial.print() во втором варианте выдаст бред, однако это неважно - вопрос же в описании PGM-ресурса.

Первый и третий фактически эквивалентны - компилятор просто выжмет лишнюю воду из исходника.

Но, кстати, интересный момент - у меня на 1.6.11 при увеличении строки потребление RAM/ROM меняется скачком по 2 байта. Почему - не особо понятно, но я и не копался в asm, который генерирует компилятор.

#pragma GCC optimize ("O0")

#define FSH_P(p) (reinterpret_cast<const __FlashStringHelper *>(p))
#define STRING_OF_NUMBERS     "0123"

//#define V1
//#define V2
#define V3


// ****** #1 the string stay into PROGMEM 

/*
  Sketch uses 1,798 bytes (5%) of program storage space. Maximum is 32,256 bytes.
  Global variables use 214 bytes (10%) of dynamic memory, leaving 1,834 bytes for local variables.
*/
#ifdef V1
const char number[] PROGMEM = STRING_OF_NUMBERS;
#endif


// ****** #2 the string going to RAM, but the pointer stay into PROGMEM

/*
  Sketch uses 1,798 bytes (5%) of program storage space. Maximum is 32,256 bytes.
  Global variables use 220 bytes (10%) of dynamic memory, leaving 1,828 bytes for local variables.
*/
#ifdef V2
//const PROGMEM char* const number = STRING_OF_NUMBERS;
const char data[] = STRING_OF_NUMBERS;
const PROGMEM char* const number = data;
#endif


// ****** #3 the string and the pointer stay into PROGMEM both

/*
Sketch uses 1,798 bytes (5%) of program storage space. Maximum is 32,256 bytes.
Global variables use 214 bytes (10%) of dynamic memory, leaving 1,834 bytes for local variables.
*/
#ifdef V3
const PROGMEM char data[] = STRING_OF_NUMBERS;
const PROGMEM char* const number = data;
#endif

void setup() {
  Serial.begin(115200);
  Serial.print(FSH_P(number));
}
void loop() {}

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

Ворота пишет:

дед просто опечатался. Он имел в виду вот так.

Да, спасибо, я просто с планшета писал, да в звёздочках запутался. :) 

Ворота лучше всех в звёздочках понимает )))

alexbmd
Offline
Зарегистрирован: 15.01.2016

Ворота пишет:

 

const char *s1 = "1"; //const char,  * нет
char * const s2 = "2"; // наоборот
const char * const s3 = "3"; //оба const

а что мешает сразу ответить - 2 вариант 197. тут получается строки в рам? но почему разница только 36 байт ? там строки явно больше занимают. даже с учетом одинаковых строк

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Прости, но я не понял о чём этот поток сознания. Дед задал тебе просто вопрос - чем отличаются эти три строки. Ответь на него, тогда поговорим и про рам. А то, у меня ощущегие. что ты основ не понимаешь и из-за этого постоянно бредишь. Давай сначала разберёмся с основами, ладно? Отвечай нормально.

alexbmd
Offline
Зарегистрирован: 15.01.2016

я цветочки рисовать не умею.

mutable pointer to const char

const pointer to mutable char

const pointer to const char

пойдет?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Не пойдёт.

alexbmd пишет:

я цветочки рисовать не умею. 

А по-русски писать умеешь? Вот и напиши мне по-русски что в этих трёх строках и как ты это понимаешь. Скопипастить много ума не надо.

alexbmd пишет:

чем ответ выше не угодил 

mutable pointer to const char

const pointer to mutable char

const pointer to const char

Где был такой ответ выше? Номер поста? Где??? Ты я вижу слегка побрехать решил? И кого обмануть хочешь? Меня или себя? Подсказка - у меня нет проблем со строками.

alexbmd
Offline
Зарегистрирован: 15.01.2016

Ворота не тот возраст у меня чтоб брехать. есть дела понасущнее чем на форумах с незнакомыми людьми непристойными вещями заниматься. скопипастить что  прости? обижаешь Ворота

чуствую себя на скамье. давно таких пристальных допросов не было

по русски так по русски

можем менять указатель но не строку //тобишь const char, * не конст

можем менять строку но не указатель  //тобишь чар не конст, * конст

ничего не можем менять  // оба конст . вот что выше. вроде одно и тоже если не придераться ;)

удовлетворил любопытсво то хоть?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

alexbmd пишет:

Ворота не тот возраст у меня чтоб брехать

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

alexbmd пишет:

можем менять указатель но не строку //тобишь const char, * не конст

можем менять строку но не указатель  //тобишь чар не конст, * конст

ничего не можем менять  // оба конст . вот что выше. вроде одно и тоже если не придераться ;)

Тогда какие у тебя вопросы про то, что указатель пихается в прогмем, а строка нет? Или ты эти тонкости только сейчас узнал? Больше нет проблемы? Если проблема осталась, то постарайся внятно задать вопрос с примеро кода (не со ссылкой "как выше", а с конкретным примером кода конкретный вопрос - что именно тебе непонятно).

alexbmd пишет:

удовлетворил любопытсво то хоть?

Мне нелюбопытно, у меня нет проблем со строками. Проблемы у тебя и я, как могу, пытаюсь тебе помочь. Так что кончай хамить, а то сам будешь во всяём разбираться.

alexbmd
Offline
Зарегистрирован: 15.01.2016

сори Ворота не серчай яж не хамлю. не цепляйся к словам - зри суть.

 Больше нет проблемы? - есть проблемма.  2 вариант из 2 поста занимает 197 байт. тут получается строки в рам? но почему разница только на 36 байт больше ? там строки явно больше занимают. даже с учетом одинаковых строк

 

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

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

alexbmd пишет:
есть проблемма.  2 вариант из 2 поста занимает 197 байт.

Правда, не читаешь, что тебе пишут? Я же тебе написал

Ворота пишет:
Если проблема осталась, то постарайся внятно задать вопрос с примером кода (не со ссылкой "как выше", а с конкретным примером кода конкретный вопрос - что именно тебе непонятно).

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

Есть вопрос, задай его целиком, без отсылок к вариантам и постам - приведи код и задай внятный вопрос. Только код полностью, чтобы я мог его взять и скомпилировать и получить твои цифры по памяти.

alexbmd
Offline
Зарегистрирован: 15.01.2016

дело в том что код не мой тут, это другая тема.

вот код - http://arduino.ru/forum/programmirovanie/progmem-tricks#comment-439006 там три примера , я запускаю на 1.8.9 и получаю:

1 вариант: 161 байт рам

2 вариант: 197 байт рам. - тут я спрашиваю - получается строки(которые внутри структуры) в рам? но почему разница (с первым вариантом) только 36 байт ? там строки явно больше занимают. даже с учетом одинаковых строк и оптимизации?

3 вариант 161 байт. - тут я просто говорю что третий вариант, как по мне, красивше - самый красивый получается.  при этом и строки и указатели во флэш

PS: вроде все понятно было 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

alexbmd пишет:

вот код - http://arduino.ru/forum/programmirovanie/progmem-tricks#comment-439006 там три 

В то время, как хрен знает сколько раз повторялось

Ворота пишет:
постарайся внятно задать вопрос с примером кода (не со ссылкой 

Прости, друг. Удачи тебе, разбирайся сам.

alexbmd
Offline
Зарегистрирован: 15.01.2016
не думал что так тяжело открыть прямой линк
struct listUsr_t
{
  const char* phoneNum;
  const char* phonePass;
  const char* phonePDU;
};

const listUsr_t PROGMEM users[] =
{
  { "70000000000", "00000", "000000000000"},
  { "70000000001", "00001", "000000000000"},
  { "70000000002", "00002", "000000000000"},
};

void setup() {
  char incomingNumber[] = "70000000001";
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

  for (int i = 0; i < 3; i++) {
    //if (0x00 == strncmp(incomingNumber, (const char*) pgm_read_word(&(users[i].phoneNum)), 12)) 
    if (0x00 == strncmp_P(incomingNumber, (const char*) users[i].phoneNum, 12)) 
    {
      digitalWrite(13, HIGH);
    }
  }
}
void loop() {}

sandman41, может вы можете объяснить, здесь же строки не во флэш?, почему разница , с первым вариантом не стыкуется по количеству символов ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, как будет нечем заняться, так и вернусь к упражнениями с прогмем.

А так - особого желания объяснять, почему авто не едет, человеку, который намеренно не снимается с ручника, у меня нет. Пусть разбирает машину сам и изучает механическую схему, если времени дофига на то, чтобы придумывать нестандартные способы управления. 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

alexbmd пишет:

не думал что так тяжело открыть прямой линк

Когда тебя уже трижды попросили, сделать без ссылок? Ну, впредь думай, если есть чем, конечно.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

alexbmd пишет:
sandman41, может вы можете объяснить, здесь же строки не во флэш?, почему разница , с первым вариантом не стыкуется по количеству символов ?

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

alexbmd
Offline
Зарегистрирован: 15.01.2016

Ворота это детские капризы.

Qwone, вопрос почему строки в оперативки занимают меньше байт чем их длина это одевать валенки на голову?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

alexbmd пишет:
Qwone, вопрос почему строки в оперативки занимают меньше байт чем их длина это одевать валенки на голову?
При чем тут оперативка. Разберитесь для начала с валенками и ногами. А как разберетесь полегче будет

// Ну что бля это.
struct listUsr_t
{
  const char* phoneNum;
  const char* phonePass;
  const char* phonePDU;
};

const listUsr_t PROGMEM users[] =
{
  { "70000000000", "00000", "000000000000"},
  { "70000000001", "00001", "000000000000"},
  { "70000000002", "00002", "000000000000"},
}
// Ну почему не написать так
struct listUsr_t
{
  const char phoneNum[12];
  const char phonePass[6];
  const char phonePDU[13];
};

const listUsr_t PROGMEM users[] =
{
  { "70000000000", "00000", "000000000000"},
  { "70000000001", "00001", "000000000000"},
  { "70000000002", "00002", "000000000000"},
};

 

alexbmd
Offline
Зарегистрирован: 15.01.2016

второй вариант массивы строк во флэш. Так?
Первый строки в оперативки. Так?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Первый вариант это человек написавший дибил и все что написал дальше можно направлять в унитаз. На что Вам и написали выше.

ПС:http://lurkmore.to/Корованы

alexbmd
Offline
Зарегистрирован: 15.01.2016

Видно без этих веществ не разобраться в этом вопросе

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Ты скажи, чотыхошь, конкретно?  Теорию разводить не будут, а пацкажут как сделать. 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

DetSimen пишет:

Ты скажи, чотыхошь, конкретно?  

Патрындеть.

alexbmd
Offline
Зарегистрирован: 15.01.2016

Так Дед Симэн. Вы задали вопрос. Я ответил. Ну про звездочки. Ну а до этого я же задал конкретный вопрос .
Первый и третий варианты ТС хранят все во флэш . И занимают у меня в 1.8.9 161 байт.
Второй вариант поинтеры во флэш а строки в оперативке и занимает 197 байт. Разница 36 байт. Но там же длина строк больше чем 36 даже если предположить что одинаковые строки по одному адресу.
Ежеле не затруднит растолкуйте плиз

nik182
Offline
Зарегистрирован: 04.05.2015

Ну вот что ты всё людей дергаешь? Открой сгенерированный ассемблерный листинг и посмотри как распределены по памяти все определения. Да ещё несколько раз с разной оптимизацией и нам расскажешь. 

alexbmd
Offline
Зарегистрирован: 15.01.2016

Ник я на первых этажах понимания си а вы мне листинг ассемблера , это не то что этаж выше, это другой подъезд :)

b707
Offline
Зарегистрирован: 26.05.2017

alexbmd пишет:
Первый и третий варианты ТС хранят все во флэш . И занимают у меня в 1.8.9 161 байт. Второй вариант поинтеры во флэш а строки в оперативке и занимает 197 байт. Разница 36 байт.

У Садмана там расклад по байтам прописан - первый и третий вариант у него занимают 21 байт, а второй 65. Разница 44 байта. Вот это правильная и понятная цифра, точно совпадающая с числом символов в строках. А почему у тебя 36 байт - я не знаю.

nik182
Offline
Зарегистрирован: 04.05.2015

Ой да ладно. При компиляции во временной папке появляется куча файлов. Там есть файл и листингом. Для его понимания ассемблер знать не обязательно. Достаточно прочитать о структуре это файла и главное в нём дан расклад по занимаемой памяти всеми элементами программы. Можно точно сказать что сколько занимает. И не будет разночтений. То что пишет в конце компиляции среда, это вся выделенная память. Ты говоришь об конкретном элементе и что бы быть точно уверенным что разница в размере связана только с исследуемым элемнтом, а не с какими то дополнительными оптимизациями, лучше следить за размером там. Иначе все разговоры тут не имеют конкретной привязки и выглядят, мягко говоря, лишёнными практического выхода. И, кстати, ответ на вопрос деда сразу был бы виден в листигах по расположению элементов записей.

alexbmd
Offline
Зарегистрирован: 15.01.2016

num = 3*11 = 33 bytes

pass = 3*5 = 15 bytes

pdu = 3*12 = 36 bytes / если оптимизируем на один адресс то 12 б

total = 33+15+36 = 84 b / если оптимизируем то 60 b

как эта цифра может совпадать с 44 как у Садмана?

 

Ник, как называется файл-листинг ? только в папке preproc  __attribute__((__progmem__))  чтото относящиеся к памяти. но никаких цифр

еще раз проверил на дефолтных (из коробки) настройках 1,8,9

1 и 3 вариант 21 байт как у Садмана но вот второй 59. как в 38 байт запихнуть 60 б строк непонимаю 

b707
Offline
Зарегистрирован: 26.05.2017

alexbmd пишет:

num = 3*11 = 33 bytes

pass = 3*5 = 15 bytes

pdu = 3*12 = 36 bytes / если оптимизируем на один адресс то 12 б

total = 33+15+36 = 84 b / если оптимизируем то 60 b

как эта цифра может совпадать с 44 как у Садмана?

 

"Как я насчитал 44 байта" :

каждая пара num и pass лежат в одной области, занимая всего 11 байт. В сумме - 33 байта. Плюс pdu один раз. Я. правда, обсчитался и насчитал в pdu 11 нулей = 33 + 11 = 44

Если их 12 - гипотеза неверна.

alexbmd
Offline
Зарегистрирован: 15.01.2016

хм, а ведь точно num and pass могут занимать одну область просто стартавая точка для поинтера будет разная. спасибо за идею. но мне кажется оптимизатор до такого не додумается. но конечно могу ошибаться.

nik182
Offline
Зарегистрирован: 04.05.2015

map файл автоматом выдается для ARM ядер. Для просмотра AVR надо использовать avr-objdump . Эта программа лежит hardware/tools/avr/bin/avr-objdump в папке установки среды. Использовать

avr-objdump -dS  *.elf > list.map

*.elf - файл полученный в результате генерации, list.map имя выходного файла (может быть любым)

Очень забавно смотреть на текст файла, который компилируется. Этот текст совсем не похож на исходный. Присутствует и main и init и прочие.