<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dev on Uzix | микроблог</title><link>https://err200.net/tags/dev/</link><description>Recent content in Dev on Uzix | микроблог</description><generator>Hugo</generator><language>ru-RU</language><lastBuildDate>Mon, 22 Apr 2024 13:15:44 +0300</lastBuildDate><atom:link href="https://err200.net/tags/dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Попробую немного рабочего написать...</title><link>https://err200.net/20240422-artery-spim/</link><pubDate>Mon, 22 Apr 2024 13:15:44 +0300</pubDate><guid>https://err200.net/20240422-artery-spim/</guid><description>&lt;p&gt;Попробую немного рабочего написать - не всё же про ретро железки :)&lt;/p&gt;
&lt;p&gt;Есть такой производитель микроконтроллеров Artery, и есть у него такая штука SPIM - которая, в теории, берёт на себя все нюансы работы с флеш-памятью - настраиваем тип микросхемы и поехали. Но вот на практике&amp;hellip;&lt;/p&gt;
&lt;p&gt;Столкнулся с багой в программе - включаю SPIM, читаю одну ячейку и получаю не то значение, которое там записано. Перечитываю через некоторое время - уже правильный байт. Хм&amp;hellip; Напаяв МГТФ-паука и подрубив логический анализатор вижу, что этот SPIM срезает углы где можно и где нельзя.&lt;/p&gt;
&lt;p&gt;После включения он пишет в два регистра статуса значение 0x02 для настройки QSPI и защиты от записи. Запись именно 0x02 в первый регистр не имеет смысла т.к. первые два бита в нём только для чтения. Ну да ладно - срезали угол, но результат тот же, ок. Но дальше полагается ожидать окончания записи (tW 10-15мс для W25Q128FV) - до этого момента микросхема не принимает почти никакие команды. А вот это сделать забыли и шпарят команды сплошным потоком. Упс.&lt;/p&gt;</description></item><item><title>CMake: указание директорий для поиска библиотек</title><link>https://err200.net/20180418-cmake-custom-libs/</link><pubDate>Wed, 18 Apr 2018 08:21:46 +0000</pubDate><guid>https://err200.net/20180418-cmake-custom-libs/</guid><description>&lt;p&gt;При сборке ПО с использованием CMake иногда возникает необходимость указать нестандартный путь для поиска библиотек.
Сделать это можно следующим образом:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cmake -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=1 -DCMAKE_PREFIX_PATH=/opt/dsview/ ../
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Полезное о C</title><link>https://err200.net/20160227-awesome-c/</link><pubDate>Sat, 27 Feb 2016 14:05:39 +0000</pubDate><guid>https://err200.net/20160227-awesome-c/</guid><description>&lt;p&gt;В этой заметке я буду собирать ссылки на полезные и интересные материалы, обязательные к прочтению каждому использующему язык Си разработчику.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What Every C Programmer Should Know About Undefined Behavior &lt;a href="http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html"&gt;1&lt;/a&gt; &lt;a href="http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html"&gt;2&lt;/a&gt; &lt;a href="http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html"&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://habrahabr.ru/company/pvs-studio/blog/276657/"&gt;Undefined behavior ближе, чем вы думаете&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ridiculousfish.com/blog/posts/will-it-optimize.html"&gt;Тест на понимание работы оптимизатора GCC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cdecl.org/"&gt;Перевод объявлений переменных с языка Си на английский и обратно&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.viva64.com/ru/a/0004/"&gt;20 ловушек переноса Си++ - кода на 64-битную платформу&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://habrahabr.ru/post/274083/"&gt;Как я написал компилятор C за 40 дней&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://habrahabr.ru/post/272269/"&gt;memset — сторона тьмы&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://habrahabr.ru/post/268989/"&gt;Объекты нулевого размера&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://habrahabr.ru/post/114117/"&gt;Про C++ алиасинг, ловкие оптимизации и подлые баги&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.viva64.com/ru/b/0391/"&gt;Разбор типичных ошибок при разработке на С/С++&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Несколько очень интересных презентаций](&lt;a href="http://www.slideshare.net/olvemaudal?utm_campaign=profiletracking&amp;amp;utm_medium=sssite&amp;amp;"&gt;http://www.slideshare.net/olvemaudal?utm_campaign=profiletracking&amp;amp;utm_medium=sssite&amp;amp;&lt;/a&gt;
utm_source=ssslideview)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cl.cam.ac.uk/~pes20/cerberus/notes50-survey-discussion.html"&gt;What is C in practice? (Cerberus survey v2): Analysis of Responses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/12264970/why-is-my-program-slow-when-looping-over-exactly-8192-elements"&gt;О пользе понимания работы кэша в современных процессорах&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard"&gt;SEI CERT C Coding Standard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html"&gt;Understanding Strict Aliasing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Различные нюансы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/2108192/what-are-the-valid-signatures-for-cs-main-function"&gt;Сигнатуры main&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/693788/c-void-arguments"&gt;(void) vs ()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/25816659/can-printf-get-replaced-by-puts-automatically-in-a-c-program"&gt;Про автоподмену builtin-функций&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Статический анализ вызовов printf-like функций</title><link>https://err200.net/20151116-printf-analysis/</link><pubDate>Mon, 16 Nov 2015 08:38:13 +0000</pubDate><guid>https://err200.net/20151116-printf-analysis/</guid><description>&lt;p&gt;При разработке для встраиваемых систем зачастую приходится писать свои реализации printf и подобных функций. Однако для самописных функций не работает опция &amp;ldquo;-Wformat&amp;rdquo;: проверка вызовов на корректность аргументов (сверка количества и типов аргументов со строкой форматирования). Для решения этой проблемы в GCC существует специальный атрибут функции &amp;ldquo;format&amp;rdquo;. Пример применения:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;int fmt( void (*put)(char,void**), void *putarg, const char *fmt, ... )
 __attribute__ ((format (__printf__, 3, 4)));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Первым аргументом атрибута идёт тип проверки (&lt;strong&gt;printf&lt;/strong&gt;, &lt;strong&gt;scanf&lt;/strong&gt;, &lt;strong&gt;strftime&lt;/strong&gt;, &lt;strong&gt;strfmon&lt;/strong&gt;), второй - номер аргумента с форматом (нумерация с 1), третий - номер аргумента с которого начинается список аргументов (&amp;hellip;).&lt;/p&gt;</description></item><item><title>Лямбды в Си</title><link>https://err200.net/20151113-c-lambdas/</link><pubDate>Fri, 13 Nov 2015 14:06:27 +0000</pubDate><guid>https://err200.net/20151113-c-lambdas/</guid><description>&lt;p&gt;Есть два пути получения лямбд в Си:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Использовать дополнительный препроцессор &lt;a href="https://github.com/eudoxia0/cmacro"&gt;cmacro&lt;/a&gt;. Идея очень интересная, но, к сожалению, реализация подводит. У меня этот препроцессор не только спотыкался на простейших конструкциях (например, лямбда, возвращающая указатель), но и умудрялся портить совершенно сторонний код (&amp;ldquo;return -1&amp;rdquo; чудесным образом превращается в &amp;ldquo;return- 1&amp;rdquo;). Проект по всей видимости заброшен.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Использовать расширения компилятора GCC. Это простой и безболезненный путь если нет необходимости сохранять совместимость с другими компиляторами. Для этого варианта достаточно объявить макрос:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#define lambda(l_ret_type, l_arguments, l_body) \
 ({ \
 l_ret_type l_anonymous_functions_name l_arguments \
 l_body \
 &amp;amp;l_anonymous_functions_name; \
 })
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Пример создания и использования лямбды:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; printf(&amp;#34;%s world\n&amp;#34;, lambda(char*, (void), { return &amp;#34;Hello&amp;#34;; } )() );
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Обратите внимание: GCC волен размещать код вложенных функций (и, как следствие, лямбд) &lt;a href="https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html"&gt;в стеке!&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Анализ сбоев МК пост-фактум</title><link>https://err200.net/20151008-crashcatcher/</link><pubDate>Thu, 08 Oct 2015 11:16:34 +0000</pubDate><guid>https://err200.net/20151008-crashcatcher/</guid><description>&lt;p&gt;Часто возникает необходимость зафиксировать состояние МК во время сбоя (деление на 0, разыменование нулевого указателя, обращение к невыровненному адресу и тысяча других возможностей прострелить себе ногу). И часто при этом нет возможности держать устройство с подключенным отладчиком.&lt;/p&gt;
&lt;p&gt;В таких случаев поможет связка ПО &lt;a href="https://github.com/adamgreen/CrashDebug"&gt;CrashDebug&lt;/a&gt; и &lt;a href="https://github.com/adamgreen/CrashCatcher"&gt;CrashCatcher&lt;/a&gt;.
CrashCatcher - библиотека подключающаяся к прошивке МК. Она берёт на себя обработку исключения HardFault и вывод содержимого регистров и памяти на последовательный порт (либо любым другим реализованным программистом способом). Полученный по последовательному порту дамп сохраняется в файл и передаётся утилите CrashDebug, выступающей в роли target для GDB. Дальше уже можно работать любыми привычными средствами - консольным arm-none-eabi-gdb, ddd, либо даже Eclipse (через тип конфигурации &amp;ldquo;GDB Hardware Debug&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Оба проекта имеют исчерпывающую документацию и достаточно легко интегрируются в существующий проект.&lt;/p&gt;</description></item><item><title>Если вы калибруете АЦП...</title><link>https://err200.net/20150903-adc-calibration/</link><pubDate>Thu, 03 Sep 2015 17:38:05 +0000</pubDate><guid>https://err200.net/20150903-adc-calibration/</guid><description>&lt;p&gt;&amp;hellip; то не забывайте перед калибровкой отключать DMA (ADC1-&amp;gt;CFGR1 &amp;amp;= ~ADC_CFGR1_DMAEN) и сбрасывать значение счётчика DMA1_ChannelN-&amp;gt;CNDTR.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;static void adc_recalibrate( void )
{
 ADC1-&amp;gt;CR |= ADC_CR_ADSTP; // Stop current conversion
 while( ADC1-&amp;gt;CR &amp;amp; ADC_CR_ADSTP ); // .. and wait
 ADC1-&amp;gt;CFGR1 &amp;amp;= ~ADC_CFGR1_DMAEN; // Disable DMA req
 ADC1-&amp;gt;CR |= ADC_CR_ADDIS; // Disable ADC
 while( ADC1-&amp;gt;CR &amp;amp; ADC_CR_ADEN ); // .. and wait
 DMA1_Channel1-&amp;gt;CCR &amp;amp;= ~DMA_CCR_EN; // Stop DMA transfer
 while( DMA1_Channel1-&amp;gt;CCR &amp;amp; DMA_CCR_EN ); // .. and wait
 ADC1-&amp;gt;CR |= ADC_CR_ADCAL; // Start ADC calibration
 while( ADC1-&amp;gt;CR &amp;amp; ADC_CR_ADCAL ); // .. and wait
 ADC1-&amp;gt;CR |= ADC_CR_ADEN; // Enable ADC
 while( !(ADC1-&amp;gt;ISR &amp;amp; ADC_ISR_ADRDY) ); // .. and wait
 ADC1-&amp;gt;CFGR1 |= ADC_CFGR1_DMAEN; // Enable DMA req
 ADC1-&amp;gt;CR |= ADC_CR_ADSTART; // Start ADC conversion
 DMA1_Channel1-&amp;gt;CNDTR = ADC_CHAN_COUNT * ADC_FILTER_SIZE; // Set cycle size
 DMA1_Channel1-&amp;gt;CCR |= DMA_CCR_EN; // Start DMA transfer
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;small&gt;&lt;em&gt;Пример кода для STM32F030C8&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Полдня убил на это - после повторного запуска АЦП (в режиме непрерывной оцифровки нескольких каналов) каналы путались местами. Из документации совершенно не очевидно что нужно не просто выключить канал DMA, но и выключить формирование DMA-запроса в самом АЦП.&lt;/p&gt;
&lt;p&gt;Такие дела.&lt;/p&gt;</description></item><item><title>Отладка RTOS в OpenOCD</title><link>https://err200.net/20150719-openocd-rtos/</link><pubDate>Sun, 19 Jul 2015 16:54:22 +0000</pubDate><guid>https://err200.net/20150719-openocd-rtos/</guid><description>&lt;p&gt;Для отладки RTOS помимо плагинов IDE можно использовать встроенные средства OpenOCD. На данный момент поддерживаются FreeRTOS, ChibiOS, eCos и другие.&lt;/p&gt;
&lt;p&gt;Для использования этой функциональности нужно в параметры запуска openocd добавить следующую строку (для openocd 0.9 и stm32f4):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-c &amp;#34;stm32f4x.cpu configure -rtos auto&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В случае FreeRTOS версий старше 7.5.3 нужно выполнить дополнительные движения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Добавить в исходный код определение:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;const volatile int __attribute__((used)) uxTopUsedPriority = configMAX_PRIORITIES;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Добавить в параметры запуска компоновщика:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-Wl,--undefined=uxTopUsedPriority
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Настройка Eclipse для разработки под STM32</title><link>https://err200.net/20150602-stm32-eclipse/</link><pubDate>Tue, 02 Jun 2015 06:01:33 +0000</pubDate><guid>https://err200.net/20150602-stm32-eclipse/</guid><description>&lt;p&gt;Инструкций сходной тематики в интернете немало, но как то вышло что информацию мне всё равно пришлось собирать по кусочкам. В этой статье я подытожу весь процесс от А до Я. Всё будет делаться на примере дистрибутива Debian Sid и отладочной платы STM32F4Discovery.&lt;/p&gt;</description></item></channel></rss>