|
Формирование int из массива char |
|
|
|
Feb 12 2016, 15:05
|
Участник

Группа: Участник
Сообщений: 45
Регистрация: 5-06-07
Пользователь №: 28 207

|
Задача такая - есть массив test_buff, из подряд идущих 4-х элементов которого нужно сформировать переменную unsigned int.
unsigned char test_buff[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; unsigned char *tst_point = &test_buff[0]; unsigned int *tst;
tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003
Т.е. в *tst пытаюсь записать unsigned int, состоящий из байтов массива с 3-го по 6-й.
При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам). При исполнении этого же кода на ПК - все ок, *tst = 100992003, как и должно быть. Компилятор Keil.
Есть идеи, как решить задачу?
Сообщение отредактировал AlexeyT - Feb 12 2016, 15:07
|
|
|
|
|
 |
Ответов
|
Feb 12 2016, 15:27
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Хм, я думал, что там опечатка в коде. Цитата(AlexeyT @ Feb 12 2016, 18:05)  unsigned int *tst;
tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003
Т.е. в *tst пытаюсь записать unsigned int, состоящий из байтов массива с 3-го по 6-й. Нет. Этот код указателю tst присваевается адрес элемента другого массива &test_buff[2]. Цитата(AlexeyT @ Feb 12 2016, 18:05)  При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам). При исполнении какой конкретно строки кода происходит зависание? Цитата(AlexeyT @ Feb 12 2016, 18:18)  1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5]. Это именно то, что я сделал в этом коде. Или вы int-переменной называете указатель? Ну так вас никто не поймёт, выражайтесь корректно.
|
|
|
|
|
Feb 12 2016, 15:32
|
Участник

Группа: Участник
Сообщений: 45
Регистрация: 5-06-07
Пользователь №: 28 207

|
Цитата(scifi @ Feb 12 2016, 18:27)  Нет. Этот код указателю tst присваевается адрес элемента другого массива &test_buff[2]. Само собой, указателю tst присваивается адрес массива test_buff[2]. При этом значение int-переменной я получаю, обратившись к *tst. В каком именно месте происходит зависание, сказать не могу, процессор - 1986ВЕ1Т, там с дебагом туго. Вот полный исходник тестового кода, на котором все виснет: unsigned char test_buff[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; unsigned char *tst_point = &test_buff[0]; unsigned int *tst; unsigned int temp; tst = (unsigned int *)(tst_point + 2*sizeof(unsigned char)); //должны получить 0x06050403 = 100992003 temp = *tst; printf("%d", temp);
Сообщение отредактировал AlexeyT - Feb 12 2016, 15:35
|
|
|
|
|
Feb 15 2016, 09:14
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(AlexeyT @ Feb 12 2016, 18:32)  В каком именно месте происходит зависание, сказать не могу, процессор - 1986ВЕ1Т, там с дебагом туго. Ничего туго там нет. Пишется обработчик hard_fault и всё... Главное, перед тем как применять этот проц, прочитать еррату, тогда вообще никаких сюрпризов. Ну, а на счёт __packed для указателя, то в GCC аналогичного инструментария нет - изучали эту тему несколько лет назад вдоль и поперёк. Из того что удалось накопать сейчас - это __builtin_assume_aligned(ptr, align), но пока нет времени вникать как это использовать...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 15 2016, 10:43
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(scifi @ Feb 15 2016, 11:40)  ИМХО, это поощрение говнокода и привязка к компилятору, что не есть гут. А по мне так наоборот - если происходит действие "обращение по указателю" - то логично было бы использовать предусмотренные для этого в языке средства разыменования указателя, а не захламлять исходник вызовами memcpy(). То, что этот указатель учитывает какие-то аппаратные особенности (невыровненный доступ), логично было бы как-то указать один раз при объявлении указателя (тот же __packed), а не распылять по исходнику в виде memcpy() и надеяться, что программист не забудет именно этот указатель использовать через memcpy(). В gcc можно обернуть искомые данные в упакованную структуру и обращаться по указателю на эту структуру.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 15 2016, 15:19
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Даже в случае безумного С кода, на асме получается необходимый минимум. В даже если проц не может читать/писать не выровненное - этот кусок он обязан выполнить. Код ldr r1, =адрес_char mov r3, #0 ldrb r0, [r1], #4 add r3, r3, r0, ldrb r0, [r1], #4 add r3, r3, r0, lsl #8 ldrb r0, [r1], #4 add r3, r3, r0, lsl #16 ldrb r0, [r1], #4 add r3, r3, r0, lsl #24 ldr r1, =адрес_uint32_t str r3, [r1]
Сообщение отредактировал AVI-crak - Feb 15 2016, 15:19
|
|
|
|
|
Feb 15 2016, 23:34
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(scifi @ Feb 16 2016, 00:02)  И это тоже. Прогресс в компиляторостроении привёл к тому, что вот эти стенания "а как же эти лишние две инструкции?" - зачастую устаревшая выдумка Типичный аргумент кодера-форточника, создающего шедевры, способные показом обычного диалога загрузить intel-i7 на 100% на минуту. Цитата(scifi @ Feb 16 2016, 00:02)  Но даже не так, пара лишних тактов и байтов вредит крайне редко. Короче, "преждевременная оптимизация", если говорить без матюков, но иметь в виду именно их  Предположим: нужна функция, инкрементирующая пакованный int. С __packed на Cortex-M это будет: Код LDR R1, [R0] ADDS R1, R1, #1 STR R1, [R0] BX LR В случае с memcpy будет: создание стекового фрейма, копирование, инкремент, опять копирование, удаление стекового фрейма - итого: не на пару байт, а во много раз (!!!) дольше + занимает доп.регистры + доп.стек.
|
|
|
|
|
Feb 16 2016, 13:08
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(jcxz @ Feb 16 2016, 02:34)  В случае с memcpy будет: создание стекового фрейма... Такого ужаса уже давно нет. По крайней мере, в gcc практически все библиотечные функции за'builtin'ены, и компилятор встраивает и разворачивает их максимально гибко, вплоть до того, что sin(const) и иже с ним считается чуть-ли не на этапе препроцессинга и может использоваться даже для инициализации констант. Цитата(Kabdim @ Feb 16 2016, 14:07)  Код typedef struct { uint16_t value __attribute__(( packed ));}unaligned_uint16_t;
(( unaligned_uint16_t *)EP0Buf)->value = 1; С выкрутасом решение, но читаемость хромает. Если запрятать это в макрос, то читаемость поднимется в разы... Спасибо! Может когда-нибудь пригодится.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 16 2016, 19:16
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (_pv @ Feb 16 2016, 20:33)  ради одной пакованной переменной писать кучу #if при объявлении, с различными прагмами/атрибутами для разных компиляторов не менее глупо. лучше уж макрос или инлайн функция которая возвращает нормальный int из невыровненного адреса. Городить какую-то функцию, которая будет разбитаться как именно невыровнен адрес а может и выровнен.... тода уж memcpy() - эта занимается тем-же самым, но понятно, что делает. И все это ради того, что-бы отвергать великолепный механизм паковки и доступа к структурам. Дурдом. Но понятный после этого заявления: QUOTE в единственном случае где могут понадобится упакованные структуры и где без этого вполне можно обойтись - в случае с протоколами обмена становится понятным, что задачи обмена данными бесконечно далеки от Вас и "контроллеров светодиодов". QUOTE , там всё равно все доступы к структуре будут обёрнуты в hton / ntoh. C какого бодуна, если это зависит от протокола и контрорлера.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Feb 16 2016, 20:16
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
Цитата(zltigo @ Feb 17 2016, 01:16)  Городить какую-то функцию, которая будет разбитаться как именно невыровнен адрес а может и выровнен.... тода уж memcpy() - эта занимается тем-же самым, но понятно, что делает. И все это ради того, что-бы отвергать великолепный механизм паковки и доступа к структурам. Дурдом. Этот великолепный механизм - костыли которые в каждом компиляторе сделаны (и хорошо если в каждом) по своему. Вон у TI, TCP стэк для msp430, как-то обошлись без великолепных механизмов. И раз уж Вы так близки к задачам обмена данными, не приведёте код объявления упакованной структуры который любой С компилятор поймёт? Цитата(zltigo @ Feb 17 2016, 01:16)  C какого бодуна, если это зависит от протокола и контрорлера. endiannes у всех всех контроллеров вдруг стала одинаковая и так получиться так что она будет отличаться от заданной в протоколе никак не может?
|
|
|
|
|
Feb 16 2016, 22:31
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (_pv @ Feb 16 2016, 22:16)  И раз уж Вы так близки к задачам обмена данными, не приведёте код объявления упакованной структуры который любой С компилятор поймёт? http://electronix.ru/forum/index.php?showt...st&p=268461В файлы постепенно добавляете все компиляторы с которыми работаете. Вот так просто. QUOTE Вон у TI, TCP стэк для msp430, как-то обошлись без великолепных механизмов. Не смотрел, по причине наличия уже лет, как 25 своих нескольких стеков. Но охотно верю, что через анус можно сделать все. Вопрос зачем? QUOTE endiannes у всех всех контроллеров вдруг стала одинаковая и так получиться так что она будет отличаться от заданной в протоколе никак не может? Это Вы сами с собой спорите опровергая свое утверждение, что в разборщиках протоколов QUOTE ...всё равно все доступы к структуре будут обёрнуты в hton / ntoh. ? Конкретные протоколы могут создаватья и с учетом уже конкретных платформ. Вот я прямо сейчас сочиняю маршрутизируемый для RS485 для трех платформ. Получается на весь протокол одно ntohs() да и то не в явном виде.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
Сообщений в этой теме
AlexeyT Формирование int из массива char Feb 12 2016, 15:05 aaarrr __packed unsigned int *tst; Feb 12 2016, 15:10 esaulenka Цитата(aaarrr @ Feb 12 2016, 18:10) __pac... Feb 12 2016, 16:02  mantech Цитата(esaulenka @ Feb 12 2016, 19:02) Са... Feb 12 2016, 20:29   aaarrr Цитата(mantech @ Feb 12 2016, 23:29) а че... Feb 12 2016, 20:41  jcxz Цитата(esaulenka @ Feb 12 2016, 22:02) Са... Feb 13 2016, 06:18 Lmx2315 Цитата(AlexeyT @ Feb 12 2016, 18:05) Есть... Feb 12 2016, 15:10 AlexeyT Цитата(Lmx2315 @ Feb 12 2016, 18:10) tst ... Feb 12 2016, 15:18  _pv Цитата(AlexeyT @ Feb 12 2016, 21:18) ????... Feb 12 2016, 15:48  andrewkrot Цитата(AlexeyT @ Feb 12 2016, 19:18) ????... Feb 13 2016, 19:03 scifi Цитата(AlexeyT @ Feb 12 2016, 18:05) При ... Feb 12 2016, 15:14  AVI-crak Цитата(AlexeyT @ Feb 12 2016, 22:32) В ка... Feb 13 2016, 20:02    jcxz Цитата(scifi @ Feb 15 2016, 15:40) А я не... Feb 15 2016, 10:05    demiurg_spb Цитата(scifi @ Feb 15 2016, 12:40) А я не... Feb 15 2016, 10:35        zltigo QUOTE (scifi @ Feb 15 2016, 20:02) И это ... Feb 15 2016, 18:44         scifi Цитата(zltigo @ Feb 15 2016, 21:44) К чем... Feb 15 2016, 19:41          zltigo QUOTE (scifi @ Feb 15 2016, 21:41) Нет вр... Feb 15 2016, 21:52         scifi Цитата(jcxz @ Feb 16 2016, 02:34) Предпол... Feb 16 2016, 08:36          zltigo QUOTE (scifi @ Feb 16 2016, 10:36) Наверн... Feb 16 2016, 10:52           demiurg_spb Цитата(jcxz @ Feb 16 2016, 16:59) Часто п... Feb 16 2016, 14:30   dimka76 Цитата(demiurg_spb @ Feb 15 2016, 12:14) ... Feb 15 2016, 11:19    scifi Цитата(dimka76 @ Feb 15 2016, 14:19) КодU... Feb 15 2016, 11:29     dimka76 Цитата(scifi @ Feb 15 2016, 14:29) Как мё... Feb 15 2016, 11:34      scifi Цитата(dimka76 @ Feb 15 2016, 14:34) Я вз... Feb 15 2016, 11:36       demiurg_spb Цитата(scifi @ Feb 15 2016, 14:36) Переда... Feb 15 2016, 13:57    Kabdim Цитата(dimka76 @ Feb 15 2016, 14:19) Кодt... Feb 16 2016, 11:07     scifi Цитата(Kabdim @ Feb 16 2016, 14:07) А исп... Feb 16 2016, 11:32      Kabdim Цитата(scifi @ Feb 16 2016, 14:32) Интере... Feb 16 2016, 12:15 AnatolyT Определяем тип: структура с пятью элементами unsig... Feb 12 2016, 15:27 scifi Какой-то разговор немого с глухим. Вы можете внятн... Feb 12 2016, 15:31 Tarbal Цитата(AlexeyT @ Feb 12 2016, 18:05) Зада... Feb 16 2016, 14:31
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|