From 528b8ae067f1326e4215f52b890e758dd5ff34e7 Mon Sep 17 00:00:00 2001 From: Jessy Diamond Exum Date: Fri, 14 Jul 2017 21:17:32 -0700 Subject: [PATCH 1/2] 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 43b54eea9..1c13395e6 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 7a0f90554..4a76bee6c 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 9cdfea497..a28624fd1 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 000000000..58ae8d032 --- /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 99f209a59..9ed364db7 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 42ff24f53..6da6ff4fb 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'') From a0358414e53a5e967a5fa70d58c1bc7d7d8ab8bc Mon Sep 17 00:00:00 2001 From: Jessy Diamond Exum Date: Mon, 17 Jul 2017 00:52:01 -0700 Subject: [PATCH 2/2] Re-differentiating CAN silence from controls_allowed. Updated incorrect comments. --- board/build.mk | 1 + board/can.h | 4 ++-- board/main.c | 12 ++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/board/build.mk b/board/build.mk index 1c13395e6..43b54eea9 100644 --- a/board/build.mk +++ b/board/build.mk @@ -7,6 +7,7 @@ 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 4a76bee6c..7a0f90554 100644 --- a/board/can.h +++ b/board/can.h @@ -1,4 +1,4 @@ -void can_init(uint8_t bus_number) { +void can_init(uint8_t bus_number, int silent) { 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) { CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM; } - if (!controls_allowed) { + if (silent) { CAN->BTR |= CAN_BTR_SILM; } diff --git a/board/main.c b/board/main.c index a28624fd1..ad6097ad3 100644 --- a/board/main.c +++ b/board/main.c @@ -14,8 +14,8 @@ // can_num_lookup: Translates from 'bus number' to 'can number'. // can_forwarding: Given a bus num, lookup bus num to forward to. -1 means no forward. -// old: CAN1 = 1 CAN2 = 0 -// panda: CAN1 = 0 CAN2 = 1 CAN3 = 4 +// NEO: Bus 1=CAN1 Bus 2=CAN2 +// Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 3=CAN3 #ifdef PANDA CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3}; uint8_t bus_lookup[] = {0,1,2}; @@ -637,7 +637,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { case 0xdc: // set controls allowed set_safety_mode(setup->b.wValue.w); for(i=0; i < CAN_MAX; i++) - can_init(i); + can_init(i, 0); break; case 0xdd: // enable can forwarding //wValue = Can Bus Num to forward from @@ -866,7 +866,11 @@ int main() { // default to silent mode to prevent issues with Ford for(i=0; i < CAN_MAX; i++) - can_init(i); + #ifdef PANDA_SAFETY + can_init(i, 1); + #else + can_init(i, 0); + #endif adc_init();