I have a small project build with Yocto. When I insert a USB device the kernel prints the info to the console. This tells me something is prompting this and I should be able to capture it in a C program that I write.
My question is, is there a way in a C thread to capture the USB inserted notification, mount, and read a file?
If my application cannot retrieve this notification I can just start a thread and every X seconds run ls /dev/sda. If I get a hit then mount and read my file.
Related
With freshly flashed L4T 21.8, the serial console stops with output like:
## Flattened Device Tree blob at 82000000
Booting using the fdt blob at 0x82000000
Using Device Tree in place at 82000000, end 83014f2d
Starting kernel ...
How do I get serial output from the kernel?
When things stop after "Starting kernel...", across boards, there are usually two causes:
serial console isn't enabled right
kernel didn't have enough space to unpack itself and start printing to serial console.
The first thing to enable is serial console. Make sure the kernel command line for TK1 includes:
console=ttyS0,115200n8 earlycon=uart8250,mmio32,0x70006300 earlyprintk
Two things are going on there: One is enabling normal serial console once boot gets far enough. The other is enabling earlycon before the proper 8250 driver is initialized, so you can see early boot failures too. This serial setup should get you output on the DB9 connector J1A2 (UART4) just like u-boot uses.
If you still don't have serial output with that, likely the issue is the kernel trashing the dtb while unpacking -- the default 16Mb between 0x81000000 kernel and 0x82000000 fdt is not enough for many kernels. You need to move the fdt address up to make space. Press the reset button, and interrupt the boot by pressing a key when prompted, then enter this in your u-boot command line:
set fdt_addr_r 0x83000000
saveenv
run bootcmd
This gets you 32MB of space for the kernel image for this boot, and thanks to saveenv also any following ones.
this might be a stupid question,
I was debugging a USB storage device on an ARM-CortexM4 platform (STM32F4 series) which runs embedded Linux. The ARM is working as USB host, and tries to communicate with a thumb drive in USB full speed (12Mb/s).
Now here is the problem. After successful enumeration and several SCSI commands thru BULK transfers, the capacity and everything can be read correctly. However, after about 15 seconds when I try to send these SCSI commands again (under same condition), the USB host controller just returns 'Transaction Error', which looks like the device is not responding to BULK transfers anymore (not ACKing) and the host controller times out. The question is, is there any timeout mechanism for USB mass-storage class or SCSI system such that, after a timeout the system must be re-enumerated or re-probed, otherwise it won't respond anymore?
I understand this might be due to a stupid error in my program, or due to some limitations on the specific hardware. However when I used usbmon module in Linux on a PC to capture the transfers on the very same thumb drive, I can see the operating system actually sends a sequence probing command (Read-max-Lun followed by Test-unit-ready) every 5 sec, which could be the reason why the thumb drive doesn't fail on my PC.
Thanks! I'm looking forward to any replies.
I think you're on the right track with the Test Unit Ready commands.. I am in the middle of writing a mass storage device driver for an embedded device and When testing on OS X, after the initial SCSI queries, my device receives Test Unit Ready command about once every second when no other activity is occurring. Since your post is quite old, I recommend you post your own solution if you've since solved your problem.
Otherwise try adding periodic test unit ready commands from the host side when there is no other activity.. You could set and activate a timer whenever USB activity is occurring. If the timer fires, u can send a Test unit ready command.. Rinse repeat.
I want to write a simple bootloader for the Raspberry Pi. The main purpose of this bootloader is to enable a Raspberry Pi at a remote location, to recover from kernel updates that make the device unbootable as the result of a kernel panic. The procedure for updating the kernel should be like this:
The default Linux kernel is /boot/rpi-kernel.img and the string 'rpi-kernel.img' is written in /boot/default-kernel.txt. The kernel parameter 'panic=10' has been added to 'cmdline=' in /boot/config.txt.
Connect to the Raspberry Pi over SSH.
Copy /boot/rpi-kernel.img to /boot/rpi-kernel-fallback.img
Create empty file /boot/kernel_update
Download kernel update and move it to /boot/rpi-kernel.img
Reboot
This is the design for the bootloader I have thought up in pseudocode:
read kernel parameters passed from start.elf
if empty file '/boot/kernel_update' does not exists
boot kernel defined in '/boot/default-kernel.txt' with kernel parameters passed from start.elf
else
if empty file '/boot/boot_kernel_update' exists
write string 'rpi-kernel-fallback.img' to file '/boot/default-kernel.txt'
delete file '/boot/kernel_update'
delete file '/boot/boot_kernel_update'
create empty file '/boot/kernel_update_failed'
boot kernel 'rpi-kernel-fallback.img' with kernel parameters passed from start.elf
else
create empty file '/boot/boot_kernel_update'
boot kernel '/boot/rpi-kernel.img' with kernel parameters passed from start.elf
As a last step in the boot process, a shell script will check if the /boot/kernel_update exists and then if network is functional and the environment is sane, before removing /boot/kernel_update.
I want to make the bootloader as clean and simple as possible, with no support for HDMI, USB, Ethernet, serial etc. The problem is that I'm not sure how to get started with this.
The main challenges are to read from and write to the FAT32 filesystem on the SD card, and booting the Linux kernel. Everything has to happen from bare metal on the Raspberry Pi.
Any code examples, resources, suggestions ect. on doing this would be very helpful.
How are you supposed to programatically detect when the remote modem on your call hangs up? I am writing a C program which interfaces with a SoftModem device /dev/ttySL0 in Ubuntu linux. I am able to configure the modem using Hayes AT commands and communicate with the remote modem. However, I haven't been able to determine how I'm supposed to detect that the other end has hung up the line.
I have the modem configured so that when the other end hangs up, the device prints NO CARRIER and switches to command mode. However, I can't use the NO CARRIER string because I can't guarantee that the modem won't receive that string while in data mode.
How do you "listen" for remote hang up?
This is a hardware signal on modems, the Carrier Detect (CD) line. You'll need to monitor it to know that the connection was lost. Basics in linux are described in this how-to, you obtain the signal state with ioctl() using the TIOCM_CAR command.
Testing for NO CARRIER as text will not suffice. This text frequently occurs on sites in the net, even on Q&A sites.
Coming from the modem, it should be enclosed in line breaks.
Besides, after you detect that text, you can try to switch to command mode with +++. If that works, your connection persists and you can reattach it and continue using it. If it doesn't (because you are already there and +++ is an invalid command), the connection has gone.
I am new to C and am trying to write a program that syncs files on my computer to a USB device. It currently works my me cd'ing to the directory that the device mounts to and typing "myprog init" which creates a .myprog file. The idea then is that when a USB device is connected my program checks for the .myprog file, if it finds it then it syncs. Problem is that I can't figure out how to detect when a new USB device is connected.
I am writing the program for Linux (I'm using Ubuntu 9.04) and using GCC.
Thanks for any help :)
Look into udev documentation for this (writing udev rules).
Also have a look at this stackoverflow thread.