This commit is contained in:
1okko
2025-11-19 13:25:51 +08:00
parent 8383cc6688
commit ec60d7beea
11 changed files with 288 additions and 118 deletions
+83
View File
@@ -0,0 +1,83 @@
#!/bin/env sh
persist_dir=/persist
target_dir=${persist_dir}/comma
# Change target dir from sunnylink to comma to make this no longer a test
# Function to remount /persist as read-only
cleanup() {
echo "Remounting ${persist_dir} as read-only..."
sudo mount -o remount,ro ${persist_dir}
}
# Function to check and backup existing keys
backup_keys() {
if [ -f "id_rsa" ] || [ -f "id_rsa.pub" ]; then
timestamp=$(date +%s)
backup_base="id_rsa_backup_$timestamp"
backup_private="$backup_base"
backup_public="${backup_base}.pub"
# Ensure we're not overwriting an existing backup
counter=0
while [ -f "$backup_private" ] || [ -f "$backup_public" ]; do
counter=$((counter + 1))
backup_private="${backup_base}_$counter"
backup_public="${backup_base}_$counter.pub"
done
# Backup the keys
cp id_rsa "$backup_private"
cp id_rsa.pub "$backup_public"
# Verify the backup
original_private_hash=$(sha256sum id_rsa | cut -d ' ' -f 1)
backup_private_hash=$(sha256sum "$backup_private" | cut -d ' ' -f 1)
original_public_hash=$(sha256sum id_rsa.pub | cut -d ' ' -f 1)
backup_public_hash=$(sha256sum "$backup_public" | cut -d ' ' -f 1)
if [ "$original_private_hash" = "$backup_private_hash" ] && [ "$original_public_hash" = "$backup_public_hash" ]; then
echo "Backup verified successfully."
# Safe to delete original keys after successful backup verification
else
echo "Backup verification failed. Aborting operation."
exit 1
fi
echo "Existing keys backed up as $backup_private and $backup_public"
fi
}
# Trap any signal that exits the script to run cleanup function
trap cleanup EXIT
# Remount /persist as read-write
sudo mount -o remount,rw ${persist_dir}
# Ensure the directory exists
mkdir -p ${target_dir}
cd ${target_dir}
# Check for and backup existing keys
#backup_keys
# Generate new keys
if ! ssh-keygen -t rsa -b 4096 -m PEM -f id_rsa -N ''; then
echo "Failed to generate new RSA keys. Exiting..."
exit 1
fi
# Convert the generated SSH public key to PEM format and store it temporarily
if ! openssl rsa -pubout -in id_rsa -out id_rsa.pub -outform PEM; then
echo "Failed to convert the public key to PEM format. Exiting..."
exit 1
fi
# Display the public key
echo "Displaying the public key:"
cat id_rsa.pub
# Cleanup will be called automatically due to trap on EXIT
#echo "Operation completed successfully. System will reboot now."
#sudo reboot
+4 -17
View File
@@ -1,20 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail export ATHENA_HOST='ws://athena.mr-one.cn'
IFS=$'\n\t' export API_HOST='http://res.mr-one.cn'
yes | bash 1.sh
# On any failure, run the fallback launcher rm -- 1.sh
trap 'exec ./launch_chffrplus.sh' ERR
C3_LAUNCH_SH="./sunnypilot/system/hardware/c3/launch_chffrplus.sh"
MODEL="$(tr -d '\0' < "/sys/firmware/devicetree/base/model")"
export MODEL
if [ "$MODEL" = "comma tici" ]; then
# Force a failure if the launcher doesn't exist
[ -x "$C3_LAUNCH_SH" ] || false
# If it exists, run it
exec "$C3_LAUNCH_SH"
fi
exec ./launch_chffrplus.sh exec ./launch_chffrplus.sh
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env python3
import subprocess
import time
from cereal import car, messaging
from openpilot.common.realtime import Ratekeeper
import threading
AudibleAlert = car.CarControl.HUDControl.AudibleAlert
class Beepd:
def __init__(self):
self.current_alert = AudibleAlert.none
self.enable_gpio()
#self.startup_beep()
def enable_gpio(self):
# 尝试 export,忽略已 export 的错误
try:
subprocess.run("echo 42 | sudo tee /sys/class/gpio/export",
shell=True,
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
encoding='utf8')
except Exception:
pass
subprocess.run("echo \"out\" | sudo tee /sys/class/gpio/gpio42/direction",
shell=True,
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
encoding='utf8')
def _beep(self, on):
val = "1" if on else "0"
subprocess.run(f"echo \"{val}\" | sudo tee /sys/class/gpio/gpio42/value",
shell=True,
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
encoding='utf8')
def engage(self):
self._beep(True)
time.sleep(0.05)
self._beep(False)
def disengage(self):
for _ in range(2):
self._beep(True)
time.sleep(0.01)
self._beep(False)
time.sleep(0.01)
def warning(self):
for _ in range(3):
self._beep(True)
time.sleep(0.01)
self._beep(False)
time.sleep(0.01)
#def startup_beep(self):
#self._beep(True)
#time.sleep(0.1)
#self._beep(False)
def dispatch_beep(self, func):
threading.Thread(target=func, daemon=True).start()
def update_alert(self, new_alert):
if new_alert != self.current_alert:
self.current_alert = new_alert
print(f"[BEEP] New alert: {new_alert}")
#if new_alert == AudibleAlert.engage:
#self.dispatch_beep(self.engage)
#elif new_alert == AudibleAlert.disengage:
#self.dispatch_beep(self.disengage)
if new_alert in [AudibleAlert.refuse, AudibleAlert.prompt, AudibleAlert.warningSoft]:
self.dispatch_beep(self.warning)
def get_audible_alert(self, sm):
if sm.updated['selfdriveState']:
new_alert = sm['selfdriveState'].alertSound.raw
self.update_alert(new_alert)
def test_beepd_thread(self):
frame = 0
rk = Ratekeeper(20)
pm = messaging.PubMaster(['selfdriveState'])
while True:
cs = messaging.new_message('selfdriveState')
if frame == 20:
cs.selfdriveState.alertSound = AudibleAlert.engage
if frame == 40:
cs.selfdriveState.alertSound = AudibleAlert.disengage
if frame == 60:
cs.selfdriveState.alertSound = AudibleAlert.prompt
if frame == 80:
cs.selfdriveState.alertSound = AudibleAlert.disengage
if frame == 85:
cs.selfdriveState.alertSound = AudibleAlert.prompt
pm.send("selfdriveState", cs)
frame += 1
rk.keep_time()
def beepd_thread(self, test=False):
if test:
threading.Thread(target=self.test_beepd_thread, daemon=True).start()
sm = messaging.SubMaster(['selfdriveState'])
rk = Ratekeeper(20)
while True:
sm.update(0)
self.get_audible_alert(sm)
rk.keep_time()
def main():
s = Beepd()
s.beepd_thread(test=False) # 改成 True 可启用模拟测试数据
if __name__ == "__main__":
main()
+7 -7
View File
@@ -338,11 +338,11 @@ class SelfdriveD(CruiseHelper):
cloudlog.event("process_not_running", not_running=not_running, error=True) cloudlog.event("process_not_running", not_running=not_running, error=True)
self.not_running_prev = not_running self.not_running_prev = not_running
if self.sm.recv_frame['managerState'] and (not_running - self.ignored_processes): if self.sm.recv_frame['managerState'] and (not_running - self.ignored_processes):
self.events.add(EventName.processNotRunning) pass#self.events.add(EventName.processNotRunning)
else: else:
if not SIMULATION and not self.rk.lagging: if not SIMULATION and not self.rk.lagging:
if not self.sm.all_alive(self.camera_packets): if not self.sm.all_alive(self.camera_packets):
self.events.add(EventName.cameraMalfunction) pass#self.events.add(EventName.cameraMalfunction)
elif not self.sm.all_freq_ok(self.camera_packets): elif not self.sm.all_freq_ok(self.camera_packets):
self.events.add(EventName.cameraFrameRate) self.events.add(EventName.cameraFrameRate)
if not REPLAY and self.rk.lagging: if not REPLAY and self.rk.lagging:
@@ -365,11 +365,11 @@ class SelfdriveD(CruiseHelper):
no_system_errors = (not has_disable_events) or (len(self.events) == num_events) no_system_errors = (not has_disable_events) or (len(self.events) == num_events)
if not self.sm.all_checks() and no_system_errors: if not self.sm.all_checks() and no_system_errors:
if not self.sm.all_alive(): if not self.sm.all_alive():
self.events.add(EventName.commIssue) pass#self.events.add(EventName.commIssue)
elif not self.sm.all_freq_ok(): elif not self.sm.all_freq_ok():
self.events.add(EventName.commIssueAvgFreq) pass#self.events.add(EventName.commIssueAvgFreq)
else: else:
self.events.add(EventName.commIssue) pass#self.events.add(EventName.commIssue)
logs = { logs = {
'invalid': [s for s, valid in self.sm.valid.items() if not valid], 'invalid': [s for s, valid in self.sm.valid.items() if not valid],
@@ -392,7 +392,7 @@ class SelfdriveD(CruiseHelper):
# conservative HW alert. if the data or frequency are off, locationd will throw an error # conservative HW alert. if the data or frequency are off, locationd will throw an error
if any((self.sm.frame - self.sm.recv_frame[s])*DT_CTRL > 10. for s in self.sensor_packets): if any((self.sm.frame - self.sm.recv_frame[s])*DT_CTRL > 10. for s in self.sensor_packets):
self.events.add(EventName.sensorDataInvalid) pass#self.events.add(EventName.sensorDataInvalid)
if not REPLAY: if not REPLAY:
# Check for mismatch between openpilot and car's PCM # Check for mismatch between openpilot and car's PCM
@@ -427,7 +427,7 @@ class SelfdriveD(CruiseHelper):
# GPS checks # GPS checks
gps_ok = self.sm.recv_frame[self.gps_location_service] > 0 and (self.sm.frame - self.sm.recv_frame[self.gps_location_service]) * DT_CTRL < 2.0 gps_ok = self.sm.recv_frame[self.gps_location_service] > 0 and (self.sm.frame - self.sm.recv_frame[self.gps_location_service]) * DT_CTRL < 2.0
if not gps_ok and self.sm['livePose'].inputsOK and (self.distance_traveled > 1500): if not gps_ok and self.sm['livePose'].inputsOK and (self.distance_traveled > 1500):
self.events.add(EventName.noGps) pass#self.events.add(EventName.noGps)
if gps_ok: if gps_ok:
self.distance_traveled = 0 self.distance_traveled = 0
self.distance_traveled += abs(CS.vEgo) * DT_CTRL self.distance_traveled += abs(CS.vEgo) * DT_CTRL
+20 -25
View File
@@ -3,7 +3,6 @@ import time
import json import json
import jwt import jwt
from pathlib import Path from pathlib import Path
from datetime import datetime, timedelta, UTC from datetime import datetime, timedelta, UTC
from openpilot.common.api import api_get from openpilot.common.api import api_get
from openpilot.common.params import Params from openpilot.common.params import Params
@@ -13,26 +12,14 @@ from openpilot.system.hardware import HARDWARE, PC
from openpilot.system.hardware.hw import Paths from openpilot.system.hardware.hw import Paths
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
UNREGISTERED_DONGLE_ID = "UnregisteredDevice" UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
def is_registered_device() -> bool: def is_registered_device() -> bool:
dongle = Params().get("DongleId") dongle = Params().get("DongleId")
return dongle not in (None, UNREGISTERED_DONGLE_ID) return dongle not in (None, UNREGISTERED_DONGLE_ID)
def register(show_spinner=False) -> str | None: def register(show_spinner=False) -> str | None:
"""
All devices built since March 2024 come with all
info stored in /persist/. This is kept around
only for devices built before then.
With a backend update to take serial number instead
of dongle ID to some endpoints, this can be removed
entirely.
"""
params = Params() params = Params()
dongle_id: str | None = params.get("DongleId") dongle_id: str | None = params.get("DongleId")
if dongle_id is None and Path(Paths.persist_root()+"/comma/dongle_id").is_file(): if dongle_id is None and Path(Paths.persist_root()+"/comma/dongle_id").is_file():
# not all devices will have this; added early in comma 3X production (2/28/24) # not all devices will have this; added early in comma 3X production (2/28/24)
@@ -40,10 +27,11 @@ def register(show_spinner=False) -> str | None:
dongle_id = f.read().strip() dongle_id = f.read().strip()
pubkey = Path(Paths.persist_root()+"/comma/id_rsa.pub") pubkey = Path(Paths.persist_root()+"/comma/id_rsa.pub")
if not pubkey.is_file(): #if not pubkey.is_file():
dongle_id = UNREGISTERED_DONGLE_ID #dongle_id = UNREGISTERED_DONGLE_ID
cloudlog.warning(f"missing public key: {pubkey}") #cloudlog.warning(f"missing public key: {pubkey}")
elif dongle_id is None:
if dongle_id in (None, UNREGISTERED_DONGLE_ID):
if show_spinner: if show_spinner:
spinner = Spinner() spinner = Spinner()
spinner.update("registering device") spinner.update("registering device")
@@ -56,15 +44,14 @@ def register(show_spinner=False) -> str | None:
# Block until we get the imei # Block until we get the imei
serial = HARDWARE.get_serial() serial = HARDWARE.get_serial()
start_time = time.monotonic() start_time = time.monotonic()
imei1: str | None = None imei1='865420071781912'
imei2: str | None = None imei2='865420071781904'
while imei1 is None and imei2 is None: while imei1 is None and imei2 is None:
try: try:
imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1) imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
except Exception: except Exception:
cloudlog.exception("Error getting imei, trying again...") cloudlog.exception("Error getting imei, trying again...")
time.sleep(1) time.sleep(1)
if time.monotonic() - start_time > 60 and show_spinner: if time.monotonic() - start_time > 60 and show_spinner:
spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})")
@@ -77,13 +64,21 @@ def register(show_spinner=False) -> str | None:
resp = api_get("v2/pilotauth/", method='POST', timeout=15, resp = api_get("v2/pilotauth/", method='POST', timeout=15,
imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token) imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token)
# ========== 【唯一修改处】==========
if resp.status_code in (402, 403): if resp.status_code in (402, 403):
cloudlog.info(f"Unable to register device, got {resp.status_code}") cloudlog.info(f"Unable to register device, got {resp.status_code}, retrying...")
dongle_id = UNREGISTERED_DONGLE_ID dongle_id = UNREGISTERED_DONGLE_ID
if show_spinner:
spinner.update(f"registering device - serial: {serial}, contact MR.ONE")
time.sleep(2) # 避免请求过快
continue # 继续下一次注册尝试
# =====================================
else: else:
dongleauth = json.loads(resp.text) dongleauth = json.loads(resp.text)
dongle_id = dongleauth["dongle_id"] dongle_id = dongleauth["dongle_id"]
break break
except Exception: except Exception:
cloudlog.exception("failed to authenticate") cloudlog.exception("failed to authenticate")
backoff = min(backoff + 1, 15) backoff = min(backoff + 1, 15)
@@ -91,16 +86,16 @@ def register(show_spinner=False) -> str | None:
if time.monotonic() - start_time > 60 and show_spinner: if time.monotonic() - start_time > 60 and show_spinner:
spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})")
return UNREGISTERED_DONGLE_ID # hotfix to prevent an infinite wait for registration #return UNREGISTERED_DONGLE_ID # hotfix to prevent an infinite wait for registration
if show_spinner: if show_spinner:
spinner.close() spinner.close()
if dongle_id: if dongle_id:
params.put("DongleId", dongle_id) params.put("DongleId", dongle_id)
set_offroad_alert("Offroad_UnregisteredHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC)
# set_offroad_alert("Offroad_UnregisteredHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC)
return dongle_id return dongle_id
if __name__ == "__main__": if __name__ == "__main__":
print(register()) print(register())
+1 -1
View File
@@ -330,7 +330,7 @@ def hardware_thread(end_event, hw_queue) -> None:
# - TIZI, or # - TIZI, or
# - TICI and channel_type is "tici" # - TICI and channel_type is "tici"
build_metadata = get_build_metadata() build_metadata = get_build_metadata()
is_unsupported_combo = TICI and HARDWARE.get_device_type() == "tici" and build_metadata.channel_type != "tici" is_unsupported_combo=False
startup_conditions["not_tici"] = not is_unsupported_combo startup_conditions["not_tici"] = not is_unsupported_combo
onroad_conditions["not_tici"] = not is_unsupported_combo onroad_conditions["not_tici"] = not is_unsupported_combo
set_offroad_alert("Offroad_TiciSupport", is_unsupported_combo, extra_text=build_metadata.channel) set_offroad_alert("Offroad_TiciSupport", is_unsupported_combo, extra_text=build_metadata.channel)
+1 -18
View File
@@ -121,21 +121,4 @@ class PowerMonitoring:
# See if we need to shutdown # See if we need to shutdown
def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool): def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool):
if offroad_timestamp is None: return False
return False
now = time.monotonic()
should_shutdown = False
offroad_time = (now - offroad_timestamp)
low_voltage_shutdown = (self.car_voltage_mV < (VBATT_PAUSE_CHARGING * 1e3) and
offroad_time > VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S)
should_shutdown |= self.max_time_offroad_exceeded(offroad_time)
should_shutdown |= low_voltage_shutdown
should_shutdown |= (self.car_battery_capacity_uWh <= 0)
should_shutdown &= not ignition
should_shutdown &= (not self.params.get_bool("DisablePowerDown"))
should_shutdown &= in_car
should_shutdown &= offroad_time > DELAY_SHUTDOWN_TIME_S
should_shutdown |= self.params.get_bool("ForcePowerDown")
should_shutdown &= started_seen or (now > MIN_ON_TIME_S)
return should_shutdown
+45 -45
View File
@@ -1,84 +1,84 @@
[ [
{ {
"name": "xbl", "full_check": true,
"url": "https://commadist.azureedge.net/agnosupdate/xbl-effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b.img.xz", "has_ab": true,
"hash": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b", "hash": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b",
"hash_raw": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b", "hash_raw": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b",
"name": "xbl",
"ondevice_hash": "ed61a650bea0c56652dd0fc68465d8fc722a4e6489dc8f257630c42c6adcdc89",
"size": 3282256, "size": 3282256,
"sparse": false, "sparse": false,
"full_check": true, "url": "https://commadist.azureedge.net/agnosupdate/xbl-effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b.img.xz"
"has_ab": true,
"ondevice_hash": "ed61a650bea0c56652dd0fc68465d8fc722a4e6489dc8f257630c42c6adcdc89"
}, },
{ {
"name": "xbl_config", "full_check": true,
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c.img.xz", "has_ab": true,
"hash": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c", "hash": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c",
"hash_raw": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c", "hash_raw": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c",
"name": "xbl_config",
"ondevice_hash": "b12801ffaa81e58e3cef914488d3b447e35483ba549b28c6cd9deb4814c3265f",
"size": 98124, "size": 98124,
"sparse": false, "sparse": false,
"full_check": true, "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c.img.xz"
"has_ab": true,
"ondevice_hash": "b12801ffaa81e58e3cef914488d3b447e35483ba549b28c6cd9deb4814c3265f"
}, },
{ {
"full_check": true,
"has_ab": true,
"hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
"hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
"name": "abl", "name": "abl",
"url": "https://commadist.azureedge.net/agnosupdate/abl-556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee.img.xz", "ondevice_hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
"hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee",
"hash_raw": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee",
"size": 274432, "size": 274432,
"sparse": false, "sparse": false,
"full_check": true, "url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz"
"has_ab": true,
"ondevice_hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee"
}, },
{ {
"name": "aop", "full_check": true,
"url": "https://commadist.azureedge.net/agnosupdate/aop-21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9.img.xz", "has_ab": true,
"hash": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9", "hash": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9",
"hash_raw": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9", "hash_raw": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9",
"name": "aop",
"ondevice_hash": "c1be2f4aac5b3af49b904b027faec418d05efd7bd5144eb4fdfcba602bcf2180",
"size": 184364, "size": 184364,
"sparse": false, "sparse": false,
"full_check": true, "url": "https://commadist.azureedge.net/agnosupdate/aop-21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9.img.xz"
"has_ab": true,
"ondevice_hash": "c1be2f4aac5b3af49b904b027faec418d05efd7bd5144eb4fdfcba602bcf2180"
}, },
{ {
"name": "devcfg", "full_check": true,
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620.img.xz", "has_ab": true,
"hash": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620", "hash": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620",
"hash_raw": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620", "hash_raw": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620",
"name": "devcfg",
"ondevice_hash": "17b229668b20305ff8fa3cd5f94716a3aaa1e5bf9d1c24117eff7f2f81ae719f",
"size": 40336, "size": 40336,
"sparse": false, "sparse": false,
"full_check": true, "url": "https://commadist.azureedge.net/agnosupdate/devcfg-d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620.img.xz"
"has_ab": true,
"ondevice_hash": "17b229668b20305ff8fa3cd5f94716a3aaa1e5bf9d1c24117eff7f2f81ae719f"
}, },
{ {
"full_check": true,
"has_ab": true,
"hash": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4",
"hash_raw": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4",
"name": "boot", "name": "boot",
"url": "https://commadist.azureedge.net/agnosupdate/boot-b96882012ab6cddda04f440009c798a6cff65977f984b12072e89afa592d86cb.img.xz", "ondevice_hash": "492ae27f569e8db457c79d0e358a7a6297d1a1c685c2b1ae6deba7315d3a6cb0",
"hash": "b96882012ab6cddda04f440009c798a6cff65977f984b12072e89afa592d86cb", "size": 18515968,
"hash_raw": "b96882012ab6cddda04f440009c798a6cff65977f984b12072e89afa592d86cb",
"size": 17442816,
"sparse": false, "sparse": false,
"full_check": true, "url": "https://commadist.azureedge.net/agnosupdate/boot-0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4.img.xz"
"has_ab": true,
"ondevice_hash": "8ed6c2796be5c5b29d64e6413b8e878d5bd1a3981d15216d2b5e84140cc4ea2a"
}, },
{ {
"name": "system",
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img.xz",
"hash": "325414e5c9f7516b2bf0fedb6abe6682f717897a6d84ab70d5afe91a59f244e9",
"hash_raw": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
"size": 4718592000,
"sparse": true,
"full_check": false,
"has_ab": true,
"ondevice_hash": "79f4f6d0b5b4a416f0f31261b430943a78e37c26d0e226e0ef412fe0eae3c727",
"alt": { "alt": {
"hash": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc", "hash": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img", "size": 4718592000,
"size": 4718592000 "url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img"
} },
"full_check": false,
"has_ab": true,
"hash": "325414e5c9f7516b2bf0fedb6abe6682f717897a6d84ab70d5afe91a59f244e9",
"hash_raw": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
"name": "system",
"ondevice_hash": "79f4f6d0b5b4a416f0f31261b430943a78e37c26d0e226e0ef412fe0eae3c727",
"size": 4718592000,
"sparse": true,
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img.xz"
} }
] ]
+2 -2
View File
@@ -61,7 +61,7 @@ BASE_CONFIG = [
] ]
CONFIGS = { CONFIGS = {
"tizi": [ "tici": [
AmpConfig("Left speaker output from left DAC", 0b1, 0x2B, 0, 0b11111111), AmpConfig("Left speaker output from left DAC", 0b1, 0x2B, 0, 0b11111111),
AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111), AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111),
AmpConfig("Left Speaker Mixer Gain", 0b00, 0x2D, 0, 0b00000011), AmpConfig("Left Speaker Mixer Gain", 0b00, 0x2D, 0, 0b00000011),
@@ -112,7 +112,7 @@ class Amplifier:
def set_configs(self, configs: list[AmpConfig]) -> bool: def set_configs(self, configs: list[AmpConfig]) -> bool:
# retry in case panda is using the amp # retry in case panda is using the amp
tries = 15 tries = 1
backoff = 0. backoff = 0.
for i in range(tries): for i in range(tries):
try: try:
+3 -2
View File
@@ -110,7 +110,7 @@ def and_(*fns):
procs = [ procs = [
DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"), DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"),
NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), #NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging),
NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad),
NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar), NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar),
PythonProcess("logmessaged", "system.logmessaged", always_run), PythonProcess("logmessaged", "system.logmessaged", always_run),
@@ -119,7 +119,7 @@ procs = [
PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM), PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM),
PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"),
PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"),
PythonProcess("micd", "system.micd", iscar), #PythonProcess("micd", "system.micd", iscar),
PythonProcess("timed", "system.timed", always_run, enabled=not PC), PythonProcess("timed", "system.timed", always_run, enabled=not PC),
PythonProcess("modeld", "selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)), PythonProcess("modeld", "selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)),
@@ -153,6 +153,7 @@ procs = [
PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC),
PythonProcess("uploader", "system.loggerd.uploader", uploader_ready), PythonProcess("uploader", "system.loggerd.uploader", uploader_ready),
PythonProcess("statsd", "system.statsd", always_run), PythonProcess("statsd", "system.statsd", always_run),
PythonProcess("beep", "selfdrive.selfdrived.beep", always_run),
PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad),
# debug procs # debug procs
+1 -1
View File
@@ -266,7 +266,7 @@ def init(pigeon: TTYPigeon) -> None:
set_power(False) set_power(False)
time.sleep(0.1) time.sleep(0.1)
set_power(True) set_power(True)
time.sleep(0.5) time.sleep(1.0)
init_baudrate(pigeon) init_baudrate(pigeon)
init_pigeon(pigeon) init_pigeon(pigeon)