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

 
 
 
Reply to this topicStart new topic
> Помогите разобраться с указателями
vesago
сообщение Mar 22 2006, 07:24
Сообщение #1


Тутэйшы
****

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



Пишу проект в карме для lpc2214. В частности кусок передачи в уарт данных с внешенй срам. Написал функцию, которая этим занимается. Компилится нормально, а вот в дебагере валят ошибки:
Non-aligned Access: Thumb Instruction at 00000CC6H, Memory Access at 4000070DH
при попытке записи в переменную, адресуемую указателем какого либо значения:
unsigned long data;
unsigned long *ptr_to_data;
unsigned long *ptr_to_addr;
unsigned char i,j;

ptr_to_addr = (unsigned long*)((&skatnet.buf[0]) + RX_MEM_ADDR); //Вычисляем адрес 32 битного окна
ptr_to_data = (unsigned long*)(&data);
i = 0;
do
{
*ptr_to_addr = i;

data = Ext_Mem_Sram_Read(&err_code, ((*ptr_to_addr)>>2));

}while(i<blbblf);
Go to the top of the page
 
+Quote Post
Lelick
сообщение Mar 22 2006, 07:30
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 14-06-05
Пользователь №: 6 007



i то в цикле не инкрементится
Go to the top of the page
 
+Quote Post
vesago
сообщение Mar 22 2006, 07:37
Сообщение #3


Тутэйшы
****

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



Это у меня случайно отправилось. Вот вся функция:
void Skatnet_Read_Data_From_Ext_Mem(void)
{
unsigned long data;
unsigned long *ptr_to_data;
unsigned long *ptr_to_addr;
unsigned char i,j;
unsigned char err_code = ERR_NOT;


if(skatnet.buf[RX_MEM_DATA_LONG] > MAX_LEN_MEM_DATA)//Если запрашиваемая длина данных превышает допустимый размер
{
Skatnet_Send_Error(ERR_MISMTH_PARAM);//Вернем код ошибки
}
else
{
skatnet.buf[TX_ERR_CODE] = ERR_NOT;
skatnet.buf[TX_MEM_DATA_LONG] = skatnet.buf[RX_MEM_DATA_LONG];

ptr_to_addr = (unsigned long*)((&skatnet.buf[0]) + RX_MEM_ADDR); //Вычисляем адрес 32 битного окна
ptr_to_data = (unsigned long*)(&data);
i = 0;
do
{
*ptr_to_addr = i; //Вот здесь выскакивает ошибка

data = Ext_Mem_Sram_Read(&err_code, ((*ptr_to_addr)>>2));//Ну и здесь

if(err_code == ERR_NOT)
{
j = ((*ptr_to_addr)&3);

do
{
skatnet.buf[TX_MEM_DATA + i] = (*(unsigned char*)(ptr_to_data + j));
i++;
j++;
}while(j<4);
}
else
{
Skatnet_Send_Error(ERR_DEV_TROUBLE);
return;
}

}while(i < skatnet.buf[RX_MEM_DATA_LONG]);

Send_Pac_To_UART(SKNET_CMD_MEMORY_CNTRL, (skatnet.buf[TX_MEM_DATA_LONG] + 2), &skatnet.buf[TX_MEM_DATA]);
}
}

Пробовал просто создавать указатель и в него писать данные. Тот-же эффект. Если-же чар создать указатель, то все норамльно. Помогите разобраться! И еще - это правильно, что при создании указателя он инициализируется нулем? Мне казалось, что с ним как и с переменными. Компилятор выбирает свободный кусок памяти и нет проблем. Может надо где галку постаить или прагму?
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Mar 22 2006, 07:46
Сообщение #4


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Посмотрите здесь, может поможет. Там по-моему те же проблемы. Вкратце -- причина в том, что указатель не выровнен как следует. Есть пути обхода.


--------------------
شامل
Go to the top of the page
 
+Quote Post
vesago
сообщение Mar 22 2006, 07:56
Сообщение #5


Тутэйшы
****

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



Спасибо, посмотрю. Но с 1 проблемой я разобрался - поделюсь. Через уарт приходил адрес байта, который надо считать из срам.
Я решил воспользоваться мощью си, и без всяких сдвигов из буфера уарта получить 32 битный адрес путем присваивания указателю значения в 4 байтах буфера.

ptr_to_addr = (unsigned long*)((&skatnet.buf[0]) + RX_MEM_ADDR); //Вычисляем адрес 32 битного окна

RX_MEM_ADDR - смещение относительно первого байта буфера. Вот из-за этого и произошли проблемы с выравниванием. Короче надо будет подумать, как другим методом получить эти 32 бита.
Go to the top of the page
 
+Quote Post
vesago
сообщение Mar 22 2006, 09:11
Сообщение #6


Тутэйшы
****

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



Действительно, если добавить перед объявлением указателя
__packed unsigned long *ptr_to_data;
__packed unsigned long *ptr_to_addr;
то все становится как надо. Одно плохо - потом трудно будет портировать.
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Mar 22 2006, 09:15
Сообщение #7


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Это точно. Поэтому считается хорошим тоном делать так, чтобы не пришлось применять директиву __packed smile.gif
Учитывать выравнивание на этапе проектирования, так сказать. Хотя признаюсь, не всегда так получается.


--------------------
شامل
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 01:54
Рейтинг@Mail.ru


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