|
IAR 6.4 Optimization Bug, изменение работы алгоритма при включении оптимизации |
|
|
|
Oct 3 2012, 05:50
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
Здравствуйте. Была в проекте написана простая функция преобразования числа uint32 в строку, без оптимизации работает, при включении Optimization/High/Speed и наличии опции Function Inlining вместо всего числа в строку заносит только последнюю цифру. Функцию конечно поправил так чтоб работала и при оптимизации но как то все равно неприятно, где еще ждать косяков. сам код: CODE // ///8************************************************* // перевод числа i в строку символов в buf длиной = maxlen uint32_t Int2Str(uint32_t i,uint8_t *buf,uint32_t maxlen){ uint32_t j; uint32_t k,l; uint32_t idx;
idx=0; // используется только для преобразования даты if((i<10000)&&(maxlen)&&(maxlen<=4)){ for(j=(maxlen-1);j;j--){ buf[idx]='0'; k=Pow10(j); for(l=9;l;l--){ if(i>=k){ i-=k; buf[idx]++; }else l=1; // выход из цикла } idx++; } buf[idx]='0'+i; idx++; } // buf[idx]=0; return idx; }
///8************************************************* uint32_t Pow10(uint32_t p){// возвращает 10^p uint32_t ret=1; if(p>8)ret=0; else{ for(;p;p--)ret*=10; } return ret; }
Отдельный проект с этими функциями в IAR:
iarbug.rar ( 15.32 килобайт )
Кол-во скачиваний: 76Было обнаружено на STM32F103, проверено наличие бага и для LPC2378 Спасибо.
|
|
|
|
|
 |
Ответов
(1 - 50)
|
Oct 3 2012, 06:17
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
Цитата(Lotor @ Oct 3 2012, 10:01)  Что Вы хотели донести до общественности? Правильнее выложить asm-листинги и указать различия до и после оптимизации. 1. Есть баги изменяющие работающий без оптимизации алгоритм 2. выложен проект, кто хочет - скомпилит и посмотрит сам.
|
|
|
|
|
Oct 3 2012, 06:50
|
Местный
  
Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866

|
Цитата(Sagittarius @ Oct 3 2012, 10:17)  1. Есть баги изменяющие работающий без оптимизации алгоритм 2. выложен проект, кто хочет - скомпилит и посмотрит сам. Т.е. Вы не в состоянии указать почему эти баги появились/исчезли? Если хотите обвинить оптимизацию в иаре, то потрудитесь выложить асм код до/после оптимизации и покажите на "IAR 6.4 Optimization Bug". Цитата(Sagittarius @ Oct 3 2012, 09:50)  но как то все равно неприятно, где еще ждать косяков. С таким подходом везде... =)
--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
|
|
|
|
|
Oct 3 2012, 06:55
|

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

|
Цитата(Sagittarius @ Oct 3 2012, 08:50)  Была в проекте написана простая функция преобразования числа uint32 в строку Вы меня извините, но это далеко не простая функция, сразу бросаются в глаза алгоритмические косяки: - вычисление степени 10 в цикле (facepalm) (это можно сделать таблицей, да и вообще без степеней можно обойтись) - вычисление очередной цифры циклом вычитания (facepalm) (про деление автору ничего неизвестно?) - выход из цикла с лишним сравнением условия (l=1) (facepalm) (банальный break там просится) ИМХО, тут не в компиляторе "собака порылась".
|
|
|
|
|
Oct 3 2012, 07:43
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
Цитата(VslavX @ Oct 3 2012, 10:55)  Вы меня извините, но это далеко не простая функция, сразу бросаются в глаза алгоритмические косяки: ИМХО, тут не в компиляторе "собака порылась". Речь не о кривости алгоритма а о разной его работе при отключенной и включенной оптимизации в компиляторе. про степень согласен, но тогда баг скорее всего бы не вылез :-) деление - писалось под ARM7TDMI, там нет аппаратного деления, был бы вызов библиотечной функции break - просто мне он не нравится, так же как и return из середины функции. 2Lotr: это просто сообщение о наличии проблемы в IAR 6.4 и проект где она воспроизводится. Я ее обошел, мне не мешает. Если кому то надо то он прочитает и разберется сам.
|
|
|
|
|
Oct 3 2012, 08:31
|
Местный
  
Группа: Свой
Сообщений: 476
Регистрация: 3-07-07
Из: Санкт-Петербург
Пользователь №: 28 866

|
Цитата(Sagittarius @ Oct 3 2012, 11:43)  это просто сообщение о наличии проблемы в IAR 6.4 и проект где она воспроизводится. Я ее обошел, мне не мешает. Если кому то надо то он прочитает и разберется сам. Я устал намекать, что скорее всего проблема не в оптимизаторе компилятора. Обходили Вы свои же косяки. PS: Вам нужно самому разобраться и осознать, что 99% ошибок в наши дни - именно авторские, а не компилятора/кристалла.
--------------------
Ковырял чукча отверткой в ухе, звук в телевизоре и пропал.
|
|
|
|
|
Oct 3 2012, 09:01
|

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

|
Цитата(Sagittarius @ Oct 3 2012, 10:43)  Речь не о кривости алгоритма а о разной его работе при отключенной и включенной оптимизации в компиляторе. про степень согласен, но тогда баг скорее всего бы не вылез :-) Ну я вообще-то осторожно намекал что там, скорее всего, еще косяки есть, а не только "бросившиеся в глаза". Цитата(Sagittarius @ Oct 3 2012, 10:43)  деление - писалось под ARM7TDMI, там нет аппаратного деления, был бы вызов библиотечной функции А почему не устраивает библиотечная функция? Недостаточно быстрая для использования при выводе строки? Ну если уж такие требования к скорости, то надо было бы рассмотреть алгоритмы быстрого деления на константу (через умножение, Кнут, том 2). И сделать две явные версии - для процессоров с аппаратным делением и без (а при использовании библиотеки это автоматом). ИМХО, разумным (чтобы не заводить таблицу из 10000 слов) по скорости для вывода в ASCII числа 0-9999 было бы одно деление на 100 с остатком, и вывод двух чисел 0-99 (частного и остатка) по готовой табличке ('00' .. '99'). В этом одном делении, даже универсальном (не константу, на любое число) программном в библиотечной функции, было бы максимум 8 итераций цикла деления. Сравните со своими средним количеством циклов 20 (циклы вычисления степени не учитываем). Цитата(Sagittarius @ Oct 3 2012, 10:43)  break - просто мне он не нравится, так же как и return из середины функции. OK, имейте лишнюю проверку условия, раз уж нравится (за скорость уже не боремся?). И необходимость полной ревизии цикла, если условие в цикле надо будет изменить. "return" - то несколько из другой оперы. ЗЫ: Я тоже думаю что 99% компилятор тут не при чем. "Листинг в студию, сестра!" ©
|
|
|
|
|
Oct 3 2012, 11:21
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
в архиве проект под IAR, оптимизация включена. Запускаем симулятор. Содержимое buf после выполнения функции {0,0,'7',0,0} Отключаем оптимизацию, запускаем. Содержимое буфера {'7','7','7',0,0}. По поводу косячности функции - была проверена записью в файл и последующем чтении из файла в диапазоне входных значений 0-9999, результат корректен Задачи оптимизации данной функции не ставилось.
|
|
|
|
|
Oct 3 2012, 11:44
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Так вы бы листинг и привели с указанием ошибки! Честно говоря такую кривую функцию даже компилировать не хочется! Если уж нужна быстрая - так у всех АРМ есть умножение и можно обойтись без циклов, примерно так (для 4 разрядных чисел) Код d=(v*8389)>>23; v=v-d*1000; buf[0]=d+'0'; d=(v*41)>>12; v=v-d*100; buf[1]=d+'0'; d=(v*103)>>10; buf[2]=d+'0'; v=v-d*10; buf[3]=d+'0';
|
|
|
|
|
Oct 3 2012, 11:47
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Может быть, кому-то захочется покопаться: Исходник (орфография и пунктуация автора сохранены): CODE #include <ctype.h> #include <stdint.h> #include <intrinsics.h>
uint32_t Int2Str(uint32_t i,uint8_t *buf,uint32_t maxlen); uint32_t Pow10(uint32_t p);
volatile uint8_t buf[5];
void main(void){ // Int2Str(777,buf,3); while(1){ Int2Str(777,(uint8_t*)buf,3); buf[0]++; buf[2]++; buf[4]++; } }
///8************************************************* // перевод числа i в строку символов в buf длиной = maxlen uint32_t Int2Str(uint32_t i,uint8_t *buf,uint32_t maxlen){ uint32_t j; uint32_t k,l; uint32_t idx;
idx=0; // используется только для преобразования даты if((i<10000)&&(maxlen)&&(maxlen<=4)){ for(j=(maxlen-1);j;j--){ buf[idx]='0'; k=Pow10(j); for(l=9;l;l--){ if(i>=k){ i-=k; buf[idx]++; }else l=1; // выход из цикла } idx++; } buf[idx]='0'+i; idx++; } // buf[idx]=0; return idx; }
/* // корректно оптимизируемый код uint32_t Int2Str(uint32_t i,uint8_t *buf,uint32_t maxlen){ uint32_t j; uint32_t k,l; uint32_t idx;
idx=0; // используется только для преобразования даты if((i<10000)&&(maxlen)&&(maxlen<=4)){ for(j=(maxlen-1);j;j--){ *buf='0'; k=Pow10(j); for(l=9;l;l--){ if(i>=k){ i-=k; (*buf)++; }else l=1; // выход из цикла } buf++; } *buf='0'+i; idx++; } // buf[idx]=0; return idx; }
*/
///8************************************************* uint32_t Pow10(uint32_t p){// возвращает 10^p uint32_t ret=1; if(p>8)ret=0; else{ for(;p;p--)ret*=10; } return ret; }
Дизассемблер: CODE void main(void){ main: 0x2f4: 0x480f LDR.N R0, ??DataTable1 ; buf 0x2f6: 0xe00f B.N ??main_0 ; 0x318 }else l=1; // auoia ec oeeea ??main_1: 0x2f8: 0x2601 MOVS R6, #1 for(l=9;l;l--){ ??main_2: 0x2fa: 0x1e76 SUBS R6, R6, #1 0x2fc: 0xd116 BNE.N ??main_3 ; 0x32c for(j=(maxlen-1);j;j--){ 0x2fe: 0x1e64 SUBS R4, R4, #1 for(j=(maxlen-1);j;j--){ 0x300: 0xd10c BNE.N ??main_4 ; 0x31c buf[idx]='0'+i; 0x302: 0x3330 ADDS R3, R3, #48 ; 0x30 0x304: 0x7083 STRB R3, [R0, #0x2] return idx; 0x306: 0x7803 LDRB R3, [R0] 0x308: 0x1c5b ADDS R3, R3, #1 0x30a: 0x7003 STRB R3, [R0] 0x30c: 0x7883 LDRB R3, [R0, #0x2] 0x30e: 0x1c5b ADDS R3, R3, #1 0x310: 0x7083 STRB R3, [R0, #0x2] 0x312: 0x7903 LDRB R3, [R0, #0x4] 0x314: 0x1c5b ADDS R3, R3, #1 0x316: 0x7103 STRB R3, [R0, #0x4] ??main_0: 0x318: 0x4b07 LDR.N R3, ??DataTable1_1 ; 0x309 (777) for(j=(maxlen-1);j;j--){ 0x31a: 0x2402 MOVS R4, #2 uint32_t ret=1; ??main_4: 0x31c: 0x2501 MOVS R5, #1 if(p>8)ret=0; 0x31e: 0x0026 MOVS R6, R4 for(;p;p--)ret*=10; ??main_5: 0x320: 0x00af LSLS R7, R5, #2 0x322: 0x197d ADDS R5, R7, R5 0x324: 0x006d LSLS R5, R5, #1 for(;p;p--)ret*=10; 0x326: 0x1e76 SUBS R6, R6, #1 for(;p;p--)ret*=10; 0x328: 0xd1fa BNE.N ??main_5 ; 0x320 for(l=9;l;l--){ 0x32a: 0x2609 MOVS R6, #9 if(i>=k){ ??main_3: 0x32c: 0x42ab CMP R3, R5 0x32e: 0xd3e3 BCC.N ??main_1 ; 0x2f8 i-=k; 0x330: 0x1b5b SUBS R3, R3, R5 buf[idx]++; 0x332: 0xe7e2 B.N ??main_2 ; 0x2fa ??DataTable1: 0x334: 0x40000120 DC32 buf ??DataTable1_1: 0x338: 0x00000309 DC32 777 ; ' ...' exit: 0x33c: 0xb580 PUSH {R7, LR} 0x33e: 0xf000 0xf825 BL ?Veneer (4) for _exit ; 0x38c 0x342: 0xbc09 POP {R0, R3} 0x344: 0x4718 BX R3
Да, код заполняет в буфере только позицию buf[2] = '7'.
|
|
|
|
|
Oct 3 2012, 12:30
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Видно что buf[idx]++; компилятор выкинул Кстати если inline отключить, т.е. и Pow и Int2Str будут как функции! Все равно buf[idx]++; выкидывает! На самом деле бага довольно серьезная!!! И может вылезти в проектах Если в цикле используется buf[i]++, а после цикла присваивание последнему элементу массива проявляется! Для иллюстрации 2 простых функции Код void test_bug(uint32_t v, uint8_t *buf) { unsigned i; for(i=0;i<3;i++){ buf[i]='0'; if (v & 1<<i) buf[i]++; } buf[i]=v & 0x8; }
void test_bug2(uint32_t v, uint8_t *buf) { unsigned i; for(i=0;i<3;i++){ buf[i]='0'; if (v & 1<<i) buf[i]++; } } А вот листинг Код 19 void test_bug(uint32_t v, uint8_t *buf) 20 { 21 unsigned i; 22 for(i=0;i<3;i++){ 23 buf[i]='0'; 24 if (v & 1<<i) 25 buf[i]++; 26 } 27 buf[i]=v & 0x8; \ test_bug: \ 00000000 0x2208 MOVS R2,#+8 \ 00000002 0x4010 ANDS R0,R0,R2 \ 00000004 0x70C8 STRB R0,[R1, #+3] 28 } \ 00000006 0x4770 BX LR ;; return 29
\ In section .text, align 2, keep-with-next 30 void test_bug2(uint32_t v, uint8_t *buf) 31 { \ test_bug2: \ 00000000 0xB418 PUSH {R3,R4} 32 unsigned i; 33 for(i=0;i<3;i++){ \ 00000002 0x2230 MOVS R2,#+48 34 buf[i]='0'; \ 00000004 0x2330 MOVS R3,#+48 35 if (v & 1<<i) \ 00000006 0x07C4 LSLS R4,R0,#+31 \ 00000008 0xD500 BPL ??test_bug2_0 36 buf[i]++; \ 0000000A 0x2331 MOVS R3,#+49 \ ??test_bug2_0: \ 0000000C 0x700B STRB R3,[R1, #+0] \ 0000000E 0x2330 MOVS R3,#+48 \ 00000010 0x0784 LSLS R4,R0,#+30 \ 00000012 0xD500 BPL ??test_bug2_1 \ 00000014 0x2331 MOVS R3,#+49 \ ??test_bug2_1: \ 00000016 0x704B STRB R3,[R1, #+1] \ 00000018 0x0740 LSLS R0,R0,#+29 \ 0000001A 0xD500 BPL ??test_bug2_2 \ 0000001C 0x2231 MOVS R2,#+49 \ ??test_bug2_2: \ 0000001E 0x708A STRB R2,[R1, #+2] 37 } 38 } \ 00000020 0xBC11 POP {R0,R4} \ 00000022 0x4770 BX LR ;; return
\ In section .text, align 4, keep-with-next \ ??DataTable0: \ 00000000 0x........ DC32 buf Видно что в первом варианте код весь убран! Вы будете смеяться!!!все еще проще  void test_bug3(uint8_t *buf) { unsigned i; for(i=0;i<3;i++){ buf[i]=0; } buf[i]=0; } Код In section .text, align 2, keep-with-next 40 void test_bug3(uint8_t *buf) 41 { 42 unsigned i; 43 for(i=0;i<3;i++){ 44 buf[i]=0; 45 } 46 buf[i]=0; \ test_bug3: \ 00000000 0x2100 MOVS R1,#+0 \ 00000002 0x70C1 STRB R1,[R0, #+3] 47 } \ 00000004 0x4770 BX LR ;; return
|
|
|
|
|
Oct 3 2012, 12:52
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
так писали про 6.4 у меня IAR ANSI C/C++ Compiler V6.40.1.53790/W32 for ARM в итоге самый простой код приводящий к ошибке Код void test_bug3(uint8_t *buf) { unsigned i; for(i=0;i<100;i++){ buf[i]=0; } buf[i]=0; } в цикле константа может быть любая! (пробовал 3,4,7,100) видимо ЯР видя за циклом buf[i]=0, не учитывает что в цикле индекс меняется и buf[i] это разные элементы массива.
|
|
|
|
|
Oct 3 2012, 13:03
|
Частый гость
 
Группа: Свой
Сообщений: 170
Регистрация: 8-02-06
Из: Москва
Пользователь №: 14 116

|
Цитата(KRS @ Oct 3 2012, 16:52)  так писали про 6.4 Я понимаю. Я написал для статистики, что результат свойственен последней версии и в одной из предыдущих все работает.
|
|
|
|
|
Oct 4 2012, 07:24
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
Цитата(KRS @ Oct 3 2012, 17:21)  а новый компилер 6.40.4 IAR C/C++ Compiler for ARM 6.40.4.24170 (6.40.4.24170) C:\Program Files (x86)\IARM64\arm\bin\iccarm.exe 13/Sep/2012 05:19:20, 27336704 bytes все еще бажит
|
|
|
|
|
Oct 4 2012, 07:29
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Глючат именно циклы с предусловием (и не только циклы с goto тоже самое) но с проверкой условия в начале. Причем независимо от управляющей переменной!из этих функций нормально компилируются только нечетные! CODE void test_bug4(uint8_t *buf) { unsigned i; unsigned j; j=100; i=0; while(i<10){ buf[i++]=j; j-=2; } buf[i]=0; }
void test_bug5(uint8_t *buf) { unsigned i; unsigned j; j=100; i=0; do { buf[i++]=j; j-=2; } while(i<10); buf[i]=0; }
void test_bug6(uint8_t *buf) { unsigned i; unsigned j; j=100; i=0; while(j>0){ buf[i++]=j; j-=2; } buf[i]=0; }
void test_bug7(uint8_t *buf) { unsigned i; unsigned j; j=100; i=0; do { buf[i++]=j; j-=2; }while(j >0); buf[i]=0; }
void test_bug8(uint8_t *buf) { unsigned i; unsigned j; j=100; i=0; loop: if (i < 10) { buf[i++]=j; j-=2; goto loop; } buf[i]=0; }
void test_bug9(uint8_t *buf) { unsigned i; unsigned j; j=100; i=0; loop: buf[i++]=j; j-=2; if (i < 10) goto loop; buf[i]=0; }
Сообщение отредактировал IgorKossak - Oct 4 2012, 07:52
Причина редактирования: [codebox] для длинного кода!!!
|
|
|
|
|
Oct 10 2012, 07:33
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 24-08-10
Пользователь №: 59 074

|
Используйте квалификатор volatile. И будет вам счастье. Справка: Квалификатор volatile указывает компилятору на то, что значение переменной может измениться независимо от программы, т.е. вследствие воздействия еще чего-либо, не являющегося оператором программы. Например, адрес глобальной переменной можно передать в подпрограмму операционной системы, следящей за временем, и тогда эта переменная будет содержать системное время. В этом случае значение переменной будет изменяться без участия какого-либо оператора программы. Знание таких подробностей важно потому, что большинство компиляторов С автоматически оптимизируют некоторые выражения, предполагая при этом неизменность переменной, если она не встречается в левой части оператора присваивания. В этом случае при очередной ссылке на переменную может использоваться ее предыдущее значение. Некоторые компиляторы изменяют порядок вычислений в выражениях, что может привести к ошибке, если в выражении присутствует переменная, вычисляемая вне программы. Квалификатор volatile предотвращает такие изменения программы.
|
|
|
|
|
Oct 10 2012, 10:58
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 24-08-10
Пользователь №: 59 074

|
Цитата(Сергей Борщ @ Oct 10 2012, 12:04)  В данном случае он абсолютно не нужен, ибо "воздействия еще чего-либо, не являющегося оператором программы" тут нет. Компилятор не знает есть внешнее воздействие или нет. Он не будет оптимизировать код где используются переменные с квалификатором volatile
|
|
|
|
|
Oct 15 2012, 13:31
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

|
QUOTE (KRS @ Oct 15 2012, 16:18)  ЕМНИП раньше кто то с электроникса им отправлял. у кого нибудь есть активная поддержка? По моему на сахаре человек с ником ASDFS имеет тех поддержку для армов. Не знаю как сейчас, но раньше иаровцы игнорили багрепорты от простых смертных. По крайней мере три моих репорта для MSP430 и ARM оставались без внимания, пока не послал их через немецкого кастомера.
|
|
|
|
|
Oct 17 2012, 06:51
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(ig_z @ Oct 15 2012, 16:31)  Не знаю как сейчас, но раньше иаровцы игнорили багрепорты от простых смертных. Ну не знаю, года два назад я переписывался с ИАРом по поводу того, что они перестали поддерживать неименнованные unions и убрали прямой доступ внутрь union. Я прикинулся триал юзером, правда немецким  Ответ был простой - пшол вон, у нас ANSI компилятор, что хотим, то делаем. А я уж порезвился тогда, корректируя проект.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Oct 19 2012, 04:59
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Если кто отправлять будет, то напишите до кучи и про мой баг (писал о нём недавно сюда: http://electronix.ru/forum/index.php?showtopic=105402 ) Вдруг - поправят?  А то сейчас по необходимости пользую IAR 6.21.1 (старый 5.50 который хорошо проверен на вшивость большими проектами с полной оптимизацией, но к сожалению 5.50 не понимает через JTAG LPC1778)  ( И поэтому приходится ставить Low оптимизацию в 6.21.1. ЗЫ: Проверил примеры из этой темы на своём IAR 6.21.1 - бага нет (ни с чётными ни с нечётными размерами циклов). Cortex-M3 High optimization (Size)
|
|
|
|
|
Oct 19 2012, 05:14
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(jcxz @ Oct 19 2012, 08:59)  Если кто отправлять будет, то напишите до кучи и про мой баг (писал о нём недавно сюда: http://electronix.ru/forum/index.php?showtopic=105402 ) Вдруг - поправят?  Чтобы послать баг с надеждой на его исправление и не имея тех.поддержки крайне желательно его локализовать в неком очень небольшом коде, который бы собрался в составе мелкого проекта, созданного в IDE IAR, архив которого им и отсылать. В вашем же коде просто кусок из программы, который не соберется. А если начать выкидывать что-то, может и баг исчезнуть. Цитата А то сейчас по необходимости пользую IAR 6.21.1 (старый 5.50 который хорошо проверен на вшивость большими проектами с полной оптимизацией, но к сожалению 5.50 не понимает через JTAG LPC1778)  ( И поэтому приходится ставить Low оптимизацию в 6.21.1. Собирайте проект в 5.50, а отладку запускайте хоть в 6.40. Там все совместимо по форматам out файлов. Главное, чтобы сам компилятор мог делать код для нужного ядра. Цитата ЗЫ: Проверил примеры из этой темы на своём IAR 6.21.1 - бага нет (ни с чётными ни с нечётными размерами циклов). Cortex-M3 High optimization (Size) на 6.30 тоже его нет.
--------------------
Пасу котов...
|
|
|
|
|
Oct 19 2012, 06:43
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Andy Mozzhevilov @ Oct 19 2012, 11:14)  В вашем же коде просто кусок из программы, который не соберется. А если начать выкидывать что-то, может и баг исчезнуть. Если бы Вы хотя-бы открыли ту тему прежде чем отвечать, Вы бы заметили, что я цеплял там полностью проект. Цитата(Andy Mozzhevilov @ Oct 19 2012, 11:14)  Собирайте проект в 5.50, а отладку запускайте хоть в 6.40. Там все совместимо по форматам out файлов. Главное, чтобы сам компилятор мог делать код для нужного ядра. Это понятно. Но хочется работать без гемора с постоянным переключением между компиляторами.....
|
|
|
|
|
Oct 22 2012, 06:21
|
Местный
  
Группа: Свой
Сообщений: 207
Регистрация: 26-01-06
Из: СПб
Пользователь №: 13 659

|
Цитата(jcxz @ Oct 19 2012, 08:59)  ЗЫ: Проверил примеры из этой темы на своём IAR 6.21.1 - бага нет (ни с чётными ни с нечётными размерами циклов). Cortex-M3 High optimization (Size) первоначально было замечено на Speed, при Size или Balanced все работало.
|
|
|
|
|
Jan 30 2013, 10:07
|

Местный
  
Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535

|
Еще один возможно прикол версии 6.4 Код static class UART_CL{ .... uint8_t start_enable; uint8_t ask_enable; .... void start_ask(){ .... ask_enable = 1; while(start_enable); ... } .... void send_codram(){ .... if(ask_enable) start_enable = 0; ....} ..... }UART1; долго бился с багом в этом коде и под отладкой заметил следующие... переменные ask_enable, start_enable в методах send_codram() и start_ask() находятся там под разными адресами!!!!! т.е. в методе send_codram() переменная start_enable находится по адресу 0х2000058С, а в start_ask() под адрессом 0х2000051С !!! подобное поведение встречается и в других статических классах. решается статическими переменными, но все равно такие фичи разочаровывают =(
|
|
|
|
|
Jan 30 2013, 10:19
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (MK2 @ Jan 30 2013, 12:07)  подобное поведение встречается и в других статических классах. Что такое "статический класс"? Намекаю дальше: в этих функциях адреса разные при вызове одной функции из одного файла, а другой функции из другого исходного файла? QUOTE (MK2 @ Jan 30 2013, 12:07)  но все равно такие фичи разочаровывают =( Боюсь, в данном случае на зеркало пенять не стоит.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|