Merge remote-tracking branch 'upstream/agnos18.1.1' into bluetooth

This commit is contained in:
Shane Smiskol
2026-05-19 23:59:47 -07:00
43 changed files with 1007 additions and 598 deletions
+4
View File
@@ -6,5 +6,9 @@
build/
output/
!output/
output/*
!output/linux-headers/
!output/linux-headers/**
edk2_tici/
agnos-kernel-sdm845/
+1 -1
View File
@@ -13,7 +13,7 @@ concurrency:
jobs:
build:
name: build kernel and system
runs-on: namespace-profile-arm64-8x16-2004-caching
runs-on: ubuntu-24.04-arm
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
-3
View File
@@ -15,7 +15,4 @@ qcom_xbl/
.vscode
edl_config.json
tools/edl_repo/
edk2_tici/
+15 -14
View File
@@ -21,12 +21,6 @@ RUN apt-get update && apt-get install -yq --no-install-recommends \
# Enable ccache
ENV PATH="/usr/lib/ccache:$PATH"
# ffmpeg
FROM agnos-compiler AS agnos-compiler-ffmpeg
COPY ./userspace/compile-ffmpeg.sh /tmp/agnos/
RUN --mount=type=cache,target=/root/.ccache,id=ffmpeg,sharing=shared \
/tmp/agnos/compile-ffmpeg.sh
# libqmi
FROM agnos-compiler AS agnos-compiler-libqmi
COPY ./userspace/compile-libqmi.sh /tmp/agnos/
@@ -118,10 +112,6 @@ RUN cd /tmp && \
apt-get -o Dpkg::Options::="--force-overwrite" install -yq ./libqmi.deb && \
apt-get -o Dpkg::Options::="--force-overwrite" install -yq ./modemmanager.deb
# Use other pre-compiled packages
COPY --from=agnos-compiler-ffmpeg /tmp/ffmpeg.deb /tmp/ffmpeg.deb
RUN cd /tmp && apt-get -o Dpkg::Options::="--force-overwrite" install -yq ./ffmpeg.deb
ARG XDG_DATA_HOME="/usr/local"
# Install openpilot python packages
@@ -169,11 +159,13 @@ COPY ./userspace/usr/comma/ /usr/$USERNAME/
COPY ./userspace/usr/share/fonts/* /usr/share/fonts/
COPY ./userspace/libs/* /usr/lib/aarch64-linux-gnu/
COPY ./userspace/libs32/* /usr/lib/arm-linux-gnueabihf/
COPY ./output/linux-headers/include/ /usr/include/
COPY ./userspace/files/amdgpu/ /usr/lib/firmware/amdgpu/
# this is big, only enable when we need it
# kernel headers for the AGNOS kernel (built on device)
#COPY ./userspace/files/linux-headers-4.9.103+_4.9.103+-1_arm64.deb /tmp/
#RUN dpkg -i /tmp/linux-headers-4.9.103+_4.9.103+-1_arm64.deb
COPY ./userspace/power_burn/power_burn_max.c /tmp/agnos/
RUN gcc -O2 -o /home/$USERNAME/power_burn_max /tmp/agnos/power_burn_max.c \
-lOpenCL -lpthread -ldl && rm /tmp/agnos/power_burn_max.c \
&& chown $USERNAME: /home/$USERNAME/power_burn_max
# Weston with hacked touch rotate and color correction
COPY ./userspace/files/weston /usr/bin/weston
@@ -234,6 +226,15 @@ RUN sed -i 's/hosts: files dns myhostname/hosts: files myhostn
# keep this last
RUN ldconfig
# ldconfig rewrites these SONAME links back to Mesa; raylib COMMA needs Adreno.
RUN cd /usr/lib/aarch64-linux-gnu && \
test -f libEGL_adreno.so && \
test -f libGLESv2_adreno.so && \
install -m 755 libgbm.so /tmp/libgbm_adreno.so && \
ln -sf libEGL_adreno.so libEGL.so.1 && \
ln -sf libGLESv2_adreno.so libGLESv2.so.2 && \
rm -f libgbm.so.1 && \
mv /tmp/libgbm_adreno.so libgbm.so.1
# Setup RO rootfs
RUN mkdir -p /rwtmp
+1 -1
View File
@@ -1 +1 @@
17
18.3
+5
View File
@@ -109,6 +109,11 @@ build_kernel() {
# Copy to output dir
mkdir -p $OUTPUT_DIR
mv $BOOT_IMG $OUTPUT_DIR/
cd $DIR/agnos-kernel-sdm845
echo "-- Install kernel UAPI headers --"
rm -rf $OUTPUT_DIR/linux-headers
make headers_install O=out INSTALL_HDR_PATH=$OUTPUT_DIR/linux-headers
}
# Run build_kernel in container
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/env bash
set -e
DEFCONFIG=tici_defconfig
# Get directories and make sure we're in the correct spot to start the build
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
TOOLS=$DIR/tools
TMP_DIR=/tmp/agnos-builder-tmp
OUTPUT_DIR=$DIR/output
BOOT_IMG=./boot.img
cd $DIR
# Clone kernel if not done already
if [ ! -d agnos-kernel-sdm845 ]; then
git submodule init agnos-kernel-sdm845
fi
cd agnos-kernel-sdm845
# Build parameters
export ARCH=arm64
if [ ! -f /TICI ]; then
export CROSS_COMPILE=$TOOLS/aarch64-linux-gnu-gcc/bin/aarch64-linux-gnu-
export CC=$TOOLS/aarch64-linux-gnu-gcc/bin/aarch64-linux-gnu-gcc
export LD=$TOOLS/aarch64-linux-gnu-gcc/bin/aarch64-linux-gnu-ld.bfd
fi
# these do anything?
export KCFLAGS="-w"
# Load defconfig and build kernel
echo "-- First make --"
make $DEFCONFIG O=out
echo "-- Second make: $(nproc --all) cores --"
ARGS=""
if [ -f /TICI ]; then
ARGS="sudo -E"
fi
$ARGS make bindeb-pkg -j$(nproc --all) O=out # Image.gz-dtb
# Copy output
mkdir -p $OUTPUT_DIR
cp linux-headers-*.deb $OUTPUT_DIR
+1 -1
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee
oid sha256:b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c
size 274432
+1 -1
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788
oid sha256:78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1
size 184364
+1 -1
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585
oid sha256:f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc
size 40336
+1 -1
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6
oid sha256:e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb
size 3282256
+1 -1
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9
oid sha256:758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85
size 98124
+2 -2
View File
@@ -5,8 +5,8 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd $DIR
for part in aop abl xbl xbl_config devcfg; do
tools/edl w ${part}_a $DIR/firmware/$part.img
tools/edl w ${part}_b $DIR/firmware/$part.img
tools/qdl flash ${part}_a $DIR/firmware/$part.img
tools/qdl flash ${part}_b $DIR/firmware/$part.img
done
./flash_kernel.sh
+1 -13
View File
@@ -4,16 +4,4 @@ set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd $DIR
echo "Checking active slot..."
ACTIVE_SLOT=$(tools/edl getactiveslot | grep "Current active slot:" | awk '{print $NF}')
if [[ "$ACTIVE_SLOT" != "a" && "$ACTIVE_SLOT" != "b" ]]; then
echo "Invalid active slot: '$ACTIVE_SLOT'"
exit 1
fi
echo "Active slot: $ACTIVE_SLOT"
echo "Flashing boot_$ACTIVE_SLOT..."
tools/edl w boot_$ACTIVE_SLOT $DIR/output/boot.img
echo "Flashed boot_$ACTIVE_SLOT!"
tools/qdl flash boot $DIR/output/boot.img
+2 -15
View File
@@ -4,18 +4,5 @@ set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd $DIR
echo "Checking active slot..."
ACTIVE_SLOT=$(tools/edl getactiveslot | grep "Current active slot:" | awk '{print $NF}')
if [[ "$ACTIVE_SLOT" != "a" && "$ACTIVE_SLOT" != "b" ]]; then
echo "Invalid active slot: '$ACTIVE_SLOT'"
exit 1
fi
echo "Active slot: $ACTIVE_SLOT"
echo "Flashing system_$ACTIVE_SLOT..."
tools/edl w system_$ACTIVE_SLOT $DIR/output/system.img
tools/edl reset
echo "Flashed system_$ACTIVE_SLOT!"
tools/qdl flash system $DIR/output/system.img
tools/qdl reset
+1 -1
View File
@@ -49,7 +49,7 @@ function create_image() {
rm -rf $WORKDIR
}
for sz in 30 89 90; do
for sz in 89 90; do
echo "Building ${sz}GB userdata image"
create_image ${sz}G
done
+1 -1
View File
@@ -8,7 +8,7 @@ from pathlib import Path
from urllib.parse import urlparse
MASTER_MANIFEST = "https://raw.githubusercontent.com/commaai/openpilot/master/system/hardware/tici/agnos.json"
RELEASE_MANIFEST = "https://raw.githubusercontent.com/commaai/openpilot/release3/system/hardware/tici/agnos.json"
RELEASE_MANIFEST = "https://raw.githubusercontent.com/commaai/openpilot/release-mici/system/hardware/tici/agnos.json"
ROOT = Path(__file__).parent.parent
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = ["pyusb"]
# ///
import argparse
import errno
import fcntl
import os
import re
import select
import sys
import termios
import time
import usb.core
SERIAL_DEV = "/dev/serial/by-id/usb-Microchip_Tech_USB2_Controller_Hub-if01"
PROMPT_RE = re.compile(rb"(?:login:|[#\$])$")
USB_RT_PORT = 0x23
USB_REQ_CLEAR_FEATURE = 1
USB_REQ_SET_FEATURE = 3
USB_PORT_POWER = 8
class Pins:
HFC_VID = 0x0424
HFC_PID = 0x704C
USB7002_VID = 0x0424
USB7002_PID = 0x7002
USB4002_VID = 0x0424
USB4002_PID = 0x4002
PIO96_OEN = 0xBF800908
PIO96_OUT = 0xBF800928
VIN_EN = 1 << (92 - 64)
class Mdma:
"""
MDMA: the mici debug and monitoring adapter
an MDMA is your best friend for low level mici (aka comma four) development.
- power the SOC on and off
- force the SOC into QDL mode for un-brickability
- read and write to the SOC's UART
- and more!
"""
def hub(self, vid, pid):
hub = usb.core.find(idVendor=vid, idProduct=pid)
if hub is None:
raise SystemExit(f"could not find hub {vid:04x}:{pid:04x}")
return hub
def available(self):
return os.path.exists(SERIAL_DEV)
def reg(self, addr, value=None, size=4):
dev = usb.core.find(idVendor=Pins.HFC_VID, idProduct=Pins.HFC_PID)
if value is None:
return int.from_bytes(bytes(dev.ctrl_transfer(0xC0, 0x04, addr & 0xFFFF, addr >> 16, size)), "little")
dev.ctrl_transfer(0x40, 0x03, addr & 0xFFFF, addr >> 16, value.to_bytes(size, "little"))
def gpio(self, bit, on):
if on:
self.reg(Pins.PIO96_OEN, self.reg(Pins.PIO96_OEN) & ~bit)
else:
self.reg(Pins.PIO96_OUT, self.reg(Pins.PIO96_OUT) & ~bit)
self.reg(Pins.PIO96_OEN, self.reg(Pins.PIO96_OEN) | bit)
def aux(self, action):
request = USB_REQ_SET_FEATURE if action == "on" else USB_REQ_CLEAR_FEATURE
for vid, pid in [(Pins.USB7002_VID, Pins.USB7002_PID), (Pins.USB4002_VID, Pins.USB4002_PID)]:
try:
self.hub(vid, pid).ctrl_transfer(USB_RT_PORT, request, USB_PORT_POWER, 1, None, timeout=1000)
except usb.core.USBError: # try one more time
self.hub(vid, pid).ctrl_transfer(USB_RT_PORT, request, USB_PORT_POWER, 1, None, timeout=1000)
def power_off(self):
self.aux("off")
self.gpio(Pins.VIN_EN, False)
def reboot(self, qdl):
self.aux("off")
self.gpio(Pins.VIN_EN, False)
time.sleep(0.1)
if qdl:
# on comma 3X and comma four, aux powering
# up first forces QDL mode on boot
self.aux("on")
else:
self.gpio(Pins.VIN_EN, True)
boot_time = time.monotonic()
time.sleep(0.1)
self.gpio(Pins.VIN_EN, True)
self.aux("on")
# give time to enumerate
if qdl:
time.sleep(1)
return boot_time
def serial(self):
os.execvp("screen", ["screen", SERIAL_DEV, "115200"])
def profile_boot(self):
# device off for clean serial
self.power_off()
# open the serial device
try:
fd = os.open(SERIAL_DEV, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
except OSError as e:
if e.errno == errno.EBUSY:
raise SystemExit(f"{SERIAL_DEV} is busy; close the serial console first")
raise
attrs = termios.tcgetattr(fd)
attrs[0] = 0
attrs[1] = 0
attrs[2] = termios.CS8 | termios.CREAD | termios.CLOCAL
attrs[3] = 0
attrs[4] = termios.B115200
attrs[5] = termios.B115200
attrs[6][termios.VMIN] = 0
attrs[6][termios.VTIME] = 0
termios.tcsetattr(fd, termios.TCSANOW, attrs)
fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) & ~os.O_NONBLOCK)
termios.tcflush(fd, termios.TCIFLUSH)
while (data := os.read(fd, 4096)):
time.sleep(0.1)
# boot!
start = self.reboot(qdl=False)
# show serial console with timestamps until boot is done
pending = b""
while True:
if not select.select([fd], [], [], 0.25)[0]:
continue
data = os.read(fd, 4096)
if not data:
continue
pending += data.replace(b"\r\n", b"\n")
while b"\n" in pending:
line, pending = pending.split(b"\n", 1)
line = line.rstrip()
print(f"[{time.monotonic() - start:8.3f}] {line.decode(errors='replace')}", flush=True)
if PROMPT_RE.search(line):
return
if PROMPT_RE.search(pending.strip()):
print(f"[{time.monotonic() - start:8.3f}] {pending.strip().decode(errors='replace')}", flush=True)
return
if __name__ == "__main__":
cmds = {
"reboot": (lambda: Mdma().reboot(qdl=False), "reboot comma four into normal boot"),
"reboot-qdl": (lambda: Mdma().reboot(qdl=True), "reboot comma four into QDL mode for flashing"),
"serial": (lambda: Mdma().serial(), "open the MSM UART console with screen"),
"serial": (lambda: Mdma().serial(), "open the MSM UART console with screen"),
"profile-boot": (lambda: Mdma().profile_boot(), "reboot comma four and profile boot time"),
}
parser = argparse.ArgumentParser()
parser.add_argument("--missing-ok", action="store_true", help="continue successfully when no MDMA is connected")
subparsers = parser.add_subparsers(dest="command", required=True)
for cmd, (_, hlp) in cmds.items():
subparsers.add_parser(cmd, help=hlp)
if len(sys.argv) == 1:
parser.print_help()
raise SystemExit(0)
args = parser.parse_args()
if not Mdma().available():
print("MDMA not found.")
raise SystemExit(0 if args.missing_ok else 1)
cmds[args.command][0]()
-1
View File
@@ -58,7 +58,6 @@ PARTITIONS = [
Partition('system', OUTPUT_DIR / 'system.img', True, True, False, True),
Partition('userdata_90', OUTPUT_DIR / 'userdata_90.img', False, False, True, True),
Partition('userdata_89', OUTPUT_DIR / 'userdata_89.img', False, False, True, True),
Partition('userdata_30', OUTPUT_DIR / 'userdata_30.img', False, False, True, True),
]
-56
View File
@@ -1,56 +0,0 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
ROOT=$DIR/../
# just a nice wrapper around the edl python tool
EDL_PATH=$DIR/edl_repo
VERSION="8573eba1b576305fec3a068393283143ffc34342"
if [ ! -d "$EDL_PATH" ]; then
rm -rf $EDL_PATH
git clone https://github.com/bkerler/edl $EDL_PATH
fi
pushd $EDL_PATH > /dev/null
NEED_INSTALL=0
if [ ! -d venv ]; then
python3 -m venv venv
NEED_INSTALL=1
fi
source venv/bin/activate
if [ "$(< .git/HEAD)" != "$VERSION" ]; then
echo "updating edl..."
git fetch origin $VERSION
git checkout $VERSION
git submodule update --depth=1 --init --recursive
NEED_INSTALL=1
fi
if [ "$NEED_INSTALL" -eq 1 ]; then
pip3 install -r requirements.txt
fi
# patch in comma four USB id (https://github.com/commaai/agnos-builder/issues/533)
if ! grep -q '0x3801' $EDL_PATH/edlclient/Config/usb_ids.py; then
sed -i '/\[0x05c6, 0x9008, -1\]/a\ [0x3801, 0x9008, -1], # comma four' $EDL_PATH/edlclient/Config/usb_ids.py
fi
popd > /dev/null
$EDL_PATH/edl "$@"
################################################################################
# On M-series macs, if you get "No backend available"
# where python is installed with pyenv and libusb with brew
# try this:
#
# brew install libusb
# sudo mkdir -p /usr/local/lib
# sudo ln -s /opt/homebrew/lib/libusb-1.0.0.dylib /usr/local/lib/libusb.dylib
#
################################################################################
Executable
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -e
if ! command -v bun &> /dev/null; then
echo "Installing bun..." >&2
curl -fsSL https://bun.sh/install | bash >&2
export PATH="$HOME/.bun/bin:$PATH"
fi
QDL="bunx --bun commaai/qdl.js"
# preload package so bunx output doesn't pollute stdout on first run
$QDL --help > /dev/null 2>&1 || true
exec $QDL "$@"
-42
View File
@@ -1,42 +0,0 @@
#!/bin/bash -e
VERSION=4.2.2
# Install build requirements
apt-get update && apt-get install -yq --no-install-recommends \
libass-dev \
libfreetype6-dev \
libgnutls28-dev \
libmp3lame-dev \
libsdl2-dev \
libtool \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libx264-dev \
libxcb1-dev \
libxcb-shm0-dev \
libxcb-xfixes0-dev \
liblzma-dev \
rsync \
texinfo \
zlib1g-dev
# Build ffmpeg (the one from the ubuntu repos doesn't work with our libOpenCL)
cd /tmp
wget https://ffmpeg.org/releases/ffmpeg-${VERSION}.tar.bz2
tar xvf ffmpeg-${VERSION}.tar.bz2
cd ffmpeg-${VERSION}
# avoid makeinfo: error parsing ./doc/t2h.pm: Undefined subroutine &Texinfo::Config::set_from_init_file called at ./doc/t2h.pm line 24.
# with --disable-htmlpages
# --disable-doc works too, disables building documentation completely
# https://gist.github.com/omegdadi/6904512c0a948225c81114b1c5acb875
# https://github.com/7Ji/archrepo/issues/10
./configure --enable-gpl --enable-libx264 --enable-shared --disable-static --disable-htmlpages
make -j$(nproc)
# remove "--fstrans=no" when checkinstall is fixed (still not fixed in 24.04)
# # https://bugs.launchpad.net/ubuntu/+source/checkinstall/+bug/78455
checkinstall -yD --install=no --fstrans=no --pkgname=ffmpeg
mv ffmpeg*.deb /tmp/ffmpeg.deb
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+229
View File
@@ -0,0 +1,229 @@
/*
* power_burn_max - short CPU/LED-only power blip for boot.
*
* power_burn_max [seconds] [n_cores]
*
* seconds may be fractional. n_cores defaults to all 8 SDM845 cores; use 4 to
* burn only the big cluster.
*/
#define _GNU_SOURCE
#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
static volatile sig_atomic_t running = 1;
static volatile sig_atomic_t exit_signum = 0;
static void stop_sig(int s) { exit_signum = s; running = 0; }
/* End-of-ramoops DDR page. Survives warm reset if DDR stays in self-refresh
* across a PSU dropout, so ABL reads this cookie on boot to detect a mid-burn
* power cut. */
#define POWER_TEST_ADDR 0xB03FFFFCull
#define POWER_TEST_MAGIC 0x57505354u /* "WPST" */
static void write_magic(uint32_t val) {
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) return;
const uintptr_t page = POWER_TEST_ADDR & ~0xFFFull;
const uintptr_t off = POWER_TEST_ADDR & 0xFFFull;
void *p = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)page);
if (p == MAP_FAILED) { close(fd); return; }
*(volatile uint32_t *)((char *)p + off) = val;
msync(p, 0x1000, MS_SYNC);
munmap(p, 0x1000);
close(fd);
}
#define MAX_SAVED 128
static struct { char path[192]; char val[64]; } saved[MAX_SAVED];
static int nsaved;
static int sysfs_read(const char *p, char *b, int sz) {
FILE *f = fopen(p, "r");
if (!f) return -1;
if (!fgets(b, sz, f)) { fclose(f); return -1; }
fclose(f);
b[strcspn(b, "\n")] = 0;
return 0;
}
static void sysfs_write(const char *p, const char *v) {
FILE *f = fopen(p, "w");
if (!f) return;
fputs(v, f);
fclose(f);
}
static void save_and_write(const char *p, const char *v) {
if (nsaved < MAX_SAVED && sysfs_read(p, saved[nsaved].val, sizeof(saved[0].val)) == 0) {
strncpy(saved[nsaved].path, p, sizeof(saved[0].path) - 1);
saved[nsaved].path[sizeof(saved[0].path) - 1] = 0;
nsaved++;
}
sysfs_write(p, v);
}
static void restore_all(void) {
for (int i = nsaved - 1; i >= 0; i--) sysfs_write(saved[i].path, saved[i].val);
}
static void fatal_sig(int s) {
write_magic(0);
restore_all();
_exit(128 + s);
}
static void leds_on(void) {
save_and_write("/sys/class/leds/led:torch_0/brightness", "500");
save_and_write("/sys/class/leds/led:torch_1/brightness", "500");
save_and_write("/sys/class/leds/led:torch_2/brightness", "300");
save_and_write("/sys/class/leds/led:switch_0/brightness", "255");
save_and_write("/sys/class/leds/led:switch_1/brightness", "255");
save_and_write("/sys/class/leds/led:switch_2/brightness", "255");
}
static void cpu_bus_freq_max(void) {
save_and_write("/sys/class/devfreq/soc:qcom,cpubw/governor", "performance");
save_and_write("/sys/class/devfreq/soc:qcom,llccbw/governor", "performance");
save_and_write("/sys/class/devfreq/soc:qcom,l3-cpu0/governor", "performance");
save_and_write("/sys/class/devfreq/soc:qcom,l3-cpu4/governor", "performance");
}
static void pin_core(int cpu) {
char path[160];
char max_freq[32];
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu);
if (sysfs_read(path, max_freq, sizeof(max_freq)) != 0)
max_freq[0] = 0;
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/online", cpu);
save_and_write(path, "1");
if (max_freq[0]) {
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu);
save_and_write(path, max_freq);
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu);
save_and_write(path, max_freq);
}
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpu);
save_and_write(path, "performance");
}
static void *cpu_burn(void *arg) {
int core = (int)(intptr_t)arg;
cpu_set_t set; CPU_ZERO(&set); CPU_SET(core, &set);
pthread_setaffinity_np(pthread_self(), sizeof(set), &set);
void *mem = NULL;
if (posix_memalign(&mem, 64, 4096) != 0)
return NULL;
memset(mem, core, 4096);
const uint32_t a = 0x3f000000u + (uint32_t)core;
const uint32_t b = 0x3e800000u + (uint32_t)core;
const uint32_t c = 0x3f4ccccdu + (uint32_t)core;
while (running) {
asm volatile(
"dup v0.4s, %w[a]\n"
"dup v1.4s, %w[b]\n"
"dup v2.4s, %w[c]\n"
"dup v3.4s, %w[a]\n"
"dup v4.4s, %w[b]\n"
"dup v5.4s, %w[c]\n"
"dup v6.4s, %w[a]\n"
"dup v7.4s, %w[b]\n"
"dup v16.4s, %w[c]\n"
"dup v17.4s, %w[a]\n"
"dup v18.4s, %w[b]\n"
"dup v19.4s, %w[c]\n"
"mov x9, #10000\n"
"1:\n"
"ldp q20, q21, [%[p], #0]\n"
"fmla v0.4s, v16.4s, v17.4s\n"
"fmla v1.4s, v17.4s, v18.4s\n"
"fmla v2.4s, v18.4s, v19.4s\n"
"fmla v3.4s, v19.4s, v16.4s\n"
"ldp q22, q23, [%[p], #32]\n"
"fmla v4.4s, v16.4s, v18.4s\n"
"fmla v5.4s, v17.4s, v19.4s\n"
"fmla v6.4s, v18.4s, v16.4s\n"
"fmla v7.4s, v19.4s, v17.4s\n"
"eor v20.16b, v20.16b, v22.16b\n"
"fmla v8.4s, v0.4s, v17.4s\n"
"fmla v9.4s, v1.4s, v18.4s\n"
"fmla v10.4s, v2.4s, v19.4s\n"
"fmla v11.4s, v3.4s, v16.4s\n"
"eor v21.16b, v21.16b, v23.16b\n"
"fmla v12.4s, v4.4s, v18.4s\n"
"fmla v13.4s, v5.4s, v19.4s\n"
"fmla v14.4s, v6.4s, v16.4s\n"
"fmla v15.4s, v7.4s, v17.4s\n"
"stp q20, q21, [%[p], #0]\n"
"stp q22, q23, [%[p], #32]\n"
"subs x9, x9, #1\n"
"b.ne 1b\n"
:
: [p] "r" (mem), [a] "r" (a), [b] "r" (b), [c] "r" (c)
: "x9", "cc", "memory",
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
}
free(mem);
return NULL;
}
static uint64_t mono_ns(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)ts.tv_sec * 1000000000ull + ts.tv_nsec;
}
int main(int argc, char **argv) {
double duration_s = argc > 1 ? strtod(argv[1], NULL) : 1.0;
int n_cores = argc > 2 ? atoi(argv[2]) : 8;
if (n_cores < 0) n_cores = 0;
if (n_cores > 8) n_cores = 8;
int first_cpu = n_cores > 4 ? 0 : 4;
signal(SIGTERM, stop_sig);
signal(SIGINT, stop_sig);
signal(SIGABRT, fatal_sig);
signal(SIGSEGV, fatal_sig);
signal(SIGBUS, fatal_sig);
cpu_bus_freq_max();
for (int i = 0; i < n_cores; i++) pin_core(first_cpu + i);
write_magic(POWER_TEST_MAGIC);
leds_on();
pthread_t th[8];
for (int i = 0; i < n_cores; i++)
pthread_create(&th[i], NULL, cpu_burn, (void *)(intptr_t)(first_cpu + i));
uint64_t end_ns = duration_s > 0.0 ? mono_ns() + (uint64_t)(duration_s * 1000000000.0) : 0;
while (running) {
if (end_ns && mono_ns() >= end_ns) break;
usleep(1000);
}
running = 0;
for (int i = 0; i < n_cores; i++) pthread_join(th[i], NULL);
restore_all();
write_magic(0);
if (exit_signum) fprintf(stderr, "[power_burn_max] interrupted by signal %d\n", (int)exit_signum);
return 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+9
View File
@@ -8,6 +8,15 @@ CONTINUE="/data/continue.sh"
INSTALLER="/tmp/installer"
RESET_TRIGGER="/data/__system_reset__"
# blip power to ~5W to see if the PSU is stable
if grep -q mici /sys/firmware/devicetree/base/model; then
sudo timeout --kill-after=2 5 /home/comma/power_burn_max 0.3 2
fi
# use max freq to boot up quickly, then limit
echo 1689600 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
echo 1689600 | sudo tee /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq
echo "waiting for magic"
for i in {1..200}; do
if systemctl is-active --quiet magic && [ -S /tmp/drmfd.sock ]; then
+3 -3
View File
@@ -5,9 +5,9 @@ for i in {0..7}; do
echo "related" | sudo tee /sys/bus/msm_subsys/devices/subsys${i}/restart_level
done
# use max freq to boot up quickly, then limit
echo 1689600 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
echo 1689600 | sudo tee /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq
# raise scaling_max so policy=performance can reach the BOOST top step
echo 2649600 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
echo 2649600 | sudo tee /sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq
# boot wifi
echo 1 | sudo tee /sys/kernel/boot_wlan/boot_wlan
+1 -1
View File
@@ -10,7 +10,7 @@ WESTON_SOCK_PATH = os.path.join(WESTON_RUNTIME_DIR, "wayland-0")
SOCK_PATH = "/tmp/drmfd.sock"
DRM_DEVICE = "/dev/dri/card0"
BACKGROUND = "/usr/comma/bg.jpg"
BACKGROUND = "/usr/comma/bg.png"
# This is needed to keep the old updater working. Updater used to be stored in
# openpilot directly instead of in AGNOS. This will intercept the old updater
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1fe91ea2b36f42f254640410453e3d79414427f202d38c9c82a6ef7d84484e06
size 71009549
oid sha256:c65063074d2a8f1c334dc6debdc708edbac5f3189eaad912f93f0eaa44a8fd28
size 23027469
+10 -9
View File
@@ -15,21 +15,22 @@ GAMMA_ADDR = [
def command_mode(mode):
return f"39 01 00 00 0A 00 02 FE {((0b1010 << 4) | mode):02X}"
def send_command(command_str):
def pack_command(command_str):
command_buf = bytes(map(lambda x: int(x, base=16), command_str.strip().split()))
data = struct.pack(f"i{len(command_buf)}s", len(command_buf), command_buf)
with open(COMMAND_FILE, "wb") as f:
f.write(data)
return struct.pack(f"i{len(command_buf)}s", len(command_buf), command_buf)
def set_gamma(gamma):
send_command(command_mode(2))
cmds = [command_mode(2)]
for color_idx in range(3):
for i, val in reversed(list(enumerate(gamma[color_idx]))):
msb, lsb = GAMMA_ADDR[color_idx][i]
send_command(f"39 0F 00 00 0A 00 02 {msb:02X} {(val >> 8) & 0xFF:02X}")
send_command(f"39 {'01' if i % 10 == 0 else '0F'} 00 00 0A 00 02 {lsb:02X} {val & 0xFF:02X}")
send_command(command_mode(0))
cmds.append(f"39 0F 00 00 0A 00 02 {msb:02X} {(val >> 8) & 0xFF:02X}")
cmds.append(f"39 {'01' if i % 10 == 0 else '0F'} 00 00 0A 00 02 {lsb:02X} {val & 0xFF:02X}")
cmds.append(command_mode(0))
data = b"".join(pack_command(c) for c in cmds)
with open(COMMAND_FILE, "wb") as f:
f.write(data)
print("Successfully setup screen calibration")
if __name__ == "__main__":
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ea3709cb4f59154b87e5a7c7e6cf4cac8f6c0a213836b87e83499f6e6ff29c51
size 71009549
oid sha256:1575da9a3e6d7e73040a1230475b1930ebbc18b7042cb437628f653a12edf3c8
size 22996241
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56e6d2858a2a876cccceea9c171334b16fea5cbe82a3c1ec16755f5c8035480c
size 71009553
oid sha256:52be23a43ccf5adf479f35f79daf69018afc0967590593c24a56b838dc101ba3
size 23027473
+40 -49
View File
@@ -26,18 +26,23 @@ dependencies = [
"numpy >=2.0",
# vendored native dependencies
"bzip2 @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=bzip2",
"capnproto @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=capnproto",
"eigen @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=eigen",
"ffmpeg @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=ffmpeg",
"libjpeg @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=libjpeg",
"libyuv @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=libyuv",
"python3-dev @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=python3-dev",
"zstd @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=zstd",
"ncurses @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=ncurses",
"zeromq @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=zeromq",
"git-lfs @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=git-lfs",
"gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=gcc-arm-none-eabi",
"bzip2 @ git+https://github.com/commaai/dependencies.git@release-bzip2#subdirectory=bzip2",
"bootstrap-icons @ git+https://github.com/commaai/dependencies.git@release-bootstrap-icons#subdirectory=bootstrap-icons",
"capnproto @ git+https://github.com/commaai/dependencies.git@release-capnproto#subdirectory=capnproto",
"catch2 @ git+https://github.com/commaai/dependencies.git@release-catch2#subdirectory=catch2",
"acados @ git+https://github.com/commaai/dependencies.git@release-acados#subdirectory=acados",
"eigen @ git+https://github.com/commaai/dependencies.git@release-eigen#subdirectory=eigen",
"ffmpeg @ git+https://github.com/commaai/dependencies.git@release-ffmpeg#subdirectory=ffmpeg",
"libjpeg @ git+https://github.com/commaai/dependencies.git@release-libjpeg#subdirectory=libjpeg",
"libyuv @ git+https://github.com/commaai/dependencies.git@release-libyuv#subdirectory=libyuv",
"zstd @ git+https://github.com/commaai/dependencies.git@release-zstd#subdirectory=zstd",
"ncurses @ git+https://github.com/commaai/dependencies.git@release-ncurses#subdirectory=ncurses",
"zeromq @ git+https://github.com/commaai/dependencies.git@release-zeromq#subdirectory=zeromq",
"libusb @ git+https://github.com/commaai/dependencies.git@release-libusb#subdirectory=libusb",
"json11 @ git+https://github.com/commaai/dependencies.git@release-json11#subdirectory=json11",
"git-lfs @ git+https://github.com/commaai/dependencies.git@release-git-lfs#subdirectory=git-lfs",
"gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@release-gcc-arm-none-eabi#subdirectory=gcc-arm-none-eabi",
"xvfb @ git+https://github.com/commaai/dependencies.git@release-xvfb#subdirectory=xvfb",
# body / webrtcd
"av",
@@ -58,9 +63,6 @@ dependencies = [
"json-rpc",
"websocket_client",
# acados deps
"casadi >=3.6.6", # 3.12 fixed in 3.6.6
# joystickd
"inputs",
@@ -73,7 +75,7 @@ dependencies = [
"zstandard",
# ui
#"raylib > 5.5.0.3",
"raylib @ git+https://github.com/commaai/dependencies.git@release-raylib#subdirectory=raylib",
"qrcode",
"jeepney",
"pillow",
@@ -82,7 +84,7 @@ dependencies = [
[project.optional-dependencies]
docs = [
"Jinja2",
"mkdocs",
"zensical",
]
testing = [
@@ -94,7 +96,6 @@ testing = [
"pytest-subtests",
# https://github.com/pytest-dev/pytest-xdist/pull/1229
"pytest-xdist @ git+https://github.com/sshane/pytest-xdist@2b4372bd62699fb412c4fe2f95bf9f01bd2018da",
"pytest-asyncio",
"pytest-mock",
"ruff",
"codespell",
@@ -107,6 +108,7 @@ dev = [
]
tools = [
"imgui @ git+https://github.com/commaai/dependencies.git@release-imgui#subdirectory=imgui",
"metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')",
]
@@ -125,15 +127,17 @@ allow-direct-references = true
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup"
addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup"
cpp_files = "test_*"
cpp_harness = "selfdrive/test/cpp_harness.py"
python_files = "test_*.py"
asyncio_default_fixture_loop_scope = "function"
markers = [
"slow: tests that take awhile to run and can be skipped with -m 'not slow'",
"tici: tests that are only meant to run on the C3/C3X",
"skip_tici_setup: mark test to skip tici setup fixture"
"skip_tici_setup: mark test to skip tici setup fixture",
"nocapture: don't capture test output",
"shared_download_cache: share download cache between tests",
"xdist_group_class_property: group tests by a property of the class that contains them",
]
testpaths = [
"common",
@@ -148,7 +152,7 @@ quiet-level = 3
# if you've got a short variable name that's getting flagged, add it here
ignore-words-list = "bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn,ws,uint,grey,deque,stdio,amin,BA,LITE,atEnd,UIs,errorString,arange,FocusIn,od,tim,relA,hist,copyable,jupyter,thead,TGE,abl,lite,ser"
builtin = "clear,rare,informal,code,names,en-GB_to_en-US"
skip = "./third_party/*, ./tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.po, uv.lock, *.onnx, ./cereal/gen/*, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html"
skip = "../tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.po, uv.lock, *.onnx, *.pem, ./cereal/gen/*, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html"
# https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml
[tool.ruff]
@@ -173,9 +177,7 @@ lint.ignore = [
"UP045", "UP007", # these don't play nice with raylib atm
]
line-length = 160
target-version ="py311"
exclude = [
"body",
"cereal",
"panda",
"opendbc",
@@ -184,7 +186,6 @@ exclude = [
"tinygrad_repo",
"teleoprtc",
"teleoprtc_repo",
"third_party",
"*.ipynb",
"generated",
]
@@ -194,7 +195,6 @@ lint.flake8-implicit-str-concat.allow-multiline = false
"selfdrive".msg = "Use openpilot.selfdrive"
"common".msg = "Use openpilot.common"
"system".msg = "Use openpilot.system"
"third_party".msg = "Use openpilot.third_party"
"tools".msg = "Use openpilot.tools"
"pytest.main".msg = "pytest.main requires special handling that is easy to mess up!"
"unittest".msg = "Use pytest"
@@ -205,13 +205,13 @@ lint.flake8-implicit-str-concat.allow-multiline = false
"pyray.is_mouse_button_pressed".msg = "This can miss events. Use Widget._handle_mouse_press"
"pyray.is_mouse_button_released".msg = "This can miss events. Use Widget._handle_mouse_release"
"pyray.draw_text".msg = "Use a function (such as rl.draw_font_ex) that takes font as an argument"
"pyray.draw_texture".msg = "Use rl.draw_texture_ex for float position support"
[tool.ruff.format]
quote-style = "preserve"
[tool.ty.src]
exclude = [
"cereal/",
"msgq/",
"msgq_repo/",
"opendbc/",
@@ -223,28 +223,19 @@ exclude = [
"tinygrad_repo/",
"teleoprtc/",
"teleoprtc_repo/",
"third_party/",
]
[tool.ty.rules]
# Ignore unresolved imports for Cython-compiled modules (.pyx)
unresolved-import = "ignore"
# Ignore unresolved attributes - many from capnp and Cython modules
unresolved-attribute = "ignore"
# Ignore invalid method overrides - signature variance issues
invalid-method-override = "ignore"
# Ignore possibly-missing-attribute - too many false positives
possibly-missing-attribute = "ignore"
# Ignore invalid assignment - often intentional monkey-patching
invalid-assignment = "ignore"
# Ignore no-matching-overload - numpy/ctypes overload matching issues
no-matching-overload = "ignore"
# Ignore invalid-argument-type - many false positives from raylib, ctypes, numpy
invalid-argument-type = "ignore"
# Ignore call-non-callable - false positives from dynamic types
call-non-callable = "ignore"
# Ignore unsupported-operator - false positives from dynamic types
unsupported-operator = "ignore"
# Ignore not-subscriptable - false positives from dynamic types
not-subscriptable = "ignore"
# not-iterable errors are now fixed
unresolved-import = "ignore" # Cython-compiled modules (.pyx)
unresolved-attribute = "ignore" # many from capnp and Cython modules
invalid-method-override = "ignore" # signature variance issues
possibly-missing-attribute = "ignore" # too many false positives
invalid-assignment = "ignore" # often intentional monkey-patching
no-matching-overload = "ignore" # numpy/ctypes overload matching issues
invalid-argument-type = "ignore" # many false positives from raylib, ctypes, numpy
call-non-callable = "ignore" # false positives from dynamic types
unsupported-operator = "ignore" # false positives from dynamic types
not-subscriptable = "ignore" # false positives from dynamic types
[tool.uv]
python-preference = "only-managed"
+4 -1
View File
@@ -17,6 +17,8 @@ dependencies = [
# provisioning
"pyusb",
# pandad
"libusb1 ==3.1.0", # recent versions segfault on comma three
"paramiko",
# extra nice-to-haves
@@ -25,9 +27,10 @@ dependencies = [
"py-spy",
"spidev2",
"flaky",
"matplotlib",
# GUIs
"raylib @ https://github.com/commaai/raylib-python-cffi/releases/download/8/raylib-5.5.0.2-cp312-cp312-linux_aarch64.whl",
"raylib @ git+https://github.com/commaai/dependencies.git@release-raylib#subdirectory=raylib",
]
[tool.uv.sources]
+471 -329
View File
File diff suppressed because it is too large Load Diff