|
Winavr сокращает функцию, если переменные размещены в регистрах |
|
|
|
Jun 12 2008, 06:21
|
Участник

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732

|
Цитата(Сергей Борщ @ Jun 11 2008, 19:48)  А, теперь понял. Идем в avr/io.h, ищем, где и как определен макрос _SFR_IO16(). Находим его в avr/sfr_defs.h: Код #define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr)) #define _MMIO_WORD(mem_addr) (*(volatile uint16_t *)(mem_addr)) #define _MMIO_DWORD(mem_addr) (*(volatile uint32_t *)(mem_addr))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + 0x20) #define _SFR_IO16(io_addr) _MMIO_WORD((io_addr) + 0x20) Дописываем в своем файле Код #define _SFR_IO32(io_addr) _MMIO_DWORD((io_addr) + 0x20) и радуемся.Какие трудности? При побайтовом доступе запись в программе на С усложняется, только и всего. Или вы имели ввиду другие трудности? Действительно, работает, хотя я раньше так уже пробовал. Мне казалось, что результат компиляции неработоспособен из-за таких разных команд как OUT и STS: Код var16++; +00000044: B18E IN R24,0x0E +00000045: B19F IN R25,0x0F +00000046: 9601 ADIW R24,0x01 +00000047: B99F OUT 0x0F,R25 +00000048: B98E OUT 0x0E,R24 var32++; +00000049: 91800029 LDS R24,0x0029 +0000004B: 9190002A LDS R25,0x002A +0000004D: 91A0002B LDS R26,0x002B +0000004F: 91B0002C LDS R27,0x002C +00000051: 9601 ADIW R24,0x01 +00000052: 1DA1 ADC R26,R1 +00000053: 1DB1 ADC R27,R1 +00000054: 93800029 STS 0x0029,R24 +00000056: 9390002A STS 0x002A,R25 +00000058: 93A0002B STS 0x002B,R26 +0000005A: 93B0002C STS 0x002C,R27 Всё правильно, только команды IN и OUT здесь были бы более уместны  . А как бы компилятору это намекнуть?
|
|
|
|
|
Jun 12 2008, 11:50
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(AHTOXA @ Jun 11 2008, 17:33)  Странно... avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221): Код 00000048 <timer_ms>: 48: 2b 01 movw r4, r22 4a: 3c 01 movw r6, r24 4c: 88 24 eor r8, r8 4e: ff cf rjmp .-2 ; 0x4e <timer_ms+0x6> Цитата(AHTOXA @ Jun 11 2008, 22:44)  Это без volatile. Тогда ничего странного - без volatile это совершенно правильный код, т.к. timer_ms никогда не завершится. Я компилировал код, приведенный в первом посте. Без каких-либо изменений. Цитата(AHTOXA @ Jun 11 2008, 17:33)  А у Вас какой GCC 4.2.2? Хочу такой же  ? не понимаю вопроса. У меня avr-gcc-4.2.2. Цитата(aesok @ Jun 12 2008, 01:57)  Во вторых почему нельзя использовать глобальные регистровые переменные в обработчиках прерываний. r2-r7 - это call-saved регистры, то-есть если есть большая функция для которой генерируется код использующий эти регистры то при В таких случаях помогает -ffixed-reg. У меня есть целая линейка проектов, где обмен данными между обработчиком прерываний и основной программой идет именно через регистры, и таких регистров аж 8 штук. Остальным функциям просто запрещено ими пользоваться в своих личных целях.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Jun 12 2008, 12:22
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(alx2 @ Jun 12 2008, 15:50)  Я компилировал код, приведенный в первом посте. Без каких-либо изменений. ? не понимаю вопроса. У меня avr-gcc-4.2.2. Да, я могу подтвердить это, код c volatile компактный и корректный. ИТОГО на этом коде: WinAVR 20060421 (Gcc 3.4.6) работает и с и без volatile WinAVR 20070525 (Gcc 4.1.2) не работает WinAVR 20071221 (Gcc 4.2.2) работает с volatile WinAVR 20080512 (Gcc 4.3.0) не работает WinAVR 200XYYZZ (Gcc 4.4.X) будет ругаться варнингом, про работоспособность ??? Сейчас попробую пособирать свои проекты с похожими конструкциями на 4.2.2
|
|
|
|
|
Jun 12 2008, 19:04
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(AHTOXA @ Jun 12 2008, 22:20)  А я компилировал код, приведённый в посте №9, там нет volatile  Теперь всё понятно, вопрос снят  Да, это я посоветовал попробовать убрать volatile т.к. на версиях 3.4.? оно вызывало варнинг и небольшое изменение кода. Т.к. я пока сижу на 3.4.6 проблем с регистровыми переменными не наблюдалось, но ведь когда-то все равно придеться переползать на что-нить поновее хотя бы из-за поддержки новых чипов... поэтому и пытаюсь понять на какую версию стоит переползать (отказываться от регистровых переменных очень не хочется, иногда это дает выигрыш в разы...) Потестировал немного 4.2.2 , вроде все корректно, правда выигрыша по оптимизации я не получил по сравнению с 3.4.6, где-то один быстрее где-то другой, по сумме, 3.4.6 на моих проектах оказался даже чуть быстрее, но разница не принципиальна. Единственный не до конца приятный/понятный момент при работе с регистровыми переменными на 4.2.2 это при чтении/записи IO в/из регистровой переменной: Код volatile register unsigned char pinb asm("r2"); ........ //запись PORTB = pinb; ; 8e: 28 ba out 0x18, r2; 24
// чтение pinb = PINB; ; a8: 86 b3 in r24, 0x16; 22 ; aa: 28 2e mov r2, r24 Почему при записи он писал прямо а при чтении читал в r24 ? 3.4.6 обходился без r24
|
|
|
|
|
Jun 12 2008, 20:51
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(singlskv @ Jun 12 2008, 17:22)  ИТОГО на этом коде: WinAVR 20060421 (Gcc 3.4.6) работает и с и без volatile WinAVR 20070525 (Gcc 4.1.2) не работает WinAVR 20071221 (Gcc 4.2.2) работает с volatile WinAVR 20080512 (Gcc 4.3.0) не работает WinAVR 200XYYZZ (Gcc 4.4.X) будет ругаться варнингом, про работоспособность ??? Могу до кучи добавить, что gcc-4.3.1 с -O1 генерит код как gcc-4.2.2, а начиная с -O2 дает rjmp на себя.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|