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

 
 
> pgm_read_xxxx и PROGMEM в winavr20071221, В листинге нет инструкций LPM
Steel_monkey
сообщение Mar 3 2008, 17:18
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 12-05-07
Из: Северная Венеция
Пользователь №: 27 684



Пишу простейшую програмку. Хочу запихать небольшой массив во флэш, и читать оттуда данные без записи всего массива в ОЗУ.

Мои действия?
1. Присоединяю библиотеку avr/pgmspace.h
2. Обьявляю массив:
uint16_t left[] PROGMEM = {60,0x93,45,70};
3. В программе читаю из массива:
REQUIRED_LEFT=pgm_read_word(&left[1]);
Переменная, куда читаю, точно такого же типа, что и в массиве.
Смотрю в файл main.lst

254:main.c **** REQUIRED_LEFT=pgm_read_word(&left[1]);
905 .LM96:
906 03b0 80E0 /* #NOAPP */
907 03b2 90E0 mov r18,r26
908 03b4 FC01 subi r18,lo8(-(1))
909 sts point.1941,r18
911 03b8 5491 .LM97:
912 cpi r18,lo8(4)
913 brlo .L50
915 03ba 5093 0000 .LM98:
916 03be 4093 0000 sts point.1941,__zero_reg__


В файле нет инструкции LPM.

4. Убираем закорючку:
REQUIRED_LEFT=pgm_read_word(left[1]);

Тогда это превращается в

254:main.c **** REQUIRED_LEFT=pgm_read_word(left[1]);
905 .LM96:
906 03b0 E3E9 /* #NOAPP */
907 03b2 F0E0 mov r18,r26
908 subi r18,lo8(-(1))
909 03b4 8591 sts point.1941,r18
911 .LM97:
912 cpi r18,lo8(4)
913 brlo .L50
915 03bc 8093 0000 .LM98:


Инструкция LPM в коде так и не появилась.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
_Pasha
сообщение Mar 4 2008, 15:01
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Сергей Борщ @ Mar 4 2008, 12:32) *
Я думаю, в обоих случаях j будет выкинуто, а цикл заменен на бесконечный.

Если бы было написано j < 255, то бесконечный цикл получился бы только если в опциях компилятора задано "char по умолчанию знаковый". В противном случае оба цикла вроде как должны бы получиться одинаковыми. Или я что-то упустил?


1. Ошибся я, j<254
2. uint8_t обрабатывается как 16-битовое, отсюда увеличение кода.

3. По поводу Lpm/Elpm, данный факт может сослужить плохую службу только в граничных ситациях, когда надо оценивать объем кода, а тут вдруг массив то есть / то нету. Это плохо. Имхо, единственный выход - избежать константных выражений.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 4 2008, 16:44
Сообщение #3


Гуру
******

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



Цитата(_Pasha @ Mar 4 2008, 17:01) *
1. Ошибся я, j<254
Попытка не защитана wink.gif signed char всегда меньше 254 (за исключением платформ, где char имеет размер более 8 битов).
Цитата(_Pasha @ Mar 4 2008, 17:01) *
2. uint8_t обрабатывается как 16-битовое, отсюда увеличение кода.
Вообще-то uint8_t - это синоним unsigned char на платформах, где char 8 -битный и не определен для платформ, где 8-битные данные не поддерживаются. Ну а дальше действуют правила языка - в арифметических операциях unsigned/signed char приводится (минимум) к int, а потом оптимизатор может выкинуть лишние операции.


--------------------
На любой вопрос даю любой ответ
"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
singlskv
сообщение Mar 4 2008, 19:50
Сообщение #4


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Сергей Борщ @ Mar 4 2008, 19:44) *
Вообще-то uint8_t - это синоним unsigned char на платформах, где char 8 -битный и не определен для платформ, где 8-битные данные не поддерживаются.

небольшой OFF:
а кто-нить знает как адекватно заставить Gcc воспринимать значения
case(...) в switch как восмибитные ?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 13th August 2025 - 00:58
Рейтинг@Mail.ru


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