|
|
  |
Порты AVR и компиляция |
|
|
|
Sep 26 2007, 15:26
|
Группа: Участник
Сообщений: 12
Регистрация: 19-05-07
Пользователь №: 27 828

|
Очень долго работал с разными МК(51, в основном ARM) решил попробовать AVR вопросы: У этих AVR что нет удобного побитового доступа к портам? Какой компилятор делает наиболее красивый код?
|
|
|
|
|
Sep 26 2007, 16:01
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(allexmor @ Sep 26 2007, 18:26)  У этих AVR что нет удобного побитового доступа к портам? есть, на запись - cbi/sbi на чтение - sbic/sbis но это будет "очень" побитовый доступ. Такого как в ARM - IOSET/IOCLR в AVR нет. Зато есть и хорошая сторона - такого "гонива" как в ARM - потребность применять 2 команды для записи конкретного значения в порт - в AVR'е тоже нет. Пишете сразу действующее значение (пример): PORTB = 0x55; // на выводах порта 0x55 PORTB = 0xAA; // на выводах порта 0xAA Цитата Какой компилятор делает наиболее красивый код? IAR
|
|
|
|
|
Sep 26 2007, 16:38
|

Частый гость
 
Группа: Участник
Сообщений: 148
Регистрация: 23-02-07
Пользователь №: 25 618

|
Цитата(allexmor @ Sep 26 2007, 18:26)  Очень долго работал с разными МК(51, в основном ARM) решил попробовать AVR вопросы: У этих AVR что нет удобного побитового доступа к портам? CVAVR дает побитовый доступ к портам (правда в некоторых процах не ко всем) Код PORTB.0 = 1; DDRB.3 = 0;
|
|
|
|
|
Sep 26 2007, 16:48
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата такого гонива как потребность применять 2 команды для записи конкретного значения в порт как в ARM в AVR'е тоже нет. Хм... Вы слегка заблуждаетесь, если говорите об LPC. В них совсем необязательно использовать IOSET/IOCLR - Вы можете просто модифицировать (чтение-модификация-запись) регистр IOPIN Writing to the IOPIN register stores the value in the port output register, bypassing the need to use both the IOSET and IOCLR registers to obtain the entire written value. This feature should be used carefully in an application since it affects the entire port. Чтение-модификация-запись возможно более привычная операция, но она неатомарна и без FIO дороже по времени (шина-то периферийная узковата). Неатомарность заставляет задумываться об использовании портов в обработчиках прерываний.
--------------------
aka Vit
|
|
|
|
|
Sep 27 2007, 04:51
|
Группа: Участник
Сообщений: 12
Регистрация: 19-05-07
Пользователь №: 27 828

|
Цитата(defunct @ Sep 27 2007, 02:19)  Ну... В реалиях этой фичей особо не попользуешься, особенно когда всего 1 порт, и после включения периферии остаются разрозненные, хаотически пронумерованные пины... IOSET/IOCLR the only way to go в этом случае.
В AVR'е те же 32 пина разбиты на 4 порта, отсюда возможность проектирования девайса так, что можно обойтись без чтения-модификации-записи. Ну с портами все понятно. На какой среде разработки остановиться? в CodeVAVR - можно ли в проект загнать не один файл?
|
|
|
|
|
Sep 27 2007, 05:08
|
Группа: Участник
Сообщений: 12
Регистрация: 19-05-07
Пользователь №: 27 828

|
Цитата(sensor_ua @ Sep 27 2007, 09:04)  Фаворит IAR. WinAVR вполне юзабилен, но когда нужно чуть более, чем дрыгать пинами, то с нуля нужно тратить больше времени для эффективного использования. CV - ничего не скажу, т.к. не пользую. Замечу только, что в последнее время автор предупреждает пользователей, что леченный продукт распознаётся и может не так чтобы совсем не работать, а генерировать неадекватный результат. Где можно IAR скачать? ну и крэк?
|
|
|
|
|
Sep 27 2007, 12:58
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(defunct @ Sep 27 2007, 12:56)  Ну почему же. Упомянутый WinAVR очень не плох, к тому же бесплатный. "глобальное" отличие между WinAVR и IAR лишь в использовании различных адресных пространств. В IAR это сделано на порядок лучше - __flash, __eeprom. Ну да - __flash, __eeprom на порядок превосходят EEMEM, PROGMEM  По теме - если дрыгать ножками, то любой. Если что-то серьезнее то WinAvr. Под него пишут сотни тысяч человек и в отличии от IAR их труды доступны в сети. Не придется адаптировать, бери и пользуйся. С ИАР-ом же придется в большинстве случаев решать все проблемы самому - типа файловых систем и т.п. Ну или адаптировать код от Winavr  У ИАРа одно преимущество - ассемблер встраивать легче.
Сообщение отредактировал Qwertty - Sep 27 2007, 13:00
|
|
|
|
|
Sep 27 2007, 14:23
|

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

|
Цитата(Qwertty @ Sep 27 2007, 15:58)  Ну да - __flash, __eeprom на порядок превосходят EEMEM, PROGMEM  На два. defunct объяснил почему. Цитата(Qwertty @ Sep 27 2007, 15:58)  С ИАР-ом же придется в большинстве случаев решать все проблемы самому - типа файловых систем и т.п. Ну или адаптировать код от Winavr  1) При наличии опыта адаптация происходит быстро. 2) Все равно придется что-то править, а в процессе адаптации глубже вникаешь в чужие исходники. 3) По закону подлости нужный код будет под какой-нибудь третий компилятор и вообще не под AVR. 4) По размеру кода ИАР сильно обгоняет WinAVR (по личному опыту, последний эксперимент - AES loader AVR231 буквально вчера. У ИАРа остается свободное место в 2К области, у WinAVRа код вылазит почти на 1К). Цитата(Qwertty @ Sep 27 2007, 15:58)  У ИАРа одно преимущество - ассемблер встраивать легче. С точностью до наоборот. Вот уж что-что, а инлайн асм у WinAVR шикарный, а у IAR вообще никакой и они сами его не рекомендуют. А в обработке отдельного асм-исходника возможности у них практически одинаковые.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 27 2007, 14:48
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 27 2007, 17:10)  Вы хотите сказать, что в WinAvr уже можно EEMEM или PROGMEM переменную просто взять и присвоить обычной переменной без использования read_eeprom_byte и прочих вспомогательных функций? В IAR можно. Цитата На два. defunct объяснил почему. А как дела обстоят в IAR c обратной операцией, те присвоением переменной __flash или __eeprom значения обычной переменной ? Цитата 4) По размеру кода ИАР сильно обгоняет WinAVR (по личному опыту, последний эксперимент - AES loader AVR231 буквально вчера. У ИАРа остается свободное место в 2К области, у WinAVRа код вылазит почти на 1К). Задачи таки разные бывают, я уже предлагал вариант задачки для сравнения IAR и WinAVR, но никто не соглашается
|
|
|
|
|
Sep 27 2007, 15:27
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 27 2007, 19:14)  Отлично, Код __flash char flChar; __eeprom char eeChar; char Ch;
int main( void ) { eeChar = Ch; // <--- OK <--- сколько времени выполняется эта операция ??? flChar = Ch; // <-- Error [Ta015] Cannot write to flash memory <--- запись не из бутлодера ??? eeChar = Ch , Вам не кажется что такая запись просто вводит в заблуждение программера ? т.е. он то думает что присвоил значение и побежал дальше, а в реальности мы там ждем как минимум 3,5мс. Привыкнув к такой простоте, программер не будет такое присваивание употреблять например в прерываниях ? ИТД...
|
|
|
|
|
Sep 27 2007, 15:33
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Sep 27 2007, 18:27)  eeChar = Ch , Вам не кажется что такая запись просто вводит в заблуждение программера ? Это был просто ответ на ваш вопрос. А так мне кажется, что одиночному "чару" вне функции вообще нечего делать. Сколько-нибудь уважающий себя "программер" волен объявить структуру с подобающим именем, которое будет кричать о том, что поля располагаются в eeprom. Цитата Привыкнув к такой простоте, программер не будет такое присваивание употреблять например в прерываниях ? Это из оперы - программисты не ищут простых путей? Или как понимать? Давайте также покритикуем возможность винды выделять гигабайтные массивы, ведь программист выделивший такой массив может думать, что весь массив лежит в ОП. PS: к сожалению мне редко приходится наслаждаться возможностями IAR'а, потому что конечный продукт у меня собирается в WinAvr. При портировании с IAR'а на WinAvr частенько приходится поматериться  в местах работы со строками во флеш и данными в eeprom.
|
|
|
|
|
Sep 27 2007, 16:23
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(defunct @ Sep 27 2007, 17:10)  Вы хотите сказать, что в WinAvr уже можно EEMEM или PROGMEM переменную просто взять и присвоить обычной переменной без использования read_eeprom_byte и прочих вспомогательных функций?
В IAR можно. Согласен, можно. И в CV можно. А еще в CV можно сделать так - PORTB.1=1. Следуя Вашей логике- "CV на порядок превосходит IAR". Меня лично не напрягают eeprom_read_byte(), зато помогают больше работать с указателями, что в итоге дает более быстрый и компактный код. При портировании проектов с IAR результирующий размер практически одинаков, но как-то было преимущество WinAvr процентов на 10. И главное - мне не надо искать кряки, пилюли, пургены успокаивать совесть типа - ничего, у них и так денег много... Чистая совесть это тоже немало.
|
|
|
|
|
Sep 27 2007, 16:32
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 27 2007, 19:33)  Это был просто ответ на ваш вопрос. А так мне кажется, что одиночному "чару" вне функции вообще нечего делать. Сколько-нибудь уважающий себя "программер" волен объявить структуру с подобающим именем, которое будет кричать о том, что поля располагаются в eeprom. Вопрос все-таки был не о именовании структуры с кричащим именем EEPROM_xxx, а о том что присвоение переменной хранящейся в EEROM занимает кучу времени. Цитата Это из оперы - программисты не ищут простых путей? Или как понимать? Давайте также покритикуем возможность винды выделять гигабайтные массивы, ведь программист выделивший такой массив может думать, что весь массив лежит в ОП. Нет, это из оперы что программисты должны понимать чем это грозит. Цитата PS: к сожалению мне редко приходится наслаждаться возможностями IAR'а, потому что конечный продукт у меня собирается в WinAvr. При портировании с IAR'а на WinAvr частенько приходится поматериться  в местах работы со строками во флеш и данными в eeprom. Дык переходите на Gcc, и будет Вам счастье  Не, я почти серьезно.
|
|
|
|
|
Sep 27 2007, 16:36
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Сергей Борщ @ Sep 27 2007, 18:23)  На два. defunct объяснил почему. Ну-ну... Про преимущества CV- выше  Цитата(Сергей Борщ @ Sep 27 2007, 18:23)  1) При наличии опыта адаптация происходит быстро. 2) Все равно придется что-то править, а в процессе адаптации глубже вникаешь в чужие исходники. Значит если я хочу ездить на машине, мне нужно ее купить, разобрать,собрать, ведь я так глубже вникну в ее устройство. Мне нужно например подключить харддрайв, считать один файл,и может больше никогда в жизни мне это не понадобиться. Зачем мне вникать во внутреннее устройсто FAT32? А если и понадобиться, лет через 5-10, то все равно придется вникать заново. Цитата(Сергей Борщ @ Sep 27 2007, 18:23)  3) По закону подлости нужный код будет под какой-нибудь третий компилятор и вообще не под AVR. 4) По размеру кода ИАР сильно обгоняет WinAVR (по личному опыту, последний эксперимент - AES loader AVR231 буквально вчера. У ИАРа остается свободное место в 2К области, у WinAVRа код вылазит почти на 1К). Мое имхо - загрузчик должен вполне помещаться в бутовую область любых контроллеров мега. И если у ИАР загрузчик помещается в эти жалких 2 килобайта и еще 2 килобайта свободно, то мне кажется тут что-то не то  Цитата(Сергей Борщ @ Sep 27 2007, 18:23)  С точностью до наоборот. Вот уж что-что, а инлайн асм у WinAVR шикарный, а у IAR вообще никакой и они сами его не рекомендуют. А в обработке отдельного асм-исходника возможности у них практически одинаковые. Возможно, что с ассемблером в ИАР тоже не все хорошо, я сам вставок в нем не делал, только видел чужие. Они не показались мне уж такими страшными. А вот WinAvr-овские вещь тяжелая, я предпочитаю ими не пользоваться. Все выношу в S файл.
|
|
|
|
|
Sep 27 2007, 17:49
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Qwertty @ Sep 27 2007, 20:36)  Значит если я хочу ездить на машине, мне нужно ее купить, разобрать,собрать, ведь я так глубже вникну в ее устройство. Мне нужно например подключить харддрайв, считать один файл,и может больше никогда в жизни мне это не понадобиться. Ездить тоже можно по разному, можно просто купить и ездить не о чем не задумываясь, чисто для своего удовольствия, а можно и разобрать/собрать, понять как оно работает, ну и дальше выбрать для себя, или ездить для удовольствия, или гонятся професионально...
|
|
|
|
|
Sep 27 2007, 20:15
|

Местный
  
Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279

|
Цитата(Marian @ Sep 26 2007, 19:38)  CVAVR дает побитовый доступ к портам (правда в некоторых процах не ко всем)
PORTB.0 = 1; DDRB.3 = 0; Эквивалент в EWAVR: PORTB_Bit1 = 1; DDRB_Bit3 = 0;
|
|
|
|
|
Sep 28 2007, 08:27
|

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

|
Цитата(Qwertty @ Sep 27 2007, 19:36)  Ну-ну... Про преимущества CV- выше  1)Хорошо, но не совсем: не для всех потров такая конструкция работает, поэтому я не могу сделать, скажем, #define LED PORTA.1 а потом безболезненно изменить на #define LED PORTE.7, в то время как конструкция PORT |= (1 << BIT); с макросами поверх нее не страдает подобным недостаком. 2)Собственно на этом преимущества CV заканчиваются и его нельзя рассматривать как серьезный инструмент из-за отсутствия раздельной компиляции и всеми вытекающими несоответствиями стандарту. Вопрос обсуждался, я излагал подробные аргументы. Если интересно, поищите по ключевому слову CV и моему имени. Цитата(Qwertty @ Sep 27 2007, 19:36)  Значит если я хочу ездить на машине, мне нужно ее купить, разобрать,собрать, ведь я так глубже вникну в ее устройство. Если мы говорим о любительстве - не за чем Но не уверен, что у любителя все пойдет сразу и без доработок напильником. Если о профессиональной работе - не помешает. Цитата(Qwertty @ Sep 27 2007, 19:36)  Мое имхо - загрузчик должен вполне помещаться в бутовую область любых контроллеров мега. И если у ИАР загрузчик помещается в эти жалких 2 килобайта и еще 2 килобайта свободно, то мне кажется тут что-то не то  Вы меня не поняли. ИАР выдал код размером ~1800 байт, WinAVR - около 2700. Цитата(Qwertty @ Sep 27 2007, 19:36)  Возможно, что с ассемблером в ИАР тоже не все хорошо, я сам вставок в нем не делал, только видел чужие. Они не показались мне уж такими страшными. Естественно. Чем примитивнее инструмент, тем меньше вы им можете сделать. Вот цитата из мануала: Цитата Inline assembler is therefore often best avoided. If there is no suitable intrinsic function available, we recommend the use of modules written in assembler language instead of inline assembler, because the function call to an assembler routine normally causes less performance reduction. Цитата(Qwertty @ Sep 27 2007, 19:36)  А вот WinAvr-овские вещь тяжелая, я предпочитаю ими не пользоваться. Все выношу в S файл. Если вы не умеете пользоваться инструментом потому, что он слишком сложный - это не значит, что инструмент плохой. На уровне ИАРовского инлайн-асма вы в винавре напишете ровно столько же и практически так же.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 28 2007, 15:16
|

Частый гость
 
Группа: Участник
Сообщений: 148
Регистрация: 23-02-07
Пользователь №: 25 618

|
Цитата(Сергей Борщ @ Sep 28 2007, 11:27)  1)Хорошо, но не совсем: не для всех потров такая конструкция работает, поэтому я не могу сделать, скажем, #define LED PORTA.1 а потом безболезненно изменить на #define LED PORTE.7, в то время как конструкция PORT |= (1 << BIT); с макросами поверх нее не страдает подобным недостаком. Я не рекламирую CVAVR, но работать можно и на нем. Я и писал Цитата CVAVR дает побитовый доступ к портам (правда в некоторых процах не ко всем) но заменить например в Atmege16 : #define LED PORTA.1 на #define LED PORTD.3 несоставит труда.
|
|
|
|
|
Sep 28 2007, 22:37
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(SasaVitebsk @ Sep 28 2007, 00:02)  Выпад по поводу данных в EEPROM и FLASH - явно бредовый. Удобная вещь - она всегда удобная.
Зачем мне для обращения к Flash переменной обращаться ч/з подпрограмму?
Это просто яркий пример как можно всё с ног на голову поставить. Давайте посмотрим, на Вашем любимом IAR: Код #include <string.h>
__eeprom char eeString[]="Prived !"; char String[10]="ABCDEFGHIJ";
int main(void) { memcpy(String, (void const *)eeString, 10); memcpy((void *)eeString, String, 10); return 0; } Скомпилируйте этот код и пройдитесь по нему отладчиком, я думаю что результат Вас сильно порадует, особенно второй memcpy P.S Тока не нужно мне рассказывать что этот пример высосан из пальца... Прямое преобразование типов конечно вставлено специально, тока где и когда Вы наткнетесь на такой результат в реальной программе будете знать тока Вы и Ваш доктор в дурке (после отладки такого кода)
|
|
|
|
|
Sep 28 2007, 23:06
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Преимущества они и в Африке преимущества.
Вы прекрасно понимаете, что ими можно не пользоваться. Иными словами, если вас не устраивает по какой то причине прямое обращение к EEPROM либо FLASH памяти, вы можете использовать обращение аналогичное применяемому в WinAVR. Никаких проблем не вижу. Более того вы, естественно можете переписать и сами процедуры обращения. Или использовать свои библиотеки.
У меня действительно один раз было, при применении в одном операторе различных видов памяти, компилятор неверно (точнее не так как я хотел) компильнул. Проблема обнаружилась легко. После локализации места, прошёл оператор по шагам на асме в отладчике. Обнаружил ошибку. Устранилась легко. Прямым приведением типа.
Трагедии никакой здесь нет. Я думаю в WinAVR тоже найдётся немало скелетов в шкафу.
Я, совершенно не приумаляю достоинства WinAVR. Я просто отметил что им не так уж просто пользоваться и привёл свои аргументы. Исключительно исходя из своих наблюдений. Мне оказалось проще и приятнее работать в IAR. В то же время, если человек свободно программирует и в IAR и в WinAVR, то ему это только плюс. Знаний, как известно, лишних не бывает.
|
|
|
|
|
Sep 29 2007, 07:05
|
Частый гость
 
Группа: Участник
Сообщений: 99
Регистрация: 22-03-07
Из: Novosibirsk
Пользователь №: 26 415

|
Если хочется писать PORTB_0 = 1, это можно сделать средствами любого ANSI C совместимого компилятора. Например, как в SDCC для HC08: Код struct __hc08_bits { unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; };
#define PTB PORTB /* Alias for PORTB */ #define PTB0 ((struct __hc08_bits *)(&PTB))->bit0 #define PTB1 ((struct __hc08_bits *)(&PTB))->bit1 #define PTB2 ((struct __hc08_bits *)(&PTB))->bit2 #define PTB3 ((struct __hc08_bits *)(&PTB))->bit3 #define PTB4 ((struct __hc08_bits *)(&PTB))->bit4 #define PTB5 ((struct __hc08_bits *)(&PTB))->bit5 #define PTB6 ((struct __hc08_bits *)(&PTB))->bit6 #define PTB7 ((struct __hc08_bits *)(&PTB))->bit7 Изменил одну строчку, чтобы работало для AVR. PTB0 = 1, и даже PTB0 = PTB2 будет работать без проблем, причем для всех портов (где-то как sbi/cbi, где-то lds + sts). Написали один раз что-нибудь типа bitio.h, и пользуйтесь. Но лучше ( надеюсь, грамотные люди со мной согласятся) для конкретной задачи шевеления ногой писать макросы или online функции типа led_busy_on(), led_busy_off() и в коде использовать уже их. led_busy = 1, IMHO, хуже, разве что led_busy = ON  ... Операцию = можно перегрузить для eeprom, но это уже будет C++. Про генерацию кода ничего не скажу. Сам использую gcc для разных платформ, включая PC.
|
|
|
|
|
Sep 29 2007, 11:54
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Sep 29 2007, 01:37)  P.S Тока не нужно мне рассказывать что этот пример высосан из пальца... Прямое преобразование типов конечно вставлено специально, тока где и когда Вы наткнетесь на такой результат в реальной программе будете знать тока Вы и Ваш доктор в дурке (после отладки такого кода)  Ок, аналогичный пример: Код char Str[]="Hello"; char SomeChar; int main(void) { memcpy( (void *)SomeChar, Str, sizeof(Str)); } Проблема здесь та же самая что и в вашем примере, и даже без переменных в eeprom. Поэтому можете также вместе с доктором ковырять и этот код. Ибо когда нет понимания, что происходит в программе и что может происходить - забудьте про (void *).
|
|
|
|
|
Sep 29 2007, 12:46
|

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

|
Цитата(singlskv @ Sep 29 2007, 01:37)  Прямое преобразование типов конечно вставлено специально, И совершенно без понимания. Отсюда сюрпризы и жалобы на компилятор. Подсказка - любой указатель (на RAM) приводится к void * автоматически. Имеено поэтому в прототипе данной функции используется указатель на void* а не на char*. А любой указатель на флеш автоматически приводится к void __flash *. Поэтому в прототипе memcpy_P в качестве источника использован void __flash *. Чтобы если вы ошибетесь - компилятор мог распознать эту ошибку. Аналогично с указателями на __eeprom. Если вы примените __eeprom указатель как аргумент memcpy, компилятор вам выругался, что вы хотите невозможного. Если после этого вы тупо делаете явное приведение (и тем самым отключаете контроль типов) - то кто же вам злобный буратина? Вот вам встречный пример: Код typedef struct { uint8_t ParamA; uint32_t ParamB; my_struct_t ParamC; }config_t;
config_t const __flash Defaults = { 1, 0x12345678, { 'a', 1, 2, } };
struct { config_t Config; uint8_t CRC; } cfg_RAM, __eeprom cfg_EE;
void ReadConfig() { cfg_RAM = cfg_EE; if( CRC(&cfg_RAM, sizeof(cfg_RAM)) != 0) { cfg_RAM = Defaults; cfg_RAM.CRC = CRC(&cfg_RAM.Config, sizeof(config_t)) cfg_EE = cfg_RAM; } } Напишите с функциями то же самое. Как минимум код будет менее понятный и вы не обойдетесь без приведений типов - а они источник потенциальных ошибок, что вы нам продемонстрировали сами чуть выше.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 29 2007, 17:21
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 29 2007, 15:54)  Ок, аналогичный пример: Код .................... Проблема здесь та же самая что и в вашем примере, и даже без переменных в eeprom. Ну все таки не совсем одно и тоже, я свой пример показал только с точки зрения потенциально проблемной части в использовании __eeprom, а в вашем примере просто нарисован баг который из-за преобразования типов не смог поймать компилятор. Насколько я знаю, в стандарте С вобще нет такого типа void __eeprom *  А вот теперь представьте себе: Код __eeprom char eeString[]="Prived !"; char String[10]="ABCDEFGHI"; int Int=1; long Long=2;
typedef struct { void *ptr; int size; } SomeData;
SomeData* MassivHrenZnaetSKakimiDannimy[10]; ...................... { MassivHrenZnaetSKakimiDannimy[0].ptr = eeString; MassivHrenZnaetSKakimiDannimy[0].size = sizeof(eeString); MassivHrenZnaetSKakimiDannimy[1].ptr = String; MassivHrenZnaetSKakimiDannimy[1].size = sizeof(String); MassivHrenZnaetSKakimiDannimy[2].ptr = ∬ MassivHrenZnaetSKakimiDannimy[2].size = sizeof(Int); MassivHrenZnaetSKakimiDannimy[3].ptr = &Long; MassivHrenZnaetSKakimiDannimy[3].size = sizeof(Long); ............................. ............................. ............................. memcpy(KudatoTam, MassivHrenZnaetSKakimiDannimy[x].ptr, MassivHrenZnaetSKakimiDannimy[x].size); .......................... .......................... } Хрен знает какие данные оказались не совсем хрен знает какими, а все по тому что кое кто придумал свой новый тип данных... __eeprom xxx
|
|
|
|
|
Sep 29 2007, 18:42
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Сергей Борщ @ Sep 29 2007, 16:46)  И совершенно без понимания. Отсюда сюрпризы и жалобы на компилятор. А я жаловался на компилятор ? Нет, ну конечно было пару раз когда я указывал на проблемы с оптимизацией, но не более того... Разговор о том что нету в С таких типов __flash xxx и что не стоит этими придуманными типами пользоваться как обычными типами. Цитата Вот вам встречный пример: Код ................ Напишите с функциями то же самое. Как минимум код будет менее понятный и вы не обойдетесь без приведений типов - а они источник потенциальных ошибок, что вы нам продемонстрировали сами чуть выше. Менее понятен/более понятен, это все таки очень субъективные вещи, для меня например значительно более понятным при работе с EEPROM является или прямой вызов функций записи в него, или просто запуск записи с последующей проверкой что запись уже закончилась. При этом вопросов с приведением типов обычно не стоит, поскольку посредством вызова функции я четко указываю о своих намерениях. Тот код который Вы привели конечно выглядит красиво, мой намного зануднее... НО, объясните мне как Вы будете пользоваться такими присвоениями в следующей ситуации: Есть прога: - все события(опросы) синхронизированны(системный тик) например с тактом 200-500мкс - есть одно или несколько прерываний которые получают данные - есть основной цикл который ведет обработку полученных в прерывании данных - НУЖНО, не прерывая обработку, писать некоторые изменения соcтояния проги в EEPROM Где в этой проге можно написать cfg_EE = cfg_RAM ? Момент номер 2, когда Вы пишите cfg_EE = cfg_RAM , Вы принудительно заставляете перезаписывать в EEPROM даже те ячейки которые в данный момент не требуют модификации. Этим Вы осознанно уменьшаете ресурс EEPROM. Во всех моих занудных алгоритмах записи в EEPROM, перед тем как записать байт из какой-то структуры в соответствующее место EEPROM происходит чтение этого адреса и проверка на то, а нужно ли его вобще перезаписывать. Как Вы думаете, в среднем, какой вариант общения с EEPROM будет более быстрым и более надежным(в смысле ресурса EEPROM) ?
|
|
|
|
|
Sep 29 2007, 19:47
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Sep 29 2007, 20:21)  Ну все таки не совсем одно и тоже, я свой пример показал только с точки зрения потенциально проблемной части в использовании __eeprom, а в вашем примере просто нарисован баг который из-за преобразования типов не смог поймать компилятор. В вашем примере баг абсолютно такой же как и в моем. Ибо нефиг несовместимый тип приводить к PVOID. Цитата Хрен знает какие данные оказались не совсем хрен знает какими, а все по тому что кое кто придумал свой новый тип данных... __eeprom xxx В AVR три адресных пространства. Насколько это удобно или неудобно не вам судить, и не мне. Они просто есть, IAR дает нам простой инструмент доступа к этим адресным пространствам, если вам такой способ доступа не подходит - пользуйтесь другим, более сложным. Цитата для меня например значительно более понятным при работе с EEPROM является или прямой вызов функций записи в него, или просто запуск записи с последующей проверкой что запись уже закончилась. Кому что.. Меня как правило интересует конечный результат, если воспользовавшись фичей X я смогу добиться конечного результата меньшим числом строк кода и не в ущерб наглядности, читабельности программы и скорости испольнения, то обязательно ей воспользуюсь (по крайней мере подумаю об ее использовании). Минусом будет только "Портируемость" внутри семейства и на другие многоадресные семейства МК, а на "протируемость" на одноадресные МК (напр ARM) оно вообще никак не повлияет. Да и палку вы здесь перегибаете. Что может быть понятнее присваивания? x = y;
|
|
|
|
|
Sep 29 2007, 19:56
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата IAR дает нам простой инструмент доступа Замечу, что чтение из "откуда-попало" куда удобнее (хотя производительность несколько ниже) при использовании указателей с модификатором __generic, реализация которого у IAR есть, а у остальных аналогичного, похоже, даже в проекте нет.
--------------------
aka Vit
|
|
|
|
|
Sep 29 2007, 20:15
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 29 2007, 23:47)  Да и палку вы здесь перегибаете. Что может быть понятнее присваивания? x = y; Хорошо, будем говорить тока за себя, лично мне очень не нравится ситуация когда x=y; выполняется несколько сот наносекунд, а e=k; (где e - eeprom) выполняется несколько миллисекунд. Ну и остальные отрицательные стороны использования EEPROM как переменных я уже описал выше.
|
|
|
|
|
Sep 29 2007, 20:20
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Sep 29 2007, 23:15)  e=k; (где e - eeprom) выполняется несколько миллисекунд. Ну и остальные отрицательные стороны использования EEPROM как переменных я уже описал выше. Ну и что?! У eeprom еще и ресурс ограничен, такова уж особенность этой памяти. 100k раз запишете дальше пойдут сбои. Какое это имеет отношение к удобному механизму обращения к этой памяти? Не нравится медленный внутренний eeprom используйте RAM или ставте быстрый внешний FRAM, но удобного способа доступа к нему средствами компилятора уже не будет, придется писать драйвер.
|
|
|
|
|
Sep 29 2007, 20:30
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 30 2007, 00:20)  Ну и что?! У eeprom еще и ресурс ограничен, такова уж особенность этой памяти. 100k раз запишете дальше пойдут сбои. Какое это имеет отношение к удобному механизму обращения к этой памяти? Похоже Вы невнимательно читаете мои посты, перечитайте пожалуйста №37, и если Вас не затруднит, ответьте на 2 поставленных мной вопроса, продублирую их на всякий случай: НО, объясните мне как Вы будете пользоваться такими присвоениями в следующей ситуации: Есть прога: - все события(опросы) синхронизированны(системный тик) например с тактом 200-500мкс - есть одно или несколько прерываний которые получают данные - есть основной цикл который ведет обработку полученных в прерывании данных - НУЖНО, не прерывая обработку, писать некоторые изменения соcтояния проги в EEPROM
Где в этой проге можно написать cfg_EE = cfg_RAM ?....................... Как Вы думаете, в среднем, какой вариант общения с EEPROM будет более быстрым и более надежным(в смысле ресурса EEPROM) ?
|
|
|
|
|
Sep 29 2007, 20:40
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Sep 29 2007, 23:30)  [i]НО, объясните мне как Вы будете пользоваться такими присвоениями в следующей ситуации: Есть прога: - все события(опросы) синхронизированны(системный тик) например с тактом 200-500мкс - есть одно или несколько прерываний которые получают данные - есть основной цикл который ведет обработку полученных в прерывании данных - НУЖНО, не прерывая обработку, писать некоторые изменения соcтояния проги в EEPROM Для этой задачи я поставлю исключительно внешний eeprom либо NVRAM и не буду даже морочиться с внутренним, которого судя по условию задачи просто не хватит для хранения какого либо существенного объема статистики. Внутренний eeprom лично я использую только для: хранения параметров конфигурации устройства, хранения информации о рестартах + дамп критических структур в случае перезагрузки по WDT. Цитата Как Вы думаете, в среднем, какой вариант общения с EEPROM будет более быстрым и более надежным(в смысле ресурса EEPROM) ? Я думаю, что вариант общения должен быть обдуманным, т.е. надо минимизировать число записей. При этом инструмент которым непосредственно производится запись/чтение может быть каким угодно, но желательно простым, что нам и дает IAR.
|
|
|
|
|
Sep 29 2007, 20:58
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 30 2007, 00:40)  Для этой задачи я поставлю исключительно внешний eeprom либо NVRAM и не буду даже морочиться с внутренним, которого судя по условию задачи просто не хватит для хранения какого либо существенного объема статистики. Внутренний eeprom лично я использую только для: хранения параметров конфигурации устройства, хранения информации о рестартах + дамп критических структур в случае перезагрузки по WDT. А мне вот и для всей остальной статистики хватает  Наверное по тому что я не умею пользоваться встроенной EEPROM ? Цитата Я думаю, что вариант общения должен быть обдуманным, т.е. надо минимизировать число записей. При этом инструмент которым непосредственно производится запись/чтение может быть каким угодно, но желательно простым, что нам и дает IAR. Это вы о чем ? Об этой простоте cfg_EE = cfg_RAM ? Ну и где здесь минимизация количества записей ? Свой вариант реализации я уже описал, читаем-проверяем-если нужно пишем, и это все на уровне байта. Раскажите мне как Вы планируете минимизировать количество записей при помощи этой простоты cfg_EE = cfg_RAM ?
|
|
|
|
|
Sep 29 2007, 21:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Где в этой проге можно написать cfg_EE = cfg_RAM ? такую операцию нельзя прерывать независимо от компилятора - это АППАРАТНОЕ ограничение. Если это не понимать, то знание особенностей использования диалекта языка и компилятора не помогут. Потому вопрос Цитата объясните мне как Вы будете пользоваться такими присвоениями в следующей ситуации просто не имеет смысла. Если используется внешняя память, о чём упомянул defunct, то задача относится опять же не к компиляторам, а есть вопрос архитектуры программы.
--------------------
aka Vit
|
|
|
|
|
Sep 29 2007, 21:26
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(sensor_ua @ Sep 30 2007, 01:05)  такую операцию нельзя прерывать независимо от компилятора - это АППАРАТНОЕ ограничение. Не очень понял что Вы хотели этим сказать. Мои варианты/предположения: - нельзя прервать потому что нельзя  - нельзя прерывать потому что кто-то еще захочет записать в EEPROM (из прерывания например)  - нельзя прерывать потому что запись в EEPROM требует остановки всех процессов  ..................... ..................... - нельзя пользоваться таким вариантом записи в EEPROM (поддерживаю!) Цитата Если это не понимать, то знание особенностей использования диалекта языка и компилятора не помогут. Вы бы уточнили о каких АППАРАТНЫХ ОГРАНИЧЕНИЯХ идет речь... Если Вы о необходимости вот этого: asm("cli"); EECR |= (1<<EEMWE); EECR |= (1<<EEWE); asm("sei"); то там речь идет о паре тактов проца... и при грамотном проектировании проги даже эти cli и sei не понадобятся.
|
|
|
|
|
Sep 29 2007, 22:09
|

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

|
Цитата(singlskv @ Sep 29 2007, 20:21)  Насколько я знаю, в стандарте С вобще нет такого типа void __eeprom *  Мы не обсуждали портируемость. В других компиляторах нет eeprom_write_byte();, а в некоторых процессорах нет eeprom  Цитата(singlskv @ Sep 29 2007, 20:21)  А вот теперь представьте себе: Код MassivHrenZnaetSKakimiDannimy[0].ptr = eeString; Получаем ошибку компилятора о несоответствии типов. Ту самую, которую в предыдущем примере вы задавили явным приведением к (void *). Ту самую, которую вы получите в WinAVR, если попытаетесь присвоть (void *) переменную типа (void EEMEM *) или prog_void. Цитата(singlskv @ Sep 29 2007, 21:42)  Где в этой проге можно написать cfg_EE = cfg_RAM ? Не поверите - именно там, где надо сохранить данные. Компилятор подставит для каждого байта вызов __eeput8_16, в котором именно там, где это необходимо будет запрет/разрешение прерываний. Поверьте, код будет практически идентичен eeprom_write_byte(), за которую вы агитируете. Для очень редких случаев есть вариант *((uint8_t *)&cfg_EE.Config.ParamA)[2] = byte; Что касается ресурса eeprom, то я не случайно взял конфиг - как наиболее общий случай, когда ресурса хватит даже самому пытливому пользователю. И не пытайтесь меня убедить, что я должен потратить лишнее время чтобы экономить ресурс там, где его и так с запасом - это все равно что агитировать писать на асме (со всеми вытекающими недостатками), чтобы втиснуть програму в 2к памяти при 8к на борту. Если же есть какие-либо специальные требования (ресурс, необходимость отслеживать окончание по прерыванию) - думать головой никто не отменял. Цитата(SergeiCh @ Sep 29 2007, 10:05)  Но лучше ( надеюсь, грамотные люди со мной согласятся) для конкретной задачи шевеления ногой писать макросы или online функции типа led_busy_on(), led_busy_off() и в коде использовать уже их. led_busy = 1, IMHO, хуже, разве что led_busy = ON  ... Почти согласен. Но писать для каждой ноги xxx_on(), xxx_off() - да, конечно так и делал раньше. Но теперь - on(LED); off(FLASH_CS); if(signal(KEY)) - тоже абсолютно портируемо на любой С-компилятор. И сгенеренный код будет идентичен тому, который надо написать вручную для xxx_on(); xxx_off();
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 29 2007, 22:36
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Сергей Борщ @ Sep 30 2007, 01:57)  Получаем ошибку компилятора о несоответствии типов. Ту самую, которую в предыдущем примере вы задавили явным приведением к (void *). Ту самую, которую вы получите в WinAVR, если попытаетесь присвоть (void *) переменную типа (void EEMEM *) или prog_void. Я даже и не сомневался что именно Вы укажите на это несоответствие  , этот код я даже и не пытался скомпилировать потому что очевидно одно из двух, если компилятор пропустит такой код, то все очень плохо и пользоваться __eeprom просто нельзя ни при каких обстоятельствах, а если не пропустит, то это говорит о том что типы которые придумал IAR(__eeprom xxx), Эээ... ну мягко говоря не являются таки типами..., по крайней мере в понимании С. Цитата Не поверите - именно там, где надо сохранить данные. Компилятор подставит для каждого байта вызов __eeput8_16, в котором именно там где это необходимо будет запрет/разрешение прерываний. Поверьте, код будет практически идентичен eeprom_write_byte(), за которую вы агитируете. Упс..., это где это я агитировал за использование eeprom_write_byte() ? Я этим ни разу не пользовался  У меня свои функции. Если Вас не затруднит ответьте таки конкретно на 2 моих вопроса из поста №37. Все равно не понимаю в чем Вы пытаетесь меня убедить. Цитата(sensor_ua @ Sep 30 2007, 02:21)  Код /* Wait for completion of previous write */ while(EECR & (1<<EEWE)); В том что я обязан висеть в этом цикле пока не закончится запись ? У меня это выглядит примерно так: Код //============================================================== // Автомат записи в EEPROM //============================================================== void EepromRun() {
if (EECR & (1<<EEWE)) return; // идет запись ? да, тогда отваливаем (другие дела)
if (CurrState == EE_FREE) { ................................... ...................................
} Цитата Запись заканчивается не сразу после засылки адреса и данных а после АППАРАТНОЙ записи - для мега16 это 8.5 ms типовое значение. Или Вы хотите сказать, что, буквы EEMEM автоматом вдруг делают неожидающей встроенную функцию static inline void __attribute__ ((always_inline)) eeprom_write_byte (uint8_t *addr,uint8_t value); ? (Может, она случайно  и неожидающая, но тогда ею пользоваться низзя) А не пробовали посмотреть, во что раскладывается аналогичная операция у IAR? Дык тоже инлайновый вариант. Если не используем встроенные функции или модификаторы, а боремся за отсутствие ожиданий при работе с EEPROM, то пример задачи не к месту - в обоих случаях нужно писать СВОЁ. Я НЕ пользуюсь ни IARовским ни каким другим вариантом доступа к EEPROM. У меня есть свой хорошо работающий автомат записи.
|
|
|
|
|
Sep 29 2007, 23:01
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Я НЕ пользуюсь ни IARовским ни каким другим вариантом доступа к EEPROM. Обчитался после, что Вы не используете встроенные возможности и удалил пост нафиг. Если Вы предлагаете для всех случаев применения EEPROM не использовать встроенные функции/модификаторы, то это не повод рассказывать, что они не годятся. Аргументы, ИМХО, сомнительны. Задачи, конечно, разные бывают. Сам для записи во внешнюю последовательную память целую артиллерию из очередей выстраиваю, но константы, хранимые во __flash никуда не деваются и удобно используются  . Встроенную EEPROM у нас юзают исключительно как описывал defunct, потому как реально для наших логов (архивов) маловато будет - для хранилищ обычно ставим FRAM и DataFlash.
--------------------
aka Vit
|
|
|
|
|
Sep 29 2007, 23:56
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Sep 30 2007, 01:36)  Упс..., это где это я агитировал за использование eeprom_write_byte() ? Я этим ни разу не пользовался  У меня свои функции. Если речь идет о задаче-драйвере записи eeprom, то что мешает внутри нее использовать уже готовые механизмы компиляторов, e.g.: Код void EEPROM_Dispatch(void) { if (EECR & (1<<EEWE)) return; .... if (*(__eeprom U8 *)адрес != data to write) *(__eeprom U8 *)адрес = data to write; } Если вы даже не удосужились посмотреть и разобраться с кодом eeprom_read_byte()/eeprom_write_byte() пакета в котором работаете, и начали сразу городить что-то свое, то спорить с вами о возможностях IAR просто бесполезная трата времени. Цитата Я НЕ пользуюсь ни IARовским ни каким другим вариантом доступа к EEPROM. У меня есть свой хорошо работающий автомат записи. Порой глупо из-за какого-то принципа не пользоваться уже имеющимися механизмами. К тому же они нисколько не помешали бы вашему автомату, а наоборот сделали бы его более прозрачным/читаемым.
|
|
|
|
|
Sep 30 2007, 07:59
|

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

|
Цитата(singlskv @ Sep 30 2007, 01:36)  а если не пропустит, то это говорит о том что типы которые придумал IAR(__eeprom xxx), Эээ... ну мягко говоря не являются таки типами..., по крайней мере в понимании С. Это является расширением языка. Нормальные типы, ибо поддерживают все операции над данными - арифметику, присваивание, взятие адреса, обращение по указателю. Указатели на эти типы полностью аналогичны указателям на данные с __attribute__(("progmem")) и __attribute__(("EEPROM")), против которых (так получается) вы нас агитируете. Причем последние, в отличие от ИАРовских, не являются полноценными типами, ибо поддерживают только операцию взятия адреса и арифметику указателей. Цитата(singlskv @ Sep 30 2007, 01:36)  Упс..., это где это я агитировал за использование eeprom_write_byte() ? Ну, раз вы агитируете за WinAVR и доступ функциями, раз вы нигде до этого не упомянули, что вами используется закат солнца вручную - телепатически я сделал вывод, что вы агитиреуте за реализованный в avr-libc метод. Цитата(singlskv @ Sep 30 2007, 01:36)  Если Вас не затруднит ответьте таки конкретно на 2 моих вопроса из поста №37. Вопросов я там нашел два: 1)Где там использовать встроенные функции. Да, согласен, я не обратил внимание на 200-500 мкс, что меньше, чем время записи. Согласен, что в этом случае надо использовать самописные функци. Но, извините, а вы эти данные только пишете, и никогда не читаете? Если все же читаете, то что мешает использовать простые и удобные встроенные возможности компилятора? Ваш вопрос номер два - про ресурс. Мне кажется, я на него ответил исчерпывающе - если ресурса хватает с запасом (а это наиболее частый случай, как в примере - при хранении конфигурации) то не имеет смысла тратить усилия на его экономию. Если он важен - можно сделать побайтовую запись с анализом. Цитата(singlskv @ Sep 30 2007, 01:36)  Все равно не понимаю в чем Вы пытаетесь меня убедить. В том, что встроенная поддержка данных в eeprom и flash не вредное (как вы утверждаете), а напротив очень полезное и удобное (первое вытекает из второго) расширение компилятора. Цитата(singlskv @ Sep 30 2007, 01:36)  Я НЕ пользуюсь ни IARовским ни каким другим вариантом доступа к EEPROM.У меня есть свой хорошо работающий автомат записи. Так я же и писал, что бывают случаи, когда надо работать головой и использовать нештатные решения. Но это не повод отказываться от удобных возможностей в остальных случаях.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 30 2007, 12:13
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Сергей Борщ @ Sep 30 2007, 11:59)  Вопросов я там нашел два: 1)Где там использовать встроенные функции. Да, согласен, я не обратил внимание на 200-500 мкс, что меньше, чем время записи. Согласен, что в этом случае надо использовать самописные функци. Собственно об этом и речь. Простое присваивание не заостряет на себе внимание, в отличии от вызова функции, и ведет к ошибкам от банальной невнимательности. Понятно, что в результате оба метода, и в ИАРе и в ГЦЦ одинаково эффективны. Но все же работа с ЕЕПРОМ у ГЦЦ больше напоминает обращение к внешней памяти, с ее неизбежными задержками, что помогает избегать глупых ошибок. Но тут уж видимо вопрос вкуса. Меня встроенные функции avr-libs вполне устраивают. Но вот никто почему-то не говорит о лицензионной чистоте используемого программного продукта....
|
|
|
|
|
Sep 30 2007, 12:42
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 3-08-05
Из: Новосибирск
Пользователь №: 7 334

|
Цитата(Qwertty @ Sep 30 2007, 19:13)  Но вот никто почему-то не говорит о лицензионной чистоте используемого программного продукта.... А зачем об этом говорить если это не влияет на функциональность и качество компиляции?
--------------------
Всяк хорошая мысля к нам приходит опосля.
|
|
|
|
|
Sep 30 2007, 18:32
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Sep 30 2007, 03:56)  Если речь идет о задаче-драйвере записи eeprom, то что мешает внутри нее использовать уже готовые механизмы компиляторов, e.g.: Воспользовался Вашим советом: Код __eeprom unsigned char a=1; unsigned char b;
void SomeFunc() { b=2; }
void EEPROM_Run() { if (EECR & (1<<EEWE)) return; if (a != b) a=b; }
int main(void) { SomeFunc(); EEPROM_Run();
return 0; } IAR, получил 81 такт на выполнение EEPROM_Run(). Написал тоже самое(по функциональности) "ручками", скомпилировал на WinAvr и на IAR, и там и там получил 33 такта. (во всех случаях использовалась максимальная оптимизация) Если Вас устраивает такой оверхед - пользуйтесь, меня не устраивает. У меня для этого автомата максимальное время каждой стадии его работы чуть боле 100 тактов, при этом поддерживается запись в два блока памяти(копии) и попутно подсчет/сравнение СRC16 c уведомлением основной проги если были ошибки... Цитата Если вы даже не удосужились посмотреть и разобраться с кодом eeprom_read_byte()/eeprom_write_byte() пакета в котором работаете, и начали сразу городить что-то свое, то спорить с вами о возможностях IAR просто бесполезная трата времени. Вы знаете, именно так и поступаю, сначала ознакомление со штатными средствами, если меня устраивает, пользуюсь штатными, если нет, пишу свою реализацию. Кстати вот вам и примерчик: CRC16 и CRC8 CRC16 - пользуюсь встроенным, поскольку после изучения кода стало понятно что я просто ничего не смогу выиграть. CRC8 - очень медленно (для моих задач) , пользуюсь своим вариантом, причем их 2 на выбор, если памяти много - табличный, мало - другой быстрый вариант. Цитата Порой глупо из-за какого-то принципа не пользоваться уже имеющимися механизмами. К тому же они нисколько не помешали бы вашему автомату, а наоборот сделали бы его более прозрачным/читаемым. Понятнее...,но в 2,5 раза медленнее Принципы здесь не при чем. Цитата(Сергей Борщ @ Sep 30 2007, 11:59)  Ну, раз вы агитируете за WinAVR и доступ функциями, раз вы нигде до этого не упомянули, что вами используется закат солнца вручную - телепатически я сделал вывод, что вы агитиреуте за реализованный в avr-libc метод. Согласен, нужно было не расчитывать на телепатию собеседников и чуть пораньше объяснить что я имею в виду. А "закат солнца вручную" иногда очень эфективный метод  Цитата Это является расширением языка. Нормальные типы, ибо поддерживают все операции над данными - арифметику, присваивание, взятие адреса, обращение по указателю. Указатели на эти типы полностью аналогичны указателям на данные с __attribute__(("progmem")) и __attribute__(("EEPROM")), против которых (так получается) вы нас агитируете. Причем последние, в отличие от ИАРовских, не являются полноценными типами, ибо поддерживают только операцию взятия адреса и арифметику указателей. ИМХО, это не нормальные типы, и мои примеры это показали. Невозможность автоматического приведения указателя на такой тип к void* говорит именно о том что тип неполноценен. Считаю подход WinAvr(Gcc) в данном случае просто более честным. Цитата Но, извините, а вы эти данные только пишете, и никогда не читаете? Чаще конечно пишу, чтение в основном при первоначальной загрузке параметров. Но иногда нужно и чтение в процессе работы, поэтому чтение тоже интегрированно в этот автомат. Цитата Если все же читаете, то что мешает использовать простые и удобные встроенные возможности компилятора? Когда нужно быстро, пользоваться своим, а когда нужно медленно, то пользоваться библиотекой ? А зачем мне плодить сущности и увеличивать код ? Цитата Так я же и писал, что бывают случаи, когда надо работать головой и использовать нештатные решения. Но это не повод отказываться от удобных возможностей в остальных случаях. У меня такие случаи в каждом первом проекте.  Всегда нужно чего-нить писать во время основной работы...
|
|
|
|
|
Sep 30 2007, 18:38
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Сергей Борщ @ Sep 30 2007, 01:09)  Но писать для каждой ноги xxx_on(), xxx_off() - да, конечно так и делал раньше. Но теперь - on(LED); off(FLASH_CS); if(signal(KEY)) - тоже абсолютно портируемо на любой С-компилятор. И сгенеренный код будет идентичен тому, который надо написать вручную для xxx_on(); xxx_off(); Спасибо за примерчик. Я по старинке пишу ON_LED; без скобок, чтобы помнить, что это макрос. Не особенно нравится, но вот думаю, а стоит ли менять? Я даже стараюсь писать unsigned int вместо uint или word, как это теперь обычно делается. Пока кнопочки жамкаешь, голова и работает (или отдыхает, что тоже неплохо). Не загоняем ли мы себя в угол, раскручивая конвейер?
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Sep 30 2007, 19:17
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(singlskv @ Sep 30 2007, 21:32)  Воспользовался Вашим советом: .... IAR, получил 81 такт на выполнение EEPROM_Run(). Написал тоже самое(по функциональности) "ручками", скомпилировал на WinAvr и на IAR, и там и там получил 33 такта. (во всех случаях использовалась максимальная оптимизация)
Если Вас устраивает такой оверхед - пользуйтесь, меня не устраивает. Об этом говорят вам все. Я, defunct, Сергей Борщ. IAR не запрещает работать вам так, как вы желаете. О чём и свидетельствуют написанные вами строчки. Другое дело если бы кроме как ч/з __eeprom компилятор не позволил бы добраться по другому к данной памяти. Но это к счастью не так. Если вам так тяжело пережить эти спецификаторы, то рассматривайте их как факультативные и не используйте их. По поводу "оверхеда". Оптимизацию целесообразно делать там, где она даст желаемый эффект. Если привести доступный пример, то целесообразно вылизывать п/программу которая вызывается 1000 раз в секунду и совершенно не целесообразно если она вызывается 1 раз во время старта программы. По скольку EEPROM используется, как правило для хранения конфига и т.п., читается редко а записывается ещё реже (иначе используют внешнюю память, доступ к которой будет быстрее в разы), то для меня __eeprom является преимуществом. Использую я его где надо и по назначению и никаких проблем это у меня не вызывает. В ближайшее время пойдёт xmega. Как уже объявлено, там будет память EEPROM в общем адресном пространстве. Я думаю IAR сохранит __eeprom. Таким образом портируемость программ у тех, кто использовал __eeprom - не пострадает. Цитата(Dog Pawlowa @ Sep 30 2007, 21:38)  Не особенно нравится, но вот думаю, а стоит ли менять? Я даже стараюсь писать unsigned int вместо uint или word, как это теперь обычно делается. Пока кнопочки жамкаешь, голова и работает (или отдыхает, что тоже неплохо). Не загоняем ли мы себя в угол, раскручивая конвейер?  Давайте всёже не забывать что мы с однокристалками работаем. С одной стороны uint8_t это тоже стандарт ISO/IEC 9899:1999 7.18 Integer types <stdint.h> С другой стороны приведу пример. Я сделал проект на m640. Сейчас планирую перенести его на LPC2106. У меня там большое количество структур и указателей. И представьте себе если бы там стоял стандартный "int" вместо int16_t. Это же лопатить не перелопатить. Ну а если глобально подходить, то да. Человечество давно само себя загоняет в угол по всем направлениям. Долой машины - дорога к счастью - назад на деревья.
|
|
|
|
|
Sep 30 2007, 19:30
|

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

|
Цитата(singlskv @ Sep 30 2007, 21:32)  А "закат солнца вручную" иногда очень эфективный метод  Согласен, если выбора нет. А если он есть - смотря какой именно из парамеров оптимизировать  Цитата(singlskv @ Sep 30 2007, 21:32)  Невозможность автоматического приведения указателя на такой тип к void* говорит именно о том что тип неполноценен. Не готов сразу ответить. "Чистый" С вообще не знает про разные адресные пространства. Да и как вы физически представляете приведение указателя на одно адресное пространство к указателю на другое? Только используя __generic указатели, что хоть и влечет дикий оверхед, но тем не менее реализовано в IAR. Цитата(singlskv @ Sep 30 2007, 21:32)  Считаю подход WinAvr(Gcc) в данном случае просто более честным. На самом деле он просто не доделан  А пока он не только не честный, но как раз наоборот: Код uint8_t EEMEM EE_data; uint8_t PROGMEM Const[] = "Tipa test"; void Test() { uint8_t Tmp; Tmp = Const[0]; EE_data = Tmp; } На фоне того, что такое компилируется молча и без ошибок тот факт, что на самом деле копирование происходит из ОЗУ в ОЗУ по совпадающим адресам кажется несущественным. Допустить такую ошибку гораздо проще (сам наступал), чем нарваться на случай, когда критично время записи в eeprom или ее ресурс. Тут четко видна недоделанность, ибо попытка присвоить что-либо Const все же вызывает сообщение об ошибке "попытка записи в read-only". Цитата(singlskv @ Sep 30 2007, 21:32)  Чаще конечно пишу, чтение в основном при первоначальной загрузке параметров. И при этом данные, которые вы читаете, всегда представляют набор байтов? Не int, long, float, структуры, а именно голые байты? Если же данные осмысленны, то почему не воспользоваться предоставляемыми компилятором средствами? Цитата(singlskv @ Sep 30 2007, 21:32)  Когда нужно быстро, пользоваться своим, а когда нужно медленно, то пользоваться библиотекой ? Честно говоря, так бы и поступил. Ибо встроенные методы дают более читаемый код. И чем больше читаемого кода в программе, тем меньше вероятность ошибки. Цитата(singlskv @ Sep 30 2007, 21:32)  А зачем мне плодить сущности и увеличивать код ? Ну хорошо, наэкономите 40 байт памяти, а смысл, если ее все равно осталось полкило а то и больше? Читаемость упала, возможностей оптимизации у компилятора меньше. Ясное дело, если утаптываем, то резать придется везде. Цитата(singlskv @ Sep 30 2007, 21:32)  У меня такие случаи в каждом первом проекте.  Всегда нужно чего-нить писать во время основной работы... "У каждого есть свои маленькие недостатки" (с)"В джазе только девушки". Цитата(SasaVitebsk @ Sep 30 2007, 22:17)  В ближайшее время пойдёт xmega. Как уже объявлено, там будет память EEPROM в общем адресном пространстве. Я думаю IAR сохранит __eeprom. Таким образом портируемость программ у тех, кто использовал __eeprom - не пострадает. Даже если не сохранит - портируемость достигнется добавлением строчки #define __eeprom
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 30 2007, 20:04
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Сергей Борщ @ Sep 30 2007, 23:30)  На самом деле он просто не доделан  А пока он не только не честный, но как раз наоборот:[code] EEMEM PROGMEM На фоне того, что такое компилируется молча и без ошибок тот факт, что на самом деле копирование происходит из ОЗУ в ОЗУ по совпадающим адресам кажется несущественным. Допустить такую ошибку гораздо проще (сам наступал), чем нарваться на случай, когда критично время записи в eeprom или ее ресурс. Тут четко видна недоделанность, ибо попытка присвоить что-либо Const все же вызывает сообщение об ошибке "попытка записи в read-only". Здесь мы видимо принципиально по разному подходим к вопросу. EEMEM, PROGMEM я типами данных просто не считаю. Это, по моему мнению, просто те расширения компилятора которые позволяют отводить/инициализировать область в eeprom/flash. + взятие адреса для выяснения куда писать. Все. Собственно в описании к avr-lib их тока так и предполагается использовать. Цитата И при этом данные, которые вы читаете, всегда представляют набор байтов? Не int, long, float, структуры, а именно голые байты? Автомат оперирует на уровне блока байтов + CRC. Цитата Если же данные осмысленны, то почему не воспользоваться предоставляемыми компилятором средствами?Честно говоря, так бы и поступил. Ну хорошо, наэкономите 40 байт памяти, а смысл, если ее все равно осталось полкило а то и больше? Читаемость упала, возможностей оптимизации у компилятора меньше. Ясное дело, если утаптываем, то резать придется везде. Ну видимо у нас все-таки сильно разные задачки... Цитата Даже если не сохранит - портируемость достигнется добавлением строчки #define __eeprom Кстати о портируемости  , мой вариант кода эквивалентный коду из поста №54 скомпилировался без вопросов и на Gcc и на IAR
|
|
|
|
|
Oct 1 2007, 05:17
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата EEMEM, PROGMEM я типами данных просто не считаю. Это, по моему мнению, просто те расширения компилятора которые позволяют отводить/инициализировать область в eeprom/flash. + взятие адреса для выяснения куда писать. Потому и руками допиливаются обычные функции и из них появляются особенные - так кроме int printf(const char *__fmt, ...); имеем int printf_P(const char *__fmt, ...); ЗЫ. Я пробую каждую свежую версию WinAVR и могу заметить, что семимильными шагами движется он в сторону IAR. Проекты под портируемость сразу протачиваем. Но пока это "утомительное застирывание".
--------------------
aka Vit
|
|
|
|
|
Oct 1 2007, 10:38
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
to Сергей БорщПодскажите, а зачем нужна обвязка из do/while? Код #define _clrL(port,bit) do { port |= (1 << bit); } while(0) Почему не так? Код #define _clrL(port,bit) port |= (1 << bit)
|
|
|
|
|
Oct 1 2007, 11:16
|

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

|
Цитата(Непомнящий Евгений @ Oct 1 2007, 13:38)  to Сергей БорщПодскажите, а зачем нужна обвязка из do/while? Код #define _clrL(port,bit) do { port |= (1 << bit); } while(0) Почему не так? Код #define _clrL(port,bit) port |= (1 << bit) В данном конкретном случае она не нужна. Сила привычки. Началось с того, что увидел такую обвязку в исходниках линукса и задал такой же вопрос в ru.embedded. ReAl мне там ответил, что если внутри макроса будет более одной команды, то их придется заключать в {} чтобы такой макрос можно было использовать как единое выражение в циклах или в конструкциях if(условие) macros(); И все будет работать до тех пор, пока не появится желание сделать if(условие) macros(); else something; - получим ошибку компиляции. Обрамление же в do {}while(0) позволяет использовать такой макрос в любом месте, где допустим вызов обычной функции и не несет никаких дополнительных накладных расходов - сам цикл выбрасывается оптимизатором, остается только его тело. Ну а здесь я их обрамил по привычке, на случай если вдруг придется добавить внутрь еще одно или несколько выражений. Кончно, если пользоваться только С++, то можно реализовать то же самое при помощи static inline функций, но пропадет универсальность в виде совместимости с С.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 1 2007, 11:55
|
Частый гость
 
Группа: Участник
Сообщений: 99
Регистрация: 22-03-07
Из: Novosibirsk
Пользователь №: 26 415

|
Цитата(Сергей Борщ @ Sep 30 2007, 05:09)  on(LED); off(FLASH_CS); if(signal(KEY)) - тоже абсолютно портируемо на любой С-компилятор. И сгенеренный код будет идентичен тому, который надо написать вручную для xxx_on(); xxx_off(); Действительно удобное решение.
|
|
|
|
|
Oct 2 2007, 11:39
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Rst7 @ Oct 2 2007, 09:42)  Ээээ... А с Вашей? Я оцениваю это положительно. Сам до такого не додумался. А мне кстати бы не помешало такое решение. И вообще - всё что сделано - остаётся на годы. Тут вообще, на мой взгляд бессмыслено оценивать. Раз Вы сделали - значит Вам это понадобилось и для Вас это оказалось удобным. Соответственно моя оценка или оценка другим человеком Вашего труда - будет весьма субъективной. Я считаю, что фактически, это разработка какой-то базы под себя. И это позволит Вам следующий раз сделать проект быстрее. Соответственно это очень положительное качество. С годами Вы, возможно, переработаете детали и вылижите что-то. Или вообще что-то измените, но наверняка наработанные знания и опыт останутся с Вами навсегда.
|
|
|
|
|
Oct 2 2007, 11:57
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(SasaVitebsk @ Oct 2 2007, 14:39)  Я оцениваю это положительно. Сам до такого не додумался. А мне кстати бы не помешало такое решение. А вообще, жалко, что нет штатных средств компилятора для создания таких адресных пространств под собственные нужды. Иногда очень бы упростило код и добавило бы красоты. Через епром - это конечно костыль, однако, с другой стороны, достаточно легко переносимый на другие платформы. В принципе была еще одна идея, но это уже злой хак  Как известно, ИАР умеет компилировать для моделей памяти с озу >64К. Была идея патчить кодегенератор, дабы он делал не OUT в RAMP?, а out в нужный порт. В результате, можно было бы увеличивать объем озу просто навесив дополнительные адреса на какой-либо порт и не думая о том, как выполнить этот маппинг програмно, все бы на себя взял компилятор. Правда, идея до реализации не дошла (уже не помню почему, кажется, отпала надобность).
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Oct 2 2007, 14:18
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Была идея патчить кодегенератор, дабы он делал не OUT в RAMP?, а out в нужный порт. Пытался. Используются несуществующие регистры RAMPx. Проблема (сомневаюсь, что показалось) нерешаема.
--------------------
aka Vit
|
|
|
|
|
Oct 2 2007, 18:06
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Rst7 @ Oct 1 2007, 17:41)  Кстати, между прочим, переделав eeprom.s90 например на работу с 24xxx получаем удобный инструмент хранения переменных во внешней епромке. Кстати, структуры там тоже отлично хранятся... и массивы... Rst7, А как Вы считаете, встраивание возможности чтения EEPROM перед ее записью(или не записью, если там ничего не изменилось) в свой код(или библиотеку) является правильным/нужным (для увеличения ресурса EEPROM) ? Время от времени на электрониксе возникают темы типа: Как сохранить текущую конфигурацию прибора при пропадании питания. Обычно(чаше всего) обсуждение ведется в русле того, что нужно аппаратными средствами обеспечить работу контроллера еще какое-то время для того, чтобы успеть записать эту самую конфигурацию. Может все-таки стоит в подобных ситуациях озаботиться возможностью "ВСЕГДА" иметь правильную конфигурацию в EEPROM ? Правда для этого(часто) придется написать свой код общения с EEPROM.
|
|
|
|
|
Oct 2 2007, 20:08
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(sensor_ua @ Oct 2 2007, 23:38)   А давайте вспомним обычную файловую операцию - сохранение файла. Чтобы записываемый файл не убил ещё целый оригинал, нужно писать в другое место. Далее возникают остальные вопросы - как разгребаться с мусоркой и т.п. Файловые системы типа JFFS и новомодная ZFS именно то же делают -записывают на свободное место, а потом разбираются с мусоркой (в JFFS - garbage collection). Но оказывается задачи подобного рода - гарантированная запись некоего блока данных - возникали и раньше, например, в бесконтактных фискальных системах (карточки Mifare). Дык там это не пальцы загибать, а денюжки хранить. Не очень понял как это касается темы спора встроенные vs собственные средства работы с EEPROM ? Если вы о том что нужно таки аппаратными средствами обеспечить запись в eeprom, Цитата ЧТо придумывать будем?  )) то придумывать ничего нового не будем, уже все придумано. Транзакция считается законченой когда записано обе копии данных в EEPROM. Если бы Вы внимательно читали мои посты, например пост №54 то Вы бы заметили что мой автомат апдейтит две копии данных и по ходу для каждой из них сохраняет/проверяет CRC.
|
|
|
|
|
Oct 2 2007, 20:32
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата Как сохранить текущую конфигурацию прибора при пропадании питания. - я писал? а это - Цитата Обычно(чаше всего) обсуждение ведется в русле того, что нужно аппаратными средствами обеспечить работу контроллера еще какое-то время для того, чтобы успеть записать эту самую конфигурацию.
Может все-таки стоит в подобных ситуациях озаботиться возможностью "ВСЕГДА" иметь правильную конфигурацию в EEPROM ? Озаботились кроме Вас ещё много людей и я Вам написал о том, что проблема не нова. И независимо от Вашего некоего "автомата" давно успешно решаема. Если Вы не знакомы с известными решениями, то это не повод рассказывать о том, что кроме Вашего решения (крохи которого Вы попытались громко показать) ничего иного нет  )) Цитата транзакция считается законченой когда записано обе копии данных в EEPROM.
Если бы Вы внимательно читали мои посты, Простите, но не заставляйте ассоциировать себя с героем старого анекдота "чукча не читатель - чукча писатель". Лучше всё-таки расскажите, чем отличается Ваше решение от общеизвестных, кроме как авторством кода и неприятием готовых решений от авторов компиляторов и сопутствующих библиотек.
--------------------
aka Vit
|
|
|
|
|
Oct 2 2007, 20:56
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(sensor_ua @ Oct 3 2007, 00:32)  Озаботились кроме Вас ещё много людей и я Вам написал о том, что проблема не нова. И независимо от Вашего некоего "автомата" давно успешно решаема. Если Вы не знакомы с известными решениями, то это не повод рассказывать о том, что кроме Вашего решения (крохи которого Вы попытались громко показать) ничего иного нет  )) Я и не пытаюсь себе присваивать пальму первенства, более того, я уверен что те решения о которых я говорю применяются очень широко. Тока почему то на электрониксе очень многим они не нравятся  Цитата Лучше всё-таки расскажите, чем отличается Ваше решение от общеизвестных, кроме как авторством кода и неприятием готовых решений от авторов компиляторов и сопутствующих библиотек. Если Вас не убедило 33 такта против 81 на записи одного байта (да еще и в ситуации когда цейтнот и питания осталось совсем мало), то я не смогу Вам объяснить чем мое решение лучше... А если Вы действительно хотите разобраться со всеми нюансами сохранения правильной конфигурации в EEPROM, то давайте это обсуждать, тока без вариантов типа в IAR это сделано круто и ничего другого я знать не хочу, и я думаю что тоже узнаю для себя что-то новое.
|
|
|
|
|
Oct 2 2007, 21:44
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Oct 2 2007, 23:56)  Если Вас не убедило 33 такта против 81 на записи одного байта (да еще и в ситуации когда цейтнот и питания осталось совсем мало), то я не смогу Вам объяснить чем мое решение лучше... Да какая разница сколько тактов уйдет на sheduling записи одного байта. Операция записи длится 3-5ms, ответьте - сколько раз при этом будет осуществлен вызов вашего автомата и "отвал" по факту занятости eeprom, сколько тактов это сожрет? Не кажется ли вам, что разница 81-33 = 48 тактов просто мизерная и стремится к нулю на фоне постоянных накладных расходов автомата. Кстати откуда 81 такт? (eeprom char *)xxx = YY - это 14 инструкций с отключенной оптимизацией Цитата А если Вы действительно хотите разобраться со всеми нюансами сохранения правильной конфигурации в EEPROM, то давайте это обсуждать что тут обсуждать. три основных момента - залог успеха: 1. пакетная организация, 2. CRC обязательно. 3. Дублировать записи. Цитата тока без вариантов типа в IAR это сделано круто и ничего другого я знать не хочу, Вы то хоть поняли что в IAR сделано? И как то, что сделано в IAR кореллирует с тем, что выставляете вы? Уровни же разные совершенно, вы хотите сопоставить пакетный уровень, байт уровню? Типа - да начерта нам эти сигналы всякие, биты, байты, вот IE с http прекрасно работает..
|
|
|
|
|
Oct 3 2007, 04:22
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(singlskv @ Oct 2 2007, 22:06)  Может все-таки стоит в подобных ситуациях озаботиться возможностью "ВСЕГДА" иметь правильную конфигурацию в EEPROM ? Правда для этого(часто) придется написать свой код общения с EEPROM.  Если у меня правильная конфигурация (состояния автоматов) меняется примерно раз в минуту, то дырку я протру за 100К/60/24 = 70 дней. Если я растиражирую эту запись 10 раз - то за 700 дней. Правда, епром у меня используется впритык, и максимум, что я могу - это 3 копии. Т.е. 70*3 = 210 дней. Все равно мало. Поэтому приходится иметь парковку... Кст, насчет спора собственные функции \ встроенные средства. Сам для епрома использую собственные - с автоматическим тиражированием, CRC и работающие в фоне. А вот для доступа к флэшу использую модификатор __flash. По моему, вполне удобно.
|
|
|
|
|
Oct 3 2007, 05:16
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата(singlskv @ Oct 2 2007, 23:56)  Я и не пытаюсь себе присваивать пальму первенства, более того, я уверен что те решения о которых я говорю применяются очень широко. Тока почему то на электрониксе очень многим они не нравятся  Если Вас не убедило 33 такта против 81 на записи одного байта (да еще и в ситуации когда цейтнот и питания осталось совсем мало), то я не смогу Вам объяснить чем мое решение лучше... А если Вы действительно хотите разобраться со всеми нюансами сохранения правильной конфигурации в EEPROM, то давайте это обсуждать, тока без вариантов типа в IAR это сделано круто и ничего другого я знать не хочу, и я думаю что тоже узнаю для себя что-то новое. 8.5 МИЛЛИСЕКУНД продолжается запись. Какие такты кого спасут? IMNHO, Вы путаете время записи адреса и данных для АППАРАТНОЙ записи с продолжительностью самой записи. И, кроме того, извините, но глядя на кусочек кода (вероятно это код Вашего автомата), не только у меня возникли сомнения в его корректности. Вопрос же о хранении и валидности данных касается более алгоритмов хранения, а не реализации их в конкретном драйвере, о котором кроме дифирамбов никакой инфы, кроме неиспользования штатных средств, толком и не было.
--------------------
aka Vit
|
|
|
|
|
Oct 3 2007, 05:38
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(sensor_ua @ Oct 2 2007, 17:18)  Пытался. Используются несуществующие регистры RAMPx. Проблема (сомневаюсь, что показалось) нерешаема. Ну я в IDA размотал этот кусок, где он генерирует комманду записи в RAMPx, ее можно там заменить, пропатчив экзешник конечно, штатными средствами не получится. Только что-то меня остановило, уже не помню что.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Oct 3 2007, 06:58
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата он генерирует комманду записи в RAMPx, ее можно там заменить, пропатчив экзешник Уже не помню, но кроме адресации по смещению какие-то нюансы с регистрами передачи параметров в функции были.
--------------------
aka Vit
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|