Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите разобраться с указателями
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
vesago
Пишу проект в карме для 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);
Lelick
i то в цикле не инкрементится
vesago
Это у меня случайно отправилось. Вот вся функция:
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]);
}
}

Пробовал просто создавать указатель и в него писать данные. Тот-же эффект. Если-же чар создать указатель, то все норамльно. Помогите разобраться! И еще - это правильно, что при создании указателя он инициализируется нулем? Мне казалось, что с ним как и с переменными. Компилятор выбирает свободный кусок памяти и нет проблем. Может надо где галку постаить или прагму?
Edmundo
Посмотрите здесь, может поможет. Там по-моему те же проблемы. Вкратце -- причина в том, что указатель не выровнен как следует. Есть пути обхода.
vesago
Спасибо, посмотрю. Но с 1 проблемой я разобрался - поделюсь. Через уарт приходил адрес байта, который надо считать из срам.
Я решил воспользоваться мощью си, и без всяких сдвигов из буфера уарта получить 32 битный адрес путем присваивания указателю значения в 4 байтах буфера.

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

RX_MEM_ADDR - смещение относительно первого байта буфера. Вот из-за этого и произошли проблемы с выравниванием. Короче надо будет подумать, как другим методом получить эти 32 бита.
vesago
Действительно, если добавить перед объявлением указателя
__packed unsigned long *ptr_to_data;
__packed unsigned long *ptr_to_addr;
то все становится как надо. Одно плохо - потом трудно будет портировать.
Edmundo
Это точно. Поэтому считается хорошим тоном делать так, чтобы не пришлось применять директиву __packed smile.gif
Учитывать выравнивание на этапе проектирования, так сказать. Хотя признаюсь, не всегда так получается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.