Вопросы по С/С++ (СИ)
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: Вопросы по С/С++ (СИ)
Не вижу файл исходника, в source code в окошке выбора файла показывает только файлы .c или .asm
Re: Вопросы по С/С++ (СИ)
Воооооо. Пошла вода по трубам. Спасип тебе мил человек.
Для полногот счастья только не хватает точек останова, все истыкал, не могу найти как на нужную строку поставить точку останова.....
(толи я такой тупой, толи протеус настолько замудрен что с ходу не допереть)
Для полногот счастья только не хватает точек останова, все истыкал, не могу найти как на нужную строку поставить точку останова.....
(толи я такой тупой, толи протеус настолько замудрен что с ходу не допереть)
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: Вопросы по С/С++ (СИ)
Кликаешь на нужную строку, чтобы стала синей и нажимаешь F9, закрашеная точка - остановка разрешена, пустая точка - остановка запрещена.
Re: Вопросы по С/С++ (СИ)
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]
Re: Вопросы по С/С++ (СИ)
zero648 писал(а):Кликаешь на нужную строку, чтобы стала синей и нажимаешь F9, закрашеная точка - остановка разрешена, пустая точка - остановка запрещена.
Гы..... Не срабатывает.....
Я понял почему я не мог найти. Оказ-ся эта ф-ция у меня не активна, поэтому я ее не увидел (такая светлая надпись, что ее и не приметить). Что это может быть?
ОТБОЙ! разобрался, оказ-ся я просто становился не на те строки на которых можно точки останова делать.....
Последний раз редактировалось shads Сб авг 04, 2012 23:09:38, всего редактировалось 1 раз.
Re: Вопросы по С/С++ (СИ)
Спасибо. Попробую разобраться, хотя сразу сложновато, т.к. с указателями еще не работал.a_skr писал(а):...
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Можно и без указателей.
Обращаемся к 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, а потом рассыпать её на отдельные байты.
Тут может быть больше кода, но зато всё строго, без никаких проблем с выравниванием и «ну на этом контроллере с этим компилятором нулевой байт массива наложится на младший байт двойного слова».
Код: Выделить всё
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);Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Re: Вопросы по С/С++ (СИ)
Спасибо AVREAL, что стока времени уделили, да еще с примерами.
Тут тоже надо будет помороковать, т.к. что указатели, что union, для меня пока темный лес. Надо будет пошшупать что это такое.avreal писал(а):Можно и без указателей. union
Ооо.... А вот это помоему самэ то!avreal писал(а):Можно просто принимать в переменную unsigned long, а потом рассыпать её на отдельные байты.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Можно ещё так:В этом случае, какой бы тупой компиль не был, он будет вытягивать байты напрямую, без всяких лишних телодвижений.
Код: Выделить всё
#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);
Re: Вопросы по С/С++ (СИ)
Все пучком! Отладка пошла.....
Но есть один странный момент, чегото не учел, подскажите чего.....
Определяю глобальную переменную
В функции приема бита, принятый бит задвигаю в эту переменную вот так:
В итоге при отладке вижу что каждый раз бит записывается в глобальную переменную, но она перед этим каждый раз обнуляется.
В дизассемблере глянул этот участок, действительно все 4 байта сначала обнуляются а уже потом дописывается бит.
Шо творится..... шо творится.....

Но есть один странный момент, чегото не учел, подскажите чего.....
Определяю глобальную переменную
Код: Выделить всё
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: Вопросы по С/С++ (СИ)
Код: Выделить всё
ReceiveData << 1;А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
U235 писал(а):Код: Выделить всё
ReceiveData << 1;
Вы уверены ?
Тогда уж
Код: Выделить всё
ReceiveData = ReceiveData << 1;Код: Выделить всё
ReceiveData <<= 1;Re: Вопросы по С/С++ (СИ)
Ошибку кажеть..... типа не будет эффекту.....U235 писал(а):Код: Выделить всё
ReceiveData << 1;
- U235
- Встал на лапы
- Сообщения: 135
- Зарегистрирован: Вт фев 21, 2012 20:42:26
- Откуда: Санкт-Петербург, Россия, Земля
Re: Вопросы по С/С++ (СИ)
Аlex писал(а):Вы уверены ?
Точно, ступил второпях

А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Конечно не будет.типа не будет эффекту.....
Код: Выделить всё
ReceiveData << 1Re: Вопросы по С/С++ (СИ)
Эге.....
Начинаю потихоньку въезжать.....
Оказ-ся это оптимизатор чудит, поставил перед объявлением переменной volatile и другое дело.....

Хотя теперь компилятор совсем тупит. Сдвинул переменную, записал ее в память, и вместо того чтобы тутже, к актуальным регистрам дописать бит, опять читает данные из памяти.....
Начинаю потихоньку въезжать.....
Оказ-ся это оптимизатор чудит, поставил перед объявлением переменной volatile и другое дело.....
Хотя теперь компилятор совсем тупит. Сдвинул переменную, записал ее в память, и вместо того чтобы тутже, к актуальным регистрам дописать бит, опять читает данные из памяти.....
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: Вопросы по С/С++ (СИ)
Почему тупит, интерпретирует каждую строку С, без оптимизации типа
Вроде все прально так то:
lds r24,0x0066 ; читает уже сдвинутую переменную
ori r24,0x01 ; включает младший бит
sts 0x0066,r24 ; сохраняет её обратно, где взял
Вроде все прально так то:
lds r24,0x0066 ; читает уже сдвинутую переменную
ori r24,0x01 ; включает младший бит
sts 0x0066,r24 ; сохраняет её обратно, где взял
Re: Вопросы по С/С++ (СИ)
Ну да все нормально, все работает.zero648 писал(а):Почему тупит, интерпретирует каждую строку С, без оптимизации типа
Просто я имею ввиду что lds r24,0x0066 (и еще 3 подобных команды) можно было не делать, т.к. эти данные только что были сохранены из этих же регистров. Т.е. 8 байтов флэша пропали просто так.....
P.S. Я просто на асме привык каждый байт экономить, теперь придется привыкать их транжырить.....
Re: Вопросы по С/С++ (СИ)
Ради прикола:
Последний вышеприведенный фрагмент, в интерпретации С компилятора, занимает 78 байт (ну или 39 слов, кому как удобно).
А вот вариант как бы я сделал на асме, занимает 30 байт (или 15 слов) 38 байт, (19 слов), ошибся малость, там перед CP командой надо сохранить 4 регистра т.е. еще +8 байт (4 слова). Но все равно разница ощутимая.

P.S. Ну это достаточно емкий участок, неудивительно что компиль так поступает.
В большинстве случаев (особенно при работе с char) получается нормальный компактный код, в чем я убедился.
Последний вышеприведенный фрагмент, в интерпретации С компилятора, занимает 78 байт (ну или 39 слов, кому как удобно).
А вот вариант как бы я сделал на асме, занимает 30 байт (или 15 слов) 38 байт, (19 слов), ошибся малость, там перед CP командой надо сохранить 4 регистра т.е. еще +8 байт (4 слова). Но все равно разница ощутимая.
P.S. Ну это достаточно емкий участок, неудивительно что компиль так поступает.
В большинстве случаев (особенно при работе с char) получается нормальный компактный код, в чем я убедился.
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Во-первых, если volatile, то он не имеет права не зачитать заново.
Во-вторых, без volatile всё уже не так страшно. Я не знаю, откуда берутся те Hi, Lo, поэтому выделил маленький кусочек с hi/lo внешними:
avr-gcc -Os -S -mmcu=atmega8
В третьих, достаточно слегка объяснить компилятору, что от него хотят
и он с криками «ба, да это же Ниагарсикй водопад» генерирует нормальный код даже если buf из других соображений таки volatile.
Во-вторых, без volatile всё уже не так страшно. Я не знаю, откуда берутся те Hi, Lo, поэтому выделил маленький кусочек с hi/lo внешними:
Код: Выделить всё
uint32_t buf;
uint8_t hi, lo;
void r()
{
buf <<= 1;
if (hi >= lo) buf |= 1;
}Код: Выделить всё
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;
}
Код: Выделить всё
.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Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.