Спасибо!
Вопросы по С/С++ (СИ)
- Сообщения: 50
- Зарегистрирован: Чт сен 04, 2014 13:22:44
Помогите еще разок. Теперь есть массив из uint8_t первый байт младший, второй старший. Как наиболее эффективно сделать массив uitn16_t?
Спасибо!
Спасибо!
- Реклама
Код: Выделить всё
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;
}самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель, я уже писал об этом:работать с таким указателем точно так же, как с массивом: dest - будет число из пары байт исходного массива. не ошибитесь только с индексацией - в новом массиве будет в 2 раза меньше элементов...
Код: Выделить всё
uint8_t source[SIZE]; // исходный массив байтов
uint16_t *dest = (void*)source; // новый массивесли рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 50
- Зарегистрирован: Чт сен 04, 2014 13:22:44
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Не не не. А как же выравнивание адресов? Некоторые архитектуры могут работать только с данными, выровненными по адресу, кратному размеру данных (или большей степени двойки). То есть, чтобы прочитать/записать в int16, это значение должно располагаться в памяти по адресу, кратному хотя бы двум, если нужно прочитать/записать int32, то оно должно располагаться по адресу, кратному хотя бы четырем, и так далее.ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
Массив байтов может быть расположен по любому адресу. Приведя его указатель к указателю на массив двухбайтных значений можно нарушить требование выравнивания. Конечно, это не обязательно приведет к ошибке, возможно просто снизиться производительность, или даже ничего не случиться. Тем не менее такое решение довольно опасно и непереносимо.
- Реклама
да да даmenzoda писал(а):Не не не.ARV писал(а):самый эффективный способ из массива байтов получить массив int-ов (при условии, что байты расположены в правильном порядке - младший-старший), это использовать указатель
теория - это сила, но совать ее бесконтрольно в практику - только мешать
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Да и на 32-битных не приведет к ошибке, выравнивание, не выравнивание, это забота компилятора. Сказали второй байт, значит второй байт.
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined. Так что все-равно нужно включать голову и писать переносимый код.ks0 писал(а):это забота компилятора. Сказали второй байт, значит второй байт.
А почему у меня программы не состоят на 90% из аппаратно-зависимых действий? Просто нужно минимизировать и отделять аппаратно-зависимый код от всего остального, и не плодить костыли да хаки там, где это не нужно. А это как раз тот случай, где их можно избежать.ARV писал(а):о какой переносимости может идти речь, если embedded-avr-программы на 90% состоят из аппаратно-зависимых (т.е. по определению непереносимых) действий?!
я не виноват, что вам не повезло...menzoda писал(а):А почему у меня программы не состоят на 90% из аппаратно-зависимых действий?
90% avr-овских проектов - это дрыгоножество и настройка периферии. если ваши проекты считают разложения Лагранжа - там будет 99% переносимого кода...
в сущности, спор бесполезен, истина где-то рядом...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!menzoda писал(а):Компилятор конечно может обернуть работу с невыравненными данными в несколько дополнительных команд, но тогда мы заметно потеряем в производительности. Вот только я не уверен, что он обязан это делать, нужно читать стандарт и документацию на конкретный компилятор. Скорее всего в стандарте как всегда будет undefined behavior или implementation defined.
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Че-то у меня лыжи не едут при попытки хранить строки во флеш. AVR GCC, пишу так
И вижу, что отладчик пишит, что во флеш по адресу 0х54 хранится число 0х60, которое есть указатель на адрес в ОЗУ, где и хранится сам текст, текст действительно там и оказывается. В буфер нефига вразумительного не копируется.
Че за фигня?! Т.е. во флеше только указатель, а сами данные в ОЗУ!
Код: Выделить всё
#include <avr/io.h>
#include <avr/pgmspace.h>
const char* s PROGMEM = "Text";
void main()
{
char c[20]; // буфер
strcpy_P(c,s);
}
Че за фигня?! Т.е. во флеше только указатель, а сами данные в ОЗУ!
прочтите о том, как правильно размещать строки во флеш при использовании старых версий AVR GCC. вы допустили ошибку - вы разместили во флеш указатель, е строка у вас окажется в ОЗУ. зачем вам флешевый указатель на ОЗУ? правильно так:
Однако, во множестве случаев может быть гораздо удобнее использование макроса PSTR:то есть можно задавать константные строки в таком виде, если более не потребуются адреса этих строк.
однако, в настоящее время WinAVR уже можно считать устаревшим компилятором, более свежие версии AVR GCC, а так же AVR Toolchain от Atmel уже поддерживают префикс __flash для определения констант в памяти программ, при этом работа с ними происходит прозрачно для большинства применений, т.е. уже не надо использовать функции с суффиксом _P или специальные средства типа pgm_read_byte
Код: Выделить всё
PROGMEM char str[] = "Что-то там";
sprcpy_P(s, str);Код: Выделить всё
strcpy_P(s, PSTR("Что-то там"));однако, в настоящее время WinAVR уже можно считать устаревшим компилятором, более свежие версии AVR GCC, а так же AVR Toolchain от Atmel уже поддерживают префикс __flash для определения констант в памяти программ, при этом работа с ними происходит прозрачно для большинства применений, т.е. уже не надо использовать функции с суффиксом _P или специальные средства типа pgm_read_byte
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 238
- Зарегистрирован: Чт фев 28, 2013 14:16:10
Сработало! Вот же костыли-то из-за малого объема ОЗУ. Сколько не писал под АВР, как правило, оперативка всегда в дефиците была по сравнению с флешем.
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Да нет, с char как раз проблем нет. Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc. В старом стандарте он возвращал как раз char*, который мы приводили к нужному типу. Вот только malloc гарантирует, что возвращенный указатель будет правильно выровнен, поэтому мы и можем смело его приводить к, например, int*.ks0 писал(а): Прикольно, представил себе почти все функции обработки строк char* оказываются undefined behavior!
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Если компилятор живёт на платформе с претензиями по выравниванию - то это забота его и его стандартных библиотек чтобы обойти все эти милые особенности как можно более прозрачно для пользователя. И подавляющее большинство последних, вряд-ли задумаются об оптимизации доступа пока конкретные грабли не оходят звонко их незамутнённые лбы. Просто из ваших реплик легко складывается впечатление, что есть ограничения по явному приведению указателей на разные типы. Хотя вряд-ли это так и тип указателя это всего-лишь подсказка компилятору - чтобы знал на сколько двигать при инкременте.menzoda писал(а):Можно привести любой указатель к типу char* и работать с ним побайтово. А вот наоборот неверно, но это нигде и не используется, разе только в malloc.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Стандарт 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.
...
Так что это только в мечтах все радужно, и компилятор все сам делает.
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
вопрос про компиляцию hidapi.lib
типа есть студия 2013, там готовый проект тестовый hidtest
https://github.com/downloads/signal11/h ... -0.7.0.zip
гимор вот какой
уменя виндовс 8.1 х64
я компилю конфиг вин32 дебаг и релиз
все проходит, софт запускается и выполняется функция
а дальше я пробую открыть усб клавиатуру
и ничего не выходит
клавиатура рабочая, ее снифер видит и печатает она
вопросов 2
проект был заточен под старую студию и вылазят предупреждения какие-то после конвертации
>hidtest.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification
когда я пробую запустить отладку, то вылазит сообщение, что не может запустить приложение hidapi.dll
я решил проверить, может быть ехе не видит длл
переименовал длл и попробовал запустить просто приложение в консоли, но собранное с отладкой - сразу ошибка, что длл не найдена
а как сделать так, чтобы один раз собрал hidapi.lib и ее прилинковывать? чтобы длл не таскалась
я ее в проект добавил в корень, запертил собирать длл в опциях линкера, но все равно что-то тупит
там есть в папке тестгуй ехе, который собран вообще статично с графической библиотекой fox toolkit
и видать хидапи тоже туда вкомпилена
а как это сделать? я давно компилил статически, но уже не помню и студия была 2003 что ли
если кому не лень - соберите проекты, у вас вылазит ошибка загрузки длл, когда начинаете отладку и какая система стоит
я пробовал создать профиль х64, но там вылазит ошибка конвертации size_t, а я понятия не имею, что это такое
в гугле говорят, что лучше ничего в коде не менять
вот уже где-то 12 часов ковыряюсь, хочу управлять светодиодами на клавиатуре для начала
типа есть студия 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
В настройках отладки в Debug Target нужно указывать экзешник а не длл-ку.kalobyte писал(а):когда я пробую запустить отладку, то вылазит сообщение, что не может запустить приложение hidapi.dll
Собрать либку статически а не пару import.lib + dll - ну это при наличии исходного текста, конечно.kalobyte писал(а):а как сделать так, чтобы один раз собрал hidapi.lib и ее прилинковывать? чтобы длл не таскалась
Если в проекте либки есть конфигурация для статического билда - дальнейшие действия очевидны. Если нету - в настройках проекта меняем Configuration Type с Dynamic Library на Static Library и пробуем собрать. Если повезёт - соберётся, иначе - обогатите свой кладезь знаний, пополните словарь матерных неологизмов и заработаете массу новых навыков в процессе рукопашного исправления ошибок.kalobyte писал(а):а как это сделать? я давно компилил статически, но уже не помню и студия была 2003 что ли
размер видать не совпадает на другой платформе - типичненько для подобной ситуации. Но как показывают мои личные экзерцисы в процессе строгания вот этой штуки http://sourceforge.net/p/ats909hoggy/at ... ggyStudio/ прямой доступ к hid.dll работает вне зависимости от разрядности приложения и системы. Оба билда, как х86 так и х64 пашут с одним и тем-же устройством на Win 7 x64 идентично успешно. Так что проблема не в разрядности.kalobyte писал(а):я пробовал создать профиль х64, но там вылазит ошибка конвертации size_t, а я понятия не имею, что это такое
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Сообщения: 13796
- Зарегистрирован: Чт сен 20, 2007 14:08:00
а ты можеш в курсе - через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает и там есть функция detach driverSiarzhuk писал(а):hid.dll работает вне зависимости от разрядности приложения и системы.
но это про линупс пишут
что-то я вызывал эту функцию, так ничего и не происходит
если я ничего не путаю, то при сборке под виндовс - там препроцессор не вставляет код в тело функции, просто ставит return 1
я еще пробовал с libusb0 + обертка на питоне
там есть фильтр, где выбираеш нужное устройство и происходит какая-то магния
клавиатура работает как обычно, но как я понял дается неэксклюзивный доступ и из других прог
но после отправки control report светодиод гаснет как и должен, но вот клавиатура больше не отвечает пока ее не передернеш
с другой стороны есть программатор авр из клавиатуры, где светодиодами мигают
https://github.com/steve-m/hidkey_gpio
правда автор под линупс делал
у другого автора я видел под виндовс на дельфях, но там непонятно какой доступ, наверное какие-то системные вызовы юзает
вот я и думают, а не страдаю ли я херней? может клавиатура и правда не дается
я просто хотел взять готовый девайс простой и расковырять
тематические ответы только в форуме, в приват не пишите
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Достоверной информацией по этому случаю не обладаю. С другой стороны - доступ через hid.dll не требует администраторских прав для доступа - так что почему-бы и не присунуть устройству контрольный пакет со стороны? Нужно экспериментировать.kalobyte писал(а):через этоту обертку будет доступ к клавиатуре? а то пишут, что типа к мышам и клавиатуре доступа нет, как бы системный драйвер не дает
Какого плана устройство? По мне так постоянно жить в ожидании подлянок со стороны системы или не дышать, боясь сделать подлянку системе - куда напряжённее чем потратиться на сборку платки с МК. Я для вышеупомянутого адаптера взял за пятнашку готовый модуль на PIC18F14K50 Devantech USB-GPIO12 для самодельщиков. Мне от него только IIC и нужен был. Платка идёт уже с бутлоадером - т.е. даже программатор не нужен.kalobyte писал(а):вот я и думают, а не страдаю ли я херней? может клавиатура и правда не дается
я просто хотел взять готовый девайс простой и расковырять
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 


