Do you have a question? Post it now! No Registration Necessary
Subject
- Posted on
глюки в AVR-GCC ?
- 11-19-2004
- Alexy Gorbach
November 19, 2004, 4:46 pm

Привет Всем !
Есть вопросики. Стал опримизировать прогу на С (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
Спасибо за исчерпывающие ответы :)
Есть вопросики. Стал опримизировать прогу на С (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
Спасибо за исчерпывающие ответы :)
--
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Re: глюки в AVR-GCC ?
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,
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,
--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua */
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua */

Re: глюки в AVR-GCC ?
Hемедленно нажми на RESET, Alexy Gorbach!
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ужен отдельный вид блокировки, в данном случае проще на пару
команд запретить все прерывания.
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ужен отдельный вид блокировки, в данном случае проще на пару
команд запретить все прерывания.
--
Black Lord - NEDO-RUL, NEDO-DEL...
Black Lord - NEDO-RUL, NEDO-DEL...
Site Timeline
- » С чего начать?
- — Next thread in » Microcontrollers (Russian)
-
- » linux on p5e
- — Previous thread in » Microcontrollers (Russian)
-
- » По моему это гениально
- — Newest thread in » Microcontrollers (Russian)
-
- » Biblioteka MQTT i dziwny kod w C
- — The site's Newest Thread. Posted in » Electronics (Polish)
-