Blog the XELFAER

Заметки *NIX

Прошивка микроконтроллера без прав root —

Наверное каждый обладатель программаторов с USB интерфейсом сталкивался с проблемой — требование прав root для работы. Являясь обладателем PROTTOSS AVR910 USB также столкнулся с данной проблемой при прошивке через утилиту avrdude. При попытке прошить от обычного пользователя выдавалась ошибка:

avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied

Можно конечно настроить использование через sudo, логиниться под root, выдать права:

# chmod ug+s /usr/bin/avrdude

что не безопасно. Но выход есть — настроить правило для udev.

Для начала подключим программатор к ПК посмотрим что нам скажет dmesg:

$ dmesg

вот сам собственно выхлоп(выхлоп урезан):

[23391.856026] usb 2-1: new low-speed USB device number 2 using uhci_hcd
[23392.015030] usb 2-1: config 1 interface 1 altsetting 0 endpoint 0x1 is Bulk; changing to Interrupt
[23392.015036] usb 2-1: config 1 interface 1 altsetting 0 endpoint 0x81 is Bulk; changing to Interrupt
[23392.037024] usb 2-1: New USB device found, idVendor=16c0, idProduct=05e1
[23392.037029] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[23392.037032] usb 2-1: Product: AVR910 USB Programmer
[23392.037035] usb 2-1: Manufacturer: PROTTOSS
[23392.066263] cdc_acm 2-1:1.0: ttyACM0: USB ACM device
[23392.073121] usbcore: registered new interface driver cdc_acm
[23392.073124] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[25630.229817] udevd[15627]: starting version 175

Устройство подключено и доступно на порту /dev/ttyACM0.
Далее логинемся в консоли от root и запросим информацию для нашего устройства:

# udevadm info -a -p $(udevadm info -q path -n /dev/ttyACM0)

соответственно изменив порт на котором висит устройство на свое.

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0/tty/ttyACM0':
    KERNEL=="ttyACM0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1:1.0':
    KERNELS=="2-1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="cdc_acm"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{bInterfaceClass}=="02"
    ATTRS{bInterfaceSubClass}=="02"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{bmCapabilities}=="2"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1':
    KERNELS=="2-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 2"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{urbnum}=="66"
    ATTRS{idVendor}=="16c0"
    ATTRS{idProduct}=="05e1"
    ATTRS{bcdDevice}=="0200"
    ATTRS{bDeviceClass}=="02"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{speed}=="1.5"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="PROTTOSS"
    ATTRS{product}=="AVR910 USB Programmer"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2':
    KERNELS=="usb2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="27"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0001"
    ATTRS{bcdDevice}=="0302"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{version}==" 1.10"
    ATTRS{maxchild}=="2"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 3.2.0-4-amd64 uhci_hcd"
    ATTRS{product}=="UHCI Host Controller"
    ATTRS{serial}=="0000:00:1d.0"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0':
    KERNELS=="0000:00:1d.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="uhci_hcd"
    ATTRS{vendor}=="0x8086"
    ATTRS{device}=="0x27c8"
    ATTRS{subsystem_vendor}=="0x1458"
    ATTRS{subsystem_device}=="0x5004"
    ATTRS{class}=="0x0c0300"
    ATTRS{irq}=="23"
    ATTRS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000003"
    ATTRS{local_cpulist}=="0-1"
    ATTRS{numa_node}=="-1"
    ATTRS{dma_mask_bits}=="32"
    ATTRS{consistent_dma_mask_bits}=="32"
    ATTRS{enable}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Теперь можно непосредственно перейти к написанию правила udev. Создадим файл для нашего правила в каталоге /etc/udev/rules.d/ с именем 80-persistent-avr.rules:

# touch 80-persistent-avr.rules

и внесем в него следующее содержимое:

# Prottoss AVR910 USB
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05e1", GROUP="plugdev", MODE="0666"

главное изменить в данной строке данные на свои, которые можно взять в выше выведенной информации по устройству. Группу «plugdev» следует также изменить на свою (группу указываем ту в которой состоит ваш пользователь). Для вывода списка групп в которых состоит текущий пользователь необходимо ввести:

$ groups

Для применения правила необходимо перезагрузить ПК или перезапустить службу udev:

# /etc/init.d/udev restart

Переподключаем программатор и можно теперь прошивать микроконтроллер без прав root.

© 2013 — 2015, XELFAER. Все права защищены. Использование материалов блога разрешается только при указании активной ссылки на статью.

Print Friendly, PDF & Email

Рубрики: Linux | Microcontrollers | Radioelectronica | Soft


комментария 2

  1. atsybulin:

    Сделал программатор из «малины». От рута работает. Хотел добавить в правила udev, но не найду id-шники. Вот, что мне выдает запрос: «udevadm info -a -p $(udevadm info -q path -n /dev/spidev0.1)»
    looking at device ‘/devices/soc/20204000.spi/spi_master/spi0/spi0.1/spidev/spidev0.1’:
    KERNEL==»spidev0.1″
    SUBSYSTEM==»spidev»
    DRIVER==»»

    looking at parent device ‘/devices/soc/20204000.spi/spi_master/spi0/spi0.1’:
    KERNELS==»spi0.1″
    SUBSYSTEMS==»spi»
    DRIVERS==»spidev»

    looking at parent device ‘/devices/soc/20204000.spi/spi_master/spi0’:
    KERNELS==»spi0″
    SUBSYSTEMS==»spi_master»
    DRIVERS==»»

    looking at parent device ‘/devices/soc/20204000.spi’:
    KERNELS==»20204000.spi»
    SUBSYSTEMS==»platform»
    DRIVERS==»bcm2708_spi»
    ATTRS{driver_override}==»(null)»

    looking at parent device ‘/devices/soc’:
    KERNELS==»soc»
    SUBSYSTEMS==»platform»
    DRIVERS==»»
    ATTRS{driver_override}==»(null)»

    • Это не USB, а SPI — правило для udev тут не прикрутишь так. Тут скорее всего необходимо выдавать права на каждый GPIO порт, что то такого характера:

      chown -R www-data:pi /sys/devices/virtual/gpio/gpio17
      chmod -R g+w /sys/devices/virtual/gpio/gpio17

      заменяя номер порта в конце на нужный и указав владельца и группу.

Добавить комментарий