реклама на сайте
подробности

 
 
> Запись в EEPROM, пишу структуру, а попадает содержимое flash'a
GoodNews
сообщение Mar 1 2010, 20:19
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Подскажите пожалуйста, что я делаю неправильно? Имеется структура, определенная как массив из 51 элемента для хранения в eeprom. Пытаюсь записать данные в один из элементов массива, однако в итоге получаю кусок flash'a в eeprom. Почему?
CODE

typedef struct _chInMem {
uint32_t returnValue;
} chInMem;
chInMem channelMem[] EEMEM = {
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{0}, {0}, {0}, {0}, {0},
{107900000}
};
...
chInMem channelInMem;
eeprom_busy_wait();
channelInMem.returnValue = channel_freq;
eeprom_write_block(&channelInMem, &channelMem, sizeof(channelMem));
...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
GoodNews
сообщение Mar 4 2010, 07:32
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 88
Регистрация: 12-01-09
Из: Minsk (BY)
Пользователь №: 43 259



Большое спасибо за помощь! Я поправки внёс согласно вашим замечаниям. По поводу значения следующей свободной ячейки. Я так понимаю, что я попутал src с dst. Т.е. вначале указываем откуда извлекаем данные, а затем - куда их пишем. Получается, что вначале данные находятся в RAM по адресу channel_number, а помещены должны быть в адрес, где находится next_free_channel, я так понимаю?

Собственно по поводу С++ я думал что он не применим относительно 8-битных контроллеров (хотя бы в данном случае с AVR-ками), поэтому и начал изучение платформы с применением именно C. По поводу области видимости - я в принципе стараюсь все переменные использовать локально. extern использую только когда действительно необходимо вызвать функцию (использовать переменную) из другой подпрограммы (ну или объявить её вобще в хедере).
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 4 2010, 09:00
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(GoodNews @ Mar 4 2010, 09:32) *
По поводу значения следующей свободной ячейки. Я так понимаю, что я попутал src с dst. Т.е. вначале указываем откуда извлекаем данные, а затем - куда их пишем. Получается, что вначале данные находятся в RAM по адресу channel_number, а помещены должны быть в адрес, где находится next_free_channel, я так понимаю?
Нет. Тут дело в разных адресных пространствах. У AVR 4 адресных пространства: I/O, ОЗУ, флеш и EEPROM. В каждом из них адреса начинаются с 0. И для доступа в каждое используются разные приемы(команды). gcc, в отличие от других компиляторов для AVR, не имеет поддержки нескольких адресных пространств. Поэтому авторы avr-gcc поместили все адресные пространства avr в разные места одного линейного адресного пространства gcc. Например, нулевой физический адрес ОЗУ попадает в логический адрес 0x00800000, нулевой физический адрес EEPROM попадает в логический адрес 0x00810000. В процессе линковки 2 старших байта логического адреса отбрасываются. Но сам компилятор не имеет возможности различать эти адресные пространства, он считает все переменные размещенными в ОЗУ. Поэтому для доступа к другим адресным пространствам пришлось создать макросы eeprom_read_???(), eeprom_write_????(), pgm_read_???().
Вот и смотрите - ваша переменная NEXT_FREE_CHANNEL объявлена с атрибутом EEMEM. значит попадает в адрес, скажем 0x008100C8. Вы обратились к ней без макроса, т.е. NEXT_FREE_CHANNEL = channel_number эквивалентно *(uint32_t *)0x008100C8 = channel_number. Это будет скомпилировано в команду ST (STD) - компилятор считает все переменные принадлежащими ОЗУ. После линковки старшие байты отбросятся и получится, что ваша строка эквивалентна *(uint32_t *)0x00C8 = channel_number. Итого, вместо желаемой записи в eeprom произошла запись в ОЗУ. И отследить эту ошибку средствами компилятора, увы, невозможно. Ждем появления 5.x версии gcc, в котрой заявлена поддержка разных адресных пространств.
Цитата(GoodNews @ Mar 4 2010, 09:32) *
Собственно по поводу С++ я думал что он не применим относительно 8-битных контроллеров (хотя бы в данном случае с AVR-ками)
Если без фанатизма - то вполне применим. Многие пользуются, не жалуются. Жалуются те, кто не пользовался или не умеет.
Цитата(GoodNews @ Mar 4 2010, 09:32) *
По поводу области видимости - я в принципе стараюсь все переменные использовать локально. extern использую только когда действительно необходимо вызвать функцию (использовать переменную) из другой подпрограммы (ну или объявить её вобще в хедере).
Да, но сдесь не об области видимости, а о связывании. Попробуйте в другом файле объявить еще одну константу uint8_t USER_CHANNELS_AVAILABLE = 50 - в С получите по копии переменной (пусть даже константной) в каждом файле и ошибку линковки. В С++ будет все нормально.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- GoodNews   Запись в EEPROM   Mar 1 2010, 20:19
- - Сергей Борщ   Цитата(GoodNews @ Mar 1 2010, 22:19) Поче...   Mar 2 2010, 08:33
|- - GoodNews   Цитата(Сергей Борщ @ Mar 2 2010, 10:33) П...   Mar 2 2010, 08:53
|- - Сергей Борщ   Цитата(GoodNews @ Mar 2 2010, 10:53) Прос...   Mar 2 2010, 11:12
|- - GoodNews   Цитата(Сергей Борщ @ Mar 2 2010, 13:12) К...   Mar 2 2010, 21:37
|- - Сергей Борщ   Цитата(GoodNews @ Mar 2 2010, 23:37) Когд...   Mar 2 2010, 23:08
- - Yaumen   Задача несколько туманная, тем более что начинаете...   Mar 2 2010, 12:22
|- - Сергей Борщ   Цитата(Yaumen @ Mar 2 2010, 14:22) Задача...   Mar 2 2010, 12:43
- - GoodNews   Я посмотрел вывод. Там как ни странно всё нормальн...   Mar 3 2010, 13:58
|- - Сергей Борщ   Полагаю, ошибка здесь:Код NEXT_FREE_CHANNEL = ...   Mar 3 2010, 16:16
- - GoodNews   Я так понимаю, что next_free_channel = channel_num...   Mar 4 2010, 09:43
|- - Сергей Борщ   Цитата(GoodNews @ Mar 4 2010, 11:43) Я та...   Mar 4 2010, 10:52
|- - GoodNews   Цитата(Сергей Борщ @ Mar 4 2010, 12:52) Д...   Mar 4 2010, 11:20
|- - Сергей Борщ   Цитата(GoodNews @ Mar 4 2010, 13:20) А во...   Mar 4 2010, 11:44
- - GoodNews   В общем что-то получилось (всмысле компилятор пока...   Mar 4 2010, 13:09
- - Сергей Борщ   Цитата(GoodNews @ Mar 4 2010, 15:09) P.S....   Mar 4 2010, 13:37
- - Сергей Борщ   Цитата(Сергей Борщ @ Mar 4 2010, 16:37) П...   May 19 2010, 14:53


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 16:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01394 секунд с 7
ELECTRONIX ©2004-2016