From 528b8ae067f1326e4215f52b890e758dd5ff34e7 Mon Sep 17 00:00:00 2001 From: Jessy Diamond Exum Date: Fri, 14 Jul 2017 21:17:32 -0700 Subject: [PATCH] Modularize safety modes to encourage 3rd party safety code contribution. --- board/build.mk | 1 - board/can.h | 4 +- board/main.c | 23 ++---- board/safety.h | 99 ++++++++++++++++++++++++ board/{honda_safety.h => safety_honda.h} | 20 +++-- panda/__init__.py | 10 +++ 6 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 board/safety.h rename board/{honda_safety.h => safety_honda.h} (83%) diff --git a/board/build.mk b/board/build.mk index 43b54eea..1c13395e 100644 --- a/board/build.mk +++ b/board/build.mk @@ -7,7 +7,6 @@ OBJDUMP = arm-none-eabi-objdump ifeq ($(RELEASE),1) CERT = ../../pandaextra/certs/release - CFLAGS += "-DPANDA_SAFETY" else CERT = ../certs/debug CFLAGS += "-DALLOW_DEBUG" diff --git a/board/can.h b/board/can.h index 7a0f9055..4a76bee6 100644 --- a/board/can.h +++ b/board/can.h @@ -1,4 +1,4 @@ -void can_init(uint8_t bus_number, int silent) { +void can_init(uint8_t bus_number) { CAN_TypeDef *CAN = CANIF_FROM_BUS_NUM(bus_number); set_can_enable(CAN, 1); @@ -22,7 +22,7 @@ void can_init(uint8_t bus_number, int silent) { CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM; } - if (silent) { + if (!controls_allowed) { CAN->BTR |= CAN_BTR_SILM; } diff --git a/board/main.c b/board/main.c index 9cdfea49..a28624fd 100644 --- a/board/main.c +++ b/board/main.c @@ -1,5 +1,6 @@ #include "config.h" #include "early.h" +#include #define NULL ((void*)0) @@ -333,16 +334,7 @@ int putc(uart_ring *q, char elem) { #include "usb.h" #include "can.h" #include "spi.h" - -void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired); -int safety_tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired); - -#ifdef PANDA_SAFETY -#include "panda_safety.h" -#else -#include "honda_safety.h" -#endif +#include "safety.h" // ***************************** CAN ***************************** @@ -643,10 +635,9 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { } break; case 0xdc: // set controls allowed - controls_allowed = setup->b.wValue.w == 0x1337; - // take CAN out of SILM, careful with speed! + set_safety_mode(setup->b.wValue.w); for(i=0; i < CAN_MAX; i++) - can_init(i, 0); + can_init(i); break; case 0xdd: // enable can forwarding //wValue = Can Bus Num to forward from @@ -875,11 +866,7 @@ int main() { // default to silent mode to prevent issues with Ford for(i=0; i < CAN_MAX; i++) - #ifdef PANDA_SAFETY - can_init(i, 1); - #else - can_init(i, 0); - #endif + can_init(i); adc_init(); diff --git a/board/safety.h b/board/safety.h new file mode 100644 index 00000000..58ae8d03 --- /dev/null +++ b/board/safety.h @@ -0,0 +1,99 @@ +void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); +int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired); +int safety_tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired); + +typedef void (*safety_hook_init)(); +typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push); +typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send, int hardwired); +typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len, int hardwired); + +typedef struct { + safety_hook_init init; + rx_hook rx; + tx_hook tx; + tx_lin_hook tx_lin; +} safety_hooks; + +// Include the actual safety policies. +#include "safety_honda.h" + +void default__rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {} + +void nooutput__init() { + controls_allowed = false; +} + +int nooutput__tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired) { + return false; +} + +int nooutput__tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired) { + return false; +} + +void alloutput__init() { + controls_allowed = true; +} + +int alloutput__tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired) { + return hardwired; +} + +int alloutput__tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired) { + return hardwired; +} + +const safety_hooks nooutput_hooks = { + .init = nooutput__init, + .rx = default__rx_hook, + .tx = alloutput__tx_hook, + .tx_lin = alloutput__tx_lin_hook, +}; + +const safety_hooks alloutput_hooks = { + .init = alloutput__init, + .rx = default__rx_hook, + .tx = alloutput__tx_hook, + .tx_lin = alloutput__tx_lin_hook, +}; + +const safety_hooks *current_hooks = &nooutput_hooks; + +void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push){ + current_hooks->rx(to_push); +} + +int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired){ + return current_hooks->tx(to_send, hardwired); +} + +int safety_tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired){ + return current_hooks->tx_lin(lin_num, data, len, hardwired); +} + + +typedef struct { + uint16_t id; + const safety_hooks *hooks; +} safety_hook_config; + +const safety_hook_config safety_hook_registry[] = { + {0x0000, &nooutput_hooks}, + {0x0001, &honda_hooks}, + {0x1337, &alloutput_hooks}, +}; + +#define HOOK_CONFIG_COUNT (sizeof(safety_hook_registry)/sizeof(safety_hook_config)) + +int set_safety_mode(uint16_t mode){ + int i; + for(i = 0; i < HOOK_CONFIG_COUNT; i++){ + if(safety_hook_registry[i].id == mode){ + current_hooks = safety_hook_registry[i].hooks; + current_hooks->init(); + return 0; + } + } + + return -1; +} diff --git a/board/honda_safety.h b/board/safety_honda.h similarity index 83% rename from board/honda_safety.h rename to board/safety_honda.h index 99f209a5..9ed364db 100644 --- a/board/honda_safety.h +++ b/board/safety_honda.h @@ -11,7 +11,7 @@ // else // block all commands that produce actuation -void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { +void honda__rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // state machine to enter and exit controls // 0x1A6 for the ILX, 0x296 for the Civic Touring if ((to_push->RIR>>21) == 0x1A6 || (to_push->RIR>>21) == 0x296) { @@ -50,7 +50,7 @@ void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } } -int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired) { +int honda__tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired) { // BRAKE: safety check if ((to_send->RIR>>21) == 0x1FA) { if (controls_allowed) { @@ -67,7 +67,7 @@ int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired) { } else { to_send->RDLR &= 0xFFFF0000; } - } + } // GAS: safety check if ((to_send->RIR>>21) == 0x200) { @@ -76,13 +76,23 @@ int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send, int hardwired) { } else { to_send->RDLR &= 0xFFFF0000; } - } + } // 1 allows the message through return hardwired; } -int safety_tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired) { +int honda__tx_lin_hook(int lin_num, uint8_t *data, int len, int hardwired) { return hardwired; } +void honda__init() { + controls_allowed = true; +} + +const safety_hooks honda_hooks = { + .init = honda__init, + .rx = honda__rx_hook, + .tx = honda__tx_hook, + .tx_lin = honda__tx_lin_hook, +}; diff --git a/panda/__init__.py b/panda/__init__.py index 42ff24f5..6da6ff4f 100644 --- a/panda/__init__.py +++ b/panda/__init__.py @@ -77,6 +77,10 @@ class WifiHandle(object): def close(self): self.sock.close() +SAFETY_NOOUTPUT = 0 +SAFETY_HONDA = 1 +SAFETY_ALLOUTPUT = 0x1337 + class Panda(object): REQUEST_TYPE = usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE @@ -147,6 +151,12 @@ class Panda(object): # ******************* configuration ******************* + def set_controls_mode(self, mode=SAFETY_ALLOUTPUT): + self._handle.controlWrite(Panda.REQUEST_TYPE, 0xdc, mode, 0, b'') + + def set_controls_allowed(self, on): + self.set_controls_mode(SAFETY_ALLOUTPUT if on else SAFETY_NOOUTPUT) + def set_controls_allowed(self, on): self._handle.controlWrite(Panda.REQUEST_TYPE, 0xdc, (0x1337 if on else 0), 0, b'')