boardd: remove global panda (#21962)

old-commit-hash: 8008cf5547
commatwo_master
Dean Lee 4 years ago committed by GitHub
parent 94d1866ccd
commit f2d7b27cbd
  1. 88
      selfdrive/boardd/boardd.cc

@ -35,14 +35,12 @@
#define SATURATE_IL 1600 #define SATURATE_IL 1600
#define NIBBLE_TO_HEX(n) ((n) < 10 ? (n) + '0' : ((n) - 10) + 'a') #define NIBBLE_TO_HEX(n) ((n) < 10 ? (n) + '0' : ((n) - 10) + 'a')
Panda * panda = nullptr;
std::atomic<bool> safety_setter_thread_running(false); std::atomic<bool> safety_setter_thread_running(false);
std::atomic<bool> ignition(false); std::atomic<bool> ignition(false);
ExitHandler do_exit; ExitHandler do_exit;
void safety_setter_thread(Panda *panda) {
void safety_setter_thread() {
LOGD("Starting safety setter thread"); LOGD("Starting safety setter thread");
// diagnostic only is the default, needed for VIN query // diagnostic only is the default, needed for VIN query
panda->set_safety_model(cereal::CarParams::SafetyModel::ELM327); panda->set_safety_model(cereal::CarParams::SafetyModel::ELM327);
@ -101,24 +99,21 @@ void safety_setter_thread() {
} }
bool usb_connect() { Panda *usb_connect() {
static bool connected_once = false; std::unique_ptr<Panda> panda;
std::unique_ptr<Panda> tmp_panda;
try { try {
assert(panda == nullptr); panda = std::make_unique<Panda>();
tmp_panda = std::make_unique<Panda>();
} catch (std::exception &e) { } catch (std::exception &e) {
return false; return nullptr;
} }
Params params = Params(); Params params = Params();
if (getenv("BOARDD_LOOPBACK")) { if (getenv("BOARDD_LOOPBACK")) {
tmp_panda->set_loopback(true); panda->set_loopback(true);
} }
if (auto fw_sig = tmp_panda->get_firmware_version(); fw_sig) { if (auto fw_sig = panda->get_firmware_version(); fw_sig) {
params.put("PandaFirmware", (const char *)fw_sig->data(), fw_sig->size()); params.put("PandaFirmware", (const char *)fw_sig->data(), fw_sig->size());
// Convert to hex for offroad // Convert to hex for offroad
@ -131,25 +126,24 @@ bool usb_connect() {
params.put("PandaFirmwareHex", fw_sig_hex_buf, 16); params.put("PandaFirmwareHex", fw_sig_hex_buf, 16);
LOGW("fw signature: %.*s", 16, fw_sig_hex_buf); LOGW("fw signature: %.*s", 16, fw_sig_hex_buf);
} else { return false; } } else { return nullptr; }
// get panda serial // get panda serial
if (auto serial = tmp_panda->get_serial(); serial) { if (auto serial = panda->get_serial(); serial) {
params.put("PandaDongleId", serial->c_str(), serial->length()); params.put("PandaDongleId", serial->c_str(), serial->length());
LOGW("panda serial: %s", serial->c_str()); LOGW("panda serial: %s", serial->c_str());
} else { return false; } } else { return nullptr; }
// power on charging, only the first time. Panda can also change mode and it causes a brief disconneciton // power on charging, only the first time. Panda can also change mode and it causes a brief disconneciton
#ifndef __x86_64__ #ifndef __x86_64__
if (!connected_once) { static std::once_flag connected_once;
tmp_panda->set_usb_power_mode(cereal::PandaState::UsbPowerMode::CDP); std::call_once(connected_once, &Panda::set_usb_power_mode, panda, cereal::PandaState::UsbPowerMode::CDP);
}
#endif #endif
if (tmp_panda->has_rtc) { if (panda->has_rtc) {
setenv("TZ","UTC",1); setenv("TZ","UTC",1);
struct tm sys_time = util::get_time(); struct tm sys_time = util::get_time();
struct tm rtc_time = tmp_panda->get_rtc(); struct tm rtc_time = panda->get_rtc();
if (!util::time_valid(sys_time) && util::time_valid(rtc_time)) { if (!util::time_valid(sys_time) && util::time_valid(rtc_time)) {
LOGE("System time wrong, setting from RTC. " LOGE("System time wrong, setting from RTC. "
@ -164,29 +158,31 @@ bool usb_connect() {
} }
} }
connected_once = true; return panda.release();
panda = tmp_panda.release();
return true;
} }
// must be called before threads or with mutex // must be called before threads or with mutex
static bool usb_retry_connect() { static Panda *usb_retry_connect() {
LOGW("attempting to connect"); LOGW("attempting to connect");
while (!do_exit && !usb_connect()) { util::sleep_for(100); } while (!do_exit) {
if (panda) { Panda *panda = usb_connect();
LOGW("connected to board"); if (panda) {
} LOGW("connected to board");
return !do_exit; return panda;
}
util::sleep_for(100);
};
return nullptr;
} }
void can_recv(PubMaster &pm) { void can_recv(Panda *panda, PubMaster &pm) {
kj::Array<capnp::word> can_data; kj::Array<capnp::word> can_data;
panda->can_receive(can_data); panda->can_receive(can_data);
auto bytes = can_data.asBytes(); auto bytes = can_data.asBytes();
pm.send("can", bytes.begin(), bytes.size()); pm.send("can", bytes.begin(), bytes.size());
} }
void can_send_thread(bool fake_send) { void can_send_thread(Panda *panda, bool fake_send) {
LOGD("start send thread"); LOGD("start send thread");
AlignedBuffer aligned_buf; AlignedBuffer aligned_buf;
@ -223,7 +219,7 @@ void can_send_thread(bool fake_send) {
delete context; delete context;
} }
void can_recv_thread() { void can_recv_thread(Panda *panda) {
LOGD("start recv thread"); LOGD("start recv thread");
// can = 8006 // can = 8006
@ -234,7 +230,7 @@ void can_recv_thread() {
uint64_t next_frame_time = nanos_since_boot() + dt; uint64_t next_frame_time = nanos_since_boot() + dt;
while (!do_exit && panda->connected) { while (!do_exit && panda->connected) {
can_recv(pm); can_recv(panda, pm);
uint64_t cur_time = nanos_since_boot(); uint64_t cur_time = nanos_since_boot();
int64_t remaining = next_frame_time - cur_time; int64_t remaining = next_frame_time - cur_time;
@ -251,7 +247,7 @@ void can_recv_thread() {
} }
} }
void panda_state_thread(bool spoofing_started) { void panda_state_thread(Panda *&panda, bool spoofing_started) {
LOGD("start panda state thread"); LOGD("start panda state thread");
PubMaster pm({"pandaState"}); PubMaster pm({"pandaState"});
@ -308,7 +304,7 @@ void panda_state_thread(bool spoofing_started) {
if (!safety_setter_thread_running) { if (!safety_setter_thread_running) {
safety_setter_thread_running = true; safety_setter_thread_running = true;
std::thread(safety_setter_thread).detach(); std::thread(safety_setter_thread, panda).detach();
} else { } else {
LOGW("Safety setter thread already running"); LOGW("Safety setter thread already running");
} }
@ -400,7 +396,7 @@ void panda_state_thread(bool spoofing_started) {
} }
} }
void hardware_control_thread() { void hardware_control_thread(Panda *panda) {
LOGD("start hardware control thread"); LOGD("start hardware control thread");
SubMaster sm({"deviceState", "driverCameraState"}); SubMaster sm({"deviceState", "driverCameraState"});
@ -481,7 +477,7 @@ static void pigeon_publish_raw(PubMaster &pm, const std::string &dat) {
pm.send("ubloxRaw", msg); pm.send("ubloxRaw", msg);
} }
void pigeon_thread() { void pigeon_thread(Panda *panda) {
PubMaster pm({"ubloxRaw"}); PubMaster pm({"ubloxRaw"});
bool ignition_last = false; bool ignition_last = false;
@ -554,28 +550,28 @@ void pigeon_thread() {
delete pigeon; delete pigeon;
} }
int main() { int main() {
int err;
LOGW("starting boardd"); LOGW("starting boardd");
// set process priority and affinity // set process priority and affinity
err = set_realtime_priority(54); int err = set_realtime_priority(54);
LOG("set priority returns %d", err); LOG("set priority returns %d", err);
err = set_core_affinity(Hardware::TICI() ? 4 : 3); err = set_core_affinity(Hardware::TICI() ? 4 : 3);
LOG("set affinity returns %d", err); LOG("set affinity returns %d", err);
while (!do_exit) { while (!do_exit) {
Panda *panda = nullptr;
std::vector<std::thread> threads; std::vector<std::thread> threads;
threads.push_back(std::thread(panda_state_thread, getenv("STARTED") != nullptr)); threads.emplace_back(panda_state_thread, std::ref(panda), getenv("STARTED") != nullptr);
// connect to the board // connect to the board
if (usb_retry_connect()) { panda = usb_retry_connect();
threads.push_back(std::thread(can_send_thread, getenv("FAKESEND") != nullptr)); if (panda != nullptr) {
threads.push_back(std::thread(can_recv_thread)); threads.emplace_back(can_send_thread, panda, getenv("FAKESEND") != nullptr);
threads.push_back(std::thread(hardware_control_thread)); threads.emplace_back(can_recv_thread, panda);
threads.push_back(std::thread(pigeon_thread)); threads.emplace_back(hardware_control_thread, panda);
threads.emplace_back(pigeon_thread, panda);
} }
for (auto &t : threads) t.join(); for (auto &t : threads) t.join();

Loading…
Cancel
Save