1

I'm having a hard time figuring out a good way to solve this problem. I have two SBCs running Buildroot Linux that are almost completely identical except for a USB ACM card that I am trying to detect at startup and loadup services dynamically based on what SBC it is (so for example, have a script "touch sbc1" if card is detected or "touch sbc2" if it is not and then use this file to load up different configurations for the network).

I am using a static dev table, Busybox init, and the 3.12.20 kernel (with which USB CDC is compiled in as a built-in driver; I disabled modules). Here is the problem: I write a script (S00setup, so it is the first script in rcS that should run; this script MUST run before the network script) to check for the presence of this card. It seems the CDC ACM driver loads on both boards regardless if it is there or not so that check does not work (buffer always says usbcore: registered new interface driver cdc_acm followed by cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters). Also, my dmesg output cuts out at about 2 seconds calling it from the script and it is only after that that it will actually assign /dev/ttyACM0 to the device. How do I force the kernel to finish booting before processing this init file so I can properly detect it? Would a "sleep" here work? If not, then what? Is there some type of DoEvents() for Bash/Linux? It is the same case with detecting the card with lsusb in that the device will not show up until after the scripts are processed, which doesn't make sense to me. So to ask a similar question, I guess another way for this to work is to force poll USB devices; is there anyway at all to do that?

I posted this question here instead of Unix&Linux since you guys here seem to be more experienced with this and in case there was any quick program I can write to force the kernel to finish processing. I am only missing an additional 1-2 seconds of the kernel buffer when it actually assigns devices to ttys and whatnot. This is the output I need to differentiate the two boards. Obviously, the reason I am doing this is because I want to use the same OS image on both systems; for configuration management purposes, it is much easier this way.

Jack
  • 361
  • 2
  • 4
  • 17

1 Answers1

4

USB devices are hotpluggable so they can appear anytime. There is just no concept relating to "finishing booting" when it comes to USB so there is no reason for Linux to wait for all currently connected devices enumerating. After all, the end result is the same as a device just being connected later.

What you should do is to hook a script to that device's appearance in udev / systemd and do your work from there.

Alternatively and simpler, just sleep in your script and hope for the best. A udevadm settle might help to wait until the devices appear if they have already caused a udev event.

Andreas Bombe
  • 2,450
  • 13
  • 20
  • As stated, I am using a static dev table so udev/udevadm is not really an option. It adds complexity and time to bootup that I don't really need. The problem is that init loads the rcS scripts before the device is assigned. I will play around with mdev (mini Busybox version of udev) but not too optimistic about it. I could have sworn the other system did not register the CDC ACM driver before because it did not see the card but they are both doing it now. – Jack May 19 '14 at 17:47
  • udevadm settle is actually a good suggestion but I don't need a hotplug manager that extensive for an embedded system. If there's no other options on the table though, I will give it a shot. – Jack May 19 '14 at 17:54
  • @Jack USB and other things are hotplug based so there really are just two approaches. Event based (with udev or similar) and handle the device as soon as it appears. Or sleep for a sufficient amount of time (where "sufficient" can never be known for certain). Maybe loop until you get what you want with short sleeps between checking. This is exactly the problem that traditional purely script based booting such as in sysvinit increasingly fail in the face of. It's not just you, big distributions wrestle with that and it's no wonder that an event based system like with systemd spreads like that. – Andreas Bombe May 19 '14 at 18:20
  • sleep 1 does do the trick; it's a total hack but I agree that with USB, there is really no other way as it's hotplug based. I will just accept this answer. I still wonder what the best approach for this is with a static table, if at all possible. – Jack May 19 '14 at 19:41