Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Жесткий баг с __farflash iar 5.20 avr
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Константин Якушев
Баг в следующем:
Имеется давно отлаженный и работающий и используемый код:

Код
unsigned short crc16_P(const void __farflash *ptr,unsigned long count)
{
  unsigned short crc=0;
  for(s=(unsigned char __farflash*)ptr;count;count--,s++) {
    crc=crctab[(unsigned char)((crc>>8) ^ *s) & 0xff ]^(crc<<8);
    __watchdog_reset();
  }
  return crc;
}


, считает свою crc16 неверно.
Естественно, раз он отлаженный то на него я подумал в последнюю очередь.

В листинге дает следующее:

Код
\                                 In  segment CODE, align 2, keep-with-next
     55          unsigned short crc16_P(const void __farflash *ptr,unsigned long count)
   \                     ??crc16_P:
     56          {
   \   00000000   93BA               ST      -Y, R27
   \   00000002   93AA               ST      -Y, R26
     57          unsigned char __farflash *s;
     58            unsigned short crc=0;
   \   00000004   2422               CLR     R2
   \   00000006   2433               CLR     R3
     59            for(s=(unsigned char __farflash*)ptr;count;count--,s++) {
   \   00000008   01D8               MOVW    R27:R26, R17:R16
   \   0000000A   2F04               MOV     R16, R20
   \   0000000C   2B05               OR      R16, R21
   \   0000000E   2B06               OR      R16, R22
   \   00000010   2B07               OR      R16, R23
   \   00000012   F0E1               BREQ    ??crc16_P_1
     60              crc=crctab[(unsigned char)((crc>>8) ^ *s) & 0xff ]^(crc<<8);
   \                     ??crc16_P_2:
   \   00000014   2D03               MOV     R16, R3
   \   00000016   01FD               MOVW    R31:R30, R27:R26
   \   00000018   BF2B               OUT     0x3B, R18
   \   0000001A   9117               ELPM    R17, Z+
   \   0000001C   01DF               MOVW    R27:R26, R31:R30
   \   0000001E   2701               EOR     R16, R17
   \   00000020   E012               LDI     R17, 2
   \   00000022   9F01               MUL     R16, R17
   \   00000024   01F0               MOVW    R31:R30, R1:R0
   \   00000026   ....               SUBI    R30, LOW((-(crctab) & 0xFFFFFF))
   \   00000028   ....               SBCI    R31, HIGH((-(crctab) & 0xFFFFFF))
   \   0000002A   ....               LDI     R19, (crctab) >> 16
   \   0000002C   BF3B               OUT     0x3B, R19
   \   0000002E   9007               ELPM    R0, Z+
   \   00000030   9036               ELPM    R3, Z
   \   00000032   2D12               MOV     R17, R2
   \   00000034   2C20               MOV     R2, R0
   \   00000036   2631               EOR     R3, R17
     61              __watchdog_reset();
   \   00000038   95A8               WDR
     62            }
   \   0000003A   5041               SUBI    R20, 1
   \   0000003C   4050               SBCI    R21, 0
   \   0000003E   4060               SBCI    R22, 0
   \   00000040   4070               SBCI    R23, 0
   \   00000042   2F04               MOV     R16, R20
   \   00000044   2B05               OR      R16, R21
   \   00000046   2B06               OR      R16, R22
   \   00000048   2B07               OR      R16, R23
   \   0000004A   F721               BRNE    ??crc16_P_2
     63            return crc;
   \                     ??crc16_P_1:
   \   0000004C   0181               MOVW    R17:R16, R3:R2
   \   0000004E   91A9               LD      R26, Y+
   \   00000050   91B9               LD      R27, Y+
   \   00000052   9508               RET
     64          }


Те компилятор зная что указатель на __farflash char -24 ,бита длиной, местами( при инкременте Z+), обращается с ним как с 16 битным. maniac.gif
Отключение оптимизации ничего не дает, проблема решается только так:

Код
unsigned short crc16_P(const void __farflash *ptr,unsigned long count)
{
unsigned char __farflash *s;
volatile unsigned long ds;
  unsigned short crc=0;
  for(s=(unsigned char __farflash*)ptr;count;count--/*,s++*/) {
    crc=crctab[(unsigned char)((crc>>8) ^ *s) & 0xff ]^(crc<<8);
    __watchdog_reset();

    ds=(unsigned long)s;
    ds++;
    s=(__farflash unsigned char*) ds;
  }
  return crc;
}


Хотя может это гдето уже было, плохо искалsmile.gif
IgorKossak
Используйте атрибут __hugeflash и будет Вам счастье.
Согласно документации, __farflash указывает на обьекты, Max object size которых 32 Kbytes.
Константин Якушев
Действительно, с __hugeflash корректно работает,
спасибо,
костыль можно убрать smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.