[an error occurred while processing this directive] [an error occurred while processing this directive]
Внимание! Грабли PICC
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
[an error occurred while processing this directive] [an error occurred while processing this directive]

Отправлено DP 23 апреля 2002 г. 08:15

При использовании кода типа этого:

typedef struct
{
unsigned char size;
unsigned long id;
unsigned char data[8];
}MyStruct_t;

#define _ARRAY_SIZE 4

MyStruct_t bank1 str1[_ARRAY_SIZE];
MyStruct_t bank2 str2[_ARRAY_SIZE];

void main(void)
{
unsigned char i;

for(i = 0; i < _ARRAY_SIZE; i++)
{
str1[i] = str2[i];
}

for(;;);
}

Генерируется следующая последовательность:
23 psect text0
24 07C2 _main
25 ; _i assigned to ?a_main+0
26 0000 _main$i set ?a_main
27 ;TEST.C: 16: unsigned char i;
28 07C2 1283 bcf 3,5
29 07C3 1303 bcf 3,6
30 07C4 01A0 clrf ?a_main
31 07C5 l3
32 ;TEST.C: 19: {
33 ;TEST.C: 20: str1[i] = str2[i];
34 07C5 300D movlw 13
35 07C6 00F2 movwf btemp+1
36 07C7 0820 movf ?a_main,w
37 07C8 120A 118A 27B6 fcall lbmul
38 07CB 3E10 addlw _str2^(0+256)
39 07CC 0084 movwf 4
40 07CD 1783 bsf 3,7
41 07CE 300D movlw 13
42 07CF 00F2 movwf btemp+1
43 07D0 0820 movf ?a_main,w
44 07D1 120A 118A 27B6 fcall lbmul
45 07D4 3EA0 addlw _str1
46 07D5 00F1 movwf btemp
47 07D6 1783 bsf 3,7
48 07D7 0871 movf btemp,w
49 07D8 300D movlw 13
50 07D9 120A 118A 27E4 fcall structbank
+ 120A 118A
51 ;TEST.C: 21: }
52 07DE 0AA0 incf ?a_main
53 07DF 3004 movlw 4
54 07E0 0220 subwf ?a_main,w
55 07E1 1C03 btfss 3,0
56 07E2 2FC5 goto l3
57 07E3 l6
58 ;TEST.C: 23: for(;;);
59 07E3 2FE3 goto l6

Как видно, для копирования сложных структур, используется функция structbank.
В нашем примере структуры размещены в разных банках. Если структуры размещены в одном банке - используется

structcopy.

Проблема заключается в том, что ни structbank, ни structcopy не восстанавливают исходный банк регистров по окончании

своей работы.

В приведённом примере локальная переменная i, назначенная компилятором на ?a_main, модифицируется не в нулевом банке,

а в первом. То есть происходит порча данных структуры str1. В данном примере это не приводит к фатальным

последствиям, так как никакой дальнейшей работы с данными не производится. Но в реальной жизни этот баг привёл к

потере некоторого времени на его локализацию.

Окончательно убедиться в наличии описываемой ошибки можно, проанализировав исходные тексты функций structbank и

structcopy, расположенных в файлах structbk.as и struct.as соответственно.

Данный пример был проверен на версиях компилятора 7.87 PL2 и 8.00 PL2. Результат одинаковый.

Work Around:
Не использовать конструкцию str1[i] = str2[i] для копирования структур.
Использовать для этой цели memcpy(&str1, &str2, sizeof(str1)).

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru