Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Вопросы по С/С++ (СИ)

Сообщение zero648 »

Не вижу файл исходника, в source code в окошке выбора файла показывает только файлы .c или .asm
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Воооооо. Пошла вода по трубам. Спасип тебе мил человек.

Для полногот счастья только не хватает точек останова, все истыкал, не могу найти как на нужную строку поставить точку останова.....
(толи я такой тупой, толи протеус настолько замудрен что с ходу не допереть)
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Вопросы по С/С++ (СИ)

Сообщение zero648 »

Кликаешь на нужную строку, чтобы стала синей и нажимаешь F9, закрашеная точка - остановка разрешена, пустая точка - остановка запрещена.
a_skr
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Re: Вопросы по С/С++ (СИ)

Сообщение a_skr »

shads писал(а):Понял. Но мне еще нужно работать с отдельными байтами данного числа, как это делается, с помощью указателя?

(Для ясности, опишу подробнее задачу:
Схемка на АВР обрабатывает радиосигнал с приемника 433МГц. Посылка с радиобрелка состоит из 3-х байт, вернее 24 бита (они передаются сплошным потоком). Т.е. мне нужно каждый принятый бит впихнуть в эти 3 байта, и после завершения приема, проанализировать эти 3 байта по отдельности.)

выделяем 4 байта
char bytes[4];
создаем указатель на наши байты
long *dword = (long *)bytes;
или
long *dword = (long *)&bytes[0];
принимаем биты (старший - первый):
for(i=0; i<24; i++)
{
*dword <<=1;
if(приняли 1) *dword |= 1;
}
или младший - первый:
for(i=0; i<24; i++)
{
if(приняли 1) *dword |= 0x01000000;
*dword >>= 1;
}
обращаемся к информации побайтно
bytes[0]
bytes[1]
bytes[2]
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

zero648 писал(а):Кликаешь на нужную строку, чтобы стала синей и нажимаешь F9, закрашеная точка - остановка разрешена, пустая точка - остановка запрещена.

Гы..... Не срабатывает.....

Я понял почему я не мог найти. Оказ-ся эта ф-ция у меня не активна, поэтому я ее не увидел (такая светлая надпись, что ее и не приметить). Что это может быть?
точки.gif
(31.75 КБ) 324 скачивания





ОТБОЙ! разобрался, оказ-ся я просто становился не на те строки на которых можно точки останова делать.....
Последний раз редактировалось shads Сб авг 04, 2012 23:09:38, всего редактировалось 1 раз.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

a_skr писал(а):...
Спасибо. Попробую разобраться, хотя сразу сложновато, т.к. с указателями еще не работал.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение avreal »

Можно и без указателей.

Код: Выделить всё

union {  // размещаем следующие переменные, накладывая их друг на друга
    unsigned char b[4];
    unsigned long dw;
} buf;


    for (i=0; i<24; i++) {
        wait_bit();
        buf.dw <<=1;
        if (input_active())  buf.dw |= 1;
    }

Обращаемся к buf.b[0] ... buf.b[2]
В зависимости от условий код можно построить по разному, может оказаться короче код при наличии временной переменной размера unsigned long или принятую единичку записывать как buf.b[0] |= 1;
Всякие достоинства-недостатки все те же, что и в варианте с указателем. Даже лучше — вариант с указателем может гавкнуться на 32-битном процессоре с запретом невыровненного доступа к 32-битным переменным, так как массив байтов может разместиться не с «круглого» адреса. А union буде выровнено на самый большой член, всё корректно.
Остаётся только BIG ENDIAN / LITTLE ENDIAN, но оно у union и указателя одинаковые проблемы вызовет (обращаться надо будет к b[3]..b[1] вместо b[0]..b[2].

Можно просто принимать в переменную unsigned long, а потом рассыпать её на отдельные байты.

Код: Выделить всё

unsigned long rxbuf;

    for (i=0; i<24; i++) {
        wait_bit();
        rxbuf <<=1;
        if (input_active())  rxbuf |= 1;
    }
 
    // обработка
    unsigned char rx_0 = (unsigned char) rxbuf;
    unsigned char rx_1 = (unsigned char) (rxbuf >> 8);
    unsigned char rx_2 = (unsigned char) (rxbuf >> 16);
Тут может быть больше кода, но зато всё строго, без никаких проблем с выравниванием и «ну на этом контроллере с этим компилятором нулевой байт массива наложится на младший байт двойного слова».
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Спасибо AVREAL, что стока времени уделили, да еще с примерами.

avreal писал(а):Можно и без указателей. union
Тут тоже надо будет помороковать, т.к. что указатели, что union, для меня пока темный лес. Надо будет пошшупать что это такое.

avreal писал(а):Можно просто принимать в переменную unsigned long, а потом рассыпать её на отдельные байты.
Ооо.... А вот это помоему самэ то!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Можно ещё так:

Код: Выделить всё

#define GET_BYTE(var, byte_num)    *((unsigned char*)&(var)+(byte_num))

unsigned long rxbuf;

.............
.............
.............

unsigned char rx_0 = GET_BYTE(rxbuf, 0)
unsigned char rx_1 = GET_BYTE(rxbuf, 1);
unsigned char rx_2 = GET_BYTE(rxbuf, 2);
В этом случае, какой бы тупой компиль не был, он будет вытягивать байты напрямую, без всяких лишних телодвижений.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Все пучком! Отладка пошла.....
Но есть один странный момент, чегото не учел, подскажите чего.....

Определяю глобальную переменную

Код: Выделить всё

unsigned long ReceiveData;


В функции приема бита, принятый бит задвигаю в эту переменную вот так:

Код: Выделить всё

ReceiveData <<= 1;
if (BitLoPartCoun < BitHiPartCoun)
   ReceiveData |=1;


В итоге при отладке вижу что каждый раз бит записывается в глобальную переменную, но она перед этим каждый раз обнуляется.
В дизассемблере глянул этот участок, действительно все 4 байта сначала обнуляются а уже потом дописывается бит.

Шо творится..... шо творится.....
Изображение
Вложения
txt.png
(14.66 КБ) 604 скачивания
Последний раз редактировалось shads Вс авг 05, 2012 15:11:03, всего редактировалось 1 раз.
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: Вопросы по С/С++ (СИ)

Сообщение U235 »

Код: Выделить всё

ReceiveData << 1;
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

U235 писал(а):

Код: Выделить всё

ReceiveData << 1;
:shock:
Вы уверены ?

Тогда уж

Код: Выделить всё

ReceiveData = ReceiveData << 1;
Что равносильно

Код: Выделить всё

ReceiveData <<= 1;
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

U235 писал(а):

Код: Выделить всё

ReceiveData << 1;
Ошибку кажеть..... типа не будет эффекту.....
Аватара пользователя
U235
Встал на лапы
Сообщения: 135
Зарегистрирован: Вт фев 21, 2012 20:42:26
Откуда: Санкт-Петербург, Россия, Земля

Re: Вопросы по С/С++ (СИ)

Сообщение U235 »

Аlex писал(а):Вы уверены ?

Точно, ступил второпях :facepalm:
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

типа не будет эффекту.....
Конечно не будет.

Код: Выделить всё

ReceiveData << 1
это просто выражение, и его нужно куда-то деть(присвоить чему либо).
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Эге.....
Начинаю потихоньку въезжать.....
Оказ-ся это оптимизатор чудит, поставил перед объявлением переменной volatile и другое дело.....

Изображение
txt1.png
(23.31 КБ) 451 скачивание

Хотя теперь компилятор совсем тупит. Сдвинул переменную, записал ее в память, и вместо того чтобы тутже, к актуальным регистрам дописать бит, опять читает данные из памяти.....
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Вопросы по С/С++ (СИ)

Сообщение zero648 »

Почему тупит, интерпретирует каждую строку С, без оптимизации типа

Вроде все прально так то:

lds r24,0x0066 ; читает уже сдвинутую переменную
ori r24,0x01 ; включает младший бит
sts 0x0066,r24 ; сохраняет её обратно, где взял
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

zero648 писал(а):Почему тупит, интерпретирует каждую строку С, без оптимизации типа
Ну да все нормально, все работает.

Просто я имею ввиду что lds r24,0x0066 (и еще 3 подобных команды) можно было не делать, т.к. эти данные только что были сохранены из этих же регистров. Т.е. 8 байтов флэша пропали просто так.....

P.S. Я просто на асме привык каждый байт экономить, теперь придется привыкать их транжырить.....
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Ради прикола:

Последний вышеприведенный фрагмент, в интерпретации С компилятора, занимает 78 байт (ну или 39 слов, кому как удобно).

А вот вариант как бы я сделал на асме, занимает 30 байт (или 15 слов) 38 байт, (19 слов), ошибся малость, там перед CP командой надо сохранить 4 регистра т.е. еще +8 байт (4 слова). Но все равно разница ощутимая.

Изображение
txt.png
(5.73 КБ) 529 скачиваний

P.S. Ну это достаточно емкий участок, неудивительно что компиль так поступает.
В большинстве случаев (особенно при работе с char) получается нормальный компактный код, в чем я убедился.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение avreal »

Во-первых, если volatile, то он не имеет права не зачитать заново.
Во-вторых, без volatile всё уже не так страшно. Я не знаю, откуда берутся те Hi, Lo, поэтому выделил маленький кусочек с hi/lo внешними:

Код: Выделить всё

uint32_t buf;
uint8_t hi, lo;

void r()
{
    buf <<= 1;
    if (hi >= lo) buf |= 1;
}
avr-gcc -Os -S -mmcu=atmega8

Код: Выделить всё

global   r
   .type   r, @function
r:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
   lds r24,buf
   lds r25,buf+1
   lds r26,buf+2
   lds r27,buf+3
   lsl r24
   rol r25
   rol r26
   rol r27
   sts buf,r24
   sts buf+1,r25
   sts buf+2,r26
   sts buf+3,r27
   lds r19,hi    ; ну вот оно
   lds r18,lo    ; слазило за теми hi/lo
   cp r19,r18
   brlo .L1
   ori r24,lo8(1)  ; лишней загрузки нет, но выше лишнее сохранение
   sts buf,r24
   sts buf+1,r25
   sts buf+2,r26
   sts buf+3,r27
.L1:
   ret

В третьих, достаточно слегка объяснить компилятору, что от него хотят

Код: Выделить всё

void r2()
{
    uint32_t temp = buf;
    temp <<= 1;
    if (hi >= lo) temp |= 1;
    buf = temp;
}
и он с криками «ба, да это же Ниагарсикй водопад» генерирует нормальный код даже если buf из других соображений таки volatile.

Код: Выделить всё

.global   r2
   .type   r2, @function
r2:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
   lds r24,buf
   lds r25,buf+1
   lds r26,buf+2
   lds r27,buf+3
   lsl r24
   rol r25
   rol r26
   rol r27
   lds r19,hi
   lds r18,lo
   cp r19,r18
   brlo .L5
   ori r24,lo8(1)
.L5:
   sts buf,r24
   sts buf+1,r25
   sts buf+2,r26
   sts buf+3,r27
/* epilogue start */
   ret
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Ответить

Вернуться в «Разные вопросы по МК»