Modularize safety modes to encourage 3rd party safety code contribution.

This commit is contained in:
Jessy Diamond Exum
2017-07-14 21:17:32 -07:00
parent 858fe889ca
commit 528b8ae067
6 changed files with 131 additions and 26 deletions

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -1,5 +1,6 @@
#include "config.h"
#include "early.h"
#include <stdbool.h>
#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();

99
board/safety.h Normal file
View File

@@ -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;
}

View File

@@ -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,
};

View File

@@ -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'')