diff --git a/yocto/README.md b/yocto/README.md new file mode 100644 index 0000000..2b18de1 --- /dev/null +++ b/yocto/README.md @@ -0,0 +1,28 @@ +# Yocto configuration for BeagleBone (esp-egycounter) + +This directory provides a Yocto setup that builds a BeagleBone image with: + +- Debian-style package management (`apt`, `dpkg`) via `package_deb` +- No X server/UI stack +- SSH (`openssh`), Python 3 (with stdlib modules), and `nginx` +- USB client Ethernet gadget support (RNDIS/ECM style) +- Kernel based on RobertCNelson `ti-linux-kernel-dev` configuration with added `qca7k` support +- Integrated `battery-control` scripts from this repository +- Included `pyPLC` and `OpenV2Gx` + +## Build quickstart (kas) + +From repository root: + +```bash +cd yocto +kas build kas-beaglebone.yml +``` + +The image target is `egycounter-image`. + +## Notes + +- `OpenV2Gx` is built as part of the Yocto build via the custom recipe. +- `pyPLC` is installed to `/opt/pyplc`. +- `battery-control` scripts are installed to `/opt/esp-egycounter/battery-control`. diff --git a/yocto/kas-beaglebone.yml b/yocto/kas-beaglebone.yml new file mode 100644 index 0000000..ea13d82 --- /dev/null +++ b/yocto/kas-beaglebone.yml @@ -0,0 +1,46 @@ +header: + version: 14 + +machine: beaglebone-yocto +distro: egycounter-debian + +target: + - egycounter-image + +repos: + poky: + url: "https://git.yoctoproject.org/poky" + branch: kirkstone + layers: + meta: + meta-poky: + meta-yocto-bsp: + + meta-openembedded: + url: "https://github.com/openembedded/meta-openembedded.git" + branch: kirkstone + layers: + meta-oe: + meta-networking: + meta-python: + + meta-arm: + url: "https://git.yoctoproject.org/meta-arm" + branch: kirkstone + layers: + meta-arm: + meta-arm-toolchain: + + meta-ti: + url: "https://git.yoctoproject.org/meta-ti" + branch: kirkstone + layers: + meta-ti-bsp: + + meta-egycounter: + path: meta-egycounter + +local_conf_header: + egycounter-common: | + PACKAGE_CLASSES = "package_deb" + EXTRA_IMAGE_FEATURES += "package-management" diff --git a/yocto/meta-egycounter/conf/distro/egycounter-debian.conf b/yocto/meta-egycounter/conf/distro/egycounter-debian.conf new file mode 100644 index 0000000..2b29684 --- /dev/null +++ b/yocto/meta-egycounter/conf/distro/egycounter-debian.conf @@ -0,0 +1,20 @@ +require conf/distro/poky.conf + +DISTRO = "egycounter-debian" +DISTRO_NAME = "egycounter Debian-style distro" + +PACKAGE_CLASSES = "package_deb" +EXTRA_IMAGE_FEATURES += "package-management" + +# headless image +DISTRO_FEATURES:remove = "x11 wayland opengl" + +VIRTUAL-RUNTIME_init_manager = "systemd" +DISTRO_FEATURES:append = " systemd" +DISTRO_FEATURES:remove = "sysvinit" + +# Prefer custom kernel recipe based on ti-linux-kernel-dev +PREFERRED_PROVIDER_virtual/kernel = "linux-ti-rcn" + +# Work around host/bitbake combinations that fail in get_git_pkgv() during parsing +GITPKGVTAG = "${PV}" diff --git a/yocto/meta-egycounter/conf/layer.conf b/yocto/meta-egycounter/conf/layer.conf new file mode 100644 index 0000000..eee857f --- /dev/null +++ b/yocto/meta-egycounter/conf/layer.conf @@ -0,0 +1,13 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "egycounter" +BBFILE_PATTERN_egycounter = "^${LAYERDIR}/" +BBFILE_PRIORITY_egycounter = "8" + +LAYERDEPENDS_egycounter = "core openembedded-layer meta-python networking-layer" +LAYERSERIES_COMPAT_egycounter = "kirkstone" diff --git a/yocto/meta-egycounter/recipes-connectivity/usb-gadget-ethernet/files/usb-gadget-ethernet.service b/yocto/meta-egycounter/recipes-connectivity/usb-gadget-ethernet/files/usb-gadget-ethernet.service new file mode 100644 index 0000000..2dbaa9f --- /dev/null +++ b/yocto/meta-egycounter/recipes-connectivity/usb-gadget-ethernet/files/usb-gadget-ethernet.service @@ -0,0 +1,11 @@ +[Unit] +Description=Enable USB Ethernet gadget +After=systemd-modules-load.service + +[Service] +Type=oneshot +ExecStart=/sbin/modprobe g_ether +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/yocto/meta-egycounter/recipes-connectivity/usb-gadget-ethernet/usb-gadget-ethernet.bb b/yocto/meta-egycounter/recipes-connectivity/usb-gadget-ethernet/usb-gadget-ethernet.bb new file mode 100644 index 0000000..6efaf00 --- /dev/null +++ b/yocto/meta-egycounter/recipes-connectivity/usb-gadget-ethernet/usb-gadget-ethernet.bb @@ -0,0 +1,15 @@ +SUMMARY = "Enable USB gadget Ethernet on BeagleBone USB client port" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd + +SRC_URI = "file://usb-gadget-ethernet.service" + +SYSTEMD_SERVICE:${PN} = "usb-gadget-ethernet.service" +SYSTEMD_AUTO_ENABLE = "enable" + +do_install() { + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/usb-gadget-ethernet.service ${D}${systemd_system_unitdir}/ +} diff --git a/yocto/meta-egycounter/recipes-core/images/egycounter-image.bb b/yocto/meta-egycounter/recipes-core/images/egycounter-image.bb new file mode 100644 index 0000000..66df51f --- /dev/null +++ b/yocto/meta-egycounter/recipes-core/images/egycounter-image.bb @@ -0,0 +1,33 @@ +SUMMARY = "Headless BeagleBone image for esp-egycounter" +LICENSE = "MIT" + +inherit core-image + +IMAGE_FEATURES += "ssh-server-openssh package-management" + +IMAGE_INSTALL:append = " \ + apt \ + dpkg \ + openssh \ + nginx \ + mosquitto \ + can-utils \ + iproute2 \ + iptables \ + usbutils \ + python3 \ + python3-modules \ + python3-paho-mqtt \ + python3-pyserial \ + python3-requests \ + python3-urllib3 \ + python3-pyyaml \ + python3-crcmod \ + python3-can \ + python3-pymodbus \ + python3-adafruit-bbio \ + pyplc \ + openv2gx \ + egycounter-battery-control \ + usb-gadget-ethernet \ +" diff --git a/yocto/meta-egycounter/recipes-devtools/python/python3-adafruit-bbio/python3-adafruit-bbio_1.2.0.bb b/yocto/meta-egycounter/recipes-devtools/python/python3-adafruit-bbio/python3-adafruit-bbio_1.2.0.bb new file mode 100644 index 0000000..e19f9a7 --- /dev/null +++ b/yocto/meta-egycounter/recipes-devtools/python/python3-adafruit-bbio/python3-adafruit-bbio_1.2.0.bb @@ -0,0 +1,8 @@ +SUMMARY = "Adafruit BBIO library for BeagleBone" +HOMEPAGE = "https://github.com/adafruit/adafruit-beaglebone-io-python" +LICENSE = "CLOSED" + +inherit pypi setuptools3 + +PYPI_PACKAGE = "Adafruit-BBIO" +SRC_URI[sha256sum] = "f6f20b3adfbfe7067ac8b9ac2b33cd807401e33ad0396b079f8c3d323f7fd540" diff --git a/yocto/meta-egycounter/recipes-kernel/linux/linux-ti-rcn/qca7k-usb-gadget.cfg b/yocto/meta-egycounter/recipes-kernel/linux/linux-ti-rcn/qca7k-usb-gadget.cfg new file mode 100644 index 0000000..1b68a7e --- /dev/null +++ b/yocto/meta-egycounter/recipes-kernel/linux/linux-ti-rcn/qca7k-usb-gadget.cfg @@ -0,0 +1,13 @@ +# qca7k / qca7000 support +CONFIG_QCA7000=y +CONFIG_QCA7000_SPI=y + +# USB gadget networking (for BeagleBone USB client connector) +CONFIG_USB_GADGET=y +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_ETH=y +CONFIG_USB_ETH_EEM=y +CONFIG_USB_ETH_RNDIS=y diff --git a/yocto/meta-egycounter/recipes-kernel/linux/linux-ti-rcn_6.6.bb b/yocto/meta-egycounter/recipes-kernel/linux/linux-ti-rcn_6.6.bb new file mode 100644 index 0000000..0db192a --- /dev/null +++ b/yocto/meta-egycounter/recipes-kernel/linux/linux-ti-rcn_6.6.bb @@ -0,0 +1,21 @@ +SUMMARY = "RobertCNelson TI Linux kernel for BeagleBone" +DESCRIPTION = "Kernel from RobertCNelson/ti-linux-kernel-dev with additional config fragment" +LICENSE = "GPL-2.0-only" +LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7" + +inherit kernel + +SRC_URI = "git://github.com/RobertCNelson/ti-linux-kernel-dev.git;branch=master;protocol=https \ + file://qca7k-usb-gadget.cfg" + +SRCREV = "${AUTOREV}" +PV = "6.6+git${SRCPV}" + +S = "${WORKDIR}/git" + +KERNEL_IMAGETYPE = "zImage" + +# Use upstream BeagleBone defconfig as baseline and append cfg fragment +KBUILD_DEFCONFIG = "omap2plus_defconfig" + +KERNEL_CONFIG_FRAGMENTS += "${WORKDIR}/qca7k-usb-gadget.cfg" diff --git a/yocto/meta-egycounter/recipes-support/egycounter-battery-control/egycounter-battery-control_git.bb b/yocto/meta-egycounter/recipes-support/egycounter-battery-control/egycounter-battery-control_git.bb new file mode 100644 index 0000000..8142ba9 --- /dev/null +++ b/yocto/meta-egycounter/recipes-support/egycounter-battery-control/egycounter-battery-control_git.bb @@ -0,0 +1,30 @@ +SUMMARY = "esp-egycounter battery-control scripts" +HOMEPAGE = "https://github.com/jsphuebner/esp-egycounter" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = "git://github.com/jsphuebner/esp-egycounter.git;branch=main;protocol=https" +SRCREV = "${AUTOREV}" + +S = "${WORKDIR}/git" + +do_install() { + install -d ${D}/opt/esp-egycounter + cp -R --no-preserve=ownership ${S}/battery-control ${D}/opt/esp-egycounter/ +} + +FILES:${PN} += "/opt/esp-egycounter/battery-control" + +RDEPENDS:${PN} += " \ + python3-core \ + python3-modules \ + python3-paho-mqtt \ + python3-pyserial \ + python3-requests \ + python3-urllib3 \ + python3-pyyaml \ + python3-crcmod \ + python3-can \ + python3-pymodbus \ + python3-adafruit-bbio \ +" diff --git a/yocto/meta-egycounter/recipes-support/openv2gx/openv2gx_git.bb b/yocto/meta-egycounter/recipes-support/openv2gx/openv2gx_git.bb new file mode 100644 index 0000000..bd5dfeb --- /dev/null +++ b/yocto/meta-egycounter/recipes-support/openv2gx/openv2gx_git.bb @@ -0,0 +1,12 @@ +SUMMARY = "OpenV2Gx EXI decoder/encoder" +HOMEPAGE = "https://github.com/uhi22/OpenV2Gx" +LICENSE = "CLOSED" + +inherit cmake pkgconfig + +SRC_URI = "git://github.com/uhi22/OpenV2Gx.git;branch=master;protocol=https" +SRCREV = "${AUTOREV}" + +S = "${WORKDIR}/git" + +FILES:${PN} += "${bindir} ${libdir}" diff --git a/yocto/meta-egycounter/recipes-support/pyplc/pyplc_git.bb b/yocto/meta-egycounter/recipes-support/pyplc/pyplc_git.bb new file mode 100644 index 0000000..531670b --- /dev/null +++ b/yocto/meta-egycounter/recipes-support/pyplc/pyplc_git.bb @@ -0,0 +1,21 @@ +SUMMARY = "pyPLC V2G implementation" +HOMEPAGE = "https://github.com/uhi22/pyPLC" +LICENSE = "CLOSED" + +SRC_URI = "git://github.com/uhi22/pyPLC.git;branch=master;protocol=https" +SRCREV = "${AUTOREV}" + +S = "${WORKDIR}/git" + +do_install() { + install -d ${D}/opt/pyplc + cp -R --no-preserve=ownership ${S}/* ${D}/opt/pyplc/ +} + +FILES:${PN} += "/opt/pyplc" + +RDEPENDS:${PN} += " \ + python3-core \ + python3-modules \ + python3-pyserial \ +"