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

 
 
> Жесткий баг с __farflash iar 5.20 avr
Константин Якуше...
сообщение May 7 2009, 08:19
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 30-08-08
Пользователь №: 39 897



Баг в следующем:
Имеется давно отлаженный и работающий и используемый код:

Код
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

Сообщение отредактировал Константин Якушев - May 7 2009, 08:22
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 2)
IgorKossak
сообщение May 7 2009, 09:24
Сообщение #2


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Используйте атрибут __hugeflash и будет Вам счастье.
Согласно документации, __farflash указывает на обьекты, Max object size которых 32 Kbytes.
Go to the top of the page
 
+Quote Post
Константин Якуше...
сообщение May 7 2009, 10:14
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 30-08-08
Пользователь №: 39 897



Действительно, с __hugeflash корректно работает,
спасибо,
костыль можно убрать smile.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th July 2025 - 05:30
Рейтинг@Mail.ru


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