Jump to content

    

Arlleex

Свой
  • Content Count

    1244
  • Joined

  • Last visited

Everything posted by Arlleex


  1. Приветствую! Keil 5.28.0.0, оптимизация -O3 и установлен чекбокс оптимизации по скорости -Ot. Есть функция #define RBTYPE u8 #define RB_BUF_SIZE (64 + 1) typedef struct { volatile s32 rp, wp; RBTYPE buf[RB_BUF_SIZE]; }sRingBuf; s32 rb_Read(sRingBuf *rb, RBTYPE buf[], s32 len) { s32 rlen = rb_GetBusy(rb); if(rlen > len) rlen = len; len = rlen; s32 rp = rb->rp; for(; len-- > 0; rp &= (rp - RB_BUF_SIZE) >> 31) *buf++ = rb->buf[rp++]; rb->rp = rp; return rlen; } На неоптимизирующей сборке все отлично. На -O3 + -Ot получаю следующий выхлоп: 0x08001634 B430 PUSH {r4-r5} 0x08001636 4605 MOV r5,r0 114: s32 t = rb->wp; 0x08001638 6840 LDR r0,[r0,#0x04] 115: if((t -= rb->rp) < 0) 0x0800163A 682B LDR r3,[r5,#0x00] 115: if((t -= rb->rp) < 0) 0x0800163C 1AC0 SUBS r0,r0,r3 44: { 45: s32 rlen = rb_GetBusy(rb); 0x0800163E D500 BPL 0x08001642 0x08001640 3041 ADDS r0,r0,#0x41 46: if(rlen > len) rlen = len; 0x08001642 4290 CMP r0,r2 0x08001644 DC11 BGT 0x0800166A 47: len = rlen; s32 rp = rb->rp; 48: #if (pwroftwo(RB_BUF_SIZE)) 49: for(; len-- > 0; rp &= RB_BUF_SIZE - 1) 50: #else 0x08001646 682C LDR r4,[r5,#0x00] 51: for(; len-- > 0; rp &= (rp - RB_BUF_SIZE) >> 31) 52: #endif 0x08001648 2800 CMP r0,#0x00 0x0800164A DD0B BLE 0x08001664 0x0800164C 4603 MOV r3,r0 53: *buf++ = rb->buf[rp++]; 0x0800164E 192A ADDS r2,r5,r4 0x08001650 7A12 LDRB r2,[r2,#0x08] 0x08001652 700A STRB r2,[r1,#0x00] 0x08001654 4622 MOV r2,r4 0x08001656 3A41 SUBS r2,r2,#0x41 0x08001658 17D2 ASRS r2,r2,#31 0x0800165A 4022 ANDS r2,r2,r4 0x0800165C 1C54 ADDS r4,r2,#1 0x0800165E 1C49 ADDS r1,r1,#1 0x08001660 1E5B SUBS r3,r3,#1 0x08001662 D1F4 BNE 0x0800164E 54: rb->rp = rp; 55: return rlen; 0x08001664 602C STR r4,[r5,#0x00] 56: } 57: 58: s32 rb_Write(sRingBuf *rb, RBTYPE buf[], s32 len) 0x08001666 BC30 POP {r4-r5} 0x08001668 4770 BX lr Интересует сам цикл: Как так??? С какого лешего сначала выполняется rp &= (rp - RB_BUF_SIZE) >> 31, а лишь потом постиндексация rp при записи в buf? Ведь после выражения *buf++ = rb->buf[rp++]; (согласно стандарту) есть точка следования, и все побочные действия вычислений уже произошли. Лишь потом должна выполниться операция очистки по маске (третий аргумент цикла)... Из-за этого косяка у меня неправильно обрабатывается кольцо на максимальной оптимизации. Если сделать тупо for(; len-- > 0; rp &= (rp - RB_BUF_SIZE) >> 31) { *buf++ = rb->buf[rp]; ++rp; } то все работает как положено. если сделать rp как volatile, то все будет тоже как положено. Что это? Глюк оптимизации или я дурак?
  2. Ребилдол пил, не помогает. Галки убирал/ставил, удалял папки с выходным шлаком, убирал/ставил галки снова - ноль реакции. .uvguix завтра попробую удалить и посмотрю, что поменяется. А то совсем как-то с такой средой не разгонишься
  3. @Xenia, Вам только готовый .bin/.hex прошить в контроллер? Скачайте штатную утилиту для программирования через ST-Link. Называется STM32 ST-Link Utility. Как поставите, жмете Target-Connect, Target-Program. Выбираете файл и жмете прошить. Это будет решение, не зависящее от компилятора/среды. Плата питается напрямую от USB-mini, того, который ST-Link-овский.
  4. +1. У себя в коде тоже имею хитрые макросы, которые рассчитывает все и в случае выхода чего-то за диапазон, вываливаются в виде ошибок или предупреждений компиляции. А делаю с тех пор, когда по неосторожности расчета тактовых частот разогнал PLL до ~450МГц. МК сильно нагрелся, и перестал фунциклировать. Я манал такие ошибки типа "ой опечатался"...
  5. В 90% случаев я оптимизацию ставлю лишь для защиты от модернизации бинарника ПО третьими лицами, а не для скорости... Бывало такое в практике. Конечно, лучшим решением в этом случае было и остается шифрование, но блин: для не сильно сложных проектов это излишество. А любителям реверса и -O3 хватит, чтобы вдоволь наиграться и сесть в лужу. К тому же, как мне известно, прошивки попадают к несильно компетентным людям. А клоноделов и любителей пошаманить что-то в прошивке мы вынуждаем отказаться от этой затеи ввиду элементарной смены ревизии СПО на взаимодействующих модулях всего комплекса. Поэтому сегодня они стырили бинарь и он работает на другой железке, а завтра мы обновляем ПО и клоны отвалились.
  6. Дело в том, что оптимизация не влияет и влиять не может на навигацию по проекту, так как она, скорее всего, работает просто как file search. А с этой красной надписью встречался и раньше, возможно именно поэтому забил на этот компилятор и работал с armcc... Я дебажу в -O0, релиз в -O3 + -Ot (либо просто -O3). Но в новом компиляторе появилась balanced, поэтому юзать буду ее. Всегда так и было, собственно
  7. Да как банальный #define A 100 может выкидываться оптимизатором? И при чем тут он... К тому же я сейчас на -O0 вообще, поскольку отлаживаюсь. То бишь не только переходы по функциям не работают, не работают вообще любый переходы по символам, будь то функции или defines, typedefs и т.д.
  8. Что на -O1? Появляется надпись или нет? Или Вы про баг компайлера?
  9. Обнаружил, что со сменой компилятора перестали работать переходы по функциям/определениям и т.д. По нажатию "Go to definition" внизу слева пишется No information available for the selected symbol. Галка "Browse information" в настройках стоит. Может, знает кто, в чем проблема?
  10. Rust вместо C

    Я тоже ценитель, если что Но Вы хоть раз хоть в одном проекте видели такую конструкцию? Вот такую или еще сложнее? Я вот нет... Бывали у меня конструкции типа массива указателей на функции или указателей на массивы функций, но не более. Я читать это могу, но пишу только в безвыходной ситуации (то есть стараюсь избегать этих конструкций).
  11. Эх... Долго я с ним (armcc) дружил На v6 все работает как положено, спасибо.
  12. Компилятор armcc v5.06 update 6 (build 750).
  13. академический вопрос про вектора прерываний

    Ну а чего не понятного? Функция для понимания человеком находится по адресу 0x0800076E. Для процессора надо в этом адресе установить младший бит, поэтому получаем 0x0800076F.
  14. академический вопрос про вектора прерываний

    Cortex-M - это профиль процессоров архитектуры ARMv7-M, и, строго говоря, настоящим ARM-процессором не является (нету у него набора инструкций ARM). А вот настоящие процессоры ARM поддерживали два набора команд: 32-битный ARM и 16/32-битный Thumb/Thumb-2. Для выполнения Thumb на ARM-процессоре требовалось адресовать их по полусловам, т.е. младший бит был установлен в 1. Этот бит копировался в бит T регистра CPSR и указывал процессору текущий набор инструкций. Cortex-M не поддерживает ARM-команды, а поддерживает только Thumb/-2. Так вот для переносимости кода решили оставить этот самый младший бит в 1, чтобы процессор понимал, что исполняет команды Thumb-набора.
  15. академический вопрос про вектора прерываний

    Младший бит адреса должен быть установлен в 1 для указания CPU, что он исполняет код из набора Thumb/-2. За подробностями в мануал на ядро.
  16. B-L475E-IOT01A

    А пошагать под отладчиком по этим самым LL-функциям? А лучше руками согласно даташиту установить MSI и проверить его Ready. Раз под отладчиком заходит, значит MSI все-таки работает.
  17. STM-ками мир не ограничен... Полно контроллеров с крайне низким потреблением. Но круг сужается, если еще одним приоритетом поставить 5-вольтовое питание контроллера.
  18. B-L475E-IOT01A

    После сброса МК итак тактируется от MSI. Не может быть такого. Вы контроллер в проекте точно тот выбрали? ИМХО, проблема не в коде а где-то в настройках самого проекта. После сброса МК, что показывает отладчик в регистре CR?
  19. Вот тоже думал, что с уходом в 32-разрядные МК в мир 8-битных больше не вернусь. Ага, щас По работе приходится порой полностью переписывать ПО под серийные старые железяки как раз с AVR-контроллерами, которые еще при царе Горохе были разработаны...
  20. Приветствую! По описаниям и отзывам понравилась вот эта вот штуковина. Сами понимаете, вещь крайне удобная и нужная. Всякие протоколы парсить, интерфейсы отлаживать... Вопрос больше не технический а политический - как думаете, китайские коробки с Aliexpress это клоны или перекупленные оригиналы? Ну, например, такая. Цены, с одной стороны, не гуманные, с другой - потратить немного больше среднего, получая более менее адекватную железку, ИМХО, нормально. Есть тут пользователи сего чуда техники? Лишний отзыв не будет лишним, как бы противоречиво это не прозвучало
  21. Думаю, нужно четко понимать разницу между "я еще не знаю, что мне нравится и чем я буду заниматься в жизни" и "я знаю, что мне нужно и я хочу глубоко изучить средства для достижения поставленной цели". Нужно не забывать, что пацану 10 лет и в его возрасте элементарно сменить круг интересов. С Пратами и Керниганами не видно сути - ребенок будет чувствовать себя как студни в универах - матан зачем-то учат, даже как-то сдают, а для чего и зачем оно надо - хз. А дальше все просто - не видно результата, не видно прогресса - *хлопок закрытой книги* - пап, пойду лучше в танки играть или раков на миде шарохать. ИМХО, пусть лучше пока глубже изучает Ардуино. Там уйму прикольных вещей можно сделать же. Наигравшись, парень сам придет к тому, что для более глубокого понимания нужно капнуть дальше и тогда уже можно и Си, и микроконтроллеры 18+ (в голом виде) и покурить мануал и т.д.
  22. Есть у меня в бумаге отличная книга для начинающих и не только... Хреново только, что книга вышла ограниченным тиражом и найти ее в электронке, наверное, невозможно. С: Руководство пользователя / Клинт Хикс ; Пер. с англ.: В.Тимофеев . – М. : БИНОМ, 1997 . – 442 с. : ил. - Пер. изд.: Using C/Hicks C.- Б.м., Cop. 1995. Когда буду в Москве, зафоткаю, в каком стиле идет повествование. Мне в свое время очень понравился. Есть в конце глав разделы "Найди ошибку", или, например, "Закрепи материал" или подобные и т.д, точно не вспомню уже. Так что, если есть у кого-то из знакомых, берите
  23. Проблема с I2C в STM32F4

    С наступившим Новым годом! Использовал аппаратный I2C в STM32 почти всех серий и калибров (кроме F7/H7, Gx), в различных режимах Master/Slave, с и без DMA. Таймауты, на мой взгляд, при окучивании флажков периферии, обязательны в любом случае. Я вообще использую аппаратный таймер для этого. Контролировать зависание надо как в Master-, так и Slave-режимах. В режиме Master, бывало, Slave затыкался. Приходилось делать по NXP-шному документу. Только я не просто SCL болтал, а сначала болтал, а потом STOP-ов столько же выдавал, тут @jcxz правильную мысль озвучил. Но самый эпик, если Slave, поддерживающий Clock Stretching, растягивал линию SCL и в таком положении зависал на бесконечно долгое время. Тут только Power Reset.
  24. Да вот было все некогда да и нужно ли... Я думал, что это то самое качество за 500р. Впрочем, макеты я делаю периодически, поэтому в следующий раз этот момент буду контролировать.