Перейти к основному содержимому

Настройка и тестирование CAN интерфейса в Linux

· 1 мин. чтения
dmn
maintainer

Настройка CAN интерфейса​

Поднимаем и проверяем CAN интерфейс.

Интересно, что CAN в Linux это сетевой интерфейс. На него нельзя повесить IP, но Linux управлять можно через ip link.

ip link set can0 down
ip link set can0 type can bitrate 500000 restart-ms 100
ip link set can0 up

Проверка loopback​

Проверяем loop (Аналог ping localhost).

Ставим пакет:

apt install can-utils

Тестирование​

В одной сессии слушаем can0:

root@napi2:~# candump -L can0

В другой на этот же интерфейс шлем посылку:

cansend can0 123#11223344

Должны получить ответ в сессии, где слушали:

(1769774861.028890) can0 123#11223344

#can #napi2

Управление светодиодами Ethernet через MDIO

· 1 мин. чтения
dmn
maintainer

Утилита для управления mdio (в частности, подсветкой лампочек Ethernet): https://github.com/wkz/phytool

Классический вид​

Левый (зелёный) - линк, правый (рыжий) - данные:

  1. Выбрать страницу LED конфигурации:
./phytool write wan/0/0x1f 0x0d04
  1. (Опционально) отключить EEE LED влияние:
./phytool write wan/0/0x11 0x0000
  1. Установить: LED1=Link(any speed), LED2=Activity:
./phytool write wan/0/0x10 0xC160
  1. Вернуть страницу 0:
./phytool write wan/0/0x1f 0x0000

Альтернативный вид​

Слева (зелёный) Link+Act (подмешивает в один диод и линк и моргание данными) 10mbit, справа (рыжий) - Link + Act 100+Mbit:

  1. Выбрать страницу LED конфигурации:
./phytool write wan/0/0x1f 0x0d04
  1. (Опционально) отключить EEE LED влияние:
./phytool write wan/0/0x11 0x0000
  1. Установить: LED1=Link+Act 10mbit, LED2=Link+Act 100+Mbit:
./phytool write wan/0/0x10 0x6251
  1. Вернуть страницу 0:
./phytool write wan/0/0x1f 0x0000

Получение уникального ID процессора Rockchip

· 1 мин. чтения
dmn
maintainer

Получение уникального ID процессора​

Встал вопрос, как получить уникальный ID процессора для идентификации конкретного экземпляра Napi-C/Napi-P/Napi-S.

Способ через OTP​

Мы нашли такой способ:

ID=$(dd if=/sys/bus/nvmem/devices/rockchip-otp0/nvmem bs=1 skip=8 count=8 2>/dev/null | xxd -p)
echo -n "$ID" | sha256sum

Описание команд​

  • dd - читает 8 байт из OTP памяти процессора Rockchip начиная с 8-го байта
  • xxd -p - конвертирует двоичные данные в hex строку
  • sha256sum - создает SHA256 хеш для обеспечения уникальности

Анализ сигналов Modbus RS485 на анализаторе

· 1 мин. чтения
dmn
maintainer

Анализ сигналов Modbus RS485​

Покажем передачу modbus пакетов, отображенную на анализаторе цифровых сигналов.

Оборудование​

  • Хост: Napi-C с программным RTS
  • Датчик: учебный Modbus Napi-датчик

Конфигурация каналов​

  • Канал 1: RTS хоста
  • Канал 2: RX хоста
  • Канал 3: TX хоста
  • Канал 4: RX датчика
  • Канал 5: TX датчика

Последовательность обмена​

  1. Хост поднимает сигнал RTS (передача)
  2. Посылает запрос по линии TX
  3. Датчик принимает запрос через RX
  4. Датчик передает ответ через TX
  5. Хост принимает ответ через RX

#rs485 #rts

Настройка параметров последовательного порта в Linux

· 1 мин. чтения
dmn
maintainer

Настройка последовательного порта​

Установка параметров последовательного порта в Linux на примере ttyS1

Просмотр текущих параметров​

stty -F /dev/ttyS1 -a

Пример вывода:

speed 115200 baud; line = 0;
-brkint -icrnl -imaxbel
opost -onlcr
cs8 -parenb -cstopb

Расшифровка параметров​

  • speed 115200 baud — текущая скорость
  • cs8 — 8 бит данных
  • -parenb — без бита четности (N)
  • -cstopb — 1 стоп-бит (если было cstopb → 2 стоп-бита)

Установка параметров порта​

stty -F /dev/ttyS1 115200 cs8 -cstopb -parenb -ixon -ixoff -crtscts

Тестирование порта​

Дальше можно прямо из командной строки:

echo "test" > /dev/ttyS1

Диагностика занятости GPIO пинов в Linux

· 4 мин. чтения
dmn
maintainer

Диагностика занятости GPIO​

В Linux можно посмотреть чем заняты все GPIO:

cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins

Пример вывода на NAPI-C​

root@rockpi-s:~# cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins
Pinmux settings per pin
Format: pin (name): mux_owner gpio_owner hog?
pin 0 (gpio0-0): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 1 (gpio0-1): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 2 (gpio0-2): sdio-pwrseq gpio0:2 function sdio-pwrseq group wifi-enable-h
pin 3 (gpio0-3): ff480000.mmc (GPIO UNCLAIMED) function sdmmc group sdmmc-det
pin 4 (gpio0-4): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 5 (gpio0-5): leds gpio0:5 function leds group heartbeat-led
pin 6 (gpio0-6): leds gpio0:6 function leds group green-led
pin 7 (gpio0-7): stmmac-0:01 gpio0:7 function gmac group mac-rst
pin 8 (gpio0-8): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 9 (gpio0-9): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 10 (gpio0-10): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 11 (gpio0-11): ff050000.i2c (GPIO UNCLAIMED) function i2c1 group i2c1-xfer
pin 12 (gpio0-12): ff050000.i2c (GPIO UNCLAIMED) function i2c1 group i2c1-xfer
pin 13 (gpio0-13): ff180000.pwm (GPIO UNCLAIMED) function pwm0 group pwm0-pin-pull-down
pin 14 (gpio0-14): (MUX UNCLAIMED) (GPIO UNCLAIMED)
pin 15 (gpio0-15): (MUX UNCLAIMED) (GPIO UNCLAIMED)

Пример занятого GPIO​

Например, GPIO0-A5 занят и мы не можем его использовать, например как DE для UART без лишних "процедур" по его освобождению:

root@rockpi-s:~/S4-GPIO2_A5# cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep gpio0-5
pin 5 (gpio0-5): leds gpio0:5 function leds group heartbeat-led
root@rockpi-s:~/S4-GPIO2_A5#

Пример свободного GPIO​

А вот GPIO2-B4 выглядит как свободный:

root@rockpi-s:~/S4-GPIO2_A5# cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep gpio2-12
pin 76 (gpio2-12): (MUX UNCLAIMED) (GPIO UNCLAIMED)

И мы можем его программно "дергать":

root@rockpi-s:~/S4-GPIO2_A5# gpioset gpiochip2 12=1
root@rockpi-s:~/S4-GPIO2_A5# gpioset gpiochip2 12=0
root@rockpi-s:~/S4-GPIO2_A5#

Использование GPIO в DTS​

А теперь "захватим" пин GPIO2_A5 для DE в UART1 таким DTS:

/dts-v1/;
/plugin/;

/ {
compatible = "rockchip,rk3308";

fragment@0 {
target = <&uart1>;
__overlay__ {
status = "okay";

pinctrl-names = "default";
pinctrl-0 = <&uart1_xfer>;

linux,rs485-enabled-at-boot-time;
rs485-rts-active-high;
rs485-rts-delay = <0 0>;
rts-gpios = <&gpio2 5 0>;
};
};
};

Проверка захвата GPIO​

Посмотрим как выглядит пин:

root@rockpi-s:~/S4-GPIO2_A5# cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep gpio2-5
pin 69 (gpio2-5): (MUX UNCLAIMED) gpio2:69
root@rockpi-s:~/S4-GPIO2_A5#

Тут не слишком понятно захватился он драйвером RS485 или нет. Но что важно, Linux не даст больше им "мигать", если он занят драйвером ядра:

root@rockpi-s:~/S4-GPIO2_A5# gpioset gpiochip2 5=0
gpioset: error setting the GPIO line values: Device or resource busy
root@rockpi-s:~/S4-GPIO2_A5# gpioset gpiochip2 5=1
gpioset: error setting the GPIO line values: Device or resource busy
root@rockpi-s:~/S4-GPIO2_A5#

Тестирование UART1​

Осталось убедиться, что мы получаем данные через UART1:

root@rockpi-s:~/S4-GPIO2_A5# mbpoll -m rtu -P none -b 115200 -a 125 -r 1 -c 4 -t4 /dev/ttyS1
mbpoll 1.0-0 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [125]
start reference = 1, count = 4
Communication.........: /dev/ttyS1, 115200-8N1
t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 125... Ctrl-C to stop)
[1]: 125
[2]: 1
[3]: 851
[4]: 772

Overlay для RS485 на UART1 с GPIO управлением направления

· 1 мин. чтения
dmn
maintainer

Оверлей для RS485 на UART1​

Оверлей для RS485 на UART1 (Napi-C) c контролем направления через GPIO (DE=GPIO2_B4)

Конфигурация DTS​

root@rockpi-s:~/S3# cat uart1-de.dts
/dts-v1/;
/plugin/;

/ {
compatible = "rockchip,rk3308";

fragment@0 {
target = <&uart1>;
__overlay__ {
status = "okay";

pinctrl-names = "default";
pinctrl-0 = <&uart1_xfer>;

linux,rs485-enabled-at-boot-time;
rs485-rts-active-high;
rs485-rts-delay = <0 0>;
rts-gpios = <&gpio2 12 0>;
};
};
};

#rs485 #napic

Получение текущего DTS из загруженной системы

· 1 мин. чтения
dmn
maintainer

Получить текущий dts из dtb, с которой загрузилась система:

dtc -I fs -O dts /sys/firmware/devicetree/base > /tmp/running.dts

Это ключевой файл, отображающий как система "понимает" всю перефирию и интерфейсы.

Внимательно изучайте файл running.dts через текстовый редактор - он ключ к пониманию как система интерпретирует интерфейсы.

И, кстати, этот dts можно "скормить" в ChatGPT и задавать вопросы или сформировать просьбу сделать overlay.

#kernel #dts

Программное включение аппаратного reset в eMMC

· 1 мин. чтения
dmn
maintainer

Продолжаем исследовать удивительный мир EMMC/SD​

Столкнулись с удивительной ситуацией на Napi Slot - при нажатии кнопки MaskRom. Эта кнопка переводит процессор в режим прошивки (на самом деле кнопка подтягивает MMC_RESET к GND и отключает EMMC, чтобы процессор не нашел с чего грузить систему и вошёл в режим прошивки).

Проблема​

Так вот процессор никак не реагировал!

Выяснилось, что в некоторых EMMC аппаратный reset включается ПРОГРАММНО!

Рецепт команд Linux​

Считать текущий статус​

sudo mmc extcsd read /dev/mmcblk0 | grep -i RST_N_FUNCTION

Включить аппаратный reset у eMMC​

Операция необратимая:

sudo mmc hwreset enable /dev/mmcblk0

Проверить результат​

sudo mmc extcsd read /dev/mmcblk0 | grep -i RST_N_FUNCTION

Должно поменяться на RST_N_FUNCTION: 0x01

#emmc #hard #napi

Компиляция ядра NapiLinux - быстрый метод

· 2 мин. чтения
dmn
maintainer

Как скомпилировать только ядро NapiLinux​

Это "грязный" быстрый метод, который позволяет не компилировать всю систему, а быстро включить какие-то опции ядра и проверить новое ядро в системе.

Правильный способ компиляции NapiLinux — через пакет Yocto.

1. Сделать клон ядра с нужной ветки (branch)​

Бранч — это версия репозитория ядра. Для разных платформ она разная, и нужно выбрать ту, которая вас интересует:

  • rk-6.1
  • orange-pi-6.6
  • rk35xx

и т. п. (выбирайте на сайте GitLab)

git clone https://gitlab.nnz-ipc.net/pub/napilinux/kernel.git --branch=rk-6.1 --depth=1
cd kernel/

2. Настроить переменные для архитектуры (ARM64)​

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

3. Подготовить конфиг​

  • Конфиги лежат в папке /arch/arm64/configs
  • В каждой ветке нужно выбрать свой конфиг:

Для Napi:

make napi_defconfig

Для CM4:

make opi_cm4_defconfig

4. Настройка конфигурации​

После этого появится файл .config, в котором вы можете изменить опции ядра под себя.

5. Запускаем компиляцию ядра​

make -j10

6. Результаты сборки​

  • Имидж ядра — arch/arm64/boot/Image
  • Главная DTB (дерево устройств) — arch/arm64/boot/<файл>.dtb
  • Оверлеи — arch/arm64/boot/dts/rockchip/

7. Замена ядра в системе​

Теперь можно заменить файлы Image и .dtb в /boot, затем перезагрузить систему.

8. Важно про overlay root!​

NapiLinux использует root (/) как виртуальную партицию overlay, поэтому просто переписать ядро и другие файлы из системы не получится (на деле вы запишете их в overlay, и u-boot их не увидит).

Что делать?​

  • Если работаете на SD-карте — выньте SD, примонтируйте обе физические партиции и запишите новые файлы в их /boot

  • Если работаете с NAND/eMMC — загрузитесь с SD, примонтируйте обе партиции и запишите туда файлы вручную

Просмотр структуры партиций​

Посмотреть структуру партиций можно командами:

lsblk
lsblk -f

#napilinux #napikernel