Due to development of IoT, I need a stable USB CDC ACM firmware in certain microcontroller. However I find the same device/firmware are not working well in all Linux OS.
I have tested the following boards/firmware:
STM32F103C8T6_USBSerial from mbed community
STM32F40X from mbed OS
Keil USB stack for STM32F103
STLinkV2 VCP from NUCLEO
NXP LPC54114 CMSIS-DAP VCP
STM32F103 CubeMX HAL (to be tested)
Maple STM32F103 USB driver (to be tested)
And I tried to connect these boards to:
OpenWRT
Ubuntu 12.04 desktop/server
Ubuntu 14.04 desktop/server
Ubuntu 15.04 desktop
And firmware #1 doesn't work for #1/2/3 OS, while some other hardware may work with most of the OS. I have tried different tools, including gtkterm/echo/cat/stty/minicom/usbmon, python serial and lua.io. The result is same.
It seems both firmware and OS have issues. However, in some cases, we can not change too much in OS. But how to identify the root cause and get it fixed.
Update
I pasted my tracking record here.
dmesg
[ 217.735609] usb 1-2: new full-speed USB device number 3 using ohci_hcd
[ 218.232189] usb 1-2: New USB device found, idVendor=1f00, idProduct=2012
[ 218.232195] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 218.232199] usb 1-2: Product: CDC DEVICE
[ 218.232202] usb 1-2: Manufacturer: mbed.org
[ 218.232205] usb 1-2: SerialNumber: 0123456789
[ 218.298612] cdc_acm 1-2:1.0: ttyACM0: USB ACM device
[ 218.320171] usbcore: registered new interface driver cdc_acm
[ 218.320179] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
lsusb
Bus 001 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 001 Device 003: ID 1f00:2012
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
lsbusb -v
Bus 001 Device 003: ID 1f00:2012
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1f00
idProduct 0x2012
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 75
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (modem)
bFunctionProtocol 0 None
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x03
call management
use DataInterface
bDataInterface 1
CDC ACM:
bmCapabilities 0x06
sends break
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 16
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
find /dev/bus
/dev/bus
/dev/bus/usb
/dev/bus/usb/001
/dev/bus/usb/001/003
/dev/bus/usb/001/002
/dev/bus/usb/001/001
USB devices info
ll /sys/bus/usb/devices
总用量 0
drwxr-xr-x 2 root root 0 1月 26 19:34 ./
drwxr-xr-x 4 root root 0 1月 26 19:34 ../
lrwxrwxrwx 1 root root 0 1月 26 19:34 1-0:1.0 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/1-0:1.0/
lrwxrwxrwx 1 root root 0 1月 26 19:34 1-1 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/1-1/
lrwxrwxrwx 1 root root 0 1月 26 19:34 1-1:1.0 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/1-1/1-1:1.0/
lrwxrwxrwx 1 root root 0 1月 26 19:38 1-2 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/1-2/
lrwxrwxrwx 1 root root 0 1月 26 19:41 1-2:1.0 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.0/
lrwxrwxrwx 1 root root 0 1月 26 19:41 1-2:1.1 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/1-2/1-2:1.1/
lrwxrwxrwx 1 root root 0 1月 26 19:34 usb1 -> ../../../devices/pci0000:00/0000:00:06.0/usb1/
cd /sys/bus/usb/devices/1-2
ll
ll
总用量 0
drwxr-xr-x 6 root root 0 1月 26 19:38 ./
drwxr-xr-x 7 root root 0 1月 26 19:34 ../
drwxr-xr-x 5 root root 0 1月 26 19:38 1-2:1.0/
drwxr-xr-x 5 root root 0 1月 26 19:38 1-2:1.1/
-rw-r--r-- 1 root root 4096 1月 26 19:54 authorized
-rw-r--r-- 1 root root 4096 1月 26 19:54 avoid_reset_quirk
-r--r--r-- 1 root root 4096 1月 26 19:38 bcdDevice
-rw-r--r-- 1 root root 4096 1月 26 19:54 bConfigurationValue
-r--r--r-- 1 root root 4096 1月 26 19:38 bDeviceClass
-r--r--r-- 1 root root 4096 1月 26 19:54 bDeviceProtocol
-r--r--r-- 1 root root 4096 1月 26 19:54 bDeviceSubClass
-r--r--r-- 1 root root 4096 1月 26 19:54 bmAttributes
-r--r--r-- 1 root root 4096 1月 26 19:54 bMaxPacketSize0
-r--r--r-- 1 root root 4096 1月 26 19:54 bMaxPower
-r--r--r-- 1 root root 4096 1月 26 19:54 bNumConfigurations
-r--r--r-- 1 root root 4096 1月 26 19:54 bNumInterfaces
-r--r--r-- 1 root root 4096 1月 26 19:38 busnum
-r--r--r-- 1 root root 4096 1月 26 19:54 configuration
-r--r--r-- 1 root root 65553 1月 26 19:38 descriptors
-r--r--r-- 1 root root 4096 1月 26 19:54 dev
-r--r--r-- 1 root root 4096 1月 26 19:38 devnum
-r--r--r-- 1 root root 4096 1月 26 19:54 devpath
lrwxrwxrwx 1 root root 0 1月 26 19:38 driver -> ../../../../../bus/usb/drivers/usb/
drwxr-xr-x 3 root root 0 1月 26 19:54 ep_00/
-r--r--r-- 1 root root 4096 1月 26 19:38 idProduct
-r--r--r-- 1 root root 4096 1月 26 19:38 idVendor
-r--r--r-- 1 root root 4096 1月 26 19:54 ltm_capable
-r--r--r-- 1 root root 4096 1月 26 19:38 manufacturer
-r--r--r-- 1 root root 4096 1月 26 19:54 maxchild
lrwxrwxrwx 1 root root 0 1月 26 19:54 port -> ../1-0:1.0/port2/
drwxr-xr-x 2 root root 0 1月 26 19:54 power/
-r--r--r-- 1 root root 4096 1月 26 19:38 product
-r--r--r-- 1 root root 4096 1月 26 19:54 quirks
-r--r--r-- 1 root root 4096 1月 26 19:38 removable
--w------- 1 root root 4096 1月 26 19:54 remove
-r--r--r-- 1 root root 4096 1月 26 19:38 serial
-r--r--r-- 1 root root 4096 1月 26 19:38 speed
lrwxrwxrwx 1 root root 0 1月 26 19:38 subsystem -> ../../../../../bus/usb/
-rw-r--r-- 1 root root 4096 1月 26 19:38 uevent
-r--r--r-- 1 root root 4096 1月 26 19:54 urbnum
-r--r--r-- 1 root root 4096 1月 26 19:54 version
cat virutal files
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat authorized
1
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat avoid_reset_quirk
0
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bcdDevice
0100
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bConfigurationValue
1
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bDeviceClass
02
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bDeviceProtocol
00
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bDeviceSubClass
00
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bmAttributes
80
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bMaxPacketSize0
64
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bMaxPower
100mA
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bNumConfigurations
1
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat bNumInterfaces
2
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat busnum
1
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat configuration
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat descriptors
# K�2
$$$$�#
�##allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat dev
189:2
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat devnum
3
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat devpath
2
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat idProduct
2012
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat idVendor
1f00
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat ltm_capable
no
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat manufacturer
mbed.org
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat maxchild
0
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat product
CDC DEVICE
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat quirks
0x0
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat removable
unknown
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat remove
cat: remove: 权限不够
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat serial
0123456789
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat speed
12
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat uevent
MAJOR=189
MINOR=2
DEVNAME=bus/usb/001/003
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=1f00/2012/100
TYPE=2/0/0
BUSNUM=001
DEVNUM=003
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat urbnum
138
allankliu#allankliu-VirtualBox:/sys/bus/usb/devices/1-2$ cat version
1.10
Check /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 1月 26 19:38 ttyACM0
usbmon
sudo ls /sys/kernel/debug/usb/usbmon
[sudo] password for allankliu:
0s 0u 1s 1t 1u
sudo cat /sys/kernel/debug/usb/devices
...
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=1f00 ProdID=2012 Rev= 1.00
S: Manufacturer=mbed.org
S: Product=CDC DEVICE
S: SerialNumber=0123456789
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=100mA
A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=02 Prot=00
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=cdc_acm
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=16ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
device file system
/dev/ttyACM0 is generated as soon as the device is plugged in.
gtkterm
The device can be opened, but not output, regardless the baudrate.
Observation
In lsusb, no product name is printed out, but working CDC devices also have same issue;
In lsusb -v, error of Couldn't open device, some information will be missing, however even Linux hub has same problem.
When cat /sys/bus/usb/devices/1-2/descriptor, it returns binary data, but other USB devices are same, it seems a binary file, anyway.
So far, based upon data, I can not find big differences or error from OS, but it has no output anyway, but it has output in Windows/Ubuntu 15 or later.
Next step, I will use wireshark/tcpdump to find out.
Update
After some labs, I found actually this STM32F103C8 (so-called bluepill) has already successfully emuerated. And the USB dongle has been supported in OpenWRT/Ubuntu12.04/14.04/16.04/18.04, but sometimes the device stalls for a while. After such pause, the communication is back to normal.
Pure firmware issue.
I would recommend getting a nice USB protocol analyzer like the Beagle USB 12 so you can look at the communication going between the device and the OS. You can study both the working case and the non-working case.
You should also run dmesg and look for messages from Linux's cdc-acm driver when you plug the device in. You can find out what kernel version you are running with uname -a and then look at the source code of the cdc-acm module in that kernel version.
You can see the USB descriptors of you device using lsusb -v and make sure they are valid.
You should also make sure you get a clear understanding of what symptoms your system has when it's not working, and use that to narrow your search for the problem. For example, if the /dev entry was not being created, that is a different type of problem than if your reads and writes to the port were failing.
Using the above methods you should be able to figure out what is wrong and fix it. This is almost certainly a firmware problem, not a hardware problem. I suspect there is something wrong with your USB descriptors so I'd start looking there first.
Related
I use Linux machine on AWS EC2 instance with Red Hat Enterprise Linux 8.6 and my cloud-init-output.log is increasing its size very quickly causing my app logs to stop writing in one-two days even though I have 20GB of storage.
user$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 195M 1.7G 11% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/xvda2 20G 17G 3.5G 83% /
tmpfs 373M 0 373M 0% /run/user/1000
user$ ls -ltr /var/log
total 10499168
drwxr-x---. 2 chrony chrony 6 Jun 15 2021 chrony
drwxr-xr-x. 2 root root 6 Apr 5 18:43 qemu-ga
drwx------. 2 root root 6 Apr 8 04:50 insights-client
drwx------. 2 root root 6 May 3 08:58 private
-rw-rw----. 1 root utmp 0 May 3 08:58 btmp
-rw-------. 1 root root 0 May 3 08:59 maillog
-rw-------. 1 root root 0 May 3 08:59 spooler
drwxr-x---. 2 sssd sssd 73 Jun 3 11:15 sssd
drwx------. 2 root root 23 Jul 12 14:43 audit
drwxr-xr-x. 2 root root 23 Jul 12 14:44 tuned
-rw-r--r--. 1 root root 128263 Jul 12 14:44 cloud-init.log
drwxr-xr-x. 2 root root 43 Jul 12 14:44 rhsm
-rw-r--r--. 1 root root 806 Jul 12 14:44 kdump.log
-rw-r--r--. 1 root root 1017 Jul 12 14:45 choose_repo.log
drwxr-xr-x. 2 root root 67 Jul 12 14:47 amazon
-rw-r--r--. 1 root root 1560 Jul 14 05:04 hawkey.log
-rw-------. 1 root root 26318 Jul 14 06:39 secure
-rw-rw-r--. 1 root utmp 4224 Jul 14 06:58 wtmp
-rw-rw-r--. 1 root utmp 292292 Jul 14 06:58 lastlog
-rw-r--r--. 1 root root 10752 Jul 14 07:00 dnf.rpm.log
-rw-r--r--. 1 root root 48816 Jul 14 07:00 dnf.librepo.log
-rw-r--r--. 1 root root 97219 Jul 14 07:00 dnf.log
-rw-------. 1 root root 12402 Jul 14 07:01 cron
-rw-------. 1 root root 2160833934 Jul 14 07:02 messages
-rw-r-----. 1 root adm 5257112056 Jul 14 07:03 cloud-init-output.log
I changed logging level from default DEBUG to ERROR in /etc/cloud/cloud.cfg.d but it didn't help. Messages are also filling up fast.
Is this log file even supposed to be filling in after the EC2 instance is up?
Is there something I can do to stop the size increase?
I tried also to manually do the logrotate logrotate --force /etc/logrotate.d/ but it didn't do much.
Here I've a strange behavior:
Virtualbox (version 5) with 6 shares to windows host system.
Four of them working fine, two of them are read-only. Configuration is similar.
/etc/fstab:
download /media/sf_Download/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw 0 0
p80 /media/sf_p80/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw 0 0
p40 /media/sf_p40/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw 0 0
p20 /media/sf_p20/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw 0 0
musik /media/sf_musik/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw 0 0
filme /media/sf_filme/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw 0 0
the upper four are mounted r+w, all fine. but the lower two are read-only. Tryed several things (chown, chmod, etc), but nothing helped.
In case musik and filme are not mounted, ls -l delivers:
user#virtualxubuntu:/media$ ls -l
insgesamt 44
drwxrwxrwx+ 2 root vboxsf 4096 Jun 16 13:55 user
drwxrwxrwx 2 root vboxsf 4096 Jun 16 15:42 sf_filme
drwxrwxrwx 1 user user 4096 Jun 16 15:35 sf_Download
drwxrwxrwx 2 root vboxsf 4096 Jun 16 15:43 sf_musik
drwxrwxrwx 1 user user 20480 Mai 29 04:34 sf_p20
drwxrwxrwx 1 user user 4096 Mai 29 04:34 sf_p40
drwxrwxrwx 1 user user 4096 Mai 29 04:34 sf_p80
After mount -a I get:
user#virtualxubuntu:/media$ ls -l
insgesamt 252
drwxrwxrwx+ 2 root vboxsf 4096 Jun 16 13:55 user
dr-xr-xr-x 1 user user 98304 Jun 15 17:39 sf_filme
drwxrwxrwx 1 user user 4096 Jun 16 15:35 sf_Download
dr-xr-xr-x 1 user user 122880 Mär 31 13:07 sf_musik
drwxrwxrwx 1 user user 20480 Mai 29 04:34 sf_p20
drwxrwxrwx 1 user user 4096 Mai 29 04:34 sf_p40
drwxrwxrwx 1 user user 4096 Mai 29 04:34 sf_p80
Do you have any idea, how to fix it? The strange thing: this configuration worked months, 'til yesterday. And "I didn't changed anything." ;-)
kind regards
Johannes
Strange...
I added fmode and dmode options to the failing mounts and this helped...
musik /media/sf_musik/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw,fmode=0644,dmode=0750 0 0
filme /media/sf_filme/ vboxsf defaults,_netdev,uid=1000,gid=1000,rw,fmode=0644,dmode=0750 0 0
Don't know why these two need this options...
I have some kind of driver in user space:
program talk via some interface(rs232) with device.
Also I have pin(gpio) to switch on/off this device.
I do not code in my program concrete gpio, to make it more portable,
so I modify device tree description of my board,
and describe regulator-fixed, after that I thought to use
userspace-consumer driver to control power on/off,
but looks like that not kernel developers expected
(link to discussion of similar problem, not my):
http://patchwork.ozlabs.org/patch/374912/
So how should I control switch on/off
of my device from user space without adding to my program
information about what conrete gpio used to switch on/off device?
More details:
In my board dts I described my pin like this:
regulator-deviceX {
status = "okay";
compatible = "regulator-fixed";
regulator-name = "DEV_X_ON#";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio5 4 GPIO_ACTIVE_LOW>;
};
And of course, after boot "gpio = <&gpio5 4 GPIO_ACTIVE_LOW>" was
locked by the kernel, and it is impossible to use it via /sys/class/gpio interface.
Bad think about such approach, that is impossible (or I don't see how) to
change regulator state from user space, as you can see "state" is read only file.
root#board:/sys/class/regulator/regulator.1# ls -l
lrwxrwxrwx 1 root root 0 May 3 03:32 device -> ../../../regulator-deviceX
-r--r--r-- 1 root root 4096 May 3 03:32 microvolts
-r--r--r-- 1 root root 4096 May 3 03:32 name
-r--r--r-- 1 root root 4096 May 3 03:32 num_users
drwxr-xr-x 2 root root 0 May 3 03:32 power
-r--r--r-- 1 root root 4096 May 3 03:32 state
lrwxrwxrwx 1 root root 0 May 3 03:25 subsystem -> ../../../../class/regulator
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_disk_state
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_mem_state
-r--r--r-- 1 root root 4096 May 3 03:32 suspend_standby_state
-r--r--r-- 1 root root 4096 May 3 03:32 type
-rw-r--r-- 1 root root 4096 May 3 03:25 uevent
So, the final solution looks like this:
Step 1
Describe device in device tree, though you no need
kernel for handling it, but looks right to describe it here
gps-reciever {
compatible = "my_company_name,gps_recv_name";
vcc-supply = <&ext_gps_recv_reg>;
comment = "connected via usb<->rs232, port0";
};
where ext_gps_recv_reg of any normal regulator.
Step 2
I wrote a simple platform device driver for linux kernel,
that compatible with device above, and in probe function of this
driver I call platform_device_register_full that setup arguments for
userspace_consumer driver.
After that I can find suitable file via name:
cat /sys/bus/platform/devices/reg-userspace-consumer*/name,
and then disable/enable regulator via:
echo "disabled" > /sys/bus/platform/devices/reg-userspace-consumer*/state
So I separate device description from linux kernel implementation.
i'm trying to understand how linux device/driver model works and to do this i've written a little module. This module is simple, retrieves a pointer to a struct net_device (let's call it netdev) by the function dev_get_by_name(&init_net, "eth0"). Why the value of netdev->dev.bus is NULL? Should that pointer represent the bus_type structure on which my device is attached? The field netdev->parent->bus is however not NULL but it should represent the bus for eth controller...any explanation?
This is because your eth device, or better said its device "object" in the kernel, is not a bus and thus its bus value is left unitialized. But its parent device usually is on a bus and it is sufficient that the parent device knows the bus it is on, since both device eventually are linked during the driver initialization.
Let's have a look at an example: here is what I have in sysfs for my eth0 device (notice the device field):
$ ll /sys/class/net/eth0/
total 0
-r--r--r-- 1 root root 4096 May 20 11:10 address
-r--r--r-- 1 root root 4096 May 20 11:10 addr_len
-r--r--r-- 1 root root 4096 May 20 11:10 broadcast
-r--r--r-- 1 root root 4096 May 20 11:10 carrier
lrwxrwxrwx 1 root root 0 May 20 11:10 device -> ../../../devices/pci0000:00/0000:00:19.0
-r--r--r-- 1 root root 4096 May 20 11:10 dev_id
-r--r--r-- 1 root root 4096 May 20 11:10 dormant
-r--r--r-- 1 root root 4096 May 20 11:10 features
-rw-r--r-- 1 root root 4096 May 20 11:10 flags
-rw-r--r-- 1 root root 4096 May 20 11:10 ifalias
-r--r--r-- 1 root root 4096 May 20 11:10 ifindex
-r--r--r-- 1 root root 4096 May 20 11:10 iflink
-r--r--r-- 1 root root 4096 May 20 11:10 link_mode
-rw-r--r-- 1 root root 4096 May 20 11:10 mtu
-r--r--r-- 1 root root 4096 May 20 11:10 operstate
drwxr-xr-x 2 root root 0 May 20 11:10 power
drwxr-xr-x 2 root root 0 May 20 11:10 statistics
lrwxrwxrwx 1 root root 0 May 20 11:10 subsystem -> ../../net
-rw-r--r-- 1 root root 4096 May 20 11:10 tx_queue_len
-r--r--r-- 1 root root 4096 May 20 11:10 type
-rw-r--r-- 1 root root 4096 May 20 11:10 uevent
The link for the device is created from this code from the driver probe function, where netdev is the network device, and pdev the associated PCI device:
SET_NETDEV_DEV(netdev, &pdev->dev);
Which according to the documentation is:
/* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization.
*/
#define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev))
And here is what I have in the corresponding PCI device, that was set by SET_NETDEV_DEV (where you can notice the bus field):
$ ll /sys/devices/pci0000\:00/0000\:00\:19.0/
total 0
-rw-r--r-- 1 root root 4096 May 20 11:54 broken_parity_status
lrwxrwxrwx 1 root root 0 May 20 11:22 bus -> ../../../bus/pci
-r--r--r-- 1 root root 4096 May 20 11:07 class
-rw-r--r-- 1 root root 256 May 20 11:22 config
-r--r--r-- 1 root root 4096 May 20 11:54 device
lrwxrwxrwx 1 root root 0 May 20 11:22 driver -> ../../../bus/pci/drivers/e1000e
-rw------- 1 root root 4096 May 20 11:22 enable
-r--r--r-- 1 root root 4096 May 20 11:07 irq
-r--r--r-- 1 root root 4096 May 20 11:54 local_cpulist
-r--r--r-- 1 root root 4096 May 20 11:07 local_cpus
-r--r--r-- 1 root root 4096 May 20 11:22 modalias
-rw-r--r-- 1 root root 4096 May 20 11:22 msi_bus
lrwxrwxrwx 1 root root 0 May 20 11:22 net:eth0 -> ../../../class/net/eth0
drwxr-xr-x 2 root root 0 May 20 11:11 power
-r--r--r-- 1 root root 4096 May 20 11:22 resource
-rw------- 1 root root 131072 May 20 11:22 resource0
-rw------- 1 root root 4096 May 20 11:22 resource1
-rw------- 1 root root 32 May 20 11:22 resource2
lrwxrwxrwx 1 root root 0 May 20 11:22 subsystem -> ../../../bus/pci
-r--r--r-- 1 root root 4096 May 20 11:22 subsystem_device
-r--r--r-- 1 root root 4096 May 20 11:22 subsystem_vendor
-rw-r--r-- 1 root root 4096 May 20 11:22 uevent
-r--r--r-- 1 root root 4096 May 20 11:22 vendor
I hope this clarifies the situtation.
If a have a /dev device node and its major/minor numbers how do i know the kernel module name that exported this node?
Short answer :
cd /sys/dev/char/major:minor/device/driver/
ls -al | grep module
Each device is generally associated with a driver, and this is all what the "device model" is about. The sysfs filesystem contains a representation of this devices and their associated driver. Unfortuantely, it seems not all sysfs have a representation of the device nodes, so this applyd only if your /sys directory contains a /dev directory.
Let's take an example, with /dev/video0
On my board, ls -al /dev/video0 output is
crw------- 1 root root 81, 0 Jan 1 00:00 video0
So major number is 81 and minor number is 0.
Let's dive into sysfs :
# cd /sys
# ls
block class devices fs module
bus dev firmware kernel
The sys/dev directory contains entry for the char and block devices of the system :
# cd dev
# cd char
# ls
10:61 13:64 1:3 1:8 249:0 252:0 29:0 4:65 81:0 89:1
10:62 1:1 1:5 1:9 250:0 253:0 29:1 5:0 81:2
10:63 1:11 1:7 248:0 251:0 254:0 4:64 5:1 81:3
What the hell are this links with strange names ?
Remember the major and minor number, 81 and 0 ?
Let's follow this link :
#cd major:minor (ie 81:0)
#ls -al
drwxr-xr-x 2 root root 0 Jan 1 01:56 .
drwxr-xr-x 3 root root 0 Jan 1 01:56 ..
-r--r--r-- 1 root root 4096 Jan 1 01:56 dev
lrwxrwxrwx 1 root root 0 Jan 1 01:56 device -> ../../../vpfe-capture
-r--r--r-- 1 root root 4096 Jan 1 01:56 index
-r--r--r-- 1 root root 4096 Jan 1 01:56 name
lrwxrwxrwx 1 root root 0 Jan 1 01:56 subsystem -> ../../../../../class/video4linux
-rw-r--r-- 1 root root 4096 Jan 1 01:56 uevent
Now we can see that this device nod, which is how the device is presented to userspace, is associated with a kernel device. This association is made through a link. If we follow this link, we end up in a directory, with a driver link. The name of the driver is usually the name of the module :
# ls -al
drwxr-xr-x 3 root root 0 Jan 1 01:56 .
drwxr-xr-x 25 root root 0 Jan 1 00:00 ..
lrwxrwxrwx 1 root root 0 Jan 1 01:56 driver -> ../../../bus/platform/drivers/vpfe-capture
-r--r--r-- 1 root root 4096 Jan 1 01:56 modalias
lrwxrwxrwx 1 root root 0 Jan 1 01:56 subsystem -> ../../../bus/platform
-rw-r--r-- 1 root root 4096 Jan 1 01:56 uevent
drwxr-xr-x 3 root root 0 Jan 1 01:56 video4linux
So here the name of the module is vpfe_capture
The answer to this question is most likely different based on a number of factors. For example, if you're running udev, devfs, pre-devfs, etc.
If you're using Ubuntu (or another equally modern distro) the udevadm command might be what you want.
% udevadm info -q path -n /dev/cdrom
/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0/block/sr0
So, my /dev/cdrom is provided by the sr driver, which resides in the sr_mod kernel module. I don't know of a command that takes /dev/cdrom as an argument and prints sr_mod as output.