Страница 226 из 386

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

Добавлено: Пн июл 13, 2015 20:51:30
vash_sa
Помогите еще разок. Теперь есть массив из uint8_t первый байт младший, второй старший. Как наиболее эффективно сделать массив uitn16_t?

Спасибо!

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

Добавлено: Пн июл 13, 2015 22:37:01
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 общая.

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

Добавлено: Вт июл 14, 2015 07:08:48
ARV
самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель, я уже писал об этом:

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

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

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

Добавлено: Ср июл 15, 2015 07:25:22
vash_sa
Еще раз огромное спасибо!

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

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

Массив байтов может быть расположен по любому адресу. Приведя его указатель к указателю на массив двухбайтных значений можно нарушить требование выравнивания. Конечно, это не обязательно приведет к ошибке, возможно просто снизиться производительность, или даже ничего не случиться. Тем не менее такое решение довольно опасно и непереносимо.

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

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

теория - это сила, но совать ее бесконтрольно в практику - только мешать :)))

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

Добавлено: Ср июл 15, 2015 09:41:30
ks0
Да и на 32-битных не приведет к ошибке, выравнивание, не выравнивание, это забота компилятора. Сказали второй байт, значит второй байт.

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

Добавлено: Ср июл 15, 2015 10:00:46
menzoda
ks0 писал(а):это забота компилятора. Сказали второй байт, значит второй байт.
Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined. Так что все-равно нужно включать голову и писать переносимый код.
ARV писал(а):о какой переносимости может идти речь, если embedded-avr-программы на 90% состоят из аппаратно-зависимых (т.е. по определению непереносимых) действий?!
А почему у меня программы не состоят на 90% из аппаратно-зависимых действий? Просто нужно минимизировать и отделять аппаратно-зависимый код от всего остального, и не плодить костыли да хаки там, где это не нужно. А это как раз тот случай, где их можно избежать.

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

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

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

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

Добавлено: Ср июл 15, 2015 18:41:21
ks0
menzoda писал(а):Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined.
Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!

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

Добавлено: Чт июл 16, 2015 19:40:17
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, которое есть указатель на адрес в ОЗУ, где и хранится сам текст, текст действительно там и оказывается. В буфер нефига вразумительного не копируется.
Че за фигня?! Т.е. во флеше только указатель, а сами данные в ОЗУ!

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

Добавлено: Чт июл 16, 2015 20:14:16
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

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

Добавлено: Чт июл 16, 2015 20:31:33
ks0
Сработало! Вот же костыли-то из-за малого объема ОЗУ. Сколько не писал под АВР, как правило, оперативка всегда в дефиците была по сравнению с флешем.

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

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

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

Добавлено: Ср июл 22, 2015 19:37:50
Siarzhuk
menzoda писал(а):Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc.
Если компилятор живёт на платформе с претензиями по выравниванию - то это забота его и его стандартных библиотек чтобы обойти все эти милые особенности как можно более прозрачно для пользователя. И подавляющее большинство последних, вряд-ли задумаются об оптимизации доступа пока конкретные грабли не оходят звонко их незамутнённые лбы. Просто из ваших реплик легко складывается впечатление, что есть ограничения по явному приведению указателей на разные типы. Хотя вряд-ли это так и тип указателя это всего-лишь подсказка компилятору - чтобы знал на сколько двигать при инкременте. ;-) Физически - ведь это просто число в памяти.

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

Добавлено: Ср июл 22, 2015 19:57:35
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.

...


Так что это только в мечтах все радужно, и компилятор все сам делает.

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

Добавлено: Сб июл 25, 2015 17:06:48
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 часов ковыряюсь, хочу управлять светодиодами на клавиатуре для начала

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

Добавлено: Сб июл 25, 2015 19:45:21
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 идентично успешно. Так что проблема не в разрядности.

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

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

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

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

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

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

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

Добавлено: Вс июл 26, 2015 12:13:08
Siarzhuk
kalobyte писал(а):через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает
Достоверной информацией по этому случаю не обладаю. С другой стороны - доступ через hid.dll не требует администраторских прав для доступа - так что почему-бы и не присунуть устройству контрольный пакет со стороны? Нужно экспериментировать.
kalobyte писал(а):вот я и думают, а не страдаю ли я херней? может клавиатура и правда не дается
я просто хотел взять готовый девайс простой и расковырять
Какого плана устройство? По мне так постоянно жить в ожидании подлянок со стороны системы или не дышать, боясь сделать подлянку системе - куда напряжённее чем потратиться на сборку платки с МК. Я для вышеупомянутого адаптера взял за пятнашку готовый модуль на PIC18F14K50 Devantech USB-GPIO12 для самодельщиков. Мне от него только IIC и нужен был. Платка идёт уже с бутлоадером - т.е. даже программатор не нужен.