реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Формирование int из массива char
AlexeyT
сообщение Feb 12 2016, 15:05
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 12 2016, 15:10
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



__packed unsigned int *tst;
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение Feb 12 2016, 15:10
Сообщение #3


отэц
*****

Группа: Свой
Сообщений: 1 729
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



Цитата(AlexeyT @ Feb 12 2016, 18:05) *
Есть идеи, как решить задачу?


tst = (test_buff[0]<<24) + (test_buff[1]<<16) + (test_buff[2]<<8) + (test_buff[3]<<0);


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 12 2016, 15:14
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(AlexeyT @ Feb 12 2016, 18:05) *
При исполнении этого кода на ARM-процессоре (ядро Cortex-M1) происходит зависание ядра (когда обращаюсь к адресу, некратному 4 байтам).

Ну естественно, Cortex-M1 не умеет делать доступ по неровным адресам.

Цитата(AlexeyT @ Feb 12 2016, 18:05) *
При исполнении этого же кода на ПК - все ок, *tst = 100992003, как и должно быть.

Почему должно? Кто сказал? Просто x86 умеет делать доступ по неровным адресам. Скажем, даже взрослый SPARC из старенького сервера Sun не умеет.

Используйте memcpy:
Код
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 int tst;
memcpy(&tst, test_buff + 2, sizeof(tst));
Go to the top of the page
 
+Quote Post
AlexeyT
сообщение Feb 12 2016, 15:18
Сообщение #5


Участник
*

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



Цитата(Lmx2315 @ Feb 12 2016, 18:10) *
tst = (test_buff[0]<<24) + (test_buff[1]<<16) + (test_buff[2]<<8) + (test_buff[3]<<0);


????

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].
2) test_buff[0]<<24 даст все нули, т.к. имеет 8 бит.
3) При чем тут арифметическое сложение, вообще непонятно.

Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 12 2016, 15:27
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 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-переменной называете указатель? Ну так вас никто не поймёт, выражайтесь корректно.
Go to the top of the page
 
+Quote Post
AnatolyT
сообщение Feb 12 2016, 15:27
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 29-03-10
Пользователь №: 56 269



Определяем тип: структура с пятью элементами unsigned int.
Присваиваем указателю с типом структуры адрес вашего массива.
Работаем с элементами структуры.
Go to the top of the page
 
+Quote Post
scifi
сообщение Feb 12 2016, 15:31
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Какой-то разговор немого с глухим. Вы можете внятно сформулировать суть проблемы? Потому что в первоначальной формулировке терминологическая путаница и код неточный (не вижу строки, на которой может зависнуть).
Go to the top of the page
 
+Quote Post
AlexeyT
сообщение Feb 12 2016, 15:32
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
_pv
сообщение Feb 12 2016, 15:48
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(AlexeyT @ Feb 12 2016, 21:18) *
????

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].
2) test_buff[0]<<24 даст все нули, т.к. имеет 8 бит.
3) При чем тут арифметическое сложение, вообще непонятно.


нельзя обращаться к 32х разрядным данным по невыровненным адресам (не кратным 4).
копируйте побайтно либо руками, как сказал Lmx2315, либо через memcpy.

3) что "+" что "|" тут без разницы.
2) компилятор вроде должен к int сначала привести, если не верите, приведите дополнительно руками или присваивайте по байтно через указатель:

int temp;
((unsigned char *)(&temp))[0] = test_buff[2];
((unsigned char *)(&temp))[1] = test_buff[3];
((unsigned char *)(&temp))[2] = test_buff[4];
((unsigned char *)(&temp))[3] = test_buff[5];
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Feb 12 2016, 16:02
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(aaarrr @ Feb 12 2016, 18:10) *
__packed unsigned int *tst;

Самый лаконичный способ, на мой взгляд.
Как бы в GCC такое сделать?..


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
mantech
сообщение Feb 12 2016, 20:29
Сообщение #12


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(esaulenka @ Feb 12 2016, 19:02) *
Самый лаконичный способ, на мой взгляд.
Как бы в GCC такое сделать?..


а чем union не подходит??
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Feb 12 2016, 20:41
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(mantech @ Feb 12 2016, 23:29) *
а чем union не подходит??

union не допускает произвольного выравнивания.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 13 2016, 06:18
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(esaulenka @ Feb 12 2016, 22:02) *
Самый лаконичный способ, на мой взгляд.
Как бы в GCC такое сделать?..

Универсально (компиляторонезависимо):
class {
unsigned char raw[4];
//здесь добавить перегрузку операторов приведения типа к unsigned и присваивания unsigned
};
Go to the top of the page
 
+Quote Post
andrewkrot
сообщение Feb 13 2016, 19:03
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 306
Регистрация: 11-11-04
Из: Москва
Пользователь №: 1 106



Цитата(AlexeyT @ Feb 12 2016, 19:18) *
????

1) Мне нужна int-переменная, состоящая из test_buff[2]...test_buff[5].
2) test_buff[0]<<24 даст все нули, т.к. имеет 8 бит.
3) При чем тут арифметическое сложение, вообще непонятно.

1) Ну так вместо 0,1,2,3 в индексах поставьте 2,3,4,5
2) Не даст все нули, т.к. сдвинется в переменную типа int, и станет там самым старшим байтом
3) Совсем даже понятно, если не нравится арифметическое сложение, то можете объединить по ИЛИ, и ничего от этого не изменится - результат должен быть одинаковым
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 2nd July 2025 - 02:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01477 секунд с 7
ELECTRONIX ©2004-2016