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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт сен 04, 2014 13:22:44

Сообщение vash_sa »

Помогите еще разок. Теперь есть массив из uint8_t первый байт младший, второй старший. Как наиболее эффективно сделать массив uitn16_t?

Спасибо!
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

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

typedef union {
  uint8_t arr8[10];
  uint16_t arr16[5];
} myType;

int main() {
  myType x;
  uint16_t a;

  x.arr8[0] = 0x34;
  x.arr8[1] = 0x57;

  a = x.arr16[0]; // a присвоили значение 0x5734;
}
Все сдвиги и прочее берёт на себя компилятор. Память у массивов arr8 и arr16 общая.
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель, я уже писал об этом:

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

uint8_t source[SIZE]; // исходный массив байтов
uint16_t *dest = (void*)source; // новый массив
работать с таким указателем точно так же, как с массивом: dest - будет число из пары байт исходного массива. не ошибитесь только с индексацией - в новом массиве будет в 2 раза меньше элементов...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Открыл глаза
Сообщения: 50
Зарегистрирован: Чт сен 04, 2014 13:22:44

Сообщение vash_sa »

Еще раз огромное спасибо!
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
Не не не. А как же выравнивание адресов? Некоторые архитектуры могут работать только с данными, выровненными по адресу, кратному размеру данных (или большей степени двойки). То есть, чтобы прочитать/записать в int16, это значение должно располагаться в памяти по адресу, кратному хотя бы двум, если нужно прочитать/записать int32, то оно должно располагаться по адресу, кратному хотя бы четырем, и так далее.

Массив байтов может быть расположен по любому адресу. Приведя его указатель к указателю на массив двухбайтных значений можно нарушить требование выравнивания. Конечно, это не обязательно приведет к ошибке, возможно просто снизиться производительность, или даже ничего не случиться. Тем не менее такое решение довольно опасно и непереносимо.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

menzoda писал(а):
ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
Не не не.
да да да :) поскольку речь идет об AVR, то рассуждения о выравнивании - это притянуто за уши. и порядок байтов в int тоже. о какой переносимости может идти речь, если embedded-avr-программы на 90% состоят из аппаратно-зависимых (т.е. по определению непереносимых) действий?!

теория - это сила, но совать ее бесконтрольно в практику - только мешать :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Да и на 32-битных не приведет к ошибке, выравнивание, не выравнивание, это забота компилятора. Сказали второй байт, значит второй байт.
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

ks0 писал(а):это забота компилятора. Сказали второй байт, значит второй байт.
Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined. Так что все-равно нужно включать голову и писать переносимый код.
ARV писал(а):о какой переносимости может идти речь, если embedded-avr-программы на 90% состоят из аппаратно-зависимых (т.е. по определению непереносимых) действий?!
А почему у меня программы не состоят на 90% из аппаратно-зависимых действий? Просто нужно минимизировать и отделять аппаратно-зависимый код от всего остального, и не плодить костыли да хаки там, где это не нужно. А это как раз тот случай, где их можно избежать.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

menzoda писал(а):А почему у меня программы не состоят на 90% из аппаратно-зависимых действий?
я не виноват, что вам не повезло... :dont_know:
:)))
90% avr-овских проектов - это дрыгоножество и настройка периферии. если ваши проекты считают разложения Лагранжа - там будет 99% переносимого кода...

в сущности, спор бесполезен, истина где-то рядом...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

menzoda писал(а):Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined.
Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Че-то у меня лыжи не едут при попытки хранить строки во флеш. AVR GCC, пишу так

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

#include <avr/io.h>
#include <avr/pgmspace.h>
const char* s PROGMEM = "Text";
void main()
{
	char c[20]; // буфер
	strcpy_P(c,s);
}
И вижу, что отладчик пишит, что во флеш по адресу 0х54 хранится число 0х60, которое есть указатель на адрес в ОЗУ, где и хранится сам текст, текст действительно там и оказывается. В буфер нефига вразумительного не копируется.
Че за фигня?! Т.е. во флеше только указатель, а сами данные в ОЗУ!
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

прочтите о том, как правильно размещать строки во флеш при использовании старых версий AVR GCC. вы допустили ошибку - вы разместили во флеш указатель, е строка у вас окажется в ОЗУ. зачем вам флешевый указатель на ОЗУ? правильно так:

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

PROGMEM char str[] = "Что-то там";
sprcpy_P(s, str);
Однако, во множестве случаев может быть гораздо удобнее использование макроса PSTR:

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

strcpy_P(s, PSTR("Что-то там"));
то есть можно задавать константные строки в таком виде, если более не потребуются адреса этих строк.

однако, в настоящее время WinAVR уже можно считать устаревшим компилятором, более свежие версии AVR GCC, а так же AVR Toolchain от Atmel уже поддерживают префикс __flash для определения констант в памяти программ, при этом работа с ними происходит прозрачно для большинства применений, т.е. уже не надо использовать функции с суффиксом _P или специальные средства типа pgm_read_byte
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Сработало! Вот же костыли-то из-за малого объема ОЗУ. Сколько не писал под АВР, как правило, оперативка всегда в дефиците была по сравнению с флешем.
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

ks0 писал(а): Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!
Да нет, с char как раз проблем нет. Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc. В старом стандарте он возвращал как раз char*, который мы приводили к нужному типу. Вот только malloc гарантирует, что возвращенный указатель будет правильно выровнен, поэтому мы и можем смело его приводить к, например, int*.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

menzoda писал(а):Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc.
Если компилятор живёт на платформе с претензиями по выравниванию - то это забота его и его стандартных библиотек чтобы обойти все эти милые особенности как можно более прозрачно для пользователя. И подавляющее большинство последних, вряд-ли задумаются об оптимизации доступа пока конкретные грабли не оходят звонко их незамутнённые лбы. Просто из ваших реплик легко складывается впечатление, что есть ограничения по явному приведению указателей на разные типы. Хотя вряд-ли это так и тип указателя это всего-лишь подсказка компилятору - чтобы знал на сколько двигать при инкременте. ;-) Физически - ведь это просто число в памяти.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Стандарт C99.

6.3.2.3 Pointers
...
7. A pointer to an object or incomplete type may be converted to a pointer to a different
object or incomplete type. If the resulting pointer is not correctly aligned(57) for the
pointed-to type, the behavior is undefined.

(57) In general, the concept ‘‘correctly aligned’’ is transitive: ifapointer to type A is correctly aligned for a
pointer to type B, which in turn is correctly aligned for a pointer to type C, then a pointer to type A is
correctly aligned for a pointer to type C.

...


Так что это только в мечтах все радужно, и компилятор все сам делает.
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Сообщение kalobyte »

вопрос про компиляцию hidapi.lib
типа есть студия 2013, там готовый проект тестовый hidtest
https://github.com/downloads/signal11/h ... -0.7.0.zip

гимор вот какой
уменя виндовс 8.1 х64
я компилю конфиг вин32 дебаг и релиз
все проходит, софт запускается и выполняется функция

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

devs = hid_enumerate(0x0, 0x0);
	cur_dev = devs;	
	while (cur_dev) {
		printf("Device Found\n  type: %04hx %04hx\n  path: %s\n  serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
		printf("\n");
		printf("  Manufacturer: %ls\n", cur_dev->manufacturer_string);
		printf("  Product:      %ls\n", cur_dev->product_string);
		printf("  Release:      %hx\n", cur_dev->release_number);
		printf("  Interface:    %d\n",  cur_dev->interface_number);
		printf("\n");
		cur_dev = cur_dev->next;
	}
	hid_free_enumeration(devs);
а дальше я пробую открыть усб клавиатуру

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

handle = hid_open(0x1241, 0x1203, NULL);
	if (!handle) {
		printf("unable to open device\n");
 		return 1;
	}
и ничего не выходит
клавиатура рабочая, ее снифер видит и печатает она

вопросов 2
проект был заточен под старую студию и вылазят предупреждения какие-то после конвертации
>hidtest.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification

когда я пробую запустить отладку, то вылазит сообщение, что не может запустить приложение hidapi.dll
я решил проверить, может быть ехе не видит длл
переименовал длл и попробовал запустить просто приложение в консоли, но собранное с отладкой - сразу ошибка, что длл не найдена

а как сделать так, чтобы один раз собрал hidapi.lib и ее прилинковывать? чтобы длл не таскалась
я ее в проект добавил в корень, запертил собирать длл в опциях линкера, но все равно что-то тупит

там есть в папке тестгуй ехе, который собран вообще статично с графической библиотекой fox toolkit
и видать хидапи тоже туда вкомпилена
а как это сделать? я давно компилил статически, но уже не помню и студия была 2003 что ли

если кому не лень - соберите проекты, у вас вылазит ошибка загрузки длл, когда начинаете отладку и какая система стоит
я пробовал создать профиль х64, но там вылазит ошибка конвертации size_t, а я понятия не имею, что это такое
в гугле говорят, что лучше ничего в коде не менять

вот уже где-то 12 часов ковыряюсь, хочу управлять светодиодами на клавиатуре для начала
тематические ответы только в форуме, в приват не пишите
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

kalobyte писал(а):когда я пробую запустить отладку, то вылазит сообщение, что не может запустить приложение hidapi.dll
В настройках отладки в Debug Target нужно указывать экзешник а не длл-ку.
kalobyte писал(а):а как сделать так, чтобы один раз собрал hidapi.lib и ее прилинковывать? чтобы длл не таскалась
Собрать либку статически а не пару import.lib + dll - ну это при наличии исходного текста, конечно.
kalobyte писал(а):а как это сделать? я давно компилил статически, но уже не помню и студия была 2003 что ли
Если в проекте либки есть конфигурация для статического билда - дальнейшие действия очевидны. Если нету - в настройках проекта меняем Configuration Type с Dynamic Library на Static Library и пробуем собрать. Если повезёт - соберётся, иначе - обогатите свой кладезь знаний, пополните словарь матерных неологизмов и заработаете массу новых навыков в процессе рукопашного исправления ошибок.
kalobyte писал(а):я пробовал создать профиль х64, но там вылазит ошибка конвертации size_t, а я понятия не имею, что это такое
размер видать не совпадает на другой платформе - типичненько для подобной ситуации. Но как показывают мои личные экзерцисы в процессе строгания вот этой штуки http://sourceforge.net/p/ats909hoggy/at ... ggyStudio/ прямой доступ к hid.dll работает вне зависимости от разрядности приложения и системы. Оба билда, как х86 так и х64 пашут с одним и тем-же устройством на Win 7 x64 идентично успешно. Так что проблема не в разрядности.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Сообщение kalobyte »

Siarzhuk писал(а):hid.dll работает вне зависимости от разрядности приложения и системы.
а ты можеш в курсе - через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает и там есть функция detach driver
но это про линупс пишут
что-то я вызывал эту функцию, так ничего и не происходит
если я ничего не путаю, то при сборке под виндовс - там препроцессор не вставляет код в тело функции, просто ставит return 1

я еще пробовал с libusb0 + обертка на питоне
там есть фильтр, где выбираеш нужное устройство и происходит какая-то магния
клавиатура работает как обычно, но как я понял дается неэксклюзивный доступ и из других прог
но после отправки control report светодиод гаснет как и должен, но вот клавиатура больше не отвечает пока ее не передернеш

с другой стороны есть программатор авр из клавиатуры, где светодиодами мигают
https://github.com/steve-m/hidkey_gpio
правда автор под линупс делал

у другого автора я видел под виндовс на дельфях, но там непонятно какой доступ, наверное какие-то системные вызовы юзает

вот я и думают, а не страдаю ли я херней? может клавиатура и правда не дается
я просто хотел взять готовый девайс простой и расковырять
тематические ответы только в форуме, в приват не пишите
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

kalobyte писал(а):через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает
Достоверной информацией по этому случаю не обладаю. С другой стороны - доступ через hid.dll не требует администраторских прав для доступа - так что почему-бы и не присунуть устройству контрольный пакет со стороны? Нужно экспериментировать.
kalobyte писал(а):вот я и думают, а не страдаю ли я херней? может клавиатура и правда не дается
я просто хотел взять готовый девайс простой и расковырять
Какого плана устройство? По мне так постоянно жить в ожидании подлянок со стороны системы или не дышать, боясь сделать подлянку системе - куда напряжённее чем потратиться на сборку платки с МК. Я для вышеупомянутого адаптера взял за пятнашку готовый модуль на PIC18F14K50 Devantech USB-GPIO12 для самодельщиков. Мне от него только IIC и нужен был. Платка идёт уже с бутлоадером - т.е. даже программатор не нужен.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Ответить

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