OpenOCD — виправлено помилку в команді stm32f1x unlock

Щось останнім часом я практично лише про помилки і пишу. Але тут поруч з поганою новиною є і хороша.

Ще десь перед новим роком виявив біду — у найсвіжішому на той час OpenOCD команда stm32f1x unlock захист зчитування наче знімає, але по тому записати у мікроконтролер нічого не вдається.

На щастя, у мене десь лежала перевірена версія, зібрав її, встановив і все пішло. Вже десь у січні підключився до OpenOCD через telnet, потикався різними командами і з’ясував, що в усі option bytes (окрім readout protection) записані випадкові значення, тобто на довільні сектори flash-пам’яті було встановлено захист від запису, а також попсовано опції SW/HW WDT і інші.

І оце лише на минулому тижні розібрався. Драйвер stm32f1x використовується для роботи з stm32f10x, stm32f0xx, stm32f3xx, але біда лише з stm32f10x. З’ясувалося, що в них захист від зчитування поширюється і на область флеш-пам’яті для блоку опцій. Для двох інших згаданих лінійок цього нема, у документації в табличках окремо відзначено можливість такого зчитування (при захисті з рівнем L1). Можливо, саме тому в коді зчитування опцій з регістрів FLASH_OBR і FLASH_WRPR замінили зчитуванням безпосередньо з адрес 0x1ffff800..0x1ffff80f.

Процедура unlock перед стиранням опцій зчитує їхні значення, щоб під час запису коду дозволу зчитування відновити те, що було. Але ж доступу нема, OpenOCD доповідав, що прочитати не може і йшов далі. Тобто записував випадкові значення, які на той час були у неініціалізованій структурі.

Відповідно, ремонт простий — повернутися до зчитування з регістрів. Зараз патч лежить на узгодженні в їхньому gerrit-і, а я вже користуюся виправленим 🙂

cstdint, arm-none-eabi- та Ubuntu

Міняв диск, заразом поміняв і Убунту 16.04 на 18.10. Як і минулого разу на шістнадцятій, поставив «рідний» для системи пакет arm-none-eabi-. Мабуть, пора закінчувати з такою практикою, всістися на якусь іншу збірку компілятора, ту ж linaro. Бо проекти перестали збиратися. І на чому, на рівному місці! Компілятор не знаходить файл cstdint.

Короткий пошук показав, що версія компілятора 6.3.1, include-файли лежать в /usr/lib/gcc/arm-none-eabi/6.3.1/include та в /usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/include, який, зрештою, вказує на /usr/include/newlib.

А от заголовочні файли C++ лежать в /usr/include/newlib/с++/7.3.1. Звідки взялася сімка — важко сказати. Може це одрук, може дійсно поклали іншу версію, але жодного файлу від C++ cpp не знаходить. Назву 7.3.1 вирішив не чіпати, просто поруч додав лінк 6.3.1->7.3.1. Після цього cpp по -v показав додаткові шляхи до файлів і все стало збиратися.

Неприємна помилка в Doxygen 1.8.11

Зазвичай я не поспішаю переповзати на нову версію Ubuntu і досі сиджу в Ubuntu Mate 16.04. І я не один такий, на роботі також 16.04 (тільки не Mate, а «звичайна», зі стільницею Unity).
І от на роботі ж і виловив помилку в Doxygen, який в убунті 16.04 стоїть версії 1.8.11. Заманулося отримати для перегляду дерева викликів, CALL_GRAPH і CALLER_GRAPH, щоб швидше ознайомитися зі структурою чужого коду. А отримав страшну кашу з довгими циклічними петлями викликів. Виявилося, що всі функції, прототипи яких описано в .h-файлі безпосередньо під inline-функцією, вважаються такими, що викликані з цієї inline-функції.
Мінімальний приклад, doxy-bug.{h,c}:

static inline foo(void) { }

void moo(void);
#include <doxy-bug.h>

void moo(void)
{
    foo();
}

Doxygen 1.8.11 генерує для inline-функції foo() такий граф викликів

Wrong call graph (doxygen 1.8.11)

а для moo() взагалі отакий:
Wrong call graph (doxygen 1.8.11)

Уявляєте, що я отримав на дереві з кількох каталогів і сотень функцій, а в h-файлах під inline-функцією може бути описано декілька прототипів, всі з яких стають «викликаними» з неї? Оскільки всі ці функції викликали ще у глибину на декілька рівнів статичні функції всередині своїх файлів, а вже ті викликали ці inline-операції, утворювалося багато довгих петель.

На щастя, у свіжій версії Doxygen 1.8.15 цю помилку виправлено. Все красиво:
Correct call graph (doxygen 1.8.15)

Переставлю тепер doxygen і на роботі, буде легше.

arm-eabi-ld buffer overflow

або помилка повертається.

Лінкер від gcc-linaro-7.2.1-2017.11-x86_64_arm-eabi (binutils 2.28), має ту ж саму біду, що й avr-ld.
А саме *** buffer overflow detected ***, переповнення буфера sprintf (і знову лаюся — чому використано не snprintf ?!)

p.s. «родич» gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf — the same, тобто те саме.
p.p.s. Arduino навіть для лінукса тягне всі компілятори з собою. Там не увімкнуто локалізацію, тому цієї проблеми нема. У старенького «рідного» в убунті-16.04 arm-none-eabi- теж. Все залежить від того, як збирався лінкер.

Теорема, протилежна оберненій

Оскільки я вже згадав у попередньому дописові про третє видання книжки Кормена і компанії «Вступ до алгоритмів» (так звану CLRS), то напишу і тут про ненароком помічену помилку в російському перекладі книжки.

Працюючи з текстом задачі 8-7 («Лема сортування 0-1 і сортування стовпцями», сторінка 208 оригіналу) вирішив зазирнути в російський переклад, як там цю лему назвали, і тут же око вихопило дуже некоректний текст.

У перекладі російською (сторінка 238) є такі слова: «докажем 0-1-лемму сортировки путём доказательства обратной к ней». Але так не буває. Ніколи-ніколи-ніколи доведення оберненого твердження не доводить пряме. Якщо істинне як пряме твердження, так і обернене, то частини тверджень еквівалентні, тобто (А⇒Б ∧ Б⇒А) ⇒ (А⇔Б). Але шляхом доведення Б⇒А неможливо довести А⇒Б.

І в оригіналі було: «prove the 0-1 sorting lemma by proving its contrapositive»

Контрапозитивне твердження (протиставлення) це протилежне оберненому (або обернене протилежному, що те ж саме), тобто (А⇒Б) ⇔ (¬Б⇒¬А) і саме ¬Б⇒¬А можна довести для доведення А⇒Б (що і зроблено далі по тексту).

Цікаво, скільки ще таких неточностей у цьому перекладі з англійської на російську? І зрозуміло, чому я проти таких подвійних перекладів навіть у «технічних» текстах.

avr-ld buffer overflow

Дійсно прикра помилка в avr-ld (binutils-avr 2.25) — та, що спонукала мене до перевірки використання Raspberry Pi як комп’ютера для роботи, — виявилася доволі цікавою.

Почала вивалюватися вона у мене доволі давно, але я помилково вважав, що вона притаманна 64-бітній версії Ubuntu 16.04, бо на роботі в 32-бітній все працювало. Думав, що це якісь проблеми невраховування розмірів чи співвідношення розмірів змінних на зразок «подаруночка від FTDI». Чесно кажучи, у повідомлення не особливо і вчитувався — «та хай, це по роботі, то на роботі й зберу» і вдома більше не запускав аж до того, як нещодавно перезібрати знадобилося негайно, бо це зупиняло термінову роботу. Тоді ж ото зібрав на Raspberry й написав про все це.

Ну й на ключову фразу *** buffer overflow detected *** Іван у коментарях пояснив, як із цим можна боротися.
Докладніше читайте » » »

The FTDI’s gift

The FTDI’s gift is very interesting.

Keeping the “See Figure 1.” motto in their minds, they have changed data types when switching over from library libftd2xx.so versions 0.4.x to libftd2xx.so.1.0.0. The gift affects on 64-bit libraries only. There is no problem for 32-bit ones.

ftd2xx library was born in Windows and contains WinAPI-like UART support functions FT_W32_ххх(). That’s why WinAPI standard types DWORD, BYTE and so on are used in the library. For Linux version of the library they have added WinTypes.h header file with typedefs for these types. In general, it seems to be a logical step, but…

Continue reading ‘The FTDI’s gift’ »

[flagcounter image]