Flash-массив в качестве параметра

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Встал на лапы
Аватара пользователя
Сообщения: 117
Зарегистрирован: Чт фев 28, 2008 23:54:35
Откуда: Воскресенск, МО

Сообщение Synergetik »

Здравствуйте!

Нужно хранить большой массив (больше 100 байт) в Attiny2313. Оперативки не хвата (всего доступно 128 байт SRAM), приходится на flash'е. Этот массив (точнее его указатель на первый элемент) должен передаваться в качестве параметра в функцию обработки массива. Массив у меня назван, допустим, flash int mass[1, 2, 3, ...].

Собственно сама проблема: если в функции-обработчике задать параметры так: void read_mass(int mel[]), то ругается компилятор (CodeVisionAVR 2.03). Если так: void read_mass(flash int mel[]), то начиная с n-го элемента массива считывание этого самого элемента даёт сбой и программа как бы подвисает. Если же тело функции поместить сразу в main, то проблем нет. Это повторяется как в Протеусе, так и в железе.

Вопрос: можно ли каким-нибудь образом организовать так, чтобы:
1. В Attiny2313 можно было бы хранить массивы подобных размеров (до двух-трёх, может чуть больше штук)
2. Обработка выполнялась бы в отдельной функции (то есть передать в функцию в качестве параметра массив, хранящийся в flash, eeprom или ещё где-нибудь)
3. Происходило правильное считывание элементов массива.
4. Хотелось бы узнать причину происходящего.

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

Заранее благодарю за ответ.
Контактная информация:
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

Что мешает сделать что-то вроде такого:

Код: Выделить всё

flash int mel[5]={1,2,3,4,5};

void read_mass(int *mel)
{
  int a;
  a=*mel;
  ...
  *mel++;
}
PS. Ногами не пинать, давно на CVAVR не писал. И его синтаксис подзабыл.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

mr.Kirill писал(а):Что мешает сделать что-то вроде такого:

Код: Выделить всё

flash int mel[5]={1,2,3,4,5};

void read_mass(int *mel)
{
  int a;
  a=*mel;
  ...
  *mel++;
}
PS. Ногами не пинать, давно на CVAVR не писал. И его синтаксис подзабыл.
наверное все-таки void read_mass(flash int *mel)...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 316
Зарегистрирован: Пт апр 17, 2009 22:45:42
Откуда: Minsk

Сообщение maglev »

ARV писал(а):наверное все-таки void read_mass(flash int *mel)...
разумеется. Более того, указатели на Flash, EEPROM и RAM имеют полное право иметь различную разрядность и между собой несовместимы.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Мучитель микросхем
Аватара пользователя
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

ARV писал(а):наверное все-таки void read_mass(flash int *mel)...
Если изначально Вы объявили массив как flash, то зачем в функции это указывать?
Функция может работать (и будет) с любым массивом, будь то Flash, EEPROM или RAM.
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

maglev писал(а):разумеется. Более того, указатели на Flash, EEPROM и RAM имеют полное право иметь различную разрядность и между собой несовместимы.
Наверное стоит напомнить что это AVR, и мало того - CodeVisionAVR.
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 316
Зарегистрирован: Пт апр 17, 2009 22:45:42
Откуда: Minsk

Сообщение maglev »

mr.Kirill писал(а):
ARV писал(а):наверное все-таки void read_mass(flash int *mel)...
Если изначально Вы объявили массив как flash, то зачем в функции это указывать?
Функция может работать (и будет) с любым массивом, будь то Flash, EEPROM или RAM.
С CodeVision я никогда не работал, но не представляю, как он может обойти эту проблему. Размер указателей разный, способ доступа к данным разный, функция не может этого знать.
IAR честно даст ошибку о том, что типы (int * и __flash int*) несовместимы. С EEPROM будет аналогично, и это правильно.
Контактная информация:
Мучитель микросхем
Аватара пользователя
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

Такая вот особенность именно компилятора CVAVR, что нужно только в инициализации массива указать тип (по-умолчанию RAM, flash или eeprom) и дальше к этому можно не возвращаться.
Встал на лапы
Аватара пользователя
Сообщения: 117
Зарегистрирован: Чт фев 28, 2008 23:54:35
Откуда: Воскресенск, МО

Сообщение Synergetik »

mr.Kirill писал(а):Такая вот особенность именно компилятора CVAVR, что нужно только в инициализации массива указать тип (по-умолчанию RAM, flash или eeprom) и дальше к этому можно не возвращаться.
В том-то и дело, что если указать только при инициализации массива, то CodeVisionAVR выдаёт: "function argument #1 of type 'flash int[11]' is incompatible with required parameter of type 'int []'". Причём, если flash добавить и в функцию, то ошибок при трансляции нет, но только массив начиная с некоторого символа читается некорректно - у меня, например, начинается воспроизведение мелодии и подвисает, точнее выдаёт заведомо неверную длинную ноту, то есть элемент массива извращается. Аналогично было, когда в символьный массив пытался запихнуть больше 256 символов - тоже происходила порча элементов.

mr. Kirill, вот этот кусок не понял:

Код: Выделить всё

  int a;
  a=*mel;
  ...
  *mel++; 
Если меется в виду локальной переменной присваивать по очереди элементы массива, то это не сработало - проверил. Явное указание длины массива тоже не помогло.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

Улыбнула великая совместимость языка Си - WinAvr, CVAVR, ICC, IAR... ну просто абалдеть, а если переносить, то оказывается у каждого свои прелести :)) .



------------------------------
Я уже десять лет смеюсь.
------------------------------
-------------
Мучитель микросхем
Аватара пользователя
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

__Alexander писал(а):Улыбнула великая совместимость языка Си - WinAvr, CVAVR, ICC, IAR... ну просто абалдеть, а если переносить, то оказывается у каждого свои прелести :))
Язык Си - он хоть и платформо-независимый, но в тоже время компиляторо-зависимый :)))

Synergetik , выложите проект, если это не супер секретно.
CVAVR порой жутко чудит.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

1. если тип указателя в параметре функции не указать явно, что он flash, то внутри функции (если обойти недовольство компилятора несовпадением типов) этот указатель будет работать с ОЗУ - оно вам надо?

2. заметил, что изначальный код с "сюрпризом". напомню его:

Код: Выделить всё

flash int mel[5]={1,2,3,4,5}; 

void read_mass(flash int *mel) 
{ 
  int a; 
  a=*mel; 
  ... 
  *mel++; 
}
что-то мне подсказывает, что многие считают, будто mel в параметре функции и массив mel - это одно и то же. однако, это не так. обращаться к функции read_mass надо примерно так:

Код: Выделить всё

d = read_mass(&mel[1]);
или так:

Код: Выделить всё

d = read_mass(mel);
P.S. после сказанного задумался: а стало ли понятнее после моих пояснений? :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

Synergetik писал(а): ... вот этот кусок не понял:

Код: Выделить всё

  int a;
  a=*mel;
  ...
  *mel++; 
Если меется в виду локальной переменной присваивать по очереди элементы массива, то это не сработало - проверил...
И не сработает, надо не а Это инкремент указателя, в первом случае - значения, на которое он указывает. Странно, что никто не обратил на это внимания...
Работайте с элементами массива через цикл и будет Вам счастье...
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Встал на лапы
Аватара пользователя
Сообщения: 117
Зарегистрирован: Чт фев 28, 2008 23:54:35
Откуда: Воскресенск, МО

Сообщение Synergetik »

Уф, разобрался! А ответ дан был почти сразу. Ещё mr.Kirill'ом, когда он написал: "void read_mass(int *mel)". Всю жизнь считал, что "int mel[]" и "int *mel" в параметре функции одно и то же. Оказывается, это так для оперативки, но не для flash'а. Если не хватает оперативки для массива и нужно использовать flash, то рецепт такой:
1. Указываем тип массива: flash int mel[]= {1, 2, 3, ...};
2. В объявлении функции обработки пишем: void read_mel(flash int *mel) {};. "Писанина" вроде "flash int mel[]" не прокатит.
3. Вызывать функцию следующим образом: read_mel(mel);

Спасибо всем, кто принимал участие в беседе, и особенно mr.Kirill, кто первый предложил правильный вариант, и ARV, благодаря последнему посту которому я почему-то сразу сообразил, в чём может быть дело. Заинтересованным прилагаю проект.

А теперь главный вопрос: почему для ОЗУ выражения "int mel[]" и "int *mel" идентичны, а для flash нет? Ведь по идее и там и там создаётся временная переменная указатель (которая, кстати, по той же идее, всё равно где может размещаться, а КодВижн ругается, если не в flash'е), которая хранит адрес нулевого элемента массива. И впоследствии обращаться к нему можно как к имени массива mel.

P.S. В железе ещё не проверял. Но Протеус ещё ни разу меня не подводил, так что почти наверняка заработает и там.
Вложения
05.rar
(82.79 КБ) 248 скачиваний
Контактная информация:
Мучитель микросхем
Аватара пользователя
Сообщения: 438
Зарегистрирован: Вт сен 25, 2007 19:40:26
Откуда: Челябинск

Сообщение mr.Kirill »

Ради интереса пришлось скачать CVAVR версии 2.
Прикольно, CVAVR начал правильно ругаться, когда из

Код: Выделить всё

void read_mel(flash int *mel)
убираем flash и оставляем

Код: Выделить всё

void read_mel(int *mel)
Выходит что либо я немного ошибся с CVAVR, хотя давным давно наступал на такие грабли в версии 1..., либо это поправили :)
Ну да ладно, главное что разобрались и помогли человеку :)
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

mr.Kirill писал(а): Язык Си - он хоть и платформо-независимый, но в тоже время компиляторо-зависимый :)))
От чего он зависимый? Ведь в тысячах книг пишут именно про Язык С, а не по Язык С для АВР или ПИК, и тем более не пишут что для CVAVR или IAR.

И если CVAVR понимает ROM, а IAR понимает __flash... то он уже не универсальный. А это плохо. :))


------------------------------
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»