Перейти к содержанию
    

const

Участник
  • Постов

    65
  • Зарегистрирован

  • Посещение

Весь контент const


  1. подскажите, что прописать в .icf я пробую так place at address mem:__ICFEDIT_region_FLASH_start__+0x20 { readonly section .checksum }; выдает ошибку Error[Lp015]: section placement failure: overcommitted content in [0x800'0000-0x800'001f]
  2. Вы кладете в восьмое прерывание отсчитывая с нуля? То есть КС будет тут? __vector_table DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved /* ТУТ */ DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler
  3. И с КС прошивки вопрос решил. Считаю как jcxz - "с разрывом". Только куда ложить КС линкеру не говорю (сморю куда положил так: &__checksum). Он ее по разному ложит при изменении исходника, но это уже не проблема, как и хотел, диапазон задаю только в одном месте - на вкладке линкера Checksum.
  4. Я так и не понял, вы ее сами располагаете или линкер без указаний ее туда ложит? Мой, если без указаний, ложит сюда: .checksum const 0x800'38e8 4 0x4 Place holder __checksum похоже, что это далеко за таблицей векторов.
  5. Потратил время, разобрался. Вопрос отпал. Как понимаю, считая КС вашим способом нет разницы по какому адресу лежит подсчитанная линкером КС. Какой смысл ее помещать в таблицу векторов? Покажите как это выглядит в линкере и как передать адрес расположения размера прошивки (в прошивке) в программу, пожалуйста. И как положить КС в конец прошивки.
  6. патч у вас автоматом запускается после компиляции?
  7. 1) Как я уже писал, считаю КС от 0х0 до 0хFFFB (КС по 0хFFFС). Если не указывать где располагать КС у меня ее кидает куда попало (в диапазоне от 0х0 до 0хFFFB). Как при этом быть с программным подсчетом, пропускать тот адрес где лежит КС в алгоритме? Или считать с ним и должен в итоге получиться "ноль". Если я считаю программно КС от 0х0 до 0хFFFF (КС по 0хFFFС) "нуля" не получаю. 2) В самой таблице векторов или сразу после? Если в самой таблице, то место какого то прерывания неиспользуемого? У вас считается вся доступная флешь с таблицей прерываний (какой диапазон адресов, для примера)? При программном подсчете КС вы результат сверяете с подсчетом линкера или у вас на выходе "ноль" когда все ОК? Читал. С лету не вышло разобраться. Ваш пример почти весь понятен (мне подходит), разбираюсь пока. Понимаю, поэтому тут с вопросами.
  8. IAR 9.50.1.69506 Приветствую. Помогите разобраться. 1. Вопрос первый а) Считаю КС способом как на скрине. б) В линкере есть такие строки для размещения КС по определенному адресу: define symbol __addr_calc_cs_end__ = 0x0800FFFB; place at address mem:__addr_calc_cs_end__ +1 { readonly section .checksum }; в) В исходнике используя константы линкера __checksum_begin, __checksum_end, __checksum счтитаю и сверяю КС (в файле .icf они не видны). Могу ли я "расширить область видимости" __checksum_end для файла линкера .icf, что бы адресс 0x0800FFFB не прописывать два раза (во вкладке Checksum и файле .icf)? 2. Вопрос второй Можно ли передать глобальную константу в inline asm, что бы вместо MOV R0, #0x20000000 было MOV R0, RAM_START? asm ( "MOV R0, #0x20000000 \n" "ADD R4, R0, #0x4000 \n" "ADD R0, R0, #0x000C \n" ... сейчас делаю это так: void r0_r1_r2(int r0, int r1, int r2) { asm ("nop"); }, после вызова ф-ции значения ее входных параметров оказываются в соответствующих регистрах, а потом уже мой inline asm учитывает это. Только не уверен, что это надежно. Понимаю, что "костыль".
  9. @Arlleex Есть такое, не обратил внимания. С "Multi-file Compilation" компилируется. Листинг тот же. Ничего не выкидывает даже когда забираю обращения к портам. При дополнительном выборе "Discard Unused Publics" - не компилируется вообще - ошибка.
  10. а как это включаеся в ИАР. Понятия не имею, что такое LTO.
  11. Если я не ошибаюсь, в С++ глобальные переменные по умолчанию static, если не указано иного (extern напр.), может в этом дело. Тогда действительно, компилятор видит, что в данной единице компиляции объект не используется и выкидывает его.
  12. вот так https://electronix.ru/forum/topic/192075-pri-maksimalnoy-optimizatsii-oshibka/?do=findComment&comment=1944224
  13. после добавления роботы с портами у вас "пустой зацикленный код" остался? Или все же не пустой цикл?
  14. в моем примере только такие файлы: 1. startup_stm32f4xx.s 2. system_stm32f4xx.c 3. main.c (весь код которого приведен) 4. foo.c (с одной лишь ф-цей foo)
  15. extern void foo(uint8_t b); uint8_t glb; void tst(void) { static uint8_t sv; uint8_t tmp; if (sv != (glb & (1 << 6))) { sv = (glb & (1 << 6)); tmp = (sv)? 0x00 : 0xFF; foo(tmp); } } int main() { while(1) { glb = GPIOA->IDR; tst(); } } ф-ция foo (в др. файле) void foo(uint8_t b) { GPIOB->ODR = b; } так не выкинет. У меня с добавлением строк работы с портами листинг не поменялся - есть ошибка 40 int main() 41 { \ main: \ 00000000 0xB570 PUSH {R4-R6,LR} \ 00000002 0x.... LDR.N R5,??DataTable3_1 \ 00000004 0x.... LDR.N R6,??DataTable3_2 ;; 0x40020010 \ 00000006 0xE001 B.N ??main_0 42 while(1) { 43 44 glb = GPIOA->IDR; 45 tst(); \ ??main_1: \ 00000008 0x.... 0x.... BL foo \ ??main_0: \ 0000000C 0x6830 LDR R0,[R6, #+0] // читаем порт \ 0000000E 0x7869 LDRB R1,[R5, #+1] // sv \ 00000010 0x7028 STRB R0,[R5, #+0] // glb = GPIOA->IDR \ 00000012 0x7828 LDRB R0,[R5, #+0] // glb \ 00000014 0xF000 0x0240 AND R2,R0,#0x40 // glb & (1 << 6) \ 00000018 0x4291 CMP R1,R2 \ 0000001A 0xD0F7 BEQ.N ??main_0 \ 0000001C 0x7068 STRB R0,[R5, #+1] // sv = glb (без маскирования) \ 0000001E 0x0640 LSLS R0,R0,#+25 \ 00000020 0xBF4C ITE MI \ 00000022 0x2000 MOVMI R0,#+0 \ 00000024 0x20FF MOVPL R0,#+255 \ 00000026 0xE7EF B.N ??main_1 46 47 } 48 }
  16. вынесите ф-цию foo в другой файл. Неужели и в таком случае выкинет. Потому что по приведенной мной ссылке выражение "On optimization level High..." встречается довольно часто. Как я понял, большенство ошибок именно при такой оптимизации, если неправ - поправьте. А на счет высокого уровня оптимизации как инструмента по вылавливанию багов непонял. Всегда пишу на максимальном и в ту закладку даже не заглядываю. Как может алгоритм зависить от уровня оптимизации?
  17. Посмотрел историю IAR: ICCARM History Хватает ошибок разных, особенно на уровне оптимизации High. Вот возможно разновидность моего случая (не утверждаю): "In EWARM 6.50.4: An indirect assignment could be optimized incorrectly if the right hand side expression was masked with a constant and the only use was in a test, comparing the value, possibly masked with the same constant as in the assignment or a constant with fewer bits set, to zero. For example: p->foo = x & 0x02; ... if (p->foo & 0x02) This has been corrected. [EW23796]" Кроме перехода на более свежую версию, наверное, и оптимизацию буду ставить не више Medium (всегда ставил High Balanced или High Speed).
  18. да мне без разницы, что и где будет хранить компилятор, мне важен алгоритм, а он нарушается. При таком поведении компилятора, ф-ция foo будет вызыватся всегда, пока glb != 0 && glb != (1 << 6). И как писал выше, когда добавляю дополнительную (временную) переменую, все встает на свои места. А более новий IAR ведет себя предсказуемо всегда.
  19. @Сергей Борщ При повторном вызове ф-ции tst при неизменной переменной glb, ф-ция foo вызываться не должна я прошу sv = glb & (1 << 6) а получаю sv = glb
  20. @jcxz не заставляют. После найденой ошибки буду переходить на более свежий IAR. Имя неповторимое (оно не glb). Проблема же в неправильном присвоении значения переменной sv. Вопрос задал так как решил, что что-то упускаю. Видемо и в самом деле компилятор глючит.
  21. @jcxz нет, переменная с таким именем одна. Ну а как же мой "изолированный" пример, разве такое поведение компилятора корректно? З.Ы. Оно соответствует поведению в моем проекте.
  22. почему же компиляция при разных уровнях оптимизации разнится, как и при добавлении дополнительной переменной. Да и более свежий компилятор дает правильный код. Что по вашему надо добавить, что бы код для компилятора был "правильный"? Проект на 1000+ строк не вижу надобности выкладывать. Проблему изолировал. вот что получается когда делаю переменную glb volatile (оптимизация High Balanced) 27 void tst(void) 28 { 29 static uint8_t sv; 30 uint8_t tmp; 31 32 if (sv != (glb & (1 << 6))) { \ `tst`: \ 00000000 0x.... LDR.N R0,??DataTable3_1 \ 00000002 0x7841 LDRB R1,[R0, #+1] \ 00000004 0x7802 LDRB R2,[R0, #+0] \ 00000006 0xF002 0x0240 AND R2,R2,#0x40 \ 0000000A 0x4291 CMP R1,R2 \ 0000000C 0xD007 BEQ.N ??tst_0 33 sv = (glb & (1 << 6)); \ 0000000E 0x7801 LDRB R1,[R0, #+0] // операция "& (1 << 6)" игнорируется \ 00000010 0x7041 STRB R1,[R0, #+1] 34 tmp = (sv)? 0x00 : 0xFF; \ 00000012 0x0648 LSLS R0,R1,#+25 \ 00000014 0xBF4C ITE MI \ 00000016 0x2000 MOVMI R0,#+0 \ 00000018 0x20FF MOVPL R0,#+255 35 foo(tmp); \ 0000001A 0x.... 0x.... B.W foo 36 } 37 38 } \ ??tst_0: \ 0000001E 0x4770 BX LR ;; return
  23. @Arlleex Программа корректна, а результат компиляции нет. Не изменяя программу, а только уровень оптимизации, получаем разный результат (алгоритм). А добавляя промежуточную переменную в "нерабочую" оптимизацию, получаем корректный результат. И еще. IAR ARM 8.30.1.17148 - компилирует правильно
×
×
  • Создать...