written at 20:45 by faberman
CSS/JS minify

A simple white space and comment stripper for CSS and JavaScript files.

USAGE

minify -js [<JS-File>..] minify -css [<CSS-File>..] minify (<file.js> [<file.js>..])|(<file.css> [<file.css>..])

If there are no file names given in -js or -css mode, stdin is used as input.

In my projects I usually run a make target like this to create minified and precompressed versions of the JS/CSS files:

minify: rm css/all.css* || true minify -css css/* > css/all.css gzip -fc9 css/all.css > css/all.css.gz rm js/all.js* || true minify -js js/* > js/all.js gzip -fc9 js/all.js > js/all.js.gz

SOURCE

minify_v2.tgz v2, 2020-11-28
written at 19:48 by faberman
Vegan Recipe Database

Corona lockdown.. after cleaning up my music and movie database finally some time to build a recipe database for my collection of vegan recipes:

vezepte.faberman.de

German only (for the moment :).

written at 23:01 by faberman
Watchdog

A watchdog daemon that supports variable timeouts and kernel watchdogs. Features:

  • no dependencies (except libc)
  • no config files, single binary
  • ideal for embedded systems
  • support for kernel watchdogs
  • permission check via UID and program name
  • millisecond precision

PROCESS WATCHDOG

A process that wants to be monitored creates a file with unique filename (e.g. command name + pid) in /run/watchdog. The file contains the following three lines:

<command name> <pid> <timeout>
where
  • command name is the name of the running process as in /proc/<PID>/command,
  • pid is the PID of the process, and
  • timeout is the timeout in milliseconds.
If the file has not been updated before last modification time + timeout has passed, the process is sent a KILL signal ONLY IF
  1. the program name given in the file in /run/watchdog matches the name in /proc/<PID>/comm, and
  2. the EUID of the process (as in /proc/<PID>/status) is the same as the UID of the file in /run/watchdog

SYSTEM WATCHDOG

All watchdogs in /dev/watchdogX are pinged every WATCHDOGTIMEOUT ms and will receive the "Magic Close" upon exit of watchdogd.

INSTALLING

KERNEL REQUIREMENTS

  • CONFIG_INOTIFY_USER
  • PROC_FS

BUILDING

make; make install

RUNNING

Simply run 'watchdogd' at startup. If /var/run/watchdog does not exist, it will be created.

STOPPING

Send the process a SIGINT or SIGTERM to exit. These signals are caught, watchdogd writes the magic close byte to all system watchdogs and exits gracefully. Any files in /var/run/watchdog are kept in place, so after a restart of watchdogd it will resume operation immediately.

LOGGING

All starts, shutdowns, process killings and errors are logged via syslog and stdout/stderr.

INTEGRATION

To use watchdogd in your program, simply include watchdogd.h and call watchdog_update() before any previous timeout runs out. To turn off the watchdog, call watchdog_disable():

#include "watchdogd.h" ... watchdog_update("myapp", getpid(), 5000); // 5s timeout during startup ... main_loop { ... watchdog_update("myapp", getpid(), 1000); // 1s during normal operation }

Make sure that "myapp" is the EXACT command name of your application as it appears in /proc/<PID>/comm.

RECOMMENDATIONS

  • /var/run should be tmpfs so you do not wear out your flash
  • if you cache your pid make sure to reset it in the child process after fork()ing

SOURCE

watchdogd_v1.tgz
written at 21:19 by faberman
GPIO detection

If you find yourself in the situation to have a board without documentation or sources in front of you and you want to identify GPIOs - gpiofinder to the rescue!

gpiofinder utilizes all GPIOs not already in use (e.g. configured as dedicated periphery) and performs a binary search, so within log2(N) steps you have your pin identified.

Why not as shell script? Embedded systems often have minimal shells with very limited features. Before building a full featured bash, hacking together a small C program seemed more feasable.

USAGE

  1. Connect an oscilloscope or level meter to the GPO you are identifying
  2. Run gpiofinder with the maximum number of gpios as argument, e.g. 223 on the i.MX6
  3. Answer the questions with y/n:
    $ ./gpiofinder 223 Initializing all GPOs to 0.. Is the level you are looking for currently low? (y/n) y Beginning search.. Enabling 0..111..did the level go up? (y/n) y Enabling 0..55..did the level go up? (y/n) y Enabling 0..27..did the level go up? (y/n) y Enabling 0..13..did the level go up? (y/n) n Enabling 14..27..did the level go up? (y/n) y Enabling 14..20..did the level go up? (y/n) y Enabling 14..17..did the level go up? (y/n) n Enabling 18..20..did the level go up? (y/n) y Enabling 18..19..did the level go up? (y/n) y Enabling 18..18..did the level go up? (y/n) n Enabling 19..19..did the level go up? (y/n) y GPIO=19

SOURCE

gpiofinder_v1.tgz
written at 19:11 by faberman
Offline Ubuntu Docker Image Creation

This script expects an Ubuntu version (YY.MM or name) as argument, pulls the files and creates a docker image. This comes in handy if your company's firewall policy forbids access to docker repositories or you want to build your own base images.

Make sure your version of debootstrap supports the Ubuntu versions you want to install.

$ ./create_image.sh focal

SOURCE

create_image.sh v1, 2019-11-12
written at 20:52 by faberman
Monkey Typer

For automated tests of user input, not connected input boards or buttons that are not there yet, I wrote this small tool to inject keypresses in the event system.

USAGE

$ keysim KEY_F1 KEY_A KEY_B KEY_C

Will enter F1 a b c with a 200ms delay. For a list of all supported key names please look in the source, you can easily add new keys or other events.

REQUIREMENTS

A kernel with CONFIG_INPUT_UINPUT support.

SOURCE

keysim_v1.tgz
written at 22:02 by faberman
IMX.6 PWM Configuration

To experiment with different PWM configurations to reduce display flickering I wrote this little tool. It reads and writes the IMX.6 registers and bypasses the Linux drivers.

USAGE

$ pwmconfig -h Usage: pwmconfig [-r] ([-f val] [-d <val>]) | ([-p <val>] [-s <val>] [-P <val>] [-S <val>]) <pwmid>] -r show the register contents Automatic PWM configuration: -f set the PWM frequency for the given PWM -d set the duty cycle, 0..100 Manual PWM configuration: -p set the period value for the given PWM -s set the sample value for the given PWM -P sets the clock prescaler, 0..4095 -S sets the clock source, 0..3

Example: To set the PWM clock of PWM 1 to 15 kHz and the duty cycle to 50%, run

$ pwmconfig -f 15000 -d 50 1

To read the registers of a PWM peripheral, run

$ pwmconfig -r 1 *** PWM1 Registers PWMCR 0x03c20001 FWM FIFO Water Mark : 0 STOPEN Stop Mode Enable : 1 DOZEN Doze Mode Enable : 1 WAITEN Wait Mode Enable : 1 DBGEN Debug Mode Enable : 1 BCTR Byte Data Swap Control : 0 HCTR Half-word Data Swap Control : 0 POUTC PWM Output Configuration : 0 CLKSRC Select Clock Source : 2 PRESCALER Counter Clock Prescaler: 0 SWR Software Reset : 0 REPEAT Sample Repeat : 0 EN PWM Enable : 1 PWMSR 0x00000038 FWE FIFO Write Error Status : 0 CMP Compare Status : 1 ROV Roll-over Status : 1 FE FIFO Empy Status Bit : 1 FIFOAV FIFO Available : 0 PWMIR 0x00000000 CIE Compare Interrupt Enable : 0 RIE Roll-over Interrupt Enable : 0 FIE FIFO Empty Interrupt Enable : 0 PWMSAR 0x00001104 SAMPLE: 0x1104 (4356) PWMPR 0x00001102 PERIOD: 0x1102 (4354) PWMCNR 0x0000042d COUNT: 0x0cea (3306) *** PWM1 Configuration Period : 4354 Duty cycle : 4356/4354 = 100% PWM clock rate: 66000000 Hz PWM prescaler : 1 PWM frequency : 15158 Hz

SOURCE

pwmconfig_v1.tgz
written at 12:00 by faberman
GPI automation

A client wanted to build a push button board connected to a rpi to trigger scripts in order to automate scene recall, audio routing and quick switching of setups. This is accomplished by this small daemon that listens to GPI changes and runs scripts depending on the type of the event.

USAGE

$ gpiod <gpi> [<gpi> ..]

e.g.

$ gpiod 4 17 22 10 9 11

If you want to have to use a GPI, create one or more scripts in /var/lib/gpiod/scripts with the following name(s):

  • <GPI>.sh for raising or falling edge (any change triggers the script)
  • <GPI>_up.sh for raising edge
  • <GPI>_down.sh for falling edge
The scripts will be invoked with two parameters, 1. the GPI id and 2. the new level (0 or 1).

SETUP

As usual, the GPIOs have to be configured in the system in order to use them. You can do this yourself (by writing the necessery values to /sys/class/gpio/...) or use the scripts provided in the archive:

  1. edit gpiod.conf so the list of GPIs and GPOs reflect your hardware setup
  2. run create_gpios.sh and run_gpiod.sh at startup (in that order!)

SOURCE

gpiod_v1.tgz 2013-09-04