Hatred's Log Place

DON'T PANIC!

Mar 14, 2023 - 7 minute read - Linux Thinkpad

Thinkpad P15 Gen2: гибридная графика

Карта у меня стоит далеко не топовая:

nVidia T1200
$ lspci -nn | grep VGA
00:02.0 VGA compatible controller [0300]: Intel Corporation TigerLake-H GT1 [UHD Graphics] [8086:9a60] (rev 01)
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU117GLM [T1200 Laptop GPU] [10de:1fbc] (rev a1)

Карта поколения NV160 family (Turing). Это будет важно в дальнейшем.

Первое, у нас, аналогично T530 (там правда mDP, а VGA - на встроенную карту, но тут VGA нет /дополнительный порт - через TypeC/), HDMI разведён на дискретную карту. Соответственно нельзя использовать её без настройки оной.

Второе, эта карта поддерживается открытым ядерными драйверами от самой nvidia: nvidia-open / nvidia-open-dkms. К сожалению, самих драйверов не завезли в репозитории Manjaro (тогда как в ArchLinux они есть). Ставим beta или git из AUR.

Внешний монитор на HDMI

Главное - удалить пакет bumblebee: он блеклистит как драйвера нуво (nouveau), так и официальный драйвера nVidia.

При этом, при загруженной системе выход на HDMI работает как с открытыми драйверами nouveau из коробки, так и с закрытыми драйверами.

Для нуво ничего, собственно, делать не нужно, единственно, стоит удалить xf86-video-nouveau, так для карт поколения NVC50+ рекомендую использовать встроенный modeset.

Для проприетарных - ниже.

Для того, что бы средствами обычного xrandr/DRM внешний порт нормально цеплялся:

  1. Удалить bumblebee
  2. Добавить в загрузку nvidia_drm (не обязательно, при удалённом bumblebee он и сам загрузится)
  3. Добавить параметр nvidia_drm.modeset=1 (я сделал через параметры модулей)

Для загрузки модуля, пишем в /etc/modules-load.d/modules.conf:

# List of modules to load at boot  
nvidia_drm

TBD:

  • nvidia
  • nvidia_drm
  • nvidia_uvm
  • nvidia_modeset

Для параметров, создаём файл /etc/modprobe.d/nvidia.conf:

options nvidia_drm modeset=1

Это автоматически подгрузит и nvidia_modeset.

Всё, после чего у нас всё магическим образом заработает:

$ xrandr --listproviders
Providers: number : 2  
Provider 0: id: 0x49 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 4 outputs: 7 associated providers: 1 name:modesetting  
Provider 1: id: 0x2a2 cap: 0x2, Sink Output crtcs: 4 outputs: 5 associated providers: 1 name:NVIDIA-G0

А в KDE Plasma по Fn+F7 будет работать выбор режима расширения экрана при подключенном внешнем мониторе.

PRIME

В отличии от HDMI выхода, драйвера nouveau не работают от слова совсем. Ошибка. TBD: добавить вывод ошибки.

Поэтому рассматриваем только официальные драйвера.

Ставим:

$ sudo pacman -S nvidia-prime

Проверяем:

$ prime-run glxinfo | grep "OpenGL renderer"
OpenGL renderer string: NVIDIA T1200 Laptop GPU/PCIe/SSE2

По сути, он просто задаёт нужные переменные окружения:

Настройки для внешнего монитора должны быть сделаны.

Power Management

Как говорится тут для новейших карт Ampere ничего делать не нужно, а наша Turing мы можем полностью отключить карту, когда она не используется. Нужно создать udev правила /etc/udev/rules.d/80-nvidia-pm.rules:

# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"

# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"

И добавить параметры для главного модуля nvidia:

options nvidia "NVreg_DynamicPowerManagement=0x02"

Затем включить сервис nvidia-persistenced.service:

sudo systemctl enable nvidia-persistenced.service

Проблемы

Зависает ядро

Точнее так, это не беда nVidia, это беда только на процессорах 11gen от Intel, который, собственно у меня и стоит:

Сама проблема описана тут:

nvidia may not boot on Linux 5.18 (or later) on systems with Intel CPUs (likely only of 11th Gen and onward) due to FS#74886/ FS#74891. Until this is fixed, a workaround is disabling the Indirect Branch Tracking CPU security feature by setting the ibt=off kernel parameter from the boot loader. This security feature is responsible for mitigating a class of exploit techniques, but is deemed safe as a temporary stopgap solution.

У меня аффектит в том числе и работу Virtual Box:

[  456.563262] SUPR0GipMap: fGetGipCpu=0x1b  
[  457.249272] traps: Missing ENDBR: 0xffffacace3a50c20  
[  457.249303] ------------[ cut here ]------------  
[  457.249304] kernel BUG at arch/x86/kernel/traps.c:255!  
[  457.249308] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI  
[  457.249312] CPU: 14 PID: 6732 Comm: EMT-0 Tainted: G           OE      6.1.12-1-MANJARO #1 d419fb51ba9431ae2a4575820ea6b5b95f50a34f  
[  457.249314] Hardware name: LENOVO 20YQ0058RT/20YQ0058RT, BIOS N37ET39W (1.20 ) 04/15/2022  
[  457.249315] RIP: 0010:exc_control_protection+0xc2/0xd0  
[  457.249320] Code: fa ff 45 31 c9 49 89 d8 b9 09 00 00 00 48 8b 93 80 00 00 00 be fc 00 00 00 48 c7 c7 09 4e 44 b9 e8 c3 84 46 ff e9 64 ff ff ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 9  
0 66 0f 1f 00 55 53 48 89  
[  457.249321] RSP: 0018:ffffacace1cf7c38 EFLAGS: 00010002  
[  457.249323] RAX: 0000000000000028 RBX: ffffacace1cf7c58 RCX: 0000000000000000  
[  457.249324] RDX: 0000000000000000 RSI: ffff8afd1f7a1660 RDI: ffff8afd1f7a1660  
[  457.249325] RBP: 0000000000000003 R08: 0000000000000000 R09: ffffacace1cf7ad0  
[  457.249325] R10: 0000000000000003 R11: ffffffffb9ccc7e8 R12: 0000000000000000  
[  457.249326] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000  
[  457.249327] FS:  00007fe0241fd6c0(0000) GS:ffff8afd1f780000(0000) knlGS:0000000000000000  
[  457.249328] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033  
[  457.249329] CR2: ffffacace38c5b10 CR3: 00000002ac0d0006 CR4: 0000000000f70ee0  
[  457.249330] PKRU: 55555554  
[  457.249331] Call Trace:  
[  457.249333]  <TASK>  
[  457.249335]  asm_exc_control_protection+0x26/0x30  
[  457.249337] RIP: 0010:0xffffacace3a50c20  
[  457.249339] Code: 16 9d e6 ff 4c 89 e7 89 c3 e8 7c 94 e6 ff 85 db 0f 48 c3 5b 41 5c 5d c3 66 90 b8 fe ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 <83> fe 0f 77 53 55 83 ce 10 48 89 e5 53 4  
8 89 fb 48 8d 7f 18 48 83  
[  457.249340] RSP: 0018:ffffacace1cf7d08 EFLAGS: 00010246  
[  457.249341] RAX: 0000000000000000 RBX: ffffacace2219010 RCX: 0000000000000001  
[  457.249342] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffacace2219030  
[  457.249343] RBP: ffffacace1cf7de0 R08: ffffacace3a5b95d R09: ffffacace2219010  
[  457.249343] R10: ffffacace226a000 R11: 0000000000000000 R12: ffff8af9c6c79a10  
[  457.249344] R13: ffffffffc0bffce0 R14: 0000000000000004 R15: ffff8af9c6c79a10  
[  457.249346]  ? asm_exc_page_fault+0x26/0x30  
[  457.249348]  ? supdrvIOCtl+0x2d77/0x31b0 [vboxdrv 2ebee49653aba23a54dbd683c8be87cd93f03860]  
[  457.249364]  ? _copy_from_user+0x47/0x60  
[  457.249368]  ? VBoxDrvLinuxIOCtl_7_0_6+0x162/0x260 [vboxdrv 2ebee49653aba23a54dbd683c8be87cd93f03860]  
[  457.249376]  ? do_syscall_64+0x6b/0x90  
[  457.249378]  ? __x64_sys_ioctl+0x91/0xd0  
[  457.249381]  ? do_syscall_64+0x5c/0x90  
[  457.249382]  ? exc_page_fault+0x74/0x170  
[  457.249384]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd  
[  457.249385]  </TASK>  
[  457.249386] Modules linked in: snd_seq_dummy snd_seq snd_seq_device ccm rfcomm qrtr cmac algif_hash algif_skcipher af_alg bnep btusb uvcvideo btrtl videobuf2_vmalloc btbcm videobuf2_memo  
ps btintel videobuf2_v4l2 btmtk videobuf2_common videodev bluetooth mc ecdh_generic joydev mousedev snd_ctl_led snd_soc_skl_hda_dsp snd_soc_intel_hda_dsp_common snd_soc_hdac_hdmi snd_sof_pr  
obes snd_hda_codec_realtek snd_hda_codec_generic snd_soc_dmic snd_sof_pci_intel_tgl snd_sof_intel_hda_common soundwire_intel soundwire_generic_allocation soundwire_cadence snd_sof_intel_hda  
snd_sof_pci snd_sof_xtensa_dsp intel_tcc_cooling snd_sof snd_sof_utils x86_pkg_temp_thermal snd_soc_hdac_hda intel_powerclamp snd_hda_ext_core coretemp snd_soc_acpi_intel_match kvm_intel s  
nd_soc_acpi vfat fat soundwire_bus kvm snd_soc_core iwlmvm irqbypass crct10dif_pclmul snd_compress crc32_pclmul ac97_bus polyval_clmulni snd_hda_codec_hdmi snd_pcm_dmaengine polyval_generic  
gf128mul ghash_clmulni_intel mac80211 sha512_ssse3  
[  457.249418]  snd_hda_intel aesni_intel processor_thermal_device_pci_legacy snd_intel_dspcfg crypto_simd snd_intel_sdw_acpi processor_thermal_device cryptd libarc4 mei_hdcp mei_pxp snd_hd  
a_codec processor_thermal_rfim iTCO_wdt rapl nouveau iwlwifi snd_hda_core spi_nor intel_pmc_bxt processor_thermal_mbox snd_hwdep mei_me intel_cstate iTCO_vendor_support ee1004 intel_rapl_ms  
r ucsi_acpi processor_thermal_rapl think_lmi snd_pcm intel_uncore cfg80211 psmouse pcspkr firmware_attributes_class mtd wmi_bmof typec_ucsi i2c_i801 mxm_wmi igc mei intel_rapl_common thunde  
rbolt snd_timer drm_ttm_helper i2c_smbus typec intel_soc_dts_iosf roles int3400_thermal int3403_thermal acpi_thermal_rel int340x_thermal_zone intel_hid acpi_pad sparse_keymap acpi_tad mac_h  
id dm_multipath dm_mod vboxnetflt(OE) vboxnetadp(OE) vboxdrv(OE) sg crypto_user fuse acpi_call(OE) bpf_preload ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 rtsx_pci_sdmmc mmc_c  
ore nvme thinkpad_acpi nvme_core crc32c_intel spi_intel_pci  
[  457.249452]  xhci_pci serio_raw rtsx_pci ledtrig_audio spi_intel nvme_common xhci_pci_renesas atkbd platform_profile libps2 snd vivaldi_fmap soundcore i8042 rfkill serio i915 drm_buddy i  
ntel_gtt video wmi drm_display_helper cec ttm  
[  457.249462] ---[ end trace 0000000000000000 ]---  
[  457.249463] RIP: 0010:exc_control_protection+0xc2/0xd0  
[  457.249465] Code: fa ff 45 31 c9 49 89 d8 b9 09 00 00 00 48 8b 93 80 00 00 00 be fc 00 00 00 48 c7 c7 09 4e 44 b9 e8 c3 84 46 ff e9 64 ff ff ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 9  
0 66 0f 1f 00 55 53 48 89  
[  457.249466] RSP: 0018:ffffacace1cf7c38 EFLAGS: 00010002  
[  457.249467] RAX: 0000000000000028 RBX: ffffacace1cf7c58 RCX: 0000000000000000  
[  457.249468] RDX: 0000000000000000 RSI: ffff8afd1f7a1660 RDI: ffff8afd1f7a1660  
[  457.249468] RBP: 0000000000000003 R08: 0000000000000000 R09: ffffacace1cf7ad0  
[  457.249469] R10: 0000000000000003 R11: ffffffffb9ccc7e8 R12: 0000000000000000  
[  457.249469] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000  
[  457.249470] FS:  00007fe0241fd6c0(0000) GS:ffff8afd1f780000(0000) knlGS:0000000000000000  
[  457.249471] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033  
[  457.249472] CR2: ffffacace38c5b10 CR3: 00000002ac0d0006 CR4: 0000000000f70ee0  
[  457.249473] PKRU: 55555554

В выхлопе nVidia тоже будет присутстввать:

traps: Missing ENDBR: 0xffffacace3a50c20  

Решение: добавить параметр ibt=off для ядра.

Открываем /etc/default/grub и добавляем:

GRUB_CMDLINE_LINUX_DEFAULT="... ibt=off ...

После чего:

sudo update-grub

и перезагрузка.

Не запускается SDDM

У меня такое на дровах из репозитория. Поставил nvidia-open-beta - проблема ушла.

Особенности

Кто кого блеклистит и когда.

Первое, пакет nvidia-utils содержит в себе конфиги для modprobe (/usr/lib/modprobe.d/nvidia-utils-beta.conf), который блеклистит nouveau. Имейте ввиду.

Второе, как было сказано выше, bumblebee блеклистит походим образом как nouveau, так и официальные драйвера. Внесение в чёрный список защищает от автоматической загрузки, а принудительно загрузить всё так же можно. Чем bumblebee и пользуется для организации offloading.

Далее, данные о блеклистинге попадают в том числе в initramfs, поэтому, вцелом, на гибридной графике можно не отказываться от kms - нуво всё равно не загрузится при наличии проприетарных драйверов, только если вы сами этого явно не скажите.

Ссылки

Mar 10, 2023 - 2 minute read - Linux Thinkpad

Thinkpad P15gen2: клавиатура, Menu, SysReq, Launch2

Для начала, методики (но не конечные решения!) описанные в прошлых связанных статьях для Thinkpad T530 вполне себе работают, поэтому стоит начать с ознакомления с ними:

Официальные Fn+ комбинации

Комбинации для T530 работают и ровно в такой же механике. Вообще вот руководство, так сказать первоисточники, где это всё описано:

Для начала небольшие пояснения для следующих кнопок:

Комбинация Название Код
Fn+F9 Открытие/свёртывание центра уведомлений XF86Messager
Fn+F10 Принятие входящих вызовов в Microsoft Teams XF86Go
Fn+F11 Отклонение входящих вызовов в Microsoft Teams Cancel
Fn+F12 Настраиваемая XF86Favorites

Все кнопки отлично распознаются и можно куда-то назначить.

А вот теперь более интересные:

Комбинация Название Код Примечание
Fn+PrtSc Открытие инструмента «Ножницы» Launch2 Т.е. на самом деле - обычная кнопка общего назначения
Fn+4 Спящий режим XF86Sleep В дополнение к основной
Fn+Left Переход к началу Home Это просто подарок для навигации какой-то
Fn+Right Переход в конец End См выше

Для работы с SysReq - смотрите прошлую заметку для T530.

Управление громкостью, отключением микрофона, динамиков, управление яркостью дисплея, отключения WiFi, уход в сон и пробуждение (однократное нажатие Fn) - как минимум в KDE Plasma заработало из коробки в том числе с сопутствующими OSD.

Делаем Menu из Fn+PrtSc aka Launch2

По аналогии как тут:

Что хорошо, за весь срок существования заметок и 10 лет существования ноутбука, даже номера event не поменялись: для встроенной клавиатуры остался 3, для Fn+ - 5.

На P15gen2 я решил не переносить PrtSc, так как отдельной кнопки Launch1 больше нет, но так как на этой же кливише появилась альтернативная функция, то решил из неё как раз сделать Menu. Все действия уже описаны, результирующий /etc/udev/hwdb.d/70-keyboard.hwdb получился такой:

# thinkpad_acpi driver  
evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*  
  KEYBOARD_KEY_46=compose                                  # Override Launch2 (prog2) to Menu (Compose): on the TP P15gen2 - Fn+PrtScr

Прочие Fn клавиши тоже можно переназначить по желанию. Главное его заиметь или придумать, куда приспособить. Я пока не придумал.

Jan 9, 2023 - 9 minute read - Туризм

Траверс Суходол-Туманная 2023

Снега в декабре в городе навалило так, что до сих пор аукается на дорогах Владивостока, поэтому возникло жгучее желание сходить потропить наши хребты в снегоступах. Кинул клич, в ответку от Коли Живова получил контр-приглашение на снегоступинг 7-8 января, но 8 были уже запланированы мероприятия, которые ну никак не получалось перенести. В результате согласились идти 4-5 января Саня, Юра и Макс. Но 3 числа Саня отвалился - внезапно заболел. Остался я, Макс и Юрка. Так и пошли.

Перечитывая С юга на север по Ливадийскому хребту при планировании маршрута разогнался на 40 км за два дня, маршрут:

74км-г.Суходол-хр.Большой Воробей-г.Туманная-р.Тигровая-(выход рядом)Бровничи-Фридман

Резервными вариантами рассматривал выход:

  1. в Тигровой
  2. по классике на 82км

Результат вышел куда более скромным, но не менее греющим душу:

74км-г.Суходол-хр.Большой Воробей-г.Туманная-серпантин-82км

map

Dec 10, 2022 - 1 minute read - programming

C++ прекрасен, как всегда

Жжот дурилко. Все помним про вызов функции vs конструирование объекта:

struct foo { foo(int) {} };
int main() {
    foo(3); // временный объект
}

vs

void foo(int){}
int main() {
    foo(3); // вызов функции
}

Теперь такое:

struct foo {
    foo() = default;
    foo(int v) : x(v) {}
    int x = 1;
    static int s;
};
int foo::s; // где храним
int main() {
    foo(s);
}

Dec 4, 2022 - 7 minute read - electronic

LGT8Fx / LGT8F328P

На правах заметки.

Intro

В народе этот чип называют “клоном” Atmega328P или “антикризисным Arduino” (ну не сам чип, а те платки, которые доступны на AliExpress).

Клоном оно не является. Это самобытная разработка, которая в некотором отношение по пинам (в некоторых режимах) совместима ATmega328P. При этом, если, к примеру, плату с Али зашить обычным примером я миганием светодиода, собранным для BSP Arduino Nano, то диод будет мигать неадекватно. Т.е. для этого контроллера нужно свой пакет BSP, как, к примеру, для совсем “левых” контроллеров, типа ESP32.

Т.е. из схожего:

  • система комманд и ассемблер, тулчейн
  • корпус и совместимость пинов, при этом, LGT8F328 может заменить 328 мегу, то обратная замена не всегда возможна (далее).

Основные особенности LGT8F328P:

  1. Питание от 1.8-5.5В для всех частот
  2. Максимальная частота на внутренней RC цепочке и внешнем кварце до 32Mhz
  3. Нет фьюзов, как следствие, все настройки периферии нужно делать в стартовом коде, аналогично “взрослым” контроллерам. Отсюда и необходимость в отдельном “ядре” (BSP - Board Support Package из “взрослой” терминологии) для Arduino IDE.
  4. Особенности BSP для Arduino IDE, что прошивается только на 57кбод.
  5. Дополнительный третий 16 битный таймер. И все таймеры существенно проапргейжены в плане максимальных частот PWM и числа ног с PWM.
  6. Появился ЦАП
  7. АЦП тут уже 12 битный, а не 10 битный. Хотя, по отзывам, реальная точность осталась в районе 10 бит
  8. Нет EEPROM. Но он может программно эмулироваться на внутреннем флеше. Т.е. - больше EEPROM - меньше на код.

Хорошее ревью с примерами кода: Обзор клона меги328 -LGT8F328P

В общем, контроллер новый, самобытный. Для домашнего использования очень интересен, но для промышленного использования я бы поостерёгся использовать.

Для домашнего использования хорош и тем, что можно купить на Али версю платы Нано за ~115 рублей с бесплатной доставкой против 250 рублей за аналогичный Nano v3. Плюс платы с односторонним расположением элементов, что позволяет монтировать на плату в виде модуля.

Поддержка в Arduino IDE

Теперь про интеграцию в Arduino IDE. Как я писал выше - нужен свой BSP. Как минимум настройки для PLL и EEPROM при старте.

Я нашёл более-менее работающих два:

  1. https://github.com/dbuezas/LGT8fx
  2. https://github.com/nulllaborg/arduino_nulllab (альтернативный репозиторий: https://gitee.com/nulllab/nulllab_arduino)

Рекомендую ознакомиться так же со ссылками на страницах обоих BSP. Можно найти полезного.

LGT8fx

Рекомендую именно его на момент 2023.06.25 (актуальная версия: 2.0.6), до этого рекомендовал Nulllab

Ставим через Board Manager в Arduino IDE. В File → Preference, Settings tab добавляем:

https://raw.githubusercontent.com/dbuezas/lgt8fx/master/package_lgt8fx_index.json

На момент первоначального составления заметки была актуальна версия 1.0.5 (оригинальный BSP LGT8fx выглядел заброшенным.) и была доступна неофициальная 1.0.6 (ака v1.0.7 pre release), которая:

  1. Работает с платами с внешним 16Mhz кварцем
  2. Реализуют классический Arduino интерфейс для работы с EEPROM.

Естественно ставить её нужно было вручную. Сейчас же (2023.06.23) актуальная версия - 2.0.6, уже содержит вышеупомянутые доработки.

Для установки в Board Manager вводим:

gt8fx

И ставим “LGT8fx Boards”

В Tools → Board → LGT8fx Board выбираем единственную (2023.06.25) борду: LGT8F328. Собственно на ней и собраны популярные “клоны” Ardunio Nano и Arduino Pro Mini.

После этого выбираем в Tools → Variants выбираем:

  • 328P-LQFP32 - для большинства клонов в форм-факторе Arduino Pro Mini и Arduino Nano Ну или посчитайте ножки :)

Из настроек полезные, по сути, только частота работы и что используется: внутренний клок или внешний кварц.

Внешний кварц понятен, есть три варианта (Tools → Clock Source):

  • External 12Mhz
  • External 16Mhz
  • External 32Mhz

Внутренний клок всегда один (там же, Tools → Clock Source):

  • Internal 32Mhz

А вот нужную частоту работы уже догоняем делителями (Tools → Clock Divider): 1, 2, 4, 8, 16, 32

Я не разбирался, работают ли делители, при выборе внешнего кварца, но для внутреннего клока они точно работают.

Следующие настройки, скорее всего, никогда не придётся менять:

  • Upload Speed: 57600, при другой у меня ничего не прошивалось, но зависит от прошитого FSBL (aka просто загрузчик, позволяющий обновляться по UART).
  • SERIAL_RX_BUFFER_SIZE: 64, скорее всего сделано как какой-то WA. Не вникал.

Настроек для размера EEPROM нет, он есть всегда и его размер - 1 кБ. Если нужна гибкость в настройке - используйте Nulllab BSP,

Ну и стоит отдельно упомянуть, что этот BSP - это развитие “официального” оного: https://github.com/LGTMCU/Larduino_HSP. Можете и его попробовать. В некоторых источниках есть и на него ссылка.

Nulllab

В целом можно и его рекомендовать: широкий набор источников клока, делителей (косвенно, через указание конкретной частоты) и возможность настройки EEPROM. Но LGT8fx Boards очень оживился, а этот как был версией 1.0.3 на момент составления заметки (2022.12.04), так и остался на момент правки (2023.06.25).

Ставим через Board Manager в Arduino IDE. В File → Preference, Settings tab добавляем:

https://raw.githubusercontent.com/nulllaborg/arduino_nulllab/master/package_nulllab_boards_index.json

Nullab в Board Manager ищется по словам… nulllab :-) При выборе борды нужно выбрать:

  • Tools → Board → Nulllab AVR Compatible Board → DIY Board

При этом станет доступен полный “тюниг” для всех борд:

  • Tools → CPU Frequency: 16 Mhz
  • Tools → Clock Source: External (16 Mhz)
  • Tools → EEPROM size: от 0 до 8кБ с шагом x2
  • Tools → Upload Speed: 57600 - это важно, иначе не будет шиться (см выше)

Как и LGT8fx Boards - это развитие “официального” BSP: https://github.com/LGTMCU/Larduino_HSP.

Покупка

Естественно - Aliexpress. Я брал:

Полезные ссылки, обсуждения и документация

Табличка, где сравнивается скорость выполнения  в тактах некоторых ассемблерных команд в обычном AVR и в LGT8 (по данным по ссылке 1):

Instruction Function                    Cycle of AVR    Cycle of LGT8XM

ADIW        Add immediate to word       2               1
SBIW        Subtract immediate to word  2               1
MUL/S/SU    8bit multiply               2               1
FMUL/S/SU   Fractional multiply         2               1
RJMP/RCALL  Relative jump/call          2/3             1
IJMP/ICALL  Indirect jump/call          2/3             2
RET/IRET    Return                      4               2
CPSE        Compare, skip if equal      1/2/3           1/2
SBIS/SBRS   Skip if set                 1/2/3           1/2
SBIC/SBRC   Skip if cleared             1/2/3           1/2
LD/LDD      Load indirect               2               1
ST/STD      Store indirect              2               1
LPM         Load program memory         3               2
PUSH/POP    Stack access                2               1

Другие MCU от LGT в платах Arduino и их сравнения:

Nov 27, 2022 - 15 minute read - Programming Thinkpad

T530: восстанавливаем батарейку на контроллере R2J240_51F51

Вместо вводного слова: начала писать аж 16 сентября, а собрался закончить только 27 ноября (я появилось только 28)…

Короткое интро: на данный ноут больше не выпускают оригинальных батареек и купить, соответственно, их не возможно. А можно купить что-то на Aliexpress или (дороже и, скорее всего, хуже) на локальных площадках.

Но покупка на Ali тоже лотереей: первая батарея нормально себя вела, но кончилась очень быстро. Вторая, пришедшая, буквально недели три назад, прекрасно разряжалась, но отказалась заряжаться в моём нотбуке. Спор не заводил, китаец предложил выслать ещё одну батарейку, правда на 6 ячеек. К слову, прошивка, которая убеждает EC принимать любую батарейку, а не те, что в белом списке, тоже не помогла.

Текущая батарейка, заказанная под видом оригинальной (вот яж лох), ещё дышала (но отрубалась резко на заряде от 10% до 30%), поэтому решил попытаться что-то с ней сделать: у меня были контроллеры от старых, но рабочих батарей.

Кому интересно - под кат.

Nov 8, 2022 - 1 minute read - Electronic

PCB: Castellated Holes

Они же:

В общем речь о переходных отверстиях по краю платы, которые “разрезаны” пополам и используются для краевого монтажа собранного модуля на другую плату…

Aug 11, 2022 - 1 minute read - Programming

Qt Creator: фикс креша при создании Generic Project

Yet another contribution. В общем :)

Зашёл очередной фикс. Поломашка в master, и скорее всего никого пока не задела. Кроме отмороженных, кто сидит на ночных сборках или собирает сам:

Больше фиксов хороших и разных!

UPD: и практически следом:

May 26, 2022 - 1 minute read - Linux

Konsole: исправлен баг с выделением окна в трее при возникновении bell

Наконец-то починили. Джва года ждал:

В Konsole есть такая возможность: при возникновении сигнала в терминале, который генерируется, например, так:

echo -e '\a'

или так:

tput bel

сделать какие-то действия.

Настраивается: Меню (если выключено: Ctrl+Shift+M) → Настройка → Настроить уведомления…

Нас интересуют:

  • Сигнал в активном сеансе
  • Сигнал в неактивном сеансе

Что бы выделить терминал в панели задач, нужно включить пункт “Выделить программу в панели задач” и нажать Применить или Ок.

Собственно, что это даёт: когда сигнал возникнет, то Konsole выделит, подсветит кнопку приложения в панели задач, примерно так:

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

Плюсом, что сигнал может быть и на удалённом сервере, при подключении через SSH: терминал обрабатывает событие локально.

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

Запуск примерно так:

make -j8 ; tput bel

Не стоит ставить &&, или ||: мы же хотим среагировать при любом коде возврата make? Но если нужно именно для успешного или наоборот неуспешного завершения сигнализировать, то карты вам в руки.

May 23, 2022 - 8 minute read - Linux Life Thinkpad

Переустановка системы на ноутбуке или переезд - хуже пожара

На днях поборол жабу, и позволил себе купить на замену стокового системного HDD HGST Travelstart Z7K500 / 500Гб, новый SSD Samsung SSD 870 EVO.

Первое впечатление - систему стероидами накачали. А дальше - увлекательная процедура миграции нужного и не очень в новое окружение.

May 23, 2022 - 2 minute read - Туризм Linux Maps

Автоматическое резервное копирование при подключении навигатора Garmin GPSMAP 64s

После неудачного удаления всех точек и треков с навигатора, решил, что автоматический бекап это наше всё.

Сделал средствами Systemd.

Для начала определяемся с местом для бекапа, пусть это будет ~/Documents/GPX и создаём там скрипт ~/Documents/GPX/sync.sh. А внутре… у ней неонка:

#!/bin/sh  
  
#  
# Ref:  
#  https://askubuntu.com/questions/25071/how-to-run-a-script-when-a-specific-flash-drive-is-mounted  
#  
# `systemctl list-units -t mount`  
#  
# "~/.local/share/systemd/user/garmin-backup.service"  
#  
#  
# ```  
# [Unit]  
# Description=Backup GARMIN GPSMAP 64s GPX data  
# # Use output from the: `systemctl list-units -t mount`  
# Requires=run-media-hatred-GARMIN.mount  
# After=run-media-hatred-GARMIN.mount  
#    
# [Service]  
# ExecStart=/home/hatred/Documents/GPX/sync.sh  
#    
# [Install]  
# WantedBy=run-media-hatred-GARMIN.mount  
# ```  
#  
# `systemctl --user start garmin-backup`  
# `systemctl --user enable garmin-backup`  
#  
# Monitor:  
#  
# ```sh  
# journalctl --user --unit garmin-backup -f  
# ```  
#  
  
prefix="/run/media/hatred/GARMIN/Garmin/GPX"  
  
dir=$(dirname $0)  
cd "$dir"  
  
echo "Work dir: " $(pwd)  
  
sleep 2  
  
stat "$prefix" 2> /dev/null && \  
   rsync -rubv --suffix=.old  "$prefix" . && \  
   touch sync_last.txt && \  
   notify-send -u normal -a "Garmin Sync" "Garmin GPSMAP 64s" "Backup done"

Да, я не разбирался с переменными для имени пользователя, поэтому указывал полные пути с учётом своего рабочего аккаунта: hatred. Т.е. нужно будет скорректировать под себя.

Следующий шаг: сам юнит. ~/.local/share/systemd/user/garmin-backup.service:

# Ref:  
#  https://askubuntu.com/questions/25071/how-to-run-a-script-when-a-specific-flash-drive-is-mounted  
#  
# systemctl list-units -t mount  
# systemctl --user start garmin-backup.service  
# systemctl --user enable garmin-backup.service  
#  
# journalctl --user --unit garmin-backup -f  
#  
[Unit]  
Description=Backup GARMIN GPSMAP 64s GPX data  
Requires=run-media-hatred-GARMIN.mount  
After=run-media-hatred-GARMIN.mount  
  
[Service]  
ExecStart=/home/hatred/Documents/GPX/sync.sh  
  
[Install]  
WantedBy=run-media-hatred-GARMIN.mount

Тут главное, это запуститься, когда увидим, что нужно устройство примонтировалось. У меня, когда монтируется GARMIN, он использует метку GARMIN для своего внутреннего хранилища (куда и пишутся GPX файлы). Путь для монтирования выходит /run/media/$USER/GARMIN.

Systemd создаёт временный сервис, на который можно сослаться. Если просто, то возьмите путь монтирования, у меня это /run/media/hatred/GARMIN, замените все / на - (кроме первого) и добавьте в конце .mount: run-media-hatred-GARMIN.mount. Ну или смотрим вывод:

systemctl list-units -t mount

после монтирования раздела GARMIN.

А за подробностями по ссылке:

После этого включаем сервис:

systemctl --user enable garmin-backup.service
systemctl --user start garmin-backup.service

Последить за работой:

journalctl --user --unit garmin-backup -f

Feb 12, 2022 - 5 minute read - Linux

ThinkPad T530: зависание при выходе из сна на ядрах 5.10+ (опять)

“Никогда такого не было и вот опять” (с). В этот раз зависание имеет место быть, если воткнуто какое-то USB устройство.

Я уже толком не вспомню ход разбирательства, но меня смущал тот факт, что на 5.10 этой проблемы изначально не было и нет на более ранних LTS ядрах, которые имеют место быть в Manjaro (вот тот самый случай, когда несколько ядер это лютый вин).

Первая мысль: помирает железо. Тем более, что в какой-то момент стало невозможно работать с мышкой Logitech MX Master, подключенный по BT. BT на ThinkPad T530 подключен по USB. Невозможность заключалась в том, что она постоянно отваливалась и подключалась опять. Лаги очень раздражали.

Потом что-то меня навело на мысль, посмотреть на параметры модулей-драйверов USB:

  • xhci_hcd - USB 3.0 (или по модному: USB 3.2 Gen1)
  • ehci-pci - USB 2.0

Больше интересовало второе, так как все проблемные подключенцы были на USB 2.0. Выхлоп примерно такой:

$ modinfo ehci-pci  
name:           ehci_pci  
filename:       (builtin)  
license:        GPL  
file:           drivers/usb/host/ehci-pci  
author:         Alan Stern  
author:         David Brownell  
description:    EHCI PCI platform driver

И тут меня заинтересовала эта строчка:

filename:       (builtin)

Это означает, что модуль встроен в ядро. К слову, даже если он встроен, его параметры и интерфейс доступны через /sys/module/.

Решил глянуть, как обстоят дела на 5.4, а там модуль собран отдельно:

$ find /lib/modules/5.4.176-1-MANJARO/ -name '*ehci*.ko*'   
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-pci.ko.xz  
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-hcd.ko.xz  
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-fsl.ko.xz  
/lib/modules/5.4.176-1-MANJARO/kernel/drivers/usb/host/ehci-platform.ko.xz

Что это означает? Всё, что встроено в ядро может инициализировать на самых ранних стадиях старта системы, ещё на этапе работы с RAM-диском (initrd) и даже вообще до подключения корневой файловой системы. А модули уже подгружаются или с initrd образа или уже с основной файловой системы, тут как настроено.

Я уже сталкивался с ситуацией по работе, когда подобное различие влияло на работу системы. Получалось, что модуль, ответственный за работу одной железки стартовал достаточно рано, когда блок, генерирующий тактовый сигнал (“клок”) не неё ещё не был проинициализирован и завершал свою инициализацию с ошибкой. Типичное состояние гонки. Да, на этот случай предусмотрен специальный код возврата EPROBE_DEFER и он не был использован в этот раз чисто по ошибке. Но дело в том, что когда драйвер был собран модулем, то он успешно грузился на более поздних стадиях загрузки системы и клок был проинициализирован и устройство запускалось нормально.

Собственно, на этом месте, у меня, похоже, и зародилась мысль: слишком ранняя инициализация, возможно что-то не стабилизировалось и нужно попытаться как-то переинициализировать железку после старта.

Самый просто способ: вынести драйвера в виде модулей. Но пересобирать ядро не хотелось. Поэтому включил логику: почти все драйвера предлагают функционал bind/unbind. Устройства на PCI шине (по крайней мере на PCIe) могут быть пересканированы (т.е. чисто теоретически PCIe - Hot Plug, но лучше не проверяйте :)). А что станет, если после загрузки, отключить железку от драйвера и потом подключить опять? Почти всё железо содержит функционал Reset настроек в исходное состояяние, что будет если сбросить и сконфигурировать всё, когда система уже готова?

Сказано - сделано. И вы не поверите: после загрузки отключил USB контроллеры, подключил обратно и попытался сделать suspend. И сработало! Ядро 5.15 - resume заработал.

К слову, на 5.16 сломано более сильно. И WA ниже не помогает. Сижу на 5.15.

Более того, вылечился BT и мышка перестала отваливаться при работе (при работе через Logitech Unify Receiver она и так работала хорошо, но теперь и по BT стала - плюс один порт свободен).

Код под катом.

Feb 12, 2022 - 3 minute read - Programming

Qt Creator: подтасовка триплета архитектуры для кодовой модели

Что текущий основной парсер, что грядущий (или нагрянувший, как посмотреть) парсер на clangd работают поверх libclang и сотоварищи и умеют разбирать то, что умеет собирать clang.

Внезапно, он умеет не всё. И это не всё, к примеру, отлично умеет GCC. Вот то, с чем я столкнулся сам:

Под катом будет хак, который я использовал, что бы запуститься и работать с этим добром. UPD: хак больше не работает, так как этот код вообще удалён из репозитория QtC ветки master на момент 23.05.2022.

Но сейчас не об этом. Просматривая изменения в апстриме, наткнулся на этот коммит:

И визуально это выглядит так:

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

# Hack QtC Clang:  
# https://bugreports.qt.io/browse/QTCREATORBUG-22329  
export QTC_CLANG_CMD_OPTIONS_BLACKLIST="-mxl-soft-mul;-mlongcalls;-fstrict-volatile-bitfields"

Данная функциональность, судя по этому списку изменений будет доступна в Qt Creator 7.0, т.е. совсем скоро:

Ну а ниже, как обещал - костыль. Требует пересборки Qt Creator из исходников.