|
Как вразумить avr-gcc ?, Компилятор заоптимизировал volatile переменную |
|
|
|
Oct 23 2006, 08:55
|
Частый гость
 
Группа: Validating
Сообщений: 169
Регистрация: 10-11-04
Из: Челябинск
Пользователь №: 1 088

|
Пробую avr-gcc-3.3.1 и avr-gcc-4.1.1. C-шный текст прост: в цикле проверяется значение переменной и если оно, скажем, не ноль, то цикл продолжает крутиться. Если бы переменная не была изменяемая извне (прерыванием), то тогда бы такой код совершенно надёжно был бы вечно зацикленным. Однако прерывание меняет переменную. Но компилятор почему-то даже объявленную переменную как volatile, засасывает в регистры и потом, в цикле, проверяет содержимое регистров, куда ты была засосана. А прерывание, как все нормальные функции, берёт переменную в ОЗУ по её адресу, меняет, и кладёт назад. таким образом, цикл не почувстует изменение переменной, что не есть гут. Если я ставлю отпимизацию -O0, то всё ОК, ошибки нет. Если -O2, -Os, то всё, неправильно - заоптимизируется до регистров. Оставлять оптимизацию -O0 - не кошерно, не годится. Что сделать, чтобы компилятор перестал игнорировать спецификатор(модификатор) volatile ?
Спасибо.
|
|
|
|
|
 |
Ответов
|
Oct 23 2006, 09:19
|
Частый гость
 
Группа: Validating
Сообщений: 169
Регистрация: 10-11-04
Из: Челябинск
Пользователь №: 1 088

|
Цитата(aesok @ Oct 23 2006, 12:07)  GCC не игнорирует volatile!!! Ошибка в чем то другом. Показывайте код.
Анатолий. Показываю (прошу прощения за кривое форматирование: не могу своим умом постигнуть, как в этом форуме делать вёрстку, может, оттого, что не знаю html ?) : Фрагмент файл uart.c: ****** Код #include "interface/uart.h" uint8_t pushToDebugBuffer(uint8_t symbol){ DEBUG_TX_INT_LOCK(); while(debugPushCursor == debugPopCursor){ DEBUG_TX_INT_UNLOCK(); SLEEP(); DEBUG_TX_INT_LOCK(); } *debugPushCursor = symbol; debugPushCursor = nextAddress(debugPushCursor); DEBUG_TX_INT_UNLOCK(); if(!globIntFlags.isDebugPortBusy) popFromDebugBuffer(); //если передача когда-то закончилась, то возобновляем её return symbol; } ****** Фрагмент файла uart.h (макрос CLARBIT, SETBIT просто логическая операция над портом, определно где-то, ) : ******* Код //SPECPREFIX пустой, если заголовок подключается из uart.c, и равен extern, если другими SPECPREFIX uint8_t debugBuffer[32]; SPECPREFIX volatile uint8_t *debugPushCursor; SPECPREFIX volatile uint8_t *debugPopCursor;
#define DEBUG_TX_INT_LOCK(s) CLEARBIT(UCSR1B, TXCIE1) #define DEBUG_TX_INT_UNLOCK(s) SETBIT(UCSR1B, TXCIE1) *******
Фрагмент кода прерывания:
****** #include "interface/uart.h" INTERRUPT(/*SIG_UART0_TRANS*/SIG_USART1_TRANS){ // например, debugPopCursor++; } ******
|
|
|
|
|
Oct 23 2006, 09:51
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Вот результат компиляции по мотивам приведеннго выше кода сорцы Код #include <avr/io.h> #include <avr/interrupt.h>
uint8_t volatile debugPopCursor; // достуап к debugPopCursor в режиме приложения void AppMode (uint8_t* Tmp ) { while(*Tmp == debugPopCursor) { debugPopCursor++; }
Tmp = &debugPopCursor; debugPopCursor -= 10; }
// достуап к debugPopCursor в режиме прерывания ISR(USART_TX_vect) { debugPopCursor++; } листинг Код uint8_t volatile debugPopCursor; // достуап к debugPopCursor в режиме приложения void AppMode (uint8_t* Tmp ) { 148: fc 01 movw r30, r24 14a: 05 c0 rjmp .+10 ; 0x156 <AppMode+0xe> while(*Tmp == debugPopCursor) { debugPopCursor++; 14c: 80 91 0d 01 lds r24, 0x010D 150: 8f 5f subi r24, 0xFF; 255 152: 80 93 0d 01 sts 0x010D, r24 156: 90 91 0d 01 lds r25, 0x010D 15a: 80 81 ld r24, Z 15c: 89 17 cp r24, r25 15e: b1 f3 breq .-20 ; 0x14c <AppMode+0x4> }
Tmp = &debugPopCursor; debugPopCursor -= 10; 160: 80 91 0d 01 lds r24, 0x010D 164: 8a 50 subi r24, 0x0A; 10 166: 80 93 0d 01 sts 0x010D, r24 16a: 08 95 ret
0000016c <__vector_20>: }
// достуап к debugPopCursor в режиме прерывания ISR(USART_TX_vect) { 16c: 1f 92 push r1 16e: 0f 92 push r0 170: 0f b6 in r0, 0x3f; 63 172: 0f 92 push r0 174: 11 24 eor r1, r1 176: 8f 93 push r24 debugPopCursor++; 178: 80 91 0d 01 lds r24, 0x010D 17c: 8f 5f subi r24, 0xFF; 255 17e: 80 93 0d 01 sts 0x010D, r24 182: 8f 91 pop r24 184: 0f 90 pop r0 186: 0f be out 0x3f, r0; 63 188: 0f 90 pop r0 18a: 1f 90 pop r1 18c: 18 95 reti Переменная заложена в 0x010D и никаких глюков. Давайте разбиратся.
|
|
|
|
|
Oct 23 2006, 10:07
|
Частый гость
 
Группа: Validating
Сообщений: 169
Регистрация: 10-11-04
Из: Челябинск
Пользователь №: 1 088

|
Цитата(klen @ Oct 23 2006, 12:51)  Вот результат компиляции по мотивам приведеннго выше кода Давайте разбиратся. Давайте. Я сейчас погляжу, поразмыслю, и напишу, что надумал. Спасибо за участие, насколькоя понял - вы из команды разработчиков GCC ? Тем более приятно
|
|
|
|
Сообщений в этой теме
impatt Как вразумить avr-gcc ? Oct 23 2006, 08:55 prottoss Цитата(impatt @ Oct 23 2006, 16:55) Пробу... Oct 23 2006, 09:02 impatt Цитата(prottoss @ Oct 23 2006, 12:02) Цит... Oct 23 2006, 09:10 zltigo Цитата(prottoss @ Oct 23 2006, 12:02) дан... Oct 23 2006, 09:18  aesok SPECPREFIX volatile uint8_t *debugPushCursor;
Есл... Oct 23 2006, 09:32   impatt Цитата(aesok @ Oct 23 2006, 12:32) SPECPR... Oct 23 2006, 09:48  zltigo Цитата(impatt @ Oct 23 2006, 12:19) Показ... Oct 23 2006, 09:35   impatt Цитата(klen @ Oct 23 2006, 12:51) Вот рез... Oct 23 2006, 10:47    aesok Что генерирует GCC смогу посмотреть вечером. (точ... Oct 23 2006, 11:45    Сергей Борщ Цитата(impatt @ Oct 23 2006, 13:47) Польз... Oct 23 2006, 11:56     impatt Цитата(Сергей Борщ @ Oct 23 2006, 14:56) ... Oct 24 2006, 02:06      zltigo Цитата(impatt @ Oct 24 2006, 05:06) Тепер... Oct 24 2006, 07:11       impatt Цитата(zltigo @ Oct 24 2006, 10:11) Вещь ... Oct 24 2006, 07:54 Andy Great ЦитатаТеперь вопрос-завершение: откуда узнаются та... Oct 24 2006, 08:06
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|