Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по выравниванию адресов
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Paramon
Столкнулся с проблемой:
При параметре addrw не кратном 4
при выполнении test = *addrw;
вываливаюсь по адресу 0x00000010

Код
//======код во флеш:
OS_TID TASK8;
unsigned int adres;
......
void    task1(unsigned int addr) __task
    {    
        unsigned int addr0;
        unsigned short test;
        unsigned int * addrw;
        for(;;)
            {
            addr0 = 0;
            while(addr0 < 7)
                {
                    addrw = addr+(addr0*4);
                    test = *addrw;
                    test++;
                    *addrw = test;
                    addr0++;
                };
            };
    }
.......
void    sys_swi_8(unsigned int adr) __swi(8)    //
    {
        adres = adr;
        TASK8 = os_tsk_create_ex(task1,2,adres);
    }
........
//======================




//======= Код загруженный в озу
unsigned short buf_swi[32];

.....
sys_swi_8(&buf_swi);
.....

//========================


Есть ли какая-нибудь возможность при внешнем вызове __SWI /имеется ввиду вызов __SWI, расположенного во флеш из загруженного в ОЗУ модуля, где процедура от SWI обращалась к данным вызвавшего модуля без выравнивания адресов(параметром обмена является только адрес
данных)/?
(Или придётся делать процедуру чтения/записи невыровненых данных?)
Как обьявить выровненый массив не знаю(надо для загружаемого в озу кода).
Хотелось бы иметь не только INT
Примечание: код для флеш и для озу компилируются отдельно
Загрузка в озу из SD/MMC


Спасибо!
GetSmart
Сильно сомневаюсь, что чтение невыровненного адреса вызывает дата аборт. Сам много раз читал такие адреса. Скорее всего процедура получает адрес вообще левый (вне ОЗУ).
Paramon
Цитата(GetSmart @ Aug 1 2007, 15:59) *
Сильно сомневаюсь, что чтение невыровненного адреса вызывает дата аборт. Сам много раз читал такие адреса. Скорее всего процедура получает адрес вообще левый (вне ОЗУ).


Простите за мою невнимательность.
Не успел ответить, что нашёл ошибку!
Я описал работу с INT/рабочий вариант/

А в начале было так:
Код
void    task1(unsigned int addr) __task
    {    
        unsigned int addr0;
        unsigned short test;
        unsigned char * addrw;  //здесь раньше было unsigned int * addrw;
        for(;;)
            {
            addr0 = 0;
            while(addr0 < 7)
                {
                    addrw = addr+addr0;
                    test = *addrw;
                    test++;
                    *addrw = test;
                    addr0++;
                };
            };
    }


а данные к которым обращался:
Код
unsigned char buf_swi[32];


Пролетел с типами данных

теперь всё нормально!
Надоже целый день потратил!

Спасибо, извините,что отвлёк!
С уважением PARAMON!

/а по адресу 0x00000010 всёравно вываливался.
незнаю с чем это связано!/
Dron_Gus
*addrw = test;
попробуйте с явным приведением *addrw = (unsigned char )test;
defunct
Цитата
Вопрос по выравниванию адресов, Возможно ли решить???

Конечно возможно - адреса просто надо выравнивать.

Если читать с невыровнянных адресов, то хотя бы так:

memcpy( &dest, addrw, sizeof( U32 ));

Медленно но, позволит избежать глюков..


Цитата
Сильно сомневаюсь, что чтение невыровненного адреса вызывает дата аборт.

Ну это смотря как MMU настроить, можно и на alignment натравить, часто полезно получается. Запись и чтение "по-тихому" слов с невыровнянных адресов, чреваты страшными глюками.
Paramon
Доброго времени суток!
Благодаря вашей помощи всё заработало!!!

У меня по ходу возник другой вопрос:
/с адресами вроде теперь понятно/
Основной модуль(назову его Системой) стартует из пзу самого контроллера.
Подгружаемые в озу модули должны пользоваться функциями и стеком Системы.
Вызываться функции из модулей должны... я думаю так:
Код
....
sys_swi_8("test");
....

их описание:
Код
void    sys_swi_8(unsigned int adr) __swi(8)    //printf
    {
        adres = adr;
        TASK8 = os_tsk_create_ex(task1,2,adres);
    }

сама фунция(здесь пример конечной,но может быть и цикличной):
Код
void    task1(unsigned int addr) __task
    {    

        printf(addr);
        os_tsk_delete_self();
    }


1) сколько штук SWI я могу сделать?
и/или номера фунций указывать одному SWI как параметр?
2) модули пишутся как просто программа (void main(void))
при компиляции у меня (в симуляторе) не происходит старт с main.
/наверное надо делать какой нибудь свой startup/
3) пока не разобрался как размещать их в озу при загрузке из SD/MMC и т.п.
/то, что пыровнять адреса это уже понятно/
4) будут ли они(загр.модули) перемещаемыми?
/можно ли их разместить в произвольном порядке/
5) пока не очень понятно как сделать __task к загруженному модулю.

Спасибо!!!
Paramon
4) будут ли они(загр.модули) перемещаемыми?
/можно ли их разместить в произвольном порядке/

Код
     6: void    main(void)
     7:         {
     8:         unsigned int    test;
     9:         for(;;)
    10:                 {
0x00100074  B500      PUSH      {LR}
    11:                         test++;
0x00100076  3001      ADD       R0,#0x01
    12:                 };
0x00100078  E7FD      B         0x00100076
    13:         }
0x0010007A  BD00      POP       {PC}


что и как "сказать" компилятору, стобы он вместо команды:
Код
      
          B                0x00100076

ставил что-нибудь типа:
Код
           SUB            PC,PC,#2

????
Я думаю тогда модули станут перемещаемыми
//извините за мой кривой ASM//
Paramon
Цитата(Paramon @ Aug 2 2007, 11:53) *
4) будут ли они(загр.модули) перемещаемыми?
/можно ли их разместить в произвольном порядке/

Код
     6: void    main(void)
     7:         {
     8:         unsigned int    test;
     9:         for(;;)
    10:                 {
0x00100074  B500      PUSH      {LR}
    11:                         test++;
0x00100076  3001      ADD       R0,#0x01
    12:                 };
0x00100078  E7FD      B         0x00100076
    13:         }
0x0010007A  BD00      POP       {PC}


что и как "сказать" компилятору, стобы он вместо команды:
Код
      
          B                0x00100076

ставил что-нибудь типа:
Код
           SUB            PC,PC,#2

????
Я думаю тогда модули станут перемещаемыми
//извините за мой кривой ASM//


//стал разбираться с инструкциями и наткнулся на это:

B: Branch (переход).
B<суффикс> <адрес>

B - это простейший переход. Когда процессор ARM натолкнётся на эту инструкцию, он сразу же перейдёт на адрес, являющийся параметром инструкции, и продолжит выполнение команд с нового адреса. Реальное значение, хранящееся в инструкции перехода, это смещение от текущего значения R15, но не абсолютный адрес.

тогда вроде бы этот вопрос наполовину решён!?
но после компиляции (thumb) вышенаписанный код.
Код
0x00100076  3001      ADD      R0,#0x01
0x00100078  E7FD      B        0x00100076

Там адреса абсолютные!
Что-то я совсем запутался 05.gif
condor
Цитата(Paramon @ Aug 2 2007, 14:34) *
Код
0x00100076  3001      ADD      R0,#0x01
0x00100078  E7FD      B        0x00100076

Там адреса абсолютные!
Что-то я совсем запутался 05.gif


В асме абсолютные адреса. Компилятор их уже преобразовывает в относительные.
В данном случае E7FD это префикс 0хЕ и относительное смещение 0x7FD = -3.
Paramon
Цитата(condor @ Aug 4 2007, 01:10) *
В асме абсолютные адреса. Компилятор их уже преобразовывает в относительные.
В данном случае E7FD это префикс 0хЕ и относительное смещение 0x7FD = -3.


Спасибо!!! Теперь понятно!
Paramon
Цитата(condor @ Aug 4 2007, 01:10) *
В асме абсолютные адреса. Компилятор их уже преобразовывает в относительные.
В данном случае E7FD это префикс 0хЕ и относительное смещение 0x7FD = -3.


Что-то уменя всё равно не так как надо:
откомпилил... записал на SD... загрузил...
Код
в проекте/нормально/:
0x00000000  E51F0000  LDR       R0,[PC]
0x00000004  E12FFF10  BX        R0 //тут должен быть переход на MAIN 0x00000050


переходим на адрес 0x00000050, но не на MAIN!!!
выходит, что всётаки абсолютная адресация.
/в проекте адрес 0x00000050 и есть MAIN/
загрузка в озу по адресу 0x00208000.

Код
загрузка/всётаки на 0x00000050/:
0x00208000  E51F0000  LDR       R0,[PC]
0x00208004  E12FFF10  BX        R0 //тут должен быть переход на MAIN 0x002080050


возможно ли как-то заставить компилить с переходами относительно значения PC???
Kirill Frolov
Цитата(Paramon @ Aug 1 2007, 15:17) *
(Или придётся делать процедуру чтения/записи невыровненых данных?)


Придётся... Для многих отличных от x86 и невосьмибитных архитектур.

Цитата
Как обьявить выровненый массив не знаю(надо для загружаемого в озу кода).


Если не играться хакерством с насильственным привидением типов, то всё изначально как надо выравнено, а то иначе ж работать просто не будет.


Цитата(Paramon @ Aug 6 2007, 09:50) *
возможно ли как-то заставить компилить с переходами относительно значения PC???


См. info gcc на тему -fPIC. Подробностей относительно возможности применения в эхотаге -- не знаю..
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.