5 Oct 2020

Pimoroni Automation-HAT Meets OpenEmbedded

Preamble

I found this device, the Automation-HAT by Pimoroni, which I thought might be fun for some HVAC experimenting I'd like to explore in the future. The creators of this Automation-HAT even provide a python library. Since I'm a fan of Yocto/OpenEmbedded (OE) I wanted to explore the steps in getting the Automation-HAT working with my own image instead of using, say, Raspberry Pi OS.

Master or Release?

Choosing between using master or basing on a release isn't easy when writing a blog post. On the one hand using a release can often be "safer", meaning a person stumbling into this post might have a greater chance of following along if everything is based on a "stable" release. But in my experience all software ages badly in blog posts, and working off of master is more fun for me. So master it is!

Getting Setup and First Build

There are lots of "Getting Started" guides for working with The Yocto Project or OpenEmbedded so if the following instructions skip too many steps, feel free to work through some of those other resources in order to get going.

Whenever I work on a technical project, I've always liked the approach of getting something working, and building from there. As such my first goal is to get a very basic image building and working on the device. Then we can start adding to what we know works, in order to build up to our goal.

For this Yocto build I'm going to start with poky. Since I'll be attaching this device to a Raspberry Pi (a Raspberry Pi 3, to be exact) I'll also need the OE BSP layer for that hardware. Create a fresh directory somewhere on your system to work and:

1
2
3
4
5
$ mkdir layers
$ pushd layers
$ git clone git://git.yoctoproject.org/poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi.git
$ popd

In my specific case the HEADs of these repositories are set at:

1
2
poky: 7cad26d585f67fa6bf873b8be361c6335a7db376
meta-raspberrypi: 6f85611576b7ccbfb6012631f741bd1daeffc9c9

Initialize your shell environment to get ready to build:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ . layers/poky/oe-init-build-env 
You had no conf/local.conf file. This configuration file has therefore been
created for you with some default values. You may wish to edit it to, for
example, select a different MACHINE (target hardware). See conf/local.conf
for more information as common configuration options are commented.

You had no conf/bblayers.conf file. This configuration file has therefore been
created for you with some default values. To add additional metadata layers
into your configuration please add entries to conf/bblayers.conf.

The Yocto Project has extensive documentation about OE including a reference
manual which can be found at:
    http://yoctoproject.org/documentation

For more information about OpenEmbedded see their website:
    http://www.openembedded.org/


### Shell environment set up for builds. ###

You can now run 'bitbake <target>'

Common targets are:
    core-image-minimal
    core-image-sato
    meta-toolchain
    meta-ide-support

You can also run generated qemu images with a command like 'runqemu qemux86'

Other commonly useful commands are:
 - 'devtool' and 'recipetool' handle common recipe tasks
 - 'bitbake-layers' handles common layer tasks
 - 'oe-pkgdata-util' handles common target package tasks

Make your build aware of the BSP layer:

1
2
$ bitbake-layers add-layer ../layers/meta-raspberrypi/
NOTE: Starting bitbake server...

When you initialized your shell earlier, it created a basic conf/local.conf template for you. You need to edit this file. The basic config file is filled with comments that can be quite useful. Stripping out the comments and adding/tweaking the build for my purposes I ended up with the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
MACHINE = "raspberrypi3-64"
DL_DIR = "/opt/Downloads"
DISTRO = "poky"

CORE_IMAGE_EXTRA_INSTALL += " \
        ${MACHINE_EXTRA_RRECOMMENDS} \
        wpa-supplicant \
        "

PACKAGECONFIG_append_pn-gdb = " tui"
PACKAGECONFIG_append_pn-gdb-cross-canadian-arm = " tui"

IMAGE_FSTYPES_append = " wic"
IMAGE_FSTYPES_remove = "wic.bz2 tar.bz2"
WARN_QA_append = " version-going-backwards"
ERROR_QA_remove = "version-going-backwards"
BB_DANGLINGAPPENDS_WARNONLY = "yes"
INHERIT += "buildhistory image-buildinfo buildstats-summary"
BUILDHISTORY_COMMIT = "1"

PACKAGE_CLASSES ?= "package_ipk"
SDKMACHINE = "x86_64"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS ??= "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    STOPTASKS,/tmp,100M,100K \
    ABORT,${TMPDIR},100M,1K \
    ABORT,${DL_DIR},100M,1K \
    ABORT,${SSTATE_DIR},100M,1K \
    ABORT,/tmp,10M,1K"
PACKAGECONFIG_append_pn-qemu-system-native = " sdl"
CONF_VERSION = "1"

  • Line 1: The MACHINE is set to "raspberrypi3-64" since that is the target I want from the set of machines that are defined in the meta-raspberrypi BSP.
  • Line 2: The DL_DIR points to a folder on my host machine which will be where all downloads for this build will be placed. You'll need to specify a location on your machine to which you have write access and which is large enough to store these downloads.
  • Line 3: I've chosen the poky DISTRO.
  • Lines 5-8: I want to add a couple things to my image so I include them here (the fact MACHINE_EXTRA_RRECOMMENDS isn't getting added by default to core-image-full-cmdline, I believe, is a bug, but we can work around it like this)
  • Lines 10-11: Whenever I used gdb I like to use its curses-based GUI mode. Therefore I've set some PACKAGECONFIGs to say that whenever gdb is built, please configure it for "tui" mode.
  • Line 13: Flashing wic images are much faster than flashing a non-wic image. Therefore I like to configure my µSD card builds to use wic.
  • Line 14: Since I'm not transferring these images over a network, or saving them for eternity on a drive somewhere, I don't care for them to be compressed; the compression stage at the end of a build just wastes time for me in this case.
  • Lines 15-16: Sometimes when building different revisions of git code, one SHA will be alphanumerically "lower" than a previous (in time) SHA. The build will flag this and error out thinking that you're downgrading a given piece of software. I like to add these lines to my builds to switch this from an error to a warning.
  • Line 17: Sometimes a layer includes metadata that appends to a recipe that doesn't exist anywhere in your build. This line switches this situation from an error to a warning.
  • Lines 18-19: I like using the buildhistory feature, as well as enabling other build metrics.
  • Line 21: I've set the PACKAGE_CLASS to ipk from poky's default of rpm
  • Line 22: I've set the SDKMACHINE to x86_64
  • Lines 23-36: Are taken from the template that is created when the build area is initialized by the oe-init-build-env script.

Now we build:
[NOTE: depending on the characteristics of your host machine and the speed of your connection to the internet, your initial build could take anywhere from 20 minutes to an hour or so]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
$ bitbake core-image-full-cmdline
Loading cache: 100% |                                                                                                                                                                          | ETA:  --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:09
Parsing of 814 .bb files complete (0 cached, 814 parsed). 1383 targets, 65 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "opensuseleap-15.1"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201017"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:03
Sstate summary: Wanted 1522 Found 0 Missed 1522 Current 0 (0% match, 0% complete)
NOTE: Executing Tasks
WARNING: linux-raspberrypi-1_5.4.69+gitAUTOINC+5d52d9eea9_31d364af25-r0 do_kernel_configcheck: [kernel config]: specified values did not make it into the kernel's final configuration:

    [NOTE]: 'CONFIG_I2C_BCM2835' last val (m) and .config val (y) do not match
    [INFO]: CONFIG_I2C_BCM2835 : y ## .config: 2783 :configs///defconfig (m) 
    [INFO]: raw config text:

        config I2C_BCM2835
                tristate "Broadcom BCM2835 I2C controller"
                depends on (ARCH_BCM2835 || ARCH_BRCMSTB) && HAS_IOMEM && I2C
                help
                  If you say yes to this option, support will be included for the
                  BCM2835 I2C controller.
          
                  If you don't know what to do here, say N.
          
                  This support is also available as a module.  If so, the module
                  will be called i2c-bcm2835.

        Config 'I2C_BCM2835' has the following Direct dependencies (I2C_BCM2835=y):
                ARCH_BCM2835(=y) || ARCH_BRCMSTB(=n) (=y) && HAS_IOMEM(=y) && I2C(=y)
        Parent dependencies are:
             HAS_IOMEM [y] ARCH_BRCMSTB [n] I2C [y] ARCH_BCM2835 [y]
    [NOTE]: 'CONFIG_DRM' last val (m) and .config val (y) do not match
    [INFO]: CONFIG_DRM : y ## .config: 4017 :configs///defconfig (m) 
    [INFO]: raw config text:

        menuconfig DRM
                tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
                select DRM_PANEL_ORIENTATION_QUIRKS
                select HDMI
                select FB_CMDLINE
                select I2C
               select I2C_ALGOBIT
                select DMA_SHARED_BUFFER
                select SYNC_FILE
                depends on (AGP || AGP = n) && !EMULATED_CMPXCHG && HAS_DMA && HAS_IOMEM
                help
                  Kernel-level support for the Direct Rendering Infrastructure (DRI)
                  introduced in XFree86 4.0. If you say Y here, you need to select
                  the module that's right for your graphics card from the list below.
                  These modules provide support for synchronization, security, and
                  DMA transfers. Please see <http://dri.sourceforge.net/> for more
                  details.  You should also select and configure AGP
                  (/dev/agpgart) support if it is available for your platform.

        Config 'DRM' has the following Direct dependencies (DRM=y):
                AGP(=n) || AGP(=n) = n (=y) && !EMULATED_CMPXCHG(undefined/n) (=y) && HAS_DMA(=y) && HAS_IOMEM(=y)
        Parent dependencies are:
             AGP [n] EMULATED_CMPXCHG [EMULATED_CMPXCHG] HAS_IOMEM [y] HAS_DMA [y]

NOTE: Tasks Summary: Attempted 3929 tasks of which 1 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 189 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 282 scratch)
NOTE:   do_deploy_source_date_epoch: 0.0% sstate reuse(0 setscene, 283 scratch)
NOTE:   do_package_qa: 0.0% sstate reuse(0 setscene, 166 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 166 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 166 scratch)
NOTE:   do_package_write_ipk: 0.0% sstate reuse(0 setscene, 166 scratch)
NOTE:   do_populate_lic: 0.0% sstate reuse(0 setscene, 285 scratch)

Summary: There was 1 WARNING message shown.

Now we write the resulting image to a µSD card. As I said earlier, I like to flash a "wic" image whenever possible. But before we can do that, we need to build the wic-flashing tool (bmap) so we can use it to flash the wic image to the µSD card:
[NOTE: this step only ever needs to be done once in a given build area]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ bitbake bmap-tools-native -caddto_recipe_sysroot
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:00
Loaded 1383 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201017"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:00
Sstate summary: Wanted 0 Found 0 Missed 0 Current 56 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 253 tasks of which 252 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds

Insert the µSD card into your host computer. You'll need to figure out where it appears in your computer so you can specify its location. The method I use is to check the system log. If I've just inserted the device, there will be an entry somewhere at the bottom of the system log indicating the fact a USB device was just inserted and it will specify where it shows up. In my case, when I insert a µSD device into my host via a USB reader, it shows up as /dev/sdk. In the examples below you'll have to replace where I write /dev/sdk with whatever path is valid for you.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ oe-run-native bmap-tools-native bmaptool copy tmp/deploy/images/raspberrypi3-64/core-image-full-cmdline-raspberrypi3-64.wic /dev/sdk
Running bitbake -e bmap-tools-native
bmaptool: info: discovered bmap file 'tmp/deploy/images/raspberrypi3-64/core-image-full-cmdline-raspberrypi3-64.wic.bmap'
bmaptool: info: block map format version 2.0
bmaptool: info: 87962 blocks of size 4096 (343.6 MiB), mapped 50393 blocks (196.8 MiB or 57.3%)
bmaptool: info: copying image 'core-image-full-cmdline-raspberrypi3-64.wic' to block device '/dev/sdk' using bmap file 'core-image-full-cmdline-raspberrypi3-64.wic.bmap'
bmaptool: WARNING: failed to disable excessive buffering, expect worse system responsiveness (reason: cannot set max. I/O ratio to 1: [Errno 13] Permission denied: '/sys/dev/block/8:160/bdi/max_ratio')
bmaptool: info: 100% copied
bmaptool: info: synchronizing '/dev/sdk'
bmaptool: info: copying time: 22.6s, copying speed 8.7 MiB/sec

Turning to the target device (i.e. the raspberrypi3) we fit the Automation-HAT to the Pi, wire up the serial console cable, and insert the µSD card.

Here are some pics of my setup:




On the host we watch the system log (again) to see where the serial console cable shows up (e.g. /dev/ttyUSB0) and start a terminal on that device (e.g. using screen, minicom, etc). Now we apply power to the target and… nothing.

As it turns out, we have to explicitly tell the raspberrypi that we want a serial console. This gets configured in the conf/local.conf as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
MACHINE = "raspberrypi3-64"
DL_DIR = "/opt/Downloads"
DISTRO = "poky"

ENABLE_UART = "1"

CORE_IMAGE_EXTRA_INSTALL += " \
        ${MACHINE_EXTRA_RRECOMMENDS} \
        wpa-supplicant \
        "

PACKAGECONFIG_append_pn-gdb = " tui"
PACKAGECONFIG_append_pn-gdb-cross-canadian-arm = " tui"

IMAGE_FSTYPES_append = " wic"
IMAGE_FSTYPES_remove = "wic.bz2 tar.bz2"
WARN_QA_append = " version-going-backwards"
ERROR_QA_remove = "version-going-backwards"
BB_DANGLINGAPPENDS_WARNONLY = "yes"
INHERIT += "buildhistory image-buildinfo buildstats-summary"
BUILDHISTORY_COMMIT = "1"

PACKAGE_CLASSES ?= "package_ipk"
SDKMACHINE = "x86_64"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS ??= "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    STOPTASKS,/tmp,100M,100K \
    ABORT,${TMPDIR},100M,1K \
    ABORT,${DL_DIR},100M,1K \
    ABORT,${SSTATE_DIR},100M,1K \
    ABORT,/tmp,10M,1K"
PACKAGECONFIG_append_pn-qemu-system-native = " sdl"
CONF_VERSION = "1"

Edit your conf/local.conf, rebuild the image, re-flash the image to your µSD card, insert the µSD card into the target, apply power and…

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
[    0.000000] Machine model: Raspberry Pi 3 Model B Rev 1.2
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] Reserved memory: created CMA memory pool at 0x000000001ec00000, size 256 MiB
[    0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
[    0.000000] percpu: Embedded 31 pages/cpu s88024 r8192 d30760 u126976
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: ARM erratum 845719
[    0.000000] CPU features: kernel page table isolation forced ON by KASLR
[    0.000000] CPU features: detected: Kernel page table isolation (KPTI)
[    0.000000] CPU features: detected: ARM erratum 843419
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 238896
[    0.000000] Kernel command line: coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1 video=Composite-1:720x480@60i vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000  dwc_otg.lpm_enable=0 console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstyt
[    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 669904K/970752K available (9724K kernel code, 1048K rwdata, 3320K rodata, 3072K init, 954K bss, 38704K reserved, 262144K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[    0.000000] ftrace: allocating 30859 entries in 121 pages
[    0.000000] rcu: Preemptible hierarchical RCU implementation.
[    0.000000]  Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] random: get_random_bytes called from start_kernel+0x334/0x4c4 with crng_init=0
[    0.000000] arch_timer: cp15 timer(s) running at 19.20MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns
[    0.000007] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns
[    0.000254] Console: colour dummy device 80x25
[    0.000323] Calibrating delay loop (skipped), value calculated using timer frequency.. 38.40 BogoMIPS (lpj=19200)
[    0.000350] pid_max: default: 32768 minimum: 301
[    0.000557] LSM: Security Framework initializing
[    0.000827] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.000863] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.002356] Disabling memory control group subsystem
[    0.004396] ASID allocator initialised with 32768 entries
[    0.004678] rcu: Hierarchical SRCU implementation.
[    0.005371] EFI services will not be available.
[    0.005935] smp: Bringing up secondary CPUs ...
[    0.007351] Detected VIPT I-cache on CPU1
[    0.007419] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.009359] Detected VIPT I-cache on CPU2
[    0.009410] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[    0.011221] Detected VIPT I-cache on CPU3
[    0.011268] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[    0.011885] smp: Brought up 1 node, 4 CPUs
[    0.011937] SMP: Total of 4 processors activated.
[    0.011957] CPU features: detected: 32-bit EL0 Support
[    0.011978] CPU features: detected: CRC32 instructions
[    0.037684] CPU: All CPU(s) started at EL2
[    0.037762] alternatives: patching kernel code
[    0.039583] devtmpfs: initialized
[    0.056561] Enabled cp15_barrier support
[    0.056610] Enabled setend support
[    0.057401] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
[    0.057438] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[    0.070451] pinctrl core: initialized pinctrl subsystem
[    0.070834] DMI not present or invalid.
[    0.071361] NET: Registered protocol family 16
[    0.080371] DMA: preallocated 1024 KiB pool for atomic allocations
[    0.080464] audit: initializing netlink subsys (disabled)
[    0.080858] audit: type=2000 audit(0.079:1): state=initialized audit_enabled=0 res=1
[    0.081662] cpuidle: using governor menu
[    0.081950] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.082313] Serial: AMBA PL011 UART driver
[    0.085113] bcm2835-mbox 3f00b880.mailbox: mailbox enabled
[    0.095260] raspberrypi-firmware soc:firmware: Attached to firmware from 2020-10-02 16:09, variant start
[    0.096274] raspberrypi-firmware soc:firmware: Firmware hash is 4672d0274057d726f3a327e2b3fe76f831b811bb
[    0.140930] bcm2835-dma 3f007000.dma: DMA legacy API manager, dmachans=0x1
[    0.143534] SCSI subsystem initialized
[    0.143880] usbcore: registered new interface driver usbfs
[    0.143957] usbcore: registered new interface driver hub
[    0.144141] usbcore: registered new device driver usb
[    0.145929] clocksource: Switched to clocksource arch_sys_counter
[    1.429264] VFS: Disk quotas dquot_6.6.0
[    1.429409] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.429643] FS-Cache: Loaded
[    1.430056] CacheFiles: Loaded
[    1.444000] thermal_sys: Registered thermal governor 'step_wise'
[    1.444462] NET: Registered protocol family 2
[    1.445522] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
[    1.445576] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    1.445702] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
[    1.445964] TCP: Hash tables configured (established 8192 bind 8192)
[    1.446214] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
[    1.446276] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
[    1.446645] NET: Registered protocol family 1
[    1.447835] RPC: Registered named UNIX socket transport module.
[    1.447855] RPC: Registered udp transport module.
[    1.447872] RPC: Registered tcp transport module.
[    1.447889] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    1.449642] hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7 counters available
[    1.452049] Initialise system trusted keyrings
[    1.452478] workingset: timestamp_bits=46 max_order=18 bucket_order=0
[    1.466411] FS-Cache: Netfs 'nfs' registered for caching
[    1.467485] NFS: Registering the id_resolver key type
[    1.467593] Key type id_resolver registered
[    1.467612] Key type id_legacy registered
[    1.467643] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    1.469406] Key type asymmetric registered
[    1.469429] Asymmetric key parser 'x509' registered
[    1.469494] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
[    1.469517] io scheduler mq-deadline registered
[    1.469536] io scheduler kyber registered
[    1.478032] Serial: 8250/16550 driver, 1 ports, IRQ sharing enabled
[    1.481110] bcm2835-rng 3f104000.rng: hwrng registered
[    1.481721] vc-mem: phys_addr:0x00000000 mem_base=0x3ec00000 mem_size:0x40000000(1024 MiB)
[    1.482825] gpiomem-bcm2835 3f200000.gpiomem: Initialised: Registers at 0x3f200000
[    1.483358] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    1.499607] brd: module loaded
[    1.517239] loop: module loaded
[    1.518966] Loading iSCSI transport class v2.0-870.
[    1.520136] libphy: Fixed MDIO Bus: probed
[    1.520290] usbcore: registered new interface driver lan78xx
[    1.520369] usbcore: registered new interface driver smsc95xx
[    1.520399] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)
[    2.249221] Core Release: 2.80a
[    2.249243] Setting default values for core params
[    2.249280] Finished setting default values for core params
[    2.449973] Using Buffer DMA mode
[    2.449993] Periodic Transfer Interrupt Enhancement - disabled
[    2.450010] Multiprocessor Interrupt Enhancement - disabled
[    2.450029] OTG VER PARAM: 0, OTG VER FLAG: 0
[    2.450052] Dedicated Tx FIFOs mode
[    2.451562] WARN::dwc_otg_hcd_init:1072: FIQ DMA bounce buffers: virt = ffffffc010251000 dma = 0x00000000ded00000 len=9024
[    2.451597] FIQ FSM acceleration enabled for :
[    2.451597] Non-periodic Split Transactions
[    2.451597] Periodic Split Transactions
[    2.451597] High-Speed Isochronous Endpoints
[    2.451597] Interrupt/Control Split Transaction hack enabled
[    2.451660] WARN::hcd_init_fiq:496: MPHI regs_base at ffffffc01005d000
[    2.451711] dwc_otg 3f980000.usb: DWC OTG Controller
[    2.451755] dwc_otg 3f980000.usb: new USB bus registered, assigned bus number 1
[    2.451830] dwc_otg 3f980000.usb: irq 9, io mem 0x00000000
[    2.451886] Init: Port Power? op_state=1
[    2.451933] Init: Power Port (0)
[    2.452382] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.04
[    2.452407] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    2.452429] usb usb1: Product: DWC OTG Controller
[    2.452451] usb usb1: Manufacturer: Linux 5.4.69-v8 dwc_otg_hcd
[    2.452472] usb usb1: SerialNumber: 3f980000.usb
[    2.453459] hub 1-0:1.0: USB hub found
[    2.453542] hub 1-0:1.0: 1 port detected
[    2.455546] usbcore: registered new interface driver usb-storage
[    2.457384] bcm2835-wdt bcm2835-wdt: Broadcom BCM2835 watchdog timer
[    2.461090] sdhci: Secure Digital Host Controller Interface driver
[    2.461110] sdhci: Copyright(c) Pierre Ossman
[    2.461765] mmc-bcm2835 3f300000.mmcnr: could not get clk, deferring probe
[    2.462539] sdhost-bcm2835 3f202000.mmc: could not get clk, deferring probe
[    2.462837] sdhci-pltfm: SDHCI platform and OF driver helper
[    2.464815] ledtrig-cpu: registered to indicate activity on CPUs
[    2.465298] hidraw: raw HID events driver (C) Jiri Kosina
[    2.465494] usbcore: registered new interface driver usbhid
[    2.465512] usbhid: USB HID core driver
[    2.466076] ashmem: initialized
[    2.466719] Initializing XFRM netlink socket
[    2.466774] NET: Registered protocol family 17
[    2.466984] Key type dns_resolver registered
[    2.467565] registered taskstats version 1
[    2.467596] Loading compiled-in X.509 certificates
[    2.468032] Key type ._fscrypt registered
[    2.468052] Key type .fscrypt registered
[    2.484212] uart-pl011 3f201000.serial: cts_event_workaround enabled
[    2.484349] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 66, base_baud = 0) is a PL011 rev2
[    2.487448] printk: console [ttyS0] disabled
[    2.487542] 3f215040.serial: ttyS0 at MMIO 0x0 (irq = 61, base_baud = 50000000) is a 16550
[    3.473145] printk: console [ttyS0] enabled
[    3.478603] bcm2835-power bcm2835-power: Broadcom BCM2835 power domains driver
[    3.487779] mmc-bcm2835 3f300000.mmcnr: mmc_debug:0 mmc_debug2:0
[    3.493937] mmc-bcm2835 3f300000.mmcnr: DMA channel allocated
[    3.526207] sdhost: log_buf @ (____ptrval____) (f8e51000)
[    3.551613] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
[    3.558881] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
[    3.566201] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
[    3.574850] mmc1: queuing unknown CIS tuple 0x80 (7 bytes)
[    3.585510] Indeed it is in host mode hprt0 = 00021501
[    3.592974] mmc0: sdhost-bcm2835 loaded - DMA enabled (>1)
[    3.602767] of_cfs_init
[    3.605452] of_cfs_init: OK
[    3.610371] Waiting for root device /dev/mmcblk0p2...
[    3.664973] random: fast init done
[    3.729776] mmc1: new high speed SDIO card at address 0001
[    3.747467] mmc0: host does not support reading read-only switch, assuming write-enable
[    3.762580] mmc0: new high speed SDHC card at address aaaa
[    3.769519] mmcblk0: mmc0:aaaa SL16G 14.8 GiB
[    3.774047] usb 1-1: new high-speed USB device number 2 using dwc_otg
[    3.780896] Indeed it is in host mode hprt0 = 00001101
[    3.797189]  mmcblk0: p1 p2
[    3.815991] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[    3.824333] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[    3.835841] devtmpfs: mounted
[    3.848102] Freeing unused kernel memory: 3072K
[    3.852800] Run /sbin/init as init process
INIT: version 2.97 booting
[    3.978789] usb 1-1: New USB device found, idVendor=0424, idProduct=9514, bcdDevice= 2.00
[    3.987214] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    3.995769] hub 1-1:1.0: USB hub found
[    3.999985] hub 1-1:1.0: 5 ports detected
Framebuffer /dev/fb0 not detected
Boot splashscreen disabled
[    4.293048] usb 1-1.1: new high-speed USB device number 3 using dwc_otg
[    4.388594] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00, bcdDevice= 2.00
[    4.397199] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    4.408145] smsc95xx v1.0.6
[    4.460223] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-3f980000.usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:fd:e3:45
Starting udev
[    4.701746] udevd[119]: starting version 3.2.9
[    4.738668] random: udevd: uninitialized urandom read (16 bytes read)
[    4.746220] random: udevd: uninitialized urandom read (16 bytes read)
[    4.758069] random: udevd: uninitialized urandom read (16 bytes read)
[    4.808414] udevd[120]: starting eudev-3.2.9
[    4.911884] random: crng init done
[    4.915359] random: 3 urandom warning(s) missed due to ratelimiting
[    4.970283] vchiq: module is from the staging directory, the quality is unknown, you have been warned.
[    4.998866] vchiq: vchiq_init_state: slot_zero = 00000000ae5c87c4
[    5.197187] vc_sm_cma: module is from the staging directory, the quality is unknown, you have been warned.
[    5.206689] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    5.216350] bcm2835_vc_sm_cma_probe: Videocore shared memory driver
[    5.222796] [vc_sm_connected_init]: start
[    5.228112] [vc_sm_connected_init]: installed successfully
[    5.234222] snd_bcm2835: module is from the staging directory, the quality is unknown, you have been warned.
[    5.251418] bcm2835_audio bcm2835_audio: card created with 8 channels
[    5.270497] mc: Linux media interface: v0.10
[    5.330355] videodev: Linux video capture interface: v2.00
[    5.342758] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    5.352409] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[    5.361291] cfg80211: failed to load regulatory.db
[    5.374974] vc4-drm soc:gpu: bound 3f600000.firmwarekms (ops vc4_fkms_ops [vc4])
[    5.382958] vc4-drm soc:gpu: bound 3fc00000.v3d (ops vc4_v3d_ops [vc4])
[    5.389812] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    5.396598] [drm] No driver support for vblank timestamp query.
[    5.402747] [drm] Setting vblank_disable_immediate to false because get_vblank_timestamp == NULL
[    5.413321] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
[    5.478261] bcm2835_mmal_vchiq: module is from the staging directory, the quality is unknown, you have been warned.
[    5.478633] bcm2835_mmal_vchiq: module is from the staging directory, the quality is unknown, you have been warned.
[    5.479494] bcm2835_mmal_vchiq: module is from the staging directory, the quality is unknown, you have been warned.
[    5.481108] Console: switching to colour frame buffer device 90x30
[    5.496212] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
[    5.496585] usbcore: registered new interface driver brcmfmac
[    5.550829] vc4-drm soc:gpu: fb0: vc4drmfb frame buffer device
[    5.561091] bcm2835_v4l2: module is from the staging directory, the quality is unknown, you have been warned.
[    5.598697] bcm2835_codec: module is from the staging directory, the quality is unknown, you have been warned.
[    5.609303] bcm2835_isp: module is from the staging directory, the quality is unknown, you have been warned.
[    5.624981] bcm2835-codec bcm2835-codec: Device registered as /dev/video10
[    5.625067] bcm2835-codec bcm2835-codec: Loaded V4L2 decode
[    5.639147] bcm2835-isp bcm2835-isp: Device node output[0] registered as /dev/video13
[    5.647793] bcm2835-isp bcm2835-isp: Device node capture[0] registered as /dev/video14
[    5.656481] bcm2835-isp bcm2835-isp: Device node capture[1] registered as /dev/video15
[    5.656588] bcm2835-codec bcm2835-codec: Device registered as /dev/video11
[    5.665123] bcm2835-isp bcm2835-isp: Device node stats[2] registered as /dev/video16
[    5.671659] bcm2835-codec bcm2835-codec: Loaded V4L2 encode
[    5.679485] bcm2835-isp bcm2835-isp: Register output node 0 with media controller
[    5.679507] bcm2835-isp bcm2835-isp: Register capture node 1 with media controller
[    5.679526] bcm2835-isp bcm2835-isp: Register capture node 2 with media controller
[    5.708379] bcm2835-isp bcm2835-isp: Register capture node 3 with media controller
[    5.716471] bcm2835-isp bcm2835-isp: Loaded V4L2 bcm2835-isp
[    5.723339] bcm2835-codec bcm2835-codec: Device registered as /dev/video12
[    5.730762] bcm2835-codec bcm2835-codec: Loaded V4L2 isp
[    5.837048] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[    5.860586] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
[    5.869718] brcmfmac: brcmf_c_process_clm_blob: no clm_blob available (err=-2), device may have limited channels available
[    5.882177] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Oct 22 2019 01:59:28 version 7.45.98.94 (r723000 CY) FWID 01-3b33decd
Fri Mar  9 12:34:56 UTC 2018
chmod: cannot access '/var/log/wtmp': No such file or directory
Failed to set mode -0664- for -/var/log/wtmp-.
Configuring packages on first boot....
 (This may take several minutes. Please do not power off the machine.)
Running postinst /etc/ipk-postinsts/000-sysvinit-inittab...
update-rc.d: /etc/init.d/run-postinsts exists during rc.d purge (continuing)
 Removing any system startup links for run-postinsts ...
  /etc/rcS.d/S99run-postinsts
INIT: Entering runlevel: 5
Configuring network interfaces... [    7.341201] smsc95xx 1-1.1:1.0 eth0: hardware isn't capable of remote wakeup
udhcpc: started, v1.32.0
udhcpc: sending discover
udhcpc: sending discover
udhcpc: sending discover
udhcpc: no lease, forking to background
done.
Starting system message bus: dbus.
Starting random number generator daemon.
Starting OpenBSD Secure Shell server: sshd
  generating ssh RSA host key...
  generating ssh ECDSA host key...
  generating ssh ED25519 host key...
[   21.472551] NET: Registered protocol family 10
[   21.486542] Segment Routing with IPv6
done.
Starting rpcbind daemon...done.
starting statd: done
Starting atd: OK
[   21.992880] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
starting 8 nfsd kernel threads: [   23.151164] NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory
[   23.163714] NFSD: Using legacy client tracking operations.
[   23.169445] NFSD: starting 90-second grace period (net f00004c1)
done
starting mountd: done
Starting system log daemon...0
Starting crond: OK
umount: /mnt/.psplash: no mount point specified.

Poky (Yocto Project Reference Distro) 3.1+snapshot raspberrypi3-64 ttyS0

raspberrypi3-64 login: 

Good! Now we have a solid base on which to work with our device!

Adding Software

As I mentioned earlier, the Pimoroni Automation-HAT comes with a python library to help you get up and running with your device. But how do you get that library onto the device? In theory you could install pip (and whatever it requires) into your image, run that image on the device, connect the device to the internet, and install the library by hand. But this isn't what we want. We don't want to generate a partial image that then needs manual intervention in the production stage. What if we were preparing 20 such devices? The moment human intervention is involved, the chances for errors goes up… significantly! What happens when all our devices are provisioned and we then discover we need to make a fix or add more steps?

What we want is a way to build a fully complete master image on the host that has all the software we need with everything configured and ready to go. Flash a µSD card, insert it into the device, add power, and it's up and running. Not: flash the µSD card, insert it into the device, log into the device, make sure the network is running, run a bunch of comands by hand…

The way we add things to an OpenEmbedded image is to create a recipe. OE layers are full of recipes. There are thousands and thousands of recipes for all sorts of software and situations. The first thing we do is to check to see if someone else had already written a recipe for the software we want to add. To do this we check the layer index: http://layers.openembedded.org/. Select Recipes, enter a string, and click search. Unfortunately there doesn't seem to be any pre-existing recipes for us.

We could just write a recipe from scratch. But before resorting to that scenario, we could use devtool. Devtool is a tool that is part of OpenEmbedded that helps users to create and maintain recipes. Before asking devtool to create the recipe for us, we have to understand what it is we want to build. We start off by visiting the code's website: https://github.com/pimoroni/automation-hat


Along the right-hand side, we see that this project has produced releases, but that the last release was about 5 months ago. There have been 8 commits since the last release. Therefore I think it would be best to work from the master branch's HEAD commit instead of the release.

Continuing to work in the same shell that was setup earlier, the same one we've been using to bitbake all our builds so far:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ devtool add --srcrev a41084cb4db02b76fc536235321a613d1c88ba52 automation-hat https://github.com/pimoroni/automation-hat.git
NOTE: Starting bitbake server...
INFO: Creating workspace layer in /z/build-master/6951/automation-hat/poky/build/workspace
NOTE: Starting bitbake server...
INFO: Fetching git://github.com/pimoroni/automation-hat.git;protocol=https;nobranch=1...
Loading cache: 100% |                                                                                                                                                                          | ETA:  --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:06
Parsing of 815 .bb files complete (0 cached, 815 parsed). 1384 targets, 65 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "<unknown>:<unknown>"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:00
Sstate summary: Wanted 0 Found 0 Missed 0 Current 0 (0% match, 0% complete)
NOTE: No setscene tasks
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 0 seconds
INFO: Using default source tree path /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat
NOTE: Starting bitbake server...
INFO: Using source tree as build directory since that would be the default for this recipe
INFO: Recipe /z/build-master/6951/automation-hat/poky/build/workspace/recipes/automation-hat/automation-hat_git.bb has been automatically created; further editing may be required to make it fully functional

As the comment says, we should take a look at what devtool created to see if it needs any tweaking. But where do we find the recipe devtool just created? Technically devtool created a workspace for you and put the recipe there. But we don't even need to know that detail since we can just let devtool do all the work:

1
$ devtool edit-recipe automation-hat

Devtool will locate the recipe for you and open it in your $EDITOR. As we can see devtool created some parts of the recipe, but it only did a so-so job. It doesn't appear to know how to handle this python library particularly well:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
#
# The following license files were not able to be identified and are
# represented as "Unknown" below, you will need to check them yourself:
#   packaging/debian/copyright
#
# NOTE: multiple licenses have been detected; they have been separated with &
# in the LICENSE value for now since it is a reasonable assumption that all
# of the licenses apply. If instead there is a choice between the multiple
# licenses then you should change the value to separate the licenses with |
# instead of &. If there is any doubt, check the accompanying documentation
# to determine which situation is applicable.
LICENSE = "MIT & Unknown"
LIC_FILES_CHKSUM = "file://LICENSE;md5=1be647ba1f2b40ff716e997a3e4a0d47 \
                    file://library/LICENSE.txt;md5=1be647ba1f2b40ff716e997a3e4a0d47 \
                    file://packaging/debian/copyright;md5=711b00d4d30e94965c8a959ae574dcc2"

SRC_URI = "git://github.com/pimoroni/automation-hat.git;protocol=https"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "a41084cb4db02b76fc536235321a613d1c88ba52"

S = "${WORKDIR}/git"

# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the
# recipe automatically - you will need to examine the Makefile yourself and ensure
# that the appropriate arguments are passed in.

do_configure () {
        # Specify any needed configure commands here
        :
}

do_compile () {
        # You will almost certainly need to add additional arguments here
        oe_runmake
}

do_install () {
        # This is a guess; additional arguments may be required
        oe_runmake install
}

Good recipes should have a SUMMARY, a DESCRIPTION, and a HOMEPAGE tag (among others). Also, experience dictates that OpenEmbedded includes many recipes for dealing with python libraries. Chances are good there's already a bbclass that takes care of this situation. A little investigation leads to the setuptools3 class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
SUMMARY = "Pimoroni Automation-HAT python library"
DESCRIPTION = "Automation HAT is a home monitoring and automation controller \
featuring relays, analog channels, powered outputs, and buffered inputs \
(all 24V tolerant)."
HOMEPAGE = "https://shop.pimoroni.com/products/automation-hat"
SECTION = "iot/python"
LICENSE = "MIT & Unknown"
LIC_FILES_CHKSUM = "file://LICENSE;md5=1be647ba1f2b40ff716e997a3e4a0d47 \
                    file://library/LICENSE.txt;md5=1be647ba1f2b40ff716e997a3e4a0d47 \
                    file://packaging/debian/copyright;md5=711b00d4d30e94965c8a959ae574dcc2"

SRC_URI = "git://github.com/pimoroni/automation-hat.git;protocol=https"

PV = "1.0+git${SRCPV}"
SRCREV = "a41084cb4db02b76fc536235321a613d1c88ba52"

S = "${WORKDIR}/git"

inherit setuptools3

Now we try building:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
$ devtool build automation-hat
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:00
Loaded 1384 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 815 .bb files complete (814 cached, 1 parsed). 1384 targets, 65 skipped, 0 masked, 0 errors.
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:01
Loaded 1384 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 815 .bb files complete (814 cached, 1 parsed). 1384 targets, 65 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:01
Sstate summary: Wanted 0 Found 0 Missed 0 Current 190 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: automation-hat: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat
ERROR: automation-hat-1.0+git999-r0 do_compile: 'python3 setup.py build ' execution failed.
ERROR: automation-hat-1.0+git999-r0 do_compile: Execution of '/z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069' failed with exit code 1:
/z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/recipe-sysroot-native/usr/bin/python3-native/python3: can't open file '/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/setup.py': [Errno 2] No such file or directory
WARNING: /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069:175 exit 1 from 'exit 1'
WARNING: Backtrace (BB generated script): 
        #1: bbfatal_log, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 175
        #2: distutils3_do_compile, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 165
        #3: do_compile, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 154
        #4: main, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 179

Backtrace (metadata-relative locations):
        #1: bbfatal_log, /opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta/classes/logging.bbclass, line 72
        #2: distutils3_do_compile, /opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta/classes/distutils3.bbclass, line 26
        #3: do_compile, autogenerated, line 2
ERROR: Logfile of failure stored in: /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/log.do_compile.16069
Log data follows:
| DEBUG: Executing python function externalsrc_compile_prefunc
| NOTE: automation-hat: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat
| DEBUG: Python function externalsrc_compile_prefunc finished
| DEBUG: Executing shell function do_compile
| /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/recipe-sysroot-native/usr/bin/python3-native/python3: can't open file '/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/setup.py': [Errno 2] No such file or directory
| ERROR: 'python3 setup.py build ' execution failed.
| WARNING: /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069:175 exit 1 from 'exit 1'
| WARNING: Backtrace (BB generated script):
|       #1: bbfatal_log, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 175
|       #2: distutils3_do_compile, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 165
|       #3: do_compile, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 154
|       #4: main, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 179
| ERROR: Execution of '/z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069' failed with exit code 1:
| /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/recipe-sysroot-native/usr/bin/python3-native/python3: can't open file '/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/setup.py': [Errno 2] No such file or directory
| WARNING: /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069:175 exit 1 from 'exit 1'
| WARNING: Backtrace (BB generated script):
|       #1: bbfatal_log, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 175
|       #2: distutils3_do_compile, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 165
|       #3: do_compile, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 154
|       #4: main, /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp/run.do_compile.16069, line 179
| 
| Backtrace (metadata-relative locations):
|       #1: bbfatal_log, /opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta/classes/logging.bbclass, line 72
|       #2: distutils3_do_compile, /opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta/classes/distutils3.bbclass, line 26
|       #3: do_compile, autogenerated, line 2
ERROR: Task (/z/build-master/6951/automation-hat/poky/build/workspace/recipes/automation-hat/automation-hat_git.bb:do_compile) failed with exit code '1'
NOTE: Tasks Summary: Attempted 723 tasks of which 719 didn't need to be rerun and 1 failed.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds
NOTE: Build completion summary:
NOTE:   do_deploy_source_date_epoch: 0.0% sstate reuse(0 setscene, 1 scratch)

Summary: 1 task failed:
  /z/build-master/6951/automation-hat/poky/build/workspace/recipes/automation-hat/automation-hat_git.bb:do_compile
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.

Looking through the error message we can see that the setuptools3 bbclass is not able to find the setup.py file from the library. Looking through the sources we see that the setup.py file is found in the library subdirectory. Therefore we edit the recipe again and tweak:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
SUMMARY = "Pimoroni Automation-HAT python library"
DESCRIPTION = "Automation HAT is a home monitoring and automation controller \
featuring relays, analog channels, powered outputs, and buffered inputs \
(all 24V tolerant)."
HOMEPAGE = "https://shop.pimoroni.com/products/automation-hat"
SECTION = "iot/python"
LICENSE = "MIT & Unknown"
LIC_FILES_CHKSUM = "file://LICENSE;md5=1be647ba1f2b40ff716e997a3e4a0d47 \
                    file://library/LICENSE.txt;md5=1be647ba1f2b40ff716e997a3e4a0d47 \
                    file://packaging/debian/copyright;md5=711b00d4d30e94965c8a959ae574dcc2"

SRC_URI = "git://github.com/pimoroni/automation-hat.git;protocol=https"

PV = "1.0+git${SRCPV}"
SRCREV = "a41084cb4db02b76fc536235321a613d1c88ba52"

S = "${WORKDIR}/git/library"

inherit setuptools3

We build again… and we get the same error? Now we need to dig a little deeper. If we've modified the S variable explicitly, why is the build still looking in the old location? Now we ask bitbake to explain itself: "bitbake what do you know about the S variable?":

1
2
$ bitbake automation-hat -e | grep "^S="
S="/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat"

This is very perplexing. We're setting the S variable explicitly in our recipe, but something is overriding it. If we look deeper into the workspace directory that devtool creates for us, we find:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
$ tree workspace
workspace
├── README
├── appends
│   └── automation-hat_git.bbappend
├── conf
│   └── layer.conf
├── recipes
│   └── automation-hat
│       └── automation-hat_git.bb
└── sources
    └── automation-hat
        ├── LICENSE
        ├── Makefile
        ├── README.md
        ├── autohat_360.png
        ├── documentation
        │   └── REFERENCE.md
        ├── examples
        │   ├── hat
        │   │   ├── analog.py
        │   │   ├── input.py
        │   │   ├── lights.py
        │   │   ├── output.py
        │   │   └── relay.py
        │   └── hat-mini
        │       ├── analog.py
        │       ├── images
        │       │   ├── analog-inputs-blank.jpg
        │       │   ├── inputs-blank.jpg
        │       │   └── outputs-blank.jpg
        │       ├── input.py
        │       └── output.py
        ├── library
        │   ├── CHANGELOG.txt
        │   ├── LICENSE.txt
        │   ├── MANIFEST.in
        │   ├── README.rst
        │   ├── automationhat
        │   │   ├── __init__.py
        │   │   ├── ads1015.py
        │   │   └── pins.py
        │   ├── setup.py
        │   ├── test.py
        │   ├── tests
        │   │   └── test_setup.py
        │   └── tox.ini
        ├── oe-logs -> /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0/temp
        ├── oe-workdir -> /z/build-master/6951/automation-hat/poky/build/tmp/work/cortexa53-poky-linux/automation-hat/1.0+git999-r0
        ├── packaging
        │   ├── CHANGELOG
        │   ├── debian
        │   │   ├── README
        │   │   ├── changelog
        │   │   ├── clean
        │   │   ├── compat
        │   │   ├── control
        │   │   ├── copyright
        │   │   ├── docs
        │   │   ├── rules
        │   │   └── source
        │   │       ├── format
        │   │       └── options
        │   ├── makeall.sh
        │   ├── makedeb.sh
        │   └── makelog.sh
        └── terminal.jpg

19 directories, 46 files

Snooping around in the workspace I'm curious about the bbappend:

1
2
3
4
5
6
$ cat workspace/appends/automation-hat_git.bbappend
inherit externalsrc
EXTERNALSRC = "/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat"
EXTERNALSRC_BUILD = "/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat"

# initial_rev: a41084cb4db02b76fc536235321a613d1c88ba52

It's pulling in the externalsrc bbclass. I wonder what the externalsrc bbclass does and whether or not it plays with the S variable? Turns out it does! Looking at the top part of the externalsrc bbclass:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# Copyright (C) 2012 Linux Foundation
# Author: Richard Purdie
# Some code and influence taken from srctree.bbclass:
# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
# Released under the MIT license (see COPYING.MIT for the terms)
#
# externalsrc.bbclass enables use of an existing source tree, usually external to
# the build system to build a piece of software rather than the usual fetch/unpack/patch
# process.
#
# To use, add externalsrc to the global inherit and set EXTERNALSRC to point at the
# directory you want to use containing the sources e.g. from local.conf for a recipe
# called "myrecipe" you would do:
#
# INHERIT += "externalsrc"
# EXTERNALSRC_pn-myrecipe = "/path/to/my/source/tree"
#
# In order to make this class work for both target and native versions (or with
# multilibs/cross or other BBCLASSEXTEND variants), B is set to point to a separate
# directory under the work directory (split source and build directories). This is
# the default, but the build directory can be set to the source directory if
# circumstances dictate by setting EXTERNALSRC_BUILD to the same value, e.g.:
#
# EXTERNALSRC_BUILD_pn-myrecipe = "/path/to/my/source/tree"
#

SRCTREECOVEREDTASKS ?= "do_patch do_unpack do_fetch"
EXTERNALSRC_SYMLINKS ?= "oe-workdir:${WORKDIR} oe-logs:${T}"

python () {
    externalsrc = d.getVar('EXTERNALSRC')
    externalsrcbuild = d.getVar('EXTERNALSRC_BUILD')

    if externalsrc and not externalsrc.startswith("/"):
        bb.error("EXTERNALSRC must be an absolute path")
    if externalsrcbuild and not externalsrcbuild.startswith("/"):
        bb.error("EXTERNALSRC_BUILD must be an absolute path")

    # If this is the base recipe and EXTERNALSRC is set for it or any of its
    # derivatives, then enable BB_DONT_CACHE to force the recipe to always be
    # re-parsed so that the file-checksums function for do_compile is run every
    # time.
    bpn = d.getVar('BPN')
    classextend = (d.getVar('BBCLASSEXTEND') or '').split()
    if bpn == d.getVar('PN') or not classextend:
        if (externalsrc or
                ('native' in classextend and 
                 d.getVar('EXTERNALSRC_pn-%s-native' % bpn)) or
                ('nativesdk' in classextend and 
                 d.getVar('EXTERNALSRC_pn-nativesdk-%s' % bpn)) or
                ('cross' in classextend and 
                 d.getVar('EXTERNALSRC_pn-%s-cross' % bpn))):
            d.setVar('BB_DONT_CACHE', '1')

    if externalsrc:
        import oe.recipeutils
        import oe.path

        d.setVar('S', externalsrc)
        if externalsrcbuild:
            d.setVar('B', externalsrcbuild)
        else:
            d.setVar('B', '${WORKDIR}/${BPN}-${PV}/')

…

We can see on line 59 that the S variable is being set to externalsrc, which is being set on line 31 to the value of EXTERNALSRC which it finds in the automation-hat.bbappend file. Therefore if we tweak the automation-hat.bbappend file it should be able to find our setup.py code:

1
2
3
4
5
6
$ cat workspace/appends/automation-hat_git.bbappend 
inherit externalsrc
EXTERNALSRC = "/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/library"
EXTERNALSRC_BUILD = "/z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/library"

# initial_rev: a41084cb4db02b76fc536235321a613d1c88ba52

and build:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$ devtool build automation-hat
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:00
Loaded 1384 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 815 .bb files complete (814 cached, 1 parsed). 1384 targets, 65 skipped, 0 masked, 0 errors.
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:01
Loaded 1384 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 815 .bb files complete (814 cached, 1 parsed). 1384 targets, 65 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:01
Sstate summary: Wanted 0 Found 0 Missed 0 Current 190 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: automation-hat: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/library
NOTE: Tasks Summary: Attempted 727 tasks of which 721 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 0 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 1 scratch)

Phew!

However, this isn't the "correct" solution. Turns out devtool has an option for this very situation (i.e. the setup.py not being in the top-level directory of a repository). If we look at the options available for devtool add we find:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ devtool add
NOTE: Starting bitbake server...
devtool add: error: At least one of recipename, srctree, fetchuri or -f/--fetch must be specified
usage: devtool add [-h] [--same-dir | --no-same-dir] [--fetch URI] [--npm-dev]
                   [--version VERSION] [--no-git]
                   [--srcrev SRCREV | --autorev] [--srcbranch SRCBRANCH]
                   [--binary] [--also-native] [--src-subdir SUBDIR]
                   [--mirrors] [--provides PROVIDES]
                   [recipename] [srctree] [fetchuri]

Adds a new recipe to the workspace to build a specified source tree. Can
optionally fetch a remote URI and unpack it to create the source tree.

arguments:
  recipename            Name for new recipe to add (just name - no version,
                        path or extension). If not specified, will attempt to
                        auto-detect it.
  srctree               Path to external source tree. If not specified, a
                        subdirectory of /z/build-master/6951/automation-
                        hat/build/workspace/sources will be used.
  fetchuri              Fetch the specified URI and extract it to create the
                        source tree

options:
  -h, --help            show this help message and exit
  --same-dir, -s        Build in same directory as source
  --no-same-dir         Force build in a separate build directory
  --fetch URI, -f URI   Fetch the specified URI and extract it to create the
                        source tree (deprecated - pass as positional argument
                        instead)
  --npm-dev             For npm, also fetch devDependencies
  --version VERSION, -V VERSION
                        Version to use within recipe (PV)
  --no-git, -g          If fetching source, do not set up source tree as a git
                        repository
  --srcrev SRCREV, -S SRCREV
                        Source revision to fetch if fetching from an SCM such
                        as git (default latest)
  --autorev, -a         When fetching from a git repository, set SRCREV in the
                        recipe to a floating revision instead of fixed
  --srcbranch SRCBRANCH, -B SRCBRANCH
                        Branch in source repository if fetching from an SCM
                        such as git (default master)
  --binary, -b          Treat the source tree as something that should be
                        installed verbatim (no compilation, same directory
                        structure). Useful with binary packages e.g. RPMs.
  --also-native         Also add native variant (i.e. support building recipe
                        for the build host as well as the target machine)
  --src-subdir SUBDIR   Specify subdirectory within source tree to use
  --mirrors             Enable PREMIRRORS and MIRRORS for source tree fetching
                        (disable by default).
  --provides PROVIDES, -p PROVIDES
                        Specify an alias for the item provided by the recipe.
                        E.g. virtual/libgl

So let's try creating the recipe again with the --src-subdir option:

1
2
3
$ devtool add --srcrev a41084cb4db02b76fc536235321a613d1c88ba52 --src-subdir library automation-hat https://github.com/pimoroni/automation-hat.git
NOTE: Starting bitbake server...
ERROR: recipe automation-hat is already in your workspace

We have to clean out the workspace before we can try again (if we want to use the same recipe name):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
$ devtool reset automation-hat
NOTE: Starting bitbake server...
INFO: Cleaning sysroot for recipe automation-hat...
WARNING: File automation-hat_git.bb modified since it was written, preserving in /z/build-master/6951/automation-hat/poky/build/workspace/attic/automation-hat
WARNING: File automation-hat_git.bbappend modified since it was written, preserving in /z/build-master/6951/automation-hat/poky/build/workspace/attic/automation-hat
INFO: Leaving source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/library as-is; if you no longer need it then please delete it manually

$ rm -fr workspace/sources/automation-hat/

$ devtool add --srcrev a41084cb4db02b76fc536235321a613d1c88ba52 --src-subdir library automation-hat https://github.com/pimoroni/automation-hat.git
NOTE: Starting bitbake server...
NOTE: Starting bitbake server...
INFO: Fetching git://github.com/pimoroni/automation-hat.git;protocol=https;nobranch=1...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:01
Loaded 1384 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 815 .bb files complete (814 cached, 1 parsed). 1384 targets, 65 skipped, 0 masked, 0 errors.
Removing 1 recipes from the cortexa53 sysroot: 100% |###########################################################################################################################################| Time: 0:00:00
Removing 1 recipes from the raspberrypi3_64 sysroot: 100% |#####################################################################################################################################| Time: 0:00:00
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:00
Sstate summary: Wanted 0 Found 0 Missed 0 Current 0 (0% match, 0% complete)
NOTE: No setscene tasks
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds
INFO: Scanning paths for packages & dependencies: automationhat
INFO: Using default source tree path /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat
WARNING: A modified recipe from a previous invocation exists in /z/build-master/6951/automation-hat/poky/build/workspace/attic/automation-hat/automation-hat_git.bb - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Reconnecting to bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Retrying server connection (#1)...
NOTE: Starting bitbake server...
INFO: Recipe /z/build-master/6951/automation-hat/poky/build/workspace/recipes/automation-hat/automation-hat_git.bb has been automatically created; further editing may be required to make it fully functional

When we look at the recipe devtool generated for us we find a lot of improvements:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

SUMMARY = "Automation HAT Driver"
HOMEPAGE = "http://www.pimoroni.com"
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=1be647ba1f2b40ff716e997a3e4a0d47"

SRC_URI = "git://github.com/pimoroni/automation-hat.git;protocol=https"

# Modify these as desired
PV = "0.2.2+git${SRCPV}"
SRCREV = "a41084cb4db02b76fc536235321a613d1c88ba52"

S = "${WORKDIR}/git/library"

inherit setuptools3

# WARNING: the following rdepends are from setuptools install_requires. These
# upstream names may not correspond exactly to bitbake package names.
RDEPENDS_${PN} += "python3-rpi-gpio python3-st7735 python3-sn3218"

# WARNING: the following rdepends are determined through basic analysis of the
# python sources, and might not be 100% accurate.
RDEPENDS_${PN} += "python3-core"

# WARNING: We were unable to map the following python package/module
# dependencies to the bitbake packages which include them:
#    smbus

  • line 5: devtool found a summary (although I'd prefer to change it to "Automation-HAT Python Library")
  • line 6: devtool found a homepage (although I'd prefer to point it to the specific product, not just the company's website)
  • lines 9-10: it's clearer about the license
  • line 15: it found a version (although the latest version is 0.2.3, not 0.2.2)
  • line 18: it set the S variable correctly
  • line 20: devtool discovered that it could use setuptools3 to build
  • lines 24 and 28: devtool found a couple runtime dependencies

This is great! This is a much nicer recipe to use as a starting point. Good job devtool.

After a little cleaning up, my recipe now looks like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
SUMMARY = "Automation-HAT Python Library"
DESCRIPTION = "Automation HAT is a home monitoring and automation controller \
featuring relays, analog channels, powered outputs, and buffered inputs (all \
24V tolerant)."
HOMEPAGE = "https://shop.pimoroni.com/products/automation-hat"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=1be647ba1f2b40ff716e997a3e4a0d47"

SRC_URI = "git://github.com/pimoroni/automation-hat.git;protocol=https"

PV = "0.2.3+git${SRCPV}"
SRCREV = "a41084cb4db02b76fc536235321a613d1c88ba52"

S = "${WORKDIR}/git/library"

inherit setuptools3

RDEPENDS_${PN} += "rpi-gpio python3-smbus python3-sn3218 python3-core"

  • line 1: I've updated the summary
  • line 2: I've added a description
  • line 5: I've updated the homepage
  • I've verified the license and therefore removed the comment warning me to check it by hand
  • line 11: I've updated the version
  • I've removed the comments around the runtime dependencies
  • line 18: I've changed the name of the python3-rpi-gpio runtime dependency to rpi-gpio and I've removed the python3-st7735 runtime dependency since I don't have the ST7735 TFT display attached to my setup. I've consolidated the two RDEPENDS lines, and figured out that the recipe needs a runtime dependency on python3-smbus

Searching the OpenEmbedded layer index for the names of the runtime dependencies that devtool has identified in creating this recipe, I found that a recipe already exists for rpi-gpio (it's in the meta-raspberrypi BSP layer, which we're already using), so I updated the name to match. A recipe for the other runtime dependency, python3-sn3218, isn't available and this is probably because this repository is also from Pimoroni's github account.

There's no point trying to build the automation-hat recipe until we've attempted to satisfy all of its (runtime) dependencies so we invoke devtool again:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ devtool add --version 1.2.7 --srcrev d497c6e9762c6d31bd9a7f9da9ccef0318b8e31c --src-subdir library python3-sn3218 https://github.com/pimoroni/sn3218
NOTE: Starting bitbake server...
NOTE: Starting bitbake server...
INFO: Fetching git://github.com/pimoroni/sn3218;protocol=https;nobranch=1...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:01
Loaded 1385 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 816 .bb files complete (814 cached, 2 parsed). 1385 targets, 65 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:00
Sstate summary: Wanted 0 Found 0 Missed 0 Current 0 (0% match, 0% complete)
NOTE: No setscene tasks
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds
INFO: Scanning paths for packages & dependencies: sn3218.py
INFO: Using default source tree path /z/build-master/6951/automation-hat/poky/build/workspace/sources/python3-sn3218
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Reconnecting to bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
NOTE: Retrying server connection (#1)...
NOTE: Starting bitbake server...
INFO: Recipe /z/build-master/6951/automation-hat/poky/build/workspace/recipes/python3-sn3218/python3-sn3218_git.bb has been automatically created; further editing may be required to make it fully functional

Looking at the resulting recipe:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

SUMMARY = "A module to drive the sn3218 i2c LED controller"
HOMEPAGE = "http://www.pimoroni.com"
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=be85037b505b21b386e82d53cd928b5e"

SRC_URI = "git://github.com/pimoroni/sn3218;protocol=https"

# Modify these as desired
PV = "1.2.7+git${SRCPV}"
SRCREV = "d497c6e9762c6d31bd9a7f9da9ccef0318b8e31c"

S = "${WORKDIR}/git/library"

inherit setuptools3

# WARNING: the following rdepends are determined through basic analysis of the
# python sources, and might not be 100% accurate.
RDEPENDS_${PN} += "python3-core"

# WARNING: We were unable to map the following python package/module
# dependencies to the bitbake packages which include them:
#    smbus

This recipe is looking pretty good already. I simply need to clean up some of the preamble tags, and remove most of the comments that devtool has placed into the file for my attention:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
SUMMARY = "A module to drive the sn3218 i2c LED controller"
HOMEPAGE = "https://github.com/pimoroni/sn3218"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=be85037b505b21b386e82d53cd928b5e"

SRC_URI = "git://github.com/pimoroni/sn3218;protocol=https"

PV = "1.2.7+git${SRCPV}"
SRCREV = "d497c6e9762c6d31bd9a7f9da9ccef0318b8e31c"

S = "${WORKDIR}/git/library"

inherit setuptools3

RDEPENDS_${PN} += "python3-smbus python3-core"

You may have noticed the reference to smbus by both recipes. smbus is another way of saying i2c, so I make a note that I probably want to add i2c user-space tools to my build. This makes sense since most (all?) of the peripherals on the Automation-HAT interface to the Raspberry Pi via i2c. This change needs to be done in my conf/local.conf.

But what about the smbus runtime dependency itself? If we search the layer index we find that there already is a recipe for python3-smbus in meta-python, which is part of meta-openembedded. Currently we're not using meta-openembeded in our build, therefore we need to clone that repository too, and add it to our build layers. We could do it manually or:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
$ bitbake-layers layerindex-fetch -b master meta-python
NOTE: Starting bitbake server...
Loading https://layers.openembedded.org/layerindex/api/;branch=master...
Layer                                              Git repository (branch)                                 Subdirectory
=============================================================================================================================
local:HEAD:openembedded-core                       git://git.yoctoproject.org/poky (master)                meta
  required by: meta-python meta-oe
layers.openembedded.org:master:meta-oe             git://git.openembedded.org/meta-openembedded (master)   meta-oe
  required by: meta-python
layers.openembedded.org:master:meta-python         git://git.openembedded.org/meta-openembedded (master)   meta-python
Cloning into '/opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta-openembedded'...
remote: Counting objects: 141039, done.
remote: Compressing objects: 100% (46829/46829), done.
remote: Total 141039 (delta 88137), reused 140214 (delta 87626)
Receiving objects: 100% (141039/141039), 37.93 MiB | 297.00 KiB/s, done.
Resolving deltas: 100% (88137/88137), done.
Updating files: 100% (5664/5664), done.
Adding layer "meta-oe" (/opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta-openembedded/meta-oe) to conf/bblayers.conf
Adding layer "meta-python" (/opt/oe/configs/z/build-master/6951/automation-hat/poky/layers/poky/meta-openembedded/meta-python) to conf/bblayers.conf

I'm not overly fond of where it placed the downloads, but the nice thing is that it took care of the dependency (meta-python depends on meta-oe) and it updated my conf/bblayers.conf file automatically for me.

Similarly to how we enabled the UART a while back, we have to explicitly tell the RaspberryPi that we want to enable i2c by setting the ENABLE_I2C to 1. NOTE: this is specific to the RaspberryPi due to the way its hardware was designed; having to explicitly enable a UART or i2c is not an OpenEmbedded thing or a thing in general. This only applies to the ENABLE_I2C setting, the other tweaks are common OpenEmbedded idioms.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
MACHINE = "raspberrypi3-64"
DL_DIR = "/opt/Downloads"
DISTRO = "poky"

ENABLE_UART = "1"
ENABLE_I2C = "1"
KERNEL_MODULE_AUTOLOAD += "i2c-dev"
CORE_IMAGE_EXTRA_INSTALL += " \
        ${MACHINE_EXTRA_RRECOMMENDS} \
        wpa-supplicant \
        i2c-tools \
        "

PACKAGECONFIG_append_pn-gdb = " tui"
PACKAGECONFIG_append_pn-gdb-cross-canadian-arm = " tui"

IMAGE_FSTYPES_append = " wic"
IMAGE_FSTYPES_remove = "wic.bz2 tar.bz2"
WARN_QA_append = " version-going-backwards"
ERROR_QA_remove = "version-going-backwards"
BB_DANGLINGAPPENDS_WARNONLY = "yes"
INHERIT += "buildhistory image-buildinfo buildstats-summary"
BUILDHISTORY_COMMIT = "1"

PACKAGE_CLASSES ?= "package_ipk"
SDKMACHINE = "x86_64"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS ??= "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    STOPTASKS,/tmp,100M,100K \
    ABORT,${TMPDIR},100M,1K \
    ABORT,${DL_DIR},100M,1K \
    ABORT,${SSTATE_DIR},100M,1K \
    ABORT,/tmp,10M,1K"
PACKAGECONFIG_append_pn-qemu-system-native = " sdl"
CONF_VERSION = "1"

Let's check to see if the new python3-sn3218 recipe will build:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$ devtool build python3-sn3218
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |                                                                                                                                                                          | ETA:  --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:16
Parsing of 2042 .bb files complete (0 cached, 2042 parsed). 3213 targets, 123 skipped, 0 masked, 0 errors.
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:03
Loaded 3211 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 2042 .bb files complete (2040 cached, 2 parsed). 3213 targets, 123 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"
meta-oe              
meta-python          = "master:86a7820b7964ff91d7a26ac5c506e83292e347a3"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:01
Sstate summary: Wanted 0 Found 0 Missed 0 Current 190 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: python3-sn3218: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/python3-sn3218/library
NOTE: Tasks Summary: Attempted 727 tasks of which 719 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 2 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_deploy_source_date_epoch: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 1 scratch)

Success!

How about automation-hat?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$ devtool build automation-hat
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:00
Loaded 3211 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 2042 .bb files complete (2040 cached, 2 parsed). 3213 targets, 123 skipped, 0 masked, 0 errors.
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:03
Loaded 3211 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 2042 .bb files complete (2040 cached, 2 parsed). 3213 targets, 123 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"
meta-oe              
meta-python          = "master:86a7820b7964ff91d7a26ac5c506e83292e347a3"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:01
Sstate summary: Wanted 0 Found 0 Missed 0 Current 190 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: automation-hat: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/library
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat-src went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat-dbg went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat-staticdev went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat-dev went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat-doc went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat-locale went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
WARNING: automation-hat-0.2.3+git999-r0 do_packagedata: QA Issue: Package version for package automation-hat went backwards which would break package feeds (from 0:1.0+git999-r0 to 0:0.2.3+git999-r0) [version-going-backwards]
NOTE: Tasks Summary: Attempted 727 tasks of which 719 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_deploy_source_date_epoch: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 1 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 1 scratch)

Summary: There were 7 WARNING messages shown.

Looking good!

Due to the fact we're adding these two new packages, plus both these packages have a runtime dependency on python3, plus we're adding i2c things and we want the i2c kernel module inserted at boot, it's probably time to build and flash a whole new image.

We could do the usual bitbake core-image-full-cmdline here, however if we do devtool build-image instead we'll find that devtool will add the recipes from our workspace (and their dependencies) into the resulting image, which is probably what we want.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$ devtool build-image core-image-full-cmdline
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:00
Loaded 3211 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 2042 .bb files complete (2040 cached, 2 parsed). 3213 targets, 123 skipped, 0 masked, 0 errors.
INFO: Building image core-image-full-cmdline with the following additional packages: automation-hat python3-sn3218
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:03
Loaded 3211 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 2042 .bb files complete (2039 cached, 3 parsed). 3213 targets, 123 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION           = "1.47.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi3-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.1+snapshot-20201018"
TUNE_FEATURES        = "aarch64 armv8a crc cortexa53"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "master:7cad26d585f67fa6bf873b8be361c6335a7db376"
meta-raspberrypi     = "master:6f85611576b7ccbfb6012631f741bd1daeffc9c9"
workspace            = "master:b1a0414a6df77674a860c365825a4500e6cd698b"
meta-oe              
meta-python          = "master:86a7820b7964ff91d7a26ac5c506e83292e347a3"

Initialising tasks: 100% |######################################################################################################################################################################| Time: 0:00:07
Sstate summary: Wanted 35 Found 0 Missed 35 Current 1508 (0% match, 97% complete)
NOTE: Executing Tasks
NOTE: python3-sn3218: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/python3-sn3218/library
NOTE: automation-hat: compiling from external source tree /z/build-master/6951/automation-hat/poky/build/workspace/sources/automation-hat/library
NOTE: Tasks Summary: Attempted 3998 tasks of which 3828 didn't need to be rerun and all succeeded.
NOTE: Writing buildhistory
NOTE: Writing buildhistory took: 1 seconds
NOTE: Build completion summary:
NOTE:   do_populate_sysroot: 0.0% sstate reuse(0 setscene, 5 scratch)
NOTE:   do_deploy_source_date_epoch: 0.0% sstate reuse(0 setscene, 4 scratch)
NOTE:   do_package_qa: 0.0% sstate reuse(0 setscene, 7 scratch)
NOTE:   do_package: 0.0% sstate reuse(0 setscene, 7 scratch)
NOTE:   do_packagedata: 0.0% sstate reuse(0 setscene, 7 scratch)
NOTE:   do_package_write_ipk: 0.0% sstate reuse(0 setscene, 7 scratch)
NOTE:   do_populate_lic: 0.0% sstate reuse(0 setscene, 5 scratch)
INFO: Successfully built core-image-full-cmdline. You can find output files in /z/build-master/6951/automation-hat/poky/build/tmp/deploy/images/raspberrypi3-64

NOTE: on line 9 the build tells you that it is installing our two new packages into the image.

Flash this image to your µSD card, insert the card into the target, and apply power. After logging in:

1
2
3
4
5
6
7
root@raspberrypi3-64:~# python3
Python 3.8.5 (default, Jul 20 2020, 13:26:22) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import automationhat
>>> automationhat.output.one.on()
>>>

Looking at the target:


Success!

Finishing Up

We used devtool to help us create two recipes. Those recipes (and their sources) are still in our "workspace". We need to finish working with them and put them somewhere. But where? The layers we're using aren't under our control. We need to create our own layer so we have a place to store these new recipes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ bitbake-layers create-layer ../layers/devtool-additions
NOTE: Starting bitbake server...
Add your new layer with 'bitbake-layers add-layer ../layers/devtool-additions'

$ bitbake-layers add-layer ../layers/devtool-additions/
NOTE: Starting bitbake server...

$ devtool finish -f -r automation-hat ../layers/devtool-additions/
NOTE: Starting bitbake server...
WARNING: Source tree is not clean, continuing as requested by -f/--force
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |                                                                                                                                                                          | ETA:  --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:14
Parsing of 2043 .bb files complete (0 cached, 2043 parsed). 3214 targets, 123 skipped, 0 masked, 0 errors.
INFO: Updating SRCREV in recipe automation-hat_git.bb
INFO: Moving recipe file to /z/build-master/6951/automation-hat/poky/layers/devtool-additions/recipes-automation-hat/automation-hat
INFO: -r argument used on automation-hat, removing source tree. You will lose any unsaved work

$ devtool finish -f -r python3-sn3218 ../layers/devtool-additions/
NOTE: Starting bitbake server...
WARNING: Source tree is not clean, continuing as requested by -f/--force
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |###########################################################################################################################################################################| Time: 0:00:00
Loaded 3212 entries from dependency cache.
Parsing recipes: 100% |#########################################################################################################################################################################| Time: 0:00:00
Parsing of 2043 .bb files complete (2041 cached, 2 parsed). 3214 targets, 123 skipped, 0 masked, 0 errors.
Removing 1 recipes from the cortexa53 sysroot: 100% |###########################################################################################################################################| Time: 0:00:00
Removing 1 recipes from the raspberrypi3_64 sysroot: 100% |#####################################################################################################################################| Time: 0:00:00
INFO: Updating SRCREV in recipe python3-sn3218_git.bb
INFO: Moving recipe file to /z/build-master/6951/automation-hat/poky/layers/devtool-additions/recipes-python3-sn3218/python3-sn3218
INFO: -r argument used on python3-sn3218, removing source tree. You will lose any unsaved work

$ rm -fr workspace/sources/

$ tree ../layers/devtool-additions/
../layers/devtool-additions/
├── COPYING.MIT
├── README
├── conf
│   └── layer.conf
├── recipes-automation-hat
│   └── automation-hat
│       └── automation-hat_git.bb
├── recipes-example
│   └── example
│       └── example_0.1.bb
└── recipes-python3-sn3218
    └── python3-sn3218
        └── python3-sn3218_git.bb

7 directories, 6 files

This looks good. The "example" boilerplate can be removed from the layer.

NOTE: if you want to build an image, you have to go back to using bitbake and you have to explicitly add the package(s) to your image. Thanks to dependencies, the only package that needs to be added to an image is automation-hat

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
MACHINE = "raspberrypi3-64"
DL_DIR = "/opt/Downloads"
DISTRO = "poky"

ENABLE_UART = "1"
ENABLE_I2C = "1"
KERNEL_MODULE_AUTOLOAD += "i2c-dev"
CORE_IMAGE_EXTRA_INSTALL += " \
        ${MACHINE_EXTRA_RRECOMMENDS} \
        wpa-supplicant \
        i2c-tools \
        automation-hat \
        "

PACKAGECONFIG_append_pn-gdb = " tui"
PACKAGECONFIG_append_pn-gdb-cross-canadian-arm = " tui"

IMAGE_FSTYPES_append = " wic"
IMAGE_FSTYPES_remove = "wic.bz2 tar.bz2"
WARN_QA_append = " version-going-backwards"
ERROR_QA_remove = "version-going-backwards"
BB_DANGLINGAPPENDS_WARNONLY = "yes"
INHERIT += "buildhistory image-buildinfo buildstats-summary"
BUILDHISTORY_COMMIT = "1"

PACKAGE_CLASSES ?= "package_ipk"
SDKMACHINE = "x86_64"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS ??= "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    STOPTASKS,/tmp,100M,100K \
    ABORT,${TMPDIR},100M,1K \
    ABORT,${DL_DIR},100M,1K \
    ABORT,${SSTATE_DIR},100M,1K \
    ABORT,/tmp,10M,1K"
PACKAGECONFIG_append_pn-qemu-system-native = " sdl"
CONF_VERSION = "1"


No comments: