Monitor Progress of Data Transfer in Console

linux console progress

Linux provides at least two handy command-line tools to monitor data transfer progress: bar and pv.

Both display a one-line progress bar with speed, elapsed or estimated time, and provide customizable formatting.

Examples with bar:

If data size is unknown:

dd if=/dev/zero | bar | dd of=/dev/null
   2.3GB at  581.8MB/s  elapsed:   0:00:04

If data size is known:

dd if=/dev/zero iflag=count_bytes count=10G | bar --size 10G | dd of=/dev/null
   1.2GB at  592.8MB/s  eta:   0:00:15   11% [=====                               ]

Examples with pv:

dd if=/dev/zero iflag=count_bytes count=10G | pv | dd of=/dev/null
2.59GiB 0:00:06 [ 397MiB/s] [      <=>                                            ]
dd if=/dev/zero iflag=count_bytes count=10G | pv --size=10G | dd of=/dev/null
2.59GiB 0:00:06 [ 467MiB/s] [========>                            ] 25% ETA 0:00:17

pv can also count lines instead of bytes, useful for monitoring log or message rates:

sudo dmesg -w | pv --line --rate > /dev/null
[ 496k/s]

On a side note, dd can also report progress at runtime, when status=progress is specified.

dd if=/dev/zero iflag=count_bytes count=10G of=/dev/null status=progress
2791971840 bytes (2.8 GB, 2.6 GiB) copied, 3 s, 931 MB/s

Interacting with I2C Peripherals from Linux Console

linux i2c

When you need to interact with I2C peripherals from the Linux console, for example during hardware bringup phase, you can use command line utilities available in the i2c-tools package. This is much faster than making changes in Linux kernel drivers, as no recompilation, installation, or reboots are needed.

In my case, it was a camera device, and I had to make sure that the camera was available on the I2C bus.

First, make sure that the required I2C bus is enabled in the device tree.

Next, you can scan the bus for I2C devices:

sudo i2cdetect -y 2

Output will look like below, indicating addresses of detected devices:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

Next, you can interact with devices using the i2ctransfer utility. Below examples are for 16-bit address registers.

# Read 2 bytes from device 0x60 at offset 0x0102
i2ctransfer -y 2 w2@0x60 0x01 0x02 r2

# Write 1 byte to device with address 0x60 at offset 0x0102
sudo i2ctransfer -y 2 w3@0x60 0x01 0x02 0x03

In my case, I also had to perform a startup sequence for the device to appear on the bus by asserting a power-up pin via GPIO:

echo 18 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio18/direction
echo 1 > /sys/class/gpio/gpio18/value
sleep 1
sudo i2cdetect -y 2

You can use POSIX API in Swift on MacOS

macos posix swift

Swift on macOS can access POSIX APIs by importing the Darwin module. This gives you access to low-level system calls, file operations, and other Unix functionality. In my case I needed to call openpty() function from Swift application and handle raw file descriptors.

import Darwin

// Example: Get current working directory
let cwd = getcwd(nil, 0)
if let path = cwd {
    print("Current directory: \(String(cString: path))")
    free(cwd)
}

// Example: Create a directory (if app is not sandboxed)
let result = mkdir("/tmp/testdir", 0o755)
if result == 0 {
    print("Directory created successfully")
} else {
    print("Failed to create directory: \(errno)")
}

Maximum DriverKit Driver Bundle Identifier Length is 64 Characters

macos dext driverkit

If you get sysex didFailWithError: extension category returned error error when trying to Install Dext from Communicating between a DriverKit extension and a client app sample application, in Xcode change Bundle Identifier for DriverKitSampleApp and NullDriver to shorter ones, length should not exceed 64 characters.

For example, replace com.example.apple-samplecode.dext-to-user-client with com.example.dext-to-user-client- to make sure whole identifier is not longer than 64 chars, as suggested on Apple Developer Forums.