реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Кто из нас сошел с ума - IAR или я?
Kitsok
сообщение Nov 22 2006, 00:13
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Итак, вот что имеем на входе:
Код
static __arm __irq void vADC_ISR(void)
{

  unsigned portCHAR sr =0;
  unsigned portCHAR i = 0;
  AT91_REG * ADDR;
  
  // Read status register
  sr = a_pADC->ADC_SR;
  
  sBUTTONS[7]=sr;
   for (i=0;i<8;i++)
   {
     ADDR = AT91C_ADC_CDR0 + (4*i);
    
     if ( (sr >> i) & 0x01)
      {
        // Bit is set, put data to array
        sADC_RAW[i] = *(ADDR);
      }
   }
  // Start new conversion
  a_pADC->ADC_CR = 0x2;
  
  /* End the interrupt in the AIC. */  
  AT91C_BASE_AIC->AIC_EOICR = 0;
}



Обратите внимание на переменную ADDR, я слева буду писать значение i, а справа - значение ADDR, полученное при отладке через JTAG:

i=0 ADDR=0xFFFD8030
i=1 ADDR=0xFFFD8040
i=2 ADDR=0xFFFD8050
ну и так далее.

Слушайте, может я умом тронулся, но вроде бы 0xFFFD8030 + 4 == 0xFFFD8034, или я чего-то недопонимаю? Контроллер - SAM7S256

Уж не знаю, почему так, но почему-то с адресом как с обычным числом работать нельзя.
Тупое ADDR= AT91C_ADC_CDR0 + i; заработало. Компиляцкий компилятор перестал умножать на 4....

Сообщение отредактировал Kitsok - Nov 22 2006, 00:20
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 22 2006, 00:27
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Kitsok @ Nov 21 2006, 23:13) *
может я умом тронулся,

Думаем, что такое указатель, почему при определении указателя задается размер объекта на который он указывает ну и дальше совсем просто - как "правильно" должно измениться значение указателя при его наращивании - на "единицу", или на размер объекта на который он указывает?

P.S.
И еще, к вопросу не относящееся - использовать умножение на степень двойки это моветон, хотя компиляторы и творят чудеса.
P.P.S.
И будьте проще:
Код
  for (i=0;i<8;i++)
   {
     if ( (sr >> i) & 0x01)
      {
        // Bit is set, put data to array
        sADC_RAW[i] = AT91C_ADC_CDR0[i];
      }
   }


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 22 2006, 00:38
Сообщение #3


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Дело в том, что ADDR - указатель на Long, поэтому что ADDR[2], что ADDR +2 будет реально смещать на 2 элемента структуры, то есть на 2*4 байт. Если попытаться сделать побайтный адрес то компилер возможно выдаст ошибку. Можно написать так:
ADDR = (char *)AT91C_ADC_CDR0 + (4*i);
Хотя в Вашем случае побайтно делать адреса не стоит. Лучше оставить как есть. Без умножения на 4. Короче, компилятор всё делает как надо.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Kitsok
сообщение Nov 22 2006, 09:47
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136



Спасибо за ответы.

Хотя я первый раз сталкиваюсь с тем, что видя в выражении указатель, компилятор приводит все выражение к указателю. Хоть отругался бы что-ли, что не (вполне) совместимые типы.
Go to the top of the page
 
+Quote Post
sff
сообщение Nov 22 2006, 10:52
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 23-04-06
Пользователь №: 16 404



Цитата(Kitsok @ Nov 22 2006, 09:47) *
Хотя я первый раз сталкиваюсь с тем, что видя в выражении указатель, компилятор приводит все выражение к указателю. Хоть отругался бы что-ли, что не (вполне) совместимые типы.

А на что он должен ругаться???
AT91C_ADC_CDR0 определён как
Код
#define AT91C_ADC_CDR0  ((AT91_REG *)     0xFFFD8030)

и в вашем выражении
Код
ADDR = AT91C_ADC_CDR0 + (4*i);
Типы указателей одинаковые (источника и назначения), и компилятор действует по стандарту как описано выше.

Вот если бы ADDR была другого типа тогда бы ругнулся или прибавляли или вычитали нецелое число.
За исключением
1. void* x = pointer_type_value + numeric_type_value; //Автоматичесики приводит к void*
2. size_t z = pointer_type_value - pointer_type_value2; // типы указателей одинаковые, возвращаемое число есть разность адресов переменных поделенное на размер типа (или структуры).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 22 2006, 11:16
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Kitsok @ Nov 22 2006, 08:47) *
Хотя я первый раз сталкиваюсь с тем, что видя в выражении указатель, компилятор приводит все выражение к указателю. Хоть отругался бы что-ли, что не (вполне) совместимые типы.

Подходите Вы значит к поезду. На каждом вагоне висит указатель 1...2..3...4...5.....6
добавляя к к номеру 1 вагона 4 Вы куда рассчитываете попасть? В 5 вагон или в 5 купе 1 вагона?
Последнее было-бы очень странным, как с точки зрения житейской логики, так и с точки зрения компилятора.
Это я "на пальцах" на случай, если вдруг закралясь мысль, что стандарт языка - "неправильный".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alex03
сообщение Nov 22 2006, 11:49
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(zltigo @ Nov 22 2006, 13:16) *
Подходите Вы значит к поезду. На каждом вагоне висит указатель 1...2..3...4...5.....6
добавляя к к номеру 1 вагона 4 Вы куда рассчитываете попасть? В 5 вагон или в 5 купе 1 вагона?
Последнее было-бы очень странным, как с точки зрения житейской логики, так и с точки зрения компилятора.
Это я "на пальцах" на случай, если вдруг закралясь мысль, что стандарт языка - "неправильный".


Это типа "мама приехала в 4-ом вагоне после первого" или как? biggrin.gif Т.е. пример не очень! smile.gif

Ну и по сабжу надо упомянуть что архитектуры всякие бывают, и не всегда можно прямо адресовать байт, а порой и байтов то нет, т.е. есть n-разрядные слова. И каков физический смысл битов переменной указателя известно лишь компиллеру.
Так что в Сях всё как надо, хотя сто лет назад после АСМа тоже не понимал почему в АСМе прибавляю 4 а в Сях 1 надо.! smile.gif

Как пример:
16-ти разрядный девайс (по крайней мере память) без возможности адресации непосредственно к байтам. Зачастую в такой сиситеме указатель (внутренний не Сишный) имеет шаг в 16-ти битное слово. И
Код
    uint8_t buff8[X];

и
Код
    uint16_t buff16[X];

будут иметь одинаковый размер, в первом случае половина объёма буфера не используется.
Далее уже модификаторы переменных или там опции компиллера позволяют исправить такую ситуювину (со своими проблемами типа оверхеда по коду/скорости).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 22 2006, 12:32
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Alex03 @ Nov 22 2006, 10:49) *
хотя сто лет назад после АСМа тоже не понимал почему в АСМе прибавляю 4 а в Сях 1 надо.! smile.gif

Это потому, что Вы на ASMе скорее всего его возможностями не пользовались - многие ASM вполне приличный сервис по структурам представляют и соответственно оперировать можно и нужно просто именами, не говоря уже о банальных вещах использования size вместо "магических" чисел.
Код
imul    bx,size Command
add     bx,offset beginn_c_array
call    ds:[bx].pointer

Вполне себе на одном из ASM написано и никаких раздумий "сколько прибавлять".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
rezident
сообщение Nov 23 2006, 02:04
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Alex03 @ Nov 22 2006, 13:49) *
Ну и по сабжу надо упомянуть что архитектуры всякие бывают, и не всегда можно прямо адресовать байт, а порой и байтов то нет, т.е. есть n-разрядные слова. И каков физический смысл битов переменной указателя известно лишь компиллеру.
Так что в Сях всё как надо, хотя сто лет назад после АСМа тоже не понимал почему в АСМе прибавляю 4 а в Сях 1 надо.! smile.gif

Как пример:
16-ти разрядный девайс (по крайней мере память) без возможности адресации непосредственно к байтам. Зачастую в такой сиситеме указатель (внутренний не Сишный) имеет шаг в 16-ти битное слово. И
Код
    uint8_t buff8[X];

и
Код
    uint16_t buff16[X];

будут иметь одинаковый размер, в первом случае половина объёма буфера не используется.
Далее уже модификаторы переменных или там опции компиллера позволяют исправить такую ситуювину (со своими проблемами типа оверхеда по коду/скорости).

В Си можно с помощью sizeof определить размер типа переменной. Результат будет в количествах байт.
http://publications.gbdirect.co.uk/c_book/...and_malloc.html
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 23:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.02807 секунд с 7
ELECTRONIX ©2004-2016