Easyelectronics.ru

Электроника для всех
Текущее время: 17 окт 2018, 02:34

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 62 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: развернуть битовый массив
СообщениеДобавлено: 19 фев 2018, 18:04 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
ув. форумчане, подскажите вариант решения, необходимо развернуть массив 144 бит, не инвертировать, а именно развернуть, т.е. было к примеру 0B01001101101... а стало 0B1011011001...?


Последний раз редактировалось Volldemar 20 фев 2018, 14:43, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:15 
Старожил
Аватара пользователя

Зарегистрирован: 14 апр 2014, 11:06
Сообщения: 1330
Откуда: Курск
Типа такого, без привязки к языку программирования:
Код:
for (i=0; i<144;i++) {
print(array[144-i])
}

или
Код:
for (i=0; i<144;i++) {
array2[i]=array1[144-i]
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 18:21 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
Cthulhu писал(а):
Типа такого, без привязки к языку программирования:
Код:
for (i=0; i<144;i++) {
print(array[144-i])
}

или
Код:
for (i=0; i<144;i++) {
array2[i]=array1[144-i]
}

Ок, спс!!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:24 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2372
__REV(word) возвратит реверсированное 4-байтное слово. __REV16 - для 2-хбайтного полуслова. Это обертки ассемблерных инструкций реверса бит.
Cthulhu, не байт, а бит. 144 бита, это 18 байт


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:35 
Старожил
Аватара пользователя

Зарегистрирован: 14 апр 2014, 11:06
Сообщения: 1330
Откуда: Курск
BusMaster писал(а):
Cthulhu, не байт, а бит. 144 бита, это 18 байт

Так массив же )))
Про 18 байт у ТС ни слова. Как массив задан ни слова. И т.д. )))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив
СообщениеДобавлено: 19 фев 2018, 18:55 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
Cthulhu писал(а):
BusMaster писал(а):
Cthulhu, не байт, а бит. 144 бита, это 18 байт

Так массив же )))
Про 18 байт у ТС ни слова. Как массив задан ни слова. И т.д. )))

Массив байтовый, но информация в массиве битовая последовательность, перед выдачей наружу, необходимо "развернуть" весь массив битов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 19:06 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2372
Ну строго говоря, массивы считаются в байтах, поскольку минимальный размер хранимой инфы - 1 байт.
Код:
   uint8_t array[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
   uint8_t array2[18] = {0};
   for(int i=0; i<18; i++)
   {
      array2[i] = (__RBIT(array[17-i])>>24);; // сдвиг на 24 бита - это если элемент массива - однобайтный
   }


Вложения:
Без-имени-1.jpg
Без-имени-1.jpg [ 67.05 Кб | Просмотров: 1331 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 19:26 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
BusMaster писал(а):
Ну строго говоря, массивы считаются в байтах, поскольку минимальный размер хранимой инфы - 1 байт.
Код:
   uint8_t array[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
   uint8_t array2[18] = {0};
   for(int i=0; i<18; i++)
   {
      array2[i] = (__RBIT(array[17-i])>>24);; // сдвиг на 24 бита - это если элемент массива - однобайтный
   }

судя по картинке, то есть несоответствие, в чёрном квадратике из array не соответствует красному из array2.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 19:53 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2372
Я думал, вы поймете без слов, как читать картинку. Черные и красные квардратики - на цвет не надо акцентироваться, это информация чисто отладчика. А нас интересует лишь границы массива, обведенные фиолетовой рамкой. Начиная от верхнего красного квадратика array2 отсчитыываем 18 байт по 8 бит (=144 бита) - это второй, реверсированный массив, его границы обведены фиолетовой рамкой.
Ниже, начиная от красного квадратика - исходный массив array, так же 18 байт.
Все биты последовательно в массиве array2 представляют собой полное реверсирование порядка битов из массива array. То есть, в красном квадратике array2 (первый его байт) содержится реверсированный последний байт исходного массива array. Второй байт array2 - это реверсированный предпоследний байт исходного array.
00010001
10001000
Вот так лучш видно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 19 фев 2018, 20:01 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
ок, спс за разъяснение!!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 00:55 
Старожил
Аватара пользователя

Зарегистрирован: 18 фев 2014, 11:27
Сообщения: 211
перевернуть байт
Код:
in - входной байт
   unsigned char out;
in = ((in & 0x0F) << 4) | ((in & 0xF0) >> 4);
   in = ((in & 0x33) << 2) | ((in & 0xCC) >> 2);
   out = ((in & 0x55) << 1) | ((in & 0xAA) >> 1);
out - перевернутый in


Последний раз редактировалось mishany984 22 фев 2018, 10:32, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 01:28 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2524
Откуда: Санкт-Петербург
Интересно, кстати, оптимизирует ли компилятор это всё в одну инструкцию (для процов, на которых есть инструкция разворота байта)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 02:24 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 662
mishany984 писал(а):
перевернуть байт
Код:
in - входной байт
   unsigned char tmp, out;
   tmp = ((in & 0x33) << 2) | ((in & 0xCC) >> 2);
   out = ((tmp & 0x55) << 1) | ((tmp & 0xAA) >> 1);
out - перевернутый in

Это не для байта, а для тетрад.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 04:53 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 487
BusMaster писал(а):
Ну строго говоря, массивы считаются в байтах, поскольку минимальный размер хранимой инфы - 1 байт.
Код:
   uint8_t array[18] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
   uint8_t array2[18] = {0};
   for(int i=0; i<18; i++)
   {
      array2[i] = (__RBIT(array[17-i])>>24);; // сдвиг на 24 бита - это если элемент массива - однобайтный
   }


А почему в байтах ? rbit обрабатывает слово и судя по ">>24" уважаемому BusMaster это известно. Массив в 5 слов обрабатывается быстрее чем 18 слов. А читать его потом можно и побайтно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 07:42 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2372
Для наглядности объяснения


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть массив [Решено]
СообщениеДобавлено: 20 фев 2018, 13:58 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
добавлю подробностей:
есть структура:
Код:
typedef struct __attribute__((packed))
{
   uint8_t hfd;
   unsigned i      : 1;
   unsigned n      : 4;
   unsigned v      : 1;
   unsigned z      : 1;
   unsigned c1      : 6;
   unsigned c2   : 1;
   unsigned d      : 11;
   unsigned v1      : 7;
   int16_t   v2;
   unsigned k      : 9;
   unsigned s           : 6;
   unsigned l1      : 7;
   unsigned l2      : 6;
   unsigned l3      : 11;
   unsigned p1            : 1;
   unsigned l4      : 8;
   unsigned l5      : 6;
   unsigned l6      : 11;
   unsigned p2           : 1;
   unsigned a      : 1;
   unsigned r      : 5;
   uint8_t crc8;
   uint8_t efd;
} TXpsp_t;
которая укладывается в массив из 18 байт, так вот задача перевернуть массив так, что бы не было "разрывов" информации, так как поля структуры не кратны байту, т.е. произвести побитный разворот 144 битов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:13 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2977
Код:
TXpsp_t s1, s2;
uint32_t * p1 = &s1;
uint32_t * p2 = &s2;
p2[0] = (__RBIT(p1[4]) >> 16) | (__RBIT(p1[3])<<16);
p2[1] = (__RBIT(p1[3]) >> 16) | (__RBIT(p1[2])<<16);
p2[2] = (__RBIT(p1[2]) >> 16) | (__RBIT(p1[1])<<16);
p2[3] = (__RBIT(p1[1]) >> 16) | (__RBIT(p1[0])<<16);
*(uint16_t*)(&p2[4]) = __RBIT(p1[0])>>16;


Последний раз редактировалось _pv 20 фев 2018, 17:33, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:32 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 487
Ну и я тогда добавлю подробностей
Код:
typedef struct  __attribute__((packed))
{
   uint8_t hfd;
   unsigned i      : 1;
   unsigned n      : 4;
   unsigned v      : 1;
   unsigned z      : 1;
   unsigned c1      : 6;
   unsigned c2   : 1;
   unsigned d      : 11;
   unsigned v1      : 7;
   int16_t   v2;
   unsigned k      : 9;
   unsigned s           : 6;
   unsigned l1      : 7;
   unsigned l2      : 6;
   unsigned l3      : 11;
   unsigned p1            : 1;
   unsigned l4      : 8;
   unsigned l5      : 6;
   unsigned l6      : 11;
   unsigned p2           : 1;
   unsigned a      : 1;
   unsigned r      : 5;
   uint8_t crc8;
   uint8_t efd;
} TXpsp_t;

uint32_t bufsrc[5];
uint32_t bufdst[5];
uint8_t *sh,cnt = 5;

        TXpsp_t *save = (TXpsp_t*)bufsrc;
        // заполняем
        save->i = 1;
        save->n = 2;
        // и так далее
        while(cnt--) dst[4-cnt] = __RBIT(src[cnt]);  переварачиваем
        sh = (uint8_t*) dst; sh += 2;
        send(sh, 18);

я вижу как то так.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:44 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 487
_pv писал(а):
Код:
TXpsp_t s;
uint32_t * p = &s;   /* так делать нельзя, так как TXpsp_t объявлен как packed, а значит выравнивание по 4 байта отменено. То есть адрес может быть не кратный 4, значит к нему нельзя будет обращаться как к слову. */
p[0] = __RBIT(p[0]);
p[1] = __RBIT(p[1]);
p[2] = __RBIT(p[2]);
p[3] = __RBIT(p[3]);
*(uint16_t*)(&p[4]) = __RBIT(p[4])>>16;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 16:53 
Старожил

Зарегистрирован: 18 июл 2016, 21:17
Сообщения: 746
Код:
for(i=0;i<144;i++)
  {
   if(GetBit(i))SetBit(144-i);
   else ClrBit(144-i);
  }

Как то так :)


Последний раз редактировалось bw429 20 фев 2018, 17:20, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 17:15 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2977
void1509 писал(а):
так делать нельзя, так как TXpsp_t объявлен как packed, а значит выравнивание по 4 байта отменено. То есть адрес может быть не кратный 4, значит к нему нельзя будет обращаться как к слову.

отменено выравнивание внутри структуры.
атрибуты packed и aligned это не одно и то же.
можно указать ((packed, aligned(4))), но оно и так 4 должно быть по умолчанию, не?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 20:04 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 487
_pv писал(а):
void1509 писал(а):
так делать нельзя, так как TXpsp_t объявлен как packed, а значит выравнивание по 4 байта отменено. То есть адрес может быть не кратный 4, значит к нему нельзя будет обращаться как к слову.

отменено выравнивание внутри структуры.
атрибуты packed и aligned это не одно и то же.
можно указать ((packed, aligned(4))), но оно и так 4 должно быть по умолчанию, не?


можно, тогда у вас упаковка будет происходить элементами кратным 4-м байтам. По умолчанию packed упаковывает по 1-му байту (как минимальный элемент).
https://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Type-Attributes.html
А если размещение идет по 1 байту, то предидущий элемент может быть размером не кратным 4. Соответственно ваша структура сместится. То есть uint8_t aa; my_pack_struct bb; будет адр:0 аа и адр:1 bb. А если uint8_t aa; my_unpack_struct bb; будет адр:0 аа и адр:4 bb.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 20:33 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2977
packed отвечает за упаковку элементов внутри структуры, а aligned - за выравнивание всей структуры целиком (без относительно того упакована она или нет), а не отдельных элементов в ней. Это два разных атрибута.

struct S { short f[3]; } __attribute__ ((aligned (8))); по прежнему будет размером 6 байт, но сама структура (первый элемент) начинаться будет с адресов кратным 8.

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

Цитата:
alignment of any given struct or union type is required by the ISO C standard to be at least a perfect multiple of the lowest common multiple of the alignments of all of the members of the struct


то что у них указан размер меньше и они упакованы на размещение думаю не повлияет, но лучше конечно указать прямо ((packed, aligned(4)))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 20:48 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2372
Что вы спорите?? Посмотрите в отладчике браузер памяти и реальное расположение переменных по байтам. Подобно той картинке, которую я выше приводил. Все спорные моменты сразу встанут на свои места.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: развернуть битовый массив
СообщениеДобавлено: 20 фев 2018, 21:11 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 487
Вы знаете не поленился и накидал простенько
Код:
typedef struct __attribute__((__packed__)) {
   uint16_t    a;
   uint8_t       b;
} MyPack_t;

volatile uint8_t q1;
volatile MyPack_t q2;
uint16_t cnt, bit, nbt;


а теперь внимание .map файл
Цитата:
*(.data_end .data_end.*)
0x000000002000001c . = ALIGN (0x4)
// бла-бла-бла .....................

COMMON 0x0000000020000024 0xb ./src/main.o
0x0000000020000024 nbt
0x0000000020000026 q2
0x000000002000002a bit
0x000000002000002c cnt
0x000000002000002e q1

Прошу обратить внимание nbt - 2-ва байта, за ним идет структура и несмотря на то что ALIGN 4, начинается структура с адреса кратного 2-ум.
То есть сразу по окончанию предидущей переменной.
А вот то же самое только без packed:
Цитата:
COMMON 0x0000000020000024 0xd ./src/main.o
0x0000000020000024 nbt
0x0000000020000028 q2
0x000000002000002c bit
0x000000002000002e cnt
0x0000000020000030 q1

Обратите внимание на адрес q2
Итого подитожу - в первом случае обращение к структуре как к указателю uint32_t *st = &q2; вызывало бы ошибку так как адрес q2 был не кратен 4.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 62 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB