Checking hardware with hwtest

From postmarketOS Wiki

This is a utility for checking hardware functionality on devices.

Currently hwtest can check the following:

  • framebuffer access
  • drm/kms
  • camera image capture (uses ffmpeg and v4l-utils)
  • input devices (uses evtest)
  • Accelerometer/magnetometer/gyroscope
  • Temperature sensors
  • Light/Proximity sensors
$ sudo apk add hwtest
$ sudo hwtest
Category         Model                Path                                      Status     Value                     
framebuffer      DRM emulated         /sys/class/graphics/fb0                   working    Not running               
drm              -                    /sys/class/drm/card1-DSI-1                working    720x1440                  
camera           ov5640               /sys/class/video4linux/v4l-subdev0        working    320x240,640x480,1280x720  
magnetometer     lis3mdl              /sys/bus/iio/devices/iio:device2          working    -0.06, 0.35, 0.93 gauss   
accelerometer    mpu6050              /sys/bus/iio/devices/iio:device1          working    1.46, 0.17, -10.53 g      
gyroscope        mpu6050              /sys/bus/iio/devices/iio:device1          working    -0.05, -0.03, 0.04 rad/s  
temperature      mpu6050              /sys/bus/iio/devices/iio:device1          working    37 deg C                  
temperature      axp813-adc           /sys/bus/iio/devices/iio:device0          working    28500 deg C               
proximity        stk3310              /sys/bus/iio/devices/iio:device3          working    300.8                     
illuminance      stk3310              /sys/bus/iio/devices/iio:device3          working    397 lux                   
input            generic ft5x06 (12)  /dev/input/event2                         working                              
input            1c21800.lradc        /dev/input/event1                         working                              
input            axp20x-pek           /dev/input/event0                         working

Export and verify

Hwtest includes the --export and --verify option. The export option generates a file with the test results, this file can later be used with the verify option to create a diff of working hardware.

This is mainly useful for testing if a kernel still works after rebasing on a newer upstream linux version.

Running hwtest with the camera module unloaded so it fails.
$ sudo hwtest --export pinephone.ini
Category         Model                Path                                Status     Value                            
framebuffer      DRM emulated         /sys/class/graphics/fb0             working    Not running                      
drm              -                    /sys/class/drm/card1-DSI-1          working    720x1440                         
camera           ov5640               /sys/class/video4linux/v4l-subdev0  broken                                      
magnetometer     lis3mdl              /sys/bus/iio/devices/iio:device2    working    0.01, -0.01, 1.19 gauss          
accelerometer    mpu6050              /sys/bus/iio/devices/iio:device1    working    0.3, 0.12, -10.52 g              
gyroscope        mpu6050              /sys/bus/iio/devices/iio:device1    working    -0.04, -0.03, 0.04 rad/s         
temperature      mpu6050              /sys/bus/iio/devices/iio:device1    working    32 deg C                         
temperature      axp813-adc           /sys/bus/iio/devices/iio:device0    working    22600 deg C                      
input            generic ft5x06 (12)  /dev/input/event1                   working                                     
input            axp20x-pek           /dev/input/event0                   working

The generated ini file:

[hwtest]
export-version = 1

[framebuffer]
; /sys/class/graphics/fb0
drm emulated = True

[drm]
; /sys/class/drm/card1-dsi-1
- = True

[camera]
; /sys/class/video4linux/v4l-subdev0
ov5640 = False

[magnetometer]
; /sys/bus/iio/devices/iio:device2
lis3mdl = True

[accelerometer]
; /sys/bus/iio/devices/iio:device1
mpu6050 = True

[gyroscope]
; /sys/bus/iio/devices/iio:device1
mpu6050 = True

[temperature]
; /sys/bus/iio/devices/iio:device1
mpu6050 = True
; /sys/bus/iio/devices/iio:device0
axp813-adc = True

[input]
; /dev/input/event1
generic ft5x06 (12) = True
; /dev/input/event0
axp20x-pek = True

After fixing the camera and running hwtest with the verify option:

$ sudo hwtest --verify pinephone.ini 
Fixed hardware: 
 * ov5640 [/sys/class/video4linux/v4l-subdev0] 320x240,640x480,1280x720

Troubleshooting

Installation

hwtest (here, 0.6.0) is implicitly dependent on the minor version number of python, 3.x.

$ apk info -a hwtest
...
hwtest-0.6.0-r4 depends on:
python3
...
hwtest-0.6.0-r4 provides:
cmd:hwtest=0.6.0-r4
py3.10:hwtest=0.6.0-r4
...

In case of a (seldom, but not unexpected) minor version upgrade to the python package (here, from 3.10 to 3.11), hwtest installation will succeed, but will refuse to run:

$ hwtest
Traceback (most recent call last):
  File "/usr/bin/hwtest", line 33, in <module>
    sys.exit(load_entry_point('hwtest==0.6.0', 'console_scripts', 'hwtest')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/bin/hwtest", line 22, in importlib_load_entry_point
    for entry_point in distribution(dist_name).entry_points
                       ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/metadata/__init__.py", line 964, in distribution
    return Distribution.from_name(distribution_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/importlib/metadata/__init__.py", line 561, in from_name
    raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for hwtest

$ python --version
Python 3.11.0

Usage: display (terminal) size

hwtest text output format is hardwired for terminal sizes typical on a desktop, e.g., 80x24. On-device terminals (e.g., gnome console) may be 44x18, and problematic. If an interactive on-device run terminates with an error such as ValueError: Sign not allowed in string format specifier, the formatter code is at fault, and must be modified. Since hwtest is written in python, the edits are easily done on-device, per-device. An example patch to formatter.py is given below:

formatter-smallscreen.patch

--- formatter.py.orig   2022-03-04 15:59:56.639759891 -0700
+++ formatter.py        2022-03-04 15:59:51.686426859 -0700
@@ -62,13 +62,24 @@

     def start(self):
         width, height = shutil.get_terminal_size((120, 25))
+        #print("(dbg) width, height", width, height) 
+        #phosh/kgx, portrait, moto-osprey w,h is 44,17 [similar for harpia, a3]
         self.row = "{: <16} {: <20} "
         width -= 16 + 1 + 20 + 1
+        if width < 12:
+                #print("(dbg) bad (adjusted) width (narrow screen?):", width, ", hardwiring to 20")
+                width = 20
         flexwidth = math.floor((width - 10) / 2)
+        if flexwidth < 0:
+               print("(dbg) flexwidth < 0; MUST NOT OCCUR; hardwiring to 5", flexwidth)
+               flexwidth = 5
         self.row += "{: <" + str(flexwidth) + "} "
         self.row += "{: <10} "
         self.row += "{}"

+        #print("(dbg) DEBUG: self.row", type(self.row), self.row)
+        if "-" in self.row:
+               print("(dbg) FAIL: self.row contains '-' sign, position", self.row.index("-"))
         print(self.row.format("Category", "Model", "Path", "Status", "Value"))

     def result(self, result):