nm: кто занял весь флэш?

Если хочется узнать какой код занимает больше всего флэша в микроконтроллере, стоит воспользоваться утилитой nm. Параметр radix задаёт формат отображения чисел. Десятичный удобен для понимания размера, но портит адреса. Пример цели size для make:

size:
    $(PREFIX)nm --print-size --size-sort --radix=d $(BUILD_DIR)/$(TARGET).elf

Таким образом можно узнать, что функция HAL_RCC_OscConfig занимает больше килобайта!

arm-none-eabi-nm --print-size --size-sort --radix=d ./build/target.elf
....
134218896 00001100 T HAL_RCC_OscConfig

Для некоторых случаев можно сократить этот размер закомментировав настройку ненужных источников тактирования. Странно, что это не делается автоматически для источников, отсутствующих в данном МК.

Pwn Adventure 3: Pwnie Island

Великолепные видео-уроки по реверс-инжинирингу сетевой игры Pwnie Island. Игра была сделана именно для этой цели, поэтому в ней оставлена отладочная информация, чтобы не скучать, а сразу перейти к веселью.

О сколько нам открытий чудных…

Узнал как инициализировать массив в Си несколькими повторяющимися значениями:

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

Поддерживается только GCC. Источник: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

На той же странице есть интересное замечание про инициализацию union из int и float — если явно инициализировать float целочисленной константой, то она будет преобразована к float. Если же привести целое к union, то оно останется целым.

О легаси коде

https://tiffnix.com/blog/2014/10/19/refactoring-legacy.html

«I’ve taken up maintaining a project that my friend Darkflux works on. It’s called Fate of the Republic (FotR), a Star-Wars MUD. The website is fateoftherepublic.com, and you can connect via Telnet to fateoftherepublic.com:1313

Отличная статья о том, что такое легаси код, насколько он может быть ужасен и как подходить к задаче приведения его в поддерживаемый вид.

Doxygen, gprof и другие

Начал использовать Doxygen для документирования кода. В поисках документации наткнулся на отличную статью Handbook of Open Source Tools из которой узнал про gprof, который можно применить к микроконтроллерам. Осталось найти время и разобраться с новым инструментом, т. к. выглядит он чрезвычайно полезным.

2.4 GHz Downconverter for an SDR

https://github.com/IanWraith/24DownConvert

Простой и дешёвый downconverter, чтобы подслушивать 2.4 ГГц. Когда-то очень хотел подобную штуку чтобы отладить передачу через NRF24 с помощью RTL-SDR, но находил только дорогие варианты.

OpenOCD RTOS Support

Оказывается, OpenOCD поддерживает отладку ОС для МК, но по умолчанию эта возможность выключена. Поскольку сейчас делаю проект на FreeRTOS, решил попробовать сделать отладку более удобной. Чтобы включить поддержку ОС нужно:

  1. Добавить флаг -rtos auto в строку $_TARGETNAME configure в файле target/xxx.cfg
  2. Добавить в проект файл с определением символа uxTopUsedPriority, т.к. он отсутствует в последних версиях FreeRTOS
  3. Исправить флаги линкера, как указано в файле, чтобы линкер не выкинул этот символ при сборке

Запустив отладку я увидел, что OpenOCD автоматически определил FreeRTOS и нашёл создаваемые ею задачи. К сожалению, собственно отладка у меня не заработала — при попытке дойти до точки останова в main() связь с отладчиком терялась. Пока что пришлось вернуться к отладке без поддержки ОС. Возможно, проблема связана с плагином cortex-debug для vscode. В Eclipse, судя по чужому опыту, всё работает без проблем. Возможно, ещё вернусь к этому вопросу.

Использованные материалы:

STM32 HAL: используем printf

В сгенерированный кубом код нужно добавить следующий кусок в main.c:

#include  <errno.h>
#include  <sys/unistd.h> // STDOUT_FILENO, STDERR_FILENO

int _write(int file, char *data, int len)
{
   if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
   {   
      errno = EBADF;
      return -1; 
   }   

   // arbitrary timeout 1000
   HAL_StatusTypeDef status =
      HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 1000);

   // return # of bytes written - as best we can tell
   return (status == HAL_OK ? len : 0); 
}

Я добавляю после /* USER CODE BEGIN 4 */. UART должен быть предварительно настроен. Да, это блокирующий код, но пока что он меня устраивает.

Смертные машины

Об это книге узнал из трейлера фильма. Захотел было сходить посмотреть, но посмотрев ещё несколько трейлеров разочаровался и взялся за книгу. Она не слишком порадовала: вместо ожидаемого стимпанка вышла детская сказка, которая, однако, совсем не годится для детей, слишком много смертей вокруг. Рекомендовать не буду, однако отзывы на вторую книгу лучше, так что попробую её.

Заводная

Альтернативное будущее, климатическая катастрофа, потеря многих технологий и расцвет биоинженерии. В этом, новом для меня, сеттинге разворачивается борьба министерств природы и торговли Банкока за власть в городе. Интересный и динамичный детектив, рекомендую.

Шантарам

Потрясающая история жизни беглого австралийского заключенного в Бомбее. Здесь есть всё: любовь, дружба, предательство, убийства, наркотики, война, бедность, тюрьма, болезни и доброта, очень много доброты и улыбок местных жителей. Длинная, интересная и очень захватывающая книга, очень рекомендую.

Remmina: unable to connect

Внезапно Remmina перестала подключаться к терминальному серверу по RDP. Сообщение об ошибке было не очень-то внятным:

[16:05:37:017] [3681:4047] [INFO][com.freerdp.client.common.cmdline] - loading channelEx cliprdr
[16:05:37:017] [3681:4047] [INFO][com.freerdp.client.common.cmdline] - loading channelEx drdynvc
[16:05:38:527] [3681:4047] [ERROR][com.winpr.timezone] - Unable to get current timezone rule
[16:05:38:539] [3681:4047] [INFO][com.freerdp.core] - ERRINFO_LICENSE_HWID_DOESNT_MATCH_LICENSE (0x00000104):The Client Access License ([MS-RDPELE] section 1.1) stored by the client has been modified.
[16:05:38:539] [3681:4047] [ERROR][com.freerdp.core.transport] - transport_check_fds: transport->ReceiveCallback() - -1
 libfreerdp returned code is 00010104

Но при внимательном изучении становится понятно, что дело где-то в libfreerdp, а точнее — в изменении сохраненной лицензии. Решил проблему топорно:

mv .config/freerdp/ .config/freerdp-old

После установки соединения Remmina предложила принять новый сертифика и без проблем подключилась к рабочему столу.

STM32: OpenOCD semihosting

Небольшая заметка для себя, чтобы не гуглить заново в следующий раз.

  • В Makefile меняем параметры линкера: вместо -specs=nano.specs пишем -specs=rdimon.specs, вместо -lnosys пишем -lrdimon. Мне также пришлось добавить -Wl,—no-wchar-size-warning, т. к. размерность wchar где-то не совпала.
  • В коде до main объявляем функцию extern void initialise_monitor_handles(void) и вызываем её в начале main. Важный момент — при отсутствии принимающей стороны на хосте этот вызов приведёт к HardFault, т. е. система сможет работать только под отладчиком.
  • Запускаем OpenOCD с командой arm semihosting enable и в его выводе увидим сообщения от printf. Ещё один важный момент — вывод будет в отладочных сообщениях, по telnet его не видно.
  • Для младших контроллеров может стать проблемой увеличение размера прошивки. В STM32F030 пришлось уменьшить размер Min_Heap_Size в LD-скрипте.

Видоизменённый углерод

Прослушал аудиокнигу, про сериал знаю, но пока не смотрел. По книге могу сказать следующее: интересно, картинка будущего мне очень нравится. Могущественные мафы, биотехнологии, перегрузка сознания между телами и виртуальными мирами. На фоне всего этого великолепия разворачивается очень странное расследование странной смерти странным детективом. В этой книге нет философских откровений, но сюжет здорово закручен, есть немало ситуаций, которые заставляют задуматься. Так что смело рекомендую любителям фантастики.

Также могу рекомендовать Схизматрицу Брюса Стерлинга. По-моему, миры этих книг довольно похожи — люди (немногие) получили возможность растянуть жизнь на столетия, вживлять себе разную электронику, но не слишком изменились — интриги, убийства и прочие не слишком приятные способы достижения цели.