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

 
 
5 страниц V  « < 2 3 4 5 >  
Reply to this topicStart new topic
> Odd address trap и LPC23xx, А что, LPC не генерит unaligned access exeption?
zltigo
сообщение Jan 18 2009, 13:18
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата
Имхо, это уж совсем клиническая ситуация - "невыровненный кольцевой буфер 16-битных слов" - такого я еще не встречал.

Ну маленько не так написал sad.gif - буфер само-собой выровненный, а слова лежащие в нем, естественно, уже нет. Буфера обслуживают 16bit SPI, протокол старинный и тоже 16bit - пришел из 70x годов с машины которая про 8bit вобще не знала smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jan 18 2009, 13:30
Сообщение #47


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Мне правда интересно. На ARM-е можно любой невыравненный USHORT (16-битное целое) загрузить за 3 инструкции
Код
ldrb R1, [R0, #0]
ldrb R2, [R0, #1]
orr  R1, R1, R2, shl #8

Как можно грузить быстрее - ума не приложу laughing.gif . Если даже воспользоваться изращенным способом загрузки от NXP - то все равно нужна проверка, что 16-битное не пересекает границу 32-битного слова.
Вот я такой тестик запустил:
Код
{
    BYTE a[8];
    DWORD i;
    for(i=0; i<sizeof(a); i++) a[i] = (BYTE)(i+1);
    dprintf("\r\n%08X %08X %08X %08X",
                *((PDWORD)&a[0]),
                *((PDWORD)&a[1]),
                *((PDWORD)&a[2]),
                *((PDWORD)&a[3]));
}

Результат: 04030201 01040302 02010403 03020104
То есть, действительно имеет место циклический сдвиг - так еще (дополнительно к проверке вмещения в одно слово) и старшие биты чистить надо. Не понимаю, где тут можно выиграть blink.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2009, 13:53
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(VslavX @ Jan 18 2009, 15:30) *
Не понимаю, где тут можно выиграть blink.gif


У меня память под буфера внешняя и замена одного из двух ldrb из внешней памяти банальным tst регистр,#0x3 мне и понравилась, хотя и те-же "три инструкции", как понравилось и использование (кусочек на ASM) только одного регистра вместо 2 ( у Вас даже 3x ).


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jan 18 2009, 14:29
Сообщение #49


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(zltigo @ Jan 18 2009, 15:53) *
У меня память под буфера внешняя и замена одного из двух ldrb из внешней памяти банальным tst регистр,#0x3 мне и понравилась, хотя и те-же "три инструкции", как понравилось и использование (кусочек на ASM) только одного регистра вместо 2 ( у Вас даже 3x ).

Ну, допустим, доступ к внешней памяти медленный. Но ведь если, например, младшие два бита адреса равны 0x03, то все равно надо читать два раза из памяти - два последовательных DWORD/WORD-a. И дополнительная проверка на равенство этих битов адреса на 0x03 с последующим ветвлением/пропуском тоже нужна. Где собак зарыт?
P.S. Переписал свой тестик на использование 16-битных невыравненных слов - там еще результаты мрачней. Ну никак за одно обращение два слова (16 или 32-битных) не читается.
P.P.S. "Листинг, сестра, листинг" smile.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2009, 15:32
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(VslavX @ Jan 18 2009, 16:29) *
Ну, допустим, доступ к внешней памяти медленный. Но ведь если, например, младшие два бита адреса равны 0x03, то все равно надо читать два раза из памяти - два последовательных DWORD/WORD-a.


В этом моем случае - нет - все двухбайтовое. 0x3 я просто так использовал. Ну а в случае реального смещения на байт речь уже идет о той-же двухкратно разнице - 2 или 4 обращения.

Цитата
И дополнительная проверка на равенство этих битов адреса на 0x03


Одна команда

Цитата
с последующим ветвлением/пропуском тоже нужна. Где собак зарыт?


Для ARM без ветвления smile.gif

Цитата
P.P.S. "Листинг, сестра, листинг" smile.gif

Код
tst      R0,#0x3
ldrh     R0,[R0, #+0]
lsrne    R0,R0,#+8

вместо
Код
ldrb     R1,[R0, #+0]
ldrb     R0,[R0, #+1]
orr      R0,R1,R0, lsl #+8


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 18 2009, 15:43
Сообщение #51


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
tst R0,#0x3
ldrh R0,[R0, #+0]
lsrne R0,R0,#+8


Простите, а разве это работает? По меньшей мере tst #1 для полуслов нужен.

Позже... чето я вообще не пойму, что тут и как...


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jan 18 2009, 15:47
Сообщение #52


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Код
tst      R0,#0x3
ldrh     R0,[R0, #+0]
lsrne    R0,R0,#+8


А это правильно работает? Проверяли?
У меня такой тест:

Код
{
    BYTE a[8];
    DWORD i;

    for(i=0; i<sizeof(a); i++) a[i] = (BYTE)(i+1);
    dprintf("\r\n%08X %08X %08X %08X",
                            *((PDWORD)&a[0]),
                            *((PDWORD)&a[1]),
                            *((PDWORD)&a[2]),
                            *((PDWORD)&a[3]));
    dprintf("\r\n%08X %08X %08X %08X %08X %08X %08X %08X",
                            *((PWORD)&a[0]),
                            *((PWORD)&a[1]),
                            *((PWORD)&a[2]),
                            *((PWORD)&a[3]),
                            *((PWORD)&a[4]),
                            *((PWORD)&a[5]),
                            *((PWORD)&a[6]),
                            *((PWORD)&a[7]));
}

Дает такой результат:
04030201 01040302 02010403 03020104
00000201 01000002 00000403 03000004 00000605 05000006 00000807 07000008

То есть, если читаем ldrh по смещению +1 - вместо 0x0302 получаем коктейль из 1 и 2. Если читать по +3, то вместо ожидаемых 0x0504 получаем опять смесь 3 и 4. Это для внутренней памяти на LPC23.

Фрагмент листинга такой (чтобы было видно ldr и ldrh)
Код
   \   000001B8   03009DE5           LDR      R0,[SP, #+3]
   \   000001BC   01002DE9           PUSH     {R0}
   \   000001C0   06309DE5           LDR      R3,[SP, #+6]
   \   000001C4   05209DE5           LDR      R2,[SP, #+5]
   \   000001C8   04109DE5           LDR      R1,[SP, #+4]
   \   000001CC   E80E84E2           ADD      R0,R4,#+3712
   \   000001D0   ........           _BLF     tn_debug_printf,??tn_debug_printf??rA
   \   000001D4   BB00DDE1           LDRH     R0,[SP, #+11]
   \   000001D8   01002DE9           PUSH     {R0}
   \   000001DC   BE00DDE1           LDRH     R0,[SP, #+14]
   \   000001E0   01002DE9           PUSH     {R0}
   \   000001E4   B101DDE1           LDRH     R0,[SP, #+17]
   \   000001E8   01002DE9           PUSH     {R0}
   \   000001EC   B401DDE1           LDRH     R0,[SP, #+20]
   \   000001F0   01002DE9           PUSH     {R0}
   \   000001F4   B701DDE1           LDRH     R0,[SP, #+23]
   \   000001F8   01002DE9           PUSH     {R0}
   \   000001FC   BA31DDE1           LDRH     R3,[SP, #+26]
   \   00000200   B921DDE1           LDRH     R2,[SP, #+25]
   \   00000204   B811DDE1           LDRH     R1,[SP, #+24]
   \   00000208   9800A0E3           MOV      R0,#+152
   \   0000020C   E00E80E3           ORR      R0,R0,#0xE00
   \   00000210   040080E0           ADD      R0,R0,R4
   \   00000214   ........           _BLF     tn_debug_printf,??tn_debug_printf??rA
   \   00000218   18D08DE2           ADD      SP,SP,#+24    ;; stack cleaning

"И чего люди не придумают - лишь бы "на картошку" не ехать" smile.gif
BTW, мне не нравится как компилятор стеком распрядился - на 4 слова можно и меньше было бы.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2009, 16:05
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Rst7 @ Jan 18 2009, 17:43) *
Простите, а разве это работает?


В железе не проверял, но проблем не вижу. Сейчас поищу дома какую-нибудь железку....

Цитата
По меньшей мере tst #1 для полуслов нужен.


В моем случае неважно 3 или 1 - есть гарантированное выравнивание на 2.



Цитата(VslavX @ Jan 18 2009, 17:47) *
То есть, если читаем ldrh по смещению +1 - вместо 0x0302 получаем коктейль из 1 и 2. Если читать по +3, то вместо ожидаемых 0x0504 получаем опять смесь 3 и 4. Это для внутренней памяти на LPC23.

Я НЕ читаю по +1 и +3 - только +0 и +2 - ну писал-же уже не раз - в этом случае у меня двухбайтовые элементы в буфере.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jan 18 2009, 16:28
Сообщение #54


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(zltigo @ Jan 18 2009, 18:05) *
Я НЕ читаю по +1 и +3 - только +0 и +2 - ну писал-же уже не раз - в этом случае у меня двухбайтовые элементы в буфере.

Я не имел ввиду смещения от начала буфера данных. Я имел ввиду смещение от границы физического 32-битного слова. В моем тесте буфер выравнен на 32-битную границу (проверено), поэтому эти значения совпадают и отсюда, видимо, путаница.
Если у Вас 16-битный буфер не выравнен, то каждое второе 16-битное слово будет пересекать границу выравненного физического (нативного для AHB) 32-битного слова. То есть младший байт 16-битного у Вас будет в одном физическом 32-битном слове, старший - в другом, не в том же где и младший, физическом 32-битном слове. Чтобы ядро могло получить это разломанное 16-битное - ему все равно надо выполнить ДВЕ транзакции. Для ARM7TDMI это означает ДВE инструкции ldr - не умеет оно иначе. Как я понял, в CortexM3 добавили AHB-AP - прослоечка между ARM-ядром и AHB - вот он это умеет. Если NXP эту приблуду не выкинет, да еще и флажок реализуют - тогда я, пожалуй, перестану NXP пинать ногами. А пока - суксь и масдай smile.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 18 2009, 16:28
Сообщение #55


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Jan 18 2009, 21:32) *
Код
lsrne    R0,R0,#+8

Это что за команда? IAR ругается. Может это movne ...,lsr #8 ?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2009, 17:27
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Jan 18 2009, 18:28) *
Это что за команда? IAR ругается. Может это movne ...,lsr #8 ?

С чего-бы это вдруг? обычный сдвиг при условии.

вот аж листинг из  сишного исходника


Код
    108          int test_b( BYTE *buff )
    109          {
    110              if( (ulong)buff & 0x3 )
   \                     test_b:
   \   00000000   030010E3           TST      R0,#0x3
   \   00000004   B000D0E1           LDRH     R0,[R0, #+0]
    111                  return( *(ushort *)buff>>8 );
   \   00000008   2004A011           LSRNE    R0,R0,#+8
    112              else
    113                  return( *(ushort *)buff );
   \   0000000C   0EF0A0E1           MOV      PC,LR           ;; return
    114          }


Другое дело, что все это бред - что-то переклинило sad.gif. В моем примере это просто ldrh вне зависимости от смещения.

Код
BYTE tbuff[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

int test( BYTE *buff )
{
 return( *(ushort *)buff );
}

void test_short(void)
{
 xprintf( "%04X %04X %04X %04X\r", test(tbuff), test(tbuff+2), test(tbuff+4), test(tbuff+6) );
}
 

Результат: 


0201 0403 0605 0807

Листинг суперфункции:

Код
    114          int test( BYTE *buff )
    115          {
    116              return( *(ushort *)buff );
   \                     test:
   \   00000000   B000D0E1           LDRH     R0,[R0, #+0]
   \   00000004   0EF0A0E1           MOV      PC,LR           ;; return
    117          }


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jan 18 2009, 19:32
Сообщение #57


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Код
BYTE tbuff[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

int test( BYTE *buff )
{
 return( *(ushort *)buff );
}

void test_short(void)
{
 xprintf( "%04X %04X %04X %04X\r", test(tbuff), test(tbuff+2), test(tbuff+4), test(tbuff+6) );
}
 
А чего Вы хотели, если у Вас буфер выравнен (как стековая переменная) на 32-битную границу?
(сорри, пропустил, это у меня стековая, а у Вас - глобальная. Но, на 99% уверен, что буфер таки выравнен -
надо для 100% гарантии еще &tbuff[0] посмотреть бы).
Так что, это - не фокус, попробуйте написать так:

Код
BYTE tbuff[9] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };

int test( BYTE *buff )
{
 return( *(ushort *)buff );
}

void test_short(void)
{
 xprintf( "%04X %04X %04X %04X\r", test(tbuff+1), test(tbuff+3), test(tbuff+5), test(tbuff+7) );
}
 

Думаю, результат будет: 1000002 3000004 5000006 7000008
А должен бы быть: 0302 0504 0706 0908.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2009, 20:06
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(VslavX @ Jan 18 2009, 21:32) *
А чего Вы хотели, если у Вас буфер выравнен (как стековая переменная) на 32-битную границу?


Писал об этом несметное число раз.

Цитата(VslavX @ Jan 18 2009, 21:32) *
Думаю, результат будет: 1000002 3000004 5000006 7000008


Я где-то для этих условий утверждал обратное?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jan 18 2009, 20:37
Сообщение #59


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(zltigo @ Jan 18 2009, 22:06) *
Писал об этом несметное число раз.

Хм, а как насчет этого:
Цитата(zltigo @ Jan 18 2009, 22:06) *
"буфер само-собой выровненный, а слова лежащие в нем, естественно, уже нет. Буфера обслуживают 16bit SPI, протокол старинный и тоже 16bit"

Я так понял, что с аппаратуры принимаете 16-битные слова, складываете в буфер - массив из 16-битных слов, начало буфера "само-собой" выравнено (на 16 или 32). А уже там - "внутри пакета/структуры" - есть инкапсулированные 16-битные данные. И вот для этих инкапсулированных - бывает что адрес нечетный. А как это еще можно понять - "невыравненные слова в само-собой выравненном буфере"? (с)? smile.gif Предполагается же что это профессионал сказал. И обсуждается, в первую очередь, доступ к этим "невыравненным словам". А тривиальный случай доступа к элементам выравненного буфера - это упражнение для новичков.

OK, ясность есть - чудес не бывает. Резюмирую - отсутствие OAT/DABT в LPC - "это - залет, воин" ©. И, к сожалению, для меня это весьма весомый недостаток sad.gif. Тут у меня в столе парочка SAM9XE лежит - надеюсь, до него скоро руки дойдут.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 18 2009, 20:55
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(VslavX @ Jan 18 2009, 22:37) *
Я так понял, что с аппаратуры принимаете 16-битные слова, складываете в буфер - массив из 16-битных слов, начало буфера "само-собой" выравнено (на 16 или 32). А уже там - "внутри пакета/структуры" - есть инкапсулированные 16-битные данные.


И только 16 бит и никаких других.

Цитата
Резюмирую - отсутствие OAT/DABT в LPC - "это - залет, воин" ©. И, к сожалению, для меня это весьма весомый недостаток sad.gif .



А для меня оказалось smile.gif - нет, причем это проверено практикой портирования. Из имеющего место быть эффекта (трюк, но вдруг) при случае можно извлечь пользу. 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 27th June 2025 - 09:47
Рейтинг@Mail.ru


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