глюки в AVR-GCC ?

Привет Всем ! Есть вопросики. Стал опримизировать прогу на С (AVR GCC) и сталкнулся с некоторыми непонятными вещами.

  1. Каким образом закрепить за переменной указателем регистр? Если у нас есть переменная типа char - то все понятно - register unsigned char spiW asm("r3"). Ну а если типа указатель на char ? И я хочу закрепить за регистрами X или Y.
  2. следующий кусок кода: { *(spi_ptr++) = SPDR; SPDR = packCnt; ++packCnt; } ассемблируется в следующий код (с флагом оптимизации -O3) { *(spi_ptr++) = SPDR; 28e: 7f b1 in r23, 0x0f ; 15 290: 71 93 st Z+, r23 292: f0 93 61 00 sts 0x0061, r31 296: e0 93 60 00 sts 0x0060, r30 SPDR = packCnt; Хотя spi_ptr обьявлен как volatile unsigned char *spi_ptr. Почему же он не обнавляется на каждом витке цикла ? Тоесть в прерываниях я изменяю spi_ptr, а реально он не меняется :( В чём же дело ?
  3. В том же куске кода непонятно что будет, если произойдет прерывание между инструкциями sts 0x0061, r31 и sts 0x0060, r30 ? тоесть в ячейке
0x0061 будет новое значение (записаное по прерыванию), а в 0x0060 - старое ? Как же быть ? P.S. у меня avr-gcc (GCC) 3.4.1 Спасибо за исчерпывающие ответы :)
Reply to
Alexy Gorbach
Loading thread data ...
19-Nov-04 16:46 Alexy Gorbach wrote to All:

AG> 1. Каким образом закрепить за переменной указателем регистр? Если у нас AG> есть переменная типа char - то все понятно - register unsigned char spiW AG> asm("r3"). Ну а если типа указатель на char ? И я хочу закрепить за AG> регистрами X или Y. Не знаю, такими вещами не баловался.

AG> 2. следующий кусок кода: AG> { AG> *(spi_ptr++) = SPDR;

AG> Хотя spi_ptr обьявлен как volatile unsigned char *spi_ptr. Почему же он AG> не обнавляется на каждом витке цикла ? Одно из распространённых заблуждений. Аналогичное легендам про const char *ptr и char const *ptr :-)

В данном случае volatile относится не к spi_ptr, а к (*spi_ptr). Т.е. volatile - та ячейка, на которую указывает указатель.

Для volatile-указателя надо написать

unsigned char * volatile spi_ptr;

AG> 3. В том же куске кода непонятно что будет, если произойдет прерывание AG> между инструкциями sts 0x0061, r31 и sts 0x0060, r30 ? тоесть AG> в ячейке AG> 0x0061 будет новое значение (записаное по прерыванию), а в 0x0060 - AG> старое ? Как же быть ? Ручками заводит критическую секцию (запрещат все для простоты или только нужное прерывание на время как доставания указателя в регистр, так и записи его назад). В языке C слово volatile только говорит компилятору о том, что переменная может измениться "неожиданно" и нельзя оптимизировать обращения к ней за счёт кеширования в регистрах. На проблемы неатомарных операций и прерываний действие volatile не распространяется.

AG> P.S. у меня avr-gcc (GCC) 3.4.1 Вопросы 2 и 3 должны иметь одинаковые ответы для любого C-компилятора. (а не компилятора С-подобного языка, все тонкости которого известны только авторам компилятора).

wbr,

Reply to
Oleksandr Redchuk

AG> 2. следующий кусок кода: AG> { AG> *(spi_ptr++) = SPDR; AG> SPDR = packCnt; AG> ++packCnt; AG> } AG> ассемблируется в следующий код (с флагом оптимизации -O3) { AG> *(spi_ptr++) = SPDR; AG> 28e: 7f b1 in r23, 0x0f ; 15 AG> 290: 71 93 st Z+, r23 AG> 292: f0 93 61 00 sts 0x0061, r31 AG> 296: e0 93 60 00 sts 0x0060, r30 AG> SPDR = packCnt; AG> Хотя spi_ptr обьявлен как volatile unsigned char *spi_ptr. Почему же он AG> не обнавляется на каждом витке цикла ?

А что по-твоему делается в адресах 290, 292 и 296?

AG> Тоесть в прерываниях я изменяю AG> spi_ptr, а реально он не меняется :( В чём же дело ? AG> 3. В том же куске кода непонятно что будет, если произойдет прерывание AG> между инструкциями sts 0x0061, r31 и sts 0x0060, r30 ? тоесть в ячейке AG> 0x0061 будет новое значение (записаное по прерыванию), а в 0x0060 - AG> старое ? Как же быть ?

volatile от прерываний не помогает (никто и не обещал...) Hужен отдельный вид блокировки, в данном случае проще на пару команд запретить все прерывания.

Reply to
Kirill Frolov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.