Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ZLib для ARM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Hexxx
Ищу имплементацию с учетом выравнивания буфера по 4 байта, и которая юзает как можно меньше RAM (мне в AT91 запихнуть надо). Знает кто-нить где взять?

Или может какой-то другой алгоритм для сжатия?
sergeeff
http://www.zlib.net/ - A Massively Spiffy Yet Delicately Unobtrusive Compression Library.

У меня поставилась на ARM без малейших проблем.
Hexxx
Цитата(sergeeff @ Nov 27 2007, 23:23) *
http://www.zlib.net/ - A Massively Spiffy Yet Delicately Unobtrusive Compression Library.

У меня поставилась на ARM без малейших проблем.

Поставилась - это только 10% всех проблем. Оно виснет/вылетает по exception при работе на всяких там операциях типа:
Цитата
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
if (*((unsigned char *)(&endian)))

Потому что проц настроен на проверку выравнивания памяти. Т.е. если
R0 = 0x1000;
STRB R1,[R0] - отработает нормально. Т.к. в R0 адрес кратный 4.

А если
R0 = 0x1001;
STRB R1,[R0] - завалится. Т.к. в R0 адрес некратный 4.

Если нужно писать по адресу 0x1001 должен генериться вот такой код:
R0 = 0x1000;
STRB R1,[R0,#1]

Сорцы zlib должны учитывать выравнивание памяти. Пока что не могу нигде найти.

p.s. Может как-то настроить можно компилер? Я на IAR'e.
aaarrr
Цитата(Hexxx @ Nov 28 2007, 13:19) *
R0 = 0x1001;
STRB R1,[R0] - завалится. Т.к. в R0 адрес некратный 4.

STRB никогда не завалится, ибо байты можно писать как угодно.

Цитата(Hexxx @ Nov 28 2007, 13:19) *
Если нужно писать по адресу 0x1001 должен генериться вот такой код:
R0 = 0x1000;
STRB R1,[R0,#1]

Способ адресации никак не влияет на корректность обращения к памяти.
Hexxx
Цитата(aaarrr @ Nov 28 2007, 14:28) *
STRB никогда не завалится, ибо байты можно писать как угодно.
Способ адресации никак не влияет на корректность обращения к памяти.


То есть программисты фирмы Samsung писавшие драйвер OneNand на самом деле не шарят, и делают лишнюю работу, когда сами руками проверяют выравнивание адресов:
Код
VOID OAM_Memcpy(VOID *pDst, VOID *pSrc, UINT32 nLen)
{
    register INT32     nCnt;
    register UINT8    *pD8, *pS8;
    register INT32    nL = nLen;
    register UINT32    *pD32, *pS32;

    pD8 = (UINT8*)pDst;
    pS8 = (UINT8*)pSrc;
    
    if ( ((INT32)pD8 % sizeof(UINT32)) == ((INT32)pS8 % sizeof(UINT32)) ) // ВОТ ЭТО!!!
    {
        while ( (INT32)pD8 % sizeof(UINT32) )
        {
            *pD8++ = *pS8++;
            nL--;

            if( nL <= 0 )
                return;
        }
    
        pD32 = (UINT32*)pD8;
        pS32 = (UINT32*)pS8;
        
        for (nCnt = 0; nCnt <(INT32)(nL / sizeof(UINT32)); nCnt++)
            *pD32++ = *pS32++;
    
        pD8 = (UINT8*)pD32;
        pS8 = (UINT8*)pS32;
            
        while( nL % sizeof(UINT32) )
        {
            *pD8++ = *pS8++;
            nL--;
        }
    }
    else
    {
        for( nCnt = 0; nCnt < nL; nCnt++)
            *pD8++ = *pS8++;
    }


Нашел вот еще на сайте ARM'a:

The ARM compiler assumes that all pointers are naturally-aligned (i.e. int* is word-aligned, short* is halfword-aligned, etc.). You need to either explicitly tell the compiler when you are using unaligned pointers by using the __packed keyword or create a temporary char* pointer to access the address

Код
#include <string.h>
unsigned int * const dest;

void example (unsigned int * const unaligned_ptr)
{
   __packed unsigned int * packed_ptr = unaligned_ptr;
   char * temp_ptr = (char *)unaligned_ptr;
   memcpy(dest, unaligned_ptr, 32);         /* Unsafe */
   memcpy(dest, (void *)packed_ptr, 32);    /* Safe   */
   memcpy(dest, temp_ptr, 32);              /* Safe   */
}


То есть проблема реально существует. И сорцы с сайт'а zlib не будут работать там, где включено выравнивание указателей.

Еще раз спрашиваю, где есть сорцы zlib с учетом выравнивания?
Сергей Борщ
Цитата(Hexxx @ Nov 28 2007, 14:40) *
Нашел вот еще на сайте ARM'a:
or create a temporary char* pointer to access the address
Вот именно - доступ по байтовому (char*) указателю может производиться к любому байту, независимо от выравнивания всей переменной. никакого противоречия нет.
Hexxx
Мдя, на тему поспорить кто круче рзабирается в архитектуре желающих пруд пруди. А на вопрос "где взять zlib учтиывающий выравнивание?" так никто и не ответил. sad.gif
Сергей Борщ
Цитата(Hexxx @ Nov 28 2007, 16:02) *
А на вопрос "где взять zlib учтиывающий выравнивание?" так никто и не ответил. sad.gif
Может его и нет? Во всяком случае привиденный вами кусок if (*((unsigned char *)(&endian))) криминала не содержит, возможно проблема не в выравнивании, а в попытках обращения к несуществующей памяти? Может zlib не виноват, может вы ему "обвеску" неправильно сделали? sergeeff ведь не жалуется...
sergeeff
Еще раз, может кто не понял. Эта библиотека одна из немногих, которая откомпилировалась сразу и используется больше года на реальном железе. Никаких data-abort и прочего из-за невыравнивания данных. В компиляторе указано выравнивание равное 4.
Hexxx
Цитата(sergeeff @ Nov 28 2007, 19:54) *
Еще раз, может кто не понял. Эта библиотека одна из немногих, которая откомпилировалась сразу и используется больше года на реальном железе. Никаких data-abort и прочего из-за невыравнивания данных. В компиляторе указано выравнивание равное 4.

Вполне возможно, что я неправ. Объясните мне пожалуйста зачем тогда нужно было программистам Samsung делать такой странный код OAM_Memcpy().
Ailinor
Цитата(sergeeff @ Nov 27 2007, 22:23) *
http://www.zlib.net/ - A Massively Spiffy Yet Delicately Unobtrusive Compression Library.

У меня поставилась на ARM без малейших проблем.


sad.gif А у меня библиотека так и не стала из-за того же 4-х байтового выравнивания

Цитата(aaarrr @ Nov 28 2007, 13:28) *
Способ адресации никак не влияет на корректность обращения к памяти.


Мне пришлось писать функцию int ToInt(const char*); и ей подобные из-за того, что
операция *(int*)buff вылетает в том случае, если buff не выровнен.
aaarrr
Цитата(Hexxx @ Nov 29 2007, 18:26) *
Вполне возможно, что я неправ. Объясните мне пожалуйста зачем тогда нужно было программистам Samsung делать такой странный код OAM_Memcpy().

Код у китайцев действительно странный. Точнее, не до конца оптимизированный.
Писать слова по не выровненным адресам, естественно, нельзя.

Цитата(Ailinor @ Nov 29 2007, 18:47) *
Мне пришлось писать функцию int ToInt(const char*); и ей подобные из-за того, что
операция *(int*)buff вылетает в том случае, если buff не выровнен.

Я писал о способе адресации, а не о разрядности данных. Т.е. что фрагменты:
Код
R0 = 0x1001;
STR R1,[R0]

и
Код
R0 = 0x1000;
STR R1,[R0,#1]

вылетят с одинаковым успехом.
andrew_b
Цитата(aaarrr @ Nov 29 2007, 19:20) *
Код у китайцев действительно странный.
У корейцев.

Цитата
Точнее, не до конца оптимизированный.
Точнее, не у корейцев, а у индусов. Наверняка, они писали.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.