Skip to content

Commit

Permalink
Merge remote-tracking branch 'sunnypilot/master' into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
nworb-cire committed Aug 2, 2024
2 parents 983a8b6 + 5d92bdc commit 41efb1d
Show file tree
Hide file tree
Showing 47 changed files with 1,731 additions and 2,480 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: repo

on:
schedule:
- cron: "0 15 * * 2"
- cron: "0 15 1 * *"
workflow_dispatch:

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ repos:
additional_dependencies: ['git+https://github.com/numpy/numpy-stubs', 'types-requests', 'types-atomicwrites',
'types-pycurl']
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.2
rev: v0.4.7
hooks:
- id: ruff
75 changes: 38 additions & 37 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,56 +73,57 @@ pipeline {
}

stages {
stage('panda tests') {
parallel {
stage('test dos') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
stage ('Acquire resource locks') {
options {
lock(resource: "pandas")
}
stages {
stage('Build Docker Image') {
steps {
phone_steps("panda-dos", [
["build", "scons -j4"],
["flash", "cd tests/ && ./reflash_internal_panda.py"],
["flash jungle", "cd board/jungle && ./flash.py"],
["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"],
])
timeout(time: 20, unit: 'MINUTES') {
script {
sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD'
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}")
}
}
}
}

stage('test tres') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
stage('jungle tests') {
steps {
phone_steps("panda-tres", [
["build", "scons -j4"],
["flash", "cd tests/ && ./reflash_internal_panda.py"],
["flash jungle", "cd board/jungle && ./flash.py"],
["test", "cd tests/hitl && HW_TYPES=9 pytest -n0 --durations=0 2*.py [5-9]*.py"],
])
script {
retry (3) {
docker_run("reset hardware", 3, "python ./tests/hitl/reset_jungles.py")
}
}
}
}

stage ('Acquire resource locks') {
options {
lock(resource: "pandas")
}
stages {
stage('Build Docker Image') {
stage('parallel tests') {
parallel {
stage('test tres') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
steps {
timeout(time: 20, unit: 'MINUTES') {
script {
sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD'
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}")
}
}
phone_steps("panda-tres", [
["build", "scons -j4"],
["flash", "cd tests/ && ./reflash_internal_panda.py"],
["flash jungle", "cd board/jungle && ./flash.py"],
["test", "cd tests/hitl && HW_TYPES=9 pytest -n0 --durations=0 2*.py [5-9]*.py"],
])
}
}
stage('jungle tests') {

stage('test dos') {
agent { docker { image 'ghcr.io/commaai/alpine-ssh'; args '--user=root' } }
steps {
script {
retry (3) {
docker_run("reset hardware", 3, "python ./tests/hitl/reset_jungles.py")
}
}
phone_steps("panda-dos", [
["build", "scons -j4"],
["flash", "cd tests/ && ./reflash_internal_panda.py"],
["flash jungle", "cd board/jungle && ./flash.py"],
["test", "cd tests/hitl && HW_TYPES=6 pytest -n0 --durations=0 [2-9]*.py -k 'not test_send_recv'"],
])
}
}

stage('bootkick tests') {
steps {
script {
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ Safety modes optionally support `controls_allowed`, which allows or blocks a sub

## Code Rigor

The panda firmware is written for its use in conjuction with [openpilot](https://github.com/commaai/openpilot). The panda firmware, through its safety model, provides and enforces the
The panda firmware is written for its use in conjunction with [openpilot](https://github.com/commaai/openpilot). The panda firmware, through its safety model, provides and enforces the
[openpilot safety](https://github.com/commaai/openpilot/blob/master/docs/SAFETY.md). Due to its critical function, it's important that the application code rigor within the `board` folder is held to high standards.

These are the [CI regression tests](https://github.com/commaai/panda/actions) we have in place:
* A generic static code analysis is performed by [cppcheck](https://github.com/danmar/cppcheck/).
* In addition, [cppcheck](https://github.com/danmar/cppcheck/) has a specific addon to check for [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) violations. See [current coverage](https://github.com/commaai/panda/blob/master/tests/misra/coverage_table).
* In addition, [cppcheck](https://github.com/danmar/cppcheck/) has a specific addon to check for [MISRA C:2012](https://misra.org.uk/) violations. See [current coverage](https://github.com/commaai/panda/blob/master/tests/misra/coverage_table).
* Compiler options are relatively strict: the flags `-Wall -Wextra -Wstrict-prototypes -Werror` are enforced.
* The [safety logic](https://github.com/commaai/panda/tree/master/board/safety) is tested and verified by [unit tests](https://github.com/commaai/panda/tree/master/tests/safety) for each supported car variant.
to ensure that the behavior remains unchanged.
Expand Down Expand Up @@ -78,7 +78,8 @@ For example, to receive CAN messages:
```
And to send one on bus 0:
``` python
>>> panda.can_send(0x1aa, "message", 0)
>>> panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
>>> panda.can_send(0x1aa, b'message', 0)
```
Note that you may have to setup [udev rules](https://github.com/commaai/panda/tree/master/drivers/linux) for Linux, such as
``` bash
Expand Down
4 changes: 2 additions & 2 deletions SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ def build_project(project_name, project, extra_flags):
'..',
panda_root,
f"{panda_root}/board/",
f"{panda_root}/board/stm32f4/inc",
f"{panda_root}/board/stm32h7/inc",
]

env = Environment(
Expand Down Expand Up @@ -138,6 +136,7 @@ base_project_f4 = {
"-mhard-float",
"-DSTM32F4",
"-DSTM32F413xx",
"-Iboard/stm32f4/inc",
"-mfpu=fpv4-sp-d16",
"-fsingle-precision-constant",
"-Os",
Expand All @@ -155,6 +154,7 @@ base_project_h7 = {
"-mhard-float",
"-DSTM32H7",
"-DSTM32H725xx",
"-Iboard/stm32h7/inc",
"-mfpu=fpv5-d16",
"-fsingle-precision-constant",
"-Os",
Expand Down
3 changes: 0 additions & 3 deletions board/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,4 @@ for project_name, project in build_projects.items():
if ("ENABLE_SPI" in os.environ or "h7" in project_name):
flags.append('-DENABLE_SPI')

if "H723" in os.environ:
flags.append('-DSTM32H723')

build_project(project_name, project, flags)
4 changes: 2 additions & 2 deletions board/can_comms.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void comms_can_write(const uint8_t *data, uint32_t len) {
if (can_write_buffer.ptr != 0U) {
if (can_write_buffer.tail_size <= (len - pos)) {
// we have enough data to complete the buffer
CANPacket_t to_push;
CANPacket_t to_push = {0};
(void)memcpy(&can_write_buffer.data[can_write_buffer.ptr], &data[pos], can_write_buffer.tail_size);
can_write_buffer.ptr += can_write_buffer.tail_size;
pos += can_write_buffer.tail_size;
Expand All @@ -89,7 +89,7 @@ void comms_can_write(const uint8_t *data, uint32_t len) {
while (pos < len) {
uint32_t pckt_len = CANPACKET_HEAD_SIZE + dlc_to_len[(data[pos] >> 4U)];
if ((pos + pckt_len) <= len) {
CANPacket_t to_push;
CANPacket_t to_push = {0};
(void)memcpy(&to_push, &data[pos], pckt_len);
can_send(&to_push, to_push.bus, false);
pos += pckt_len;
Expand Down
6 changes: 3 additions & 3 deletions board/drivers/can_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ void can_set_forwarding(uint8_t from, uint8_t to) {

void ignition_can_hook(CANPacket_t *to_push) {
int bus = GET_BUS(to_push);
int addr = GET_ADDR(to_push);
int len = GET_LEN(to_push);

if (bus == 0) {
int addr = GET_ADDR(to_push);
int len = GET_LEN(to_push);

// GM exception
if ((addr == 0x1F1) && (len == 8)) {
// SystemPowerMode (2=Run, 3=Crank Request)
Expand Down
4 changes: 2 additions & 2 deletions board/drivers/registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ void register_set(volatile uint32_t *addr, uint32_t val, uint32_t mask){
// Set individual bits. Also add them to the check_mask.
// Do not use this to change bits that get reset by the hardware
void register_set_bits(volatile uint32_t *addr, uint32_t val) {
return register_set(addr, val, val);
register_set(addr, val, val);
}

// Clear individual bits. Also add them to the check_mask.
// Do not use this to clear bits that get set by the hardware
void register_clear_bits(volatile uint32_t *addr, uint32_t val) {
return register_set(addr, (~val), val);
register_set(addr, (~val), val);
}

// To be called periodically
Expand Down
8 changes: 6 additions & 2 deletions board/drivers/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ uint16_t spi_data_len_miso;
uint16_t spi_checksum_error_count = 0;
bool spi_can_tx_ready = false;

const char version_text[] = "VERSION";
const unsigned char version_text[] = "VERSION";

#define SPI_HEADER_SIZE 7U

Expand Down Expand Up @@ -152,7 +152,7 @@ void spi_rx_done(void) {
if (checksum_valid) {
if (spi_endpoint == 0U) {
if (spi_data_len_mosi >= sizeof(ControlPacket_t)) {
ControlPacket_t ctrl;
ControlPacket_t ctrl = {0};
(void)memcpy(&ctrl, &spi_buf_rx[SPI_HEADER_SIZE], sizeof(ControlPacket_t));
response_len = comms_control_handler(&ctrl, &spi_buf_tx[3]);
response_ack = true;
Expand Down Expand Up @@ -182,6 +182,10 @@ void spi_rx_done(void) {
} else {
print("SPI: did expect data for can_write\n");
}
} else if (spi_endpoint == 0xABU) {
// test endpoint, send max response length
response_len = spi_data_len_miso;
response_ack = true;
} else {
print("SPI: unexpected endpoint"); puth(spi_endpoint); print("\n");
}
Expand Down
7 changes: 6 additions & 1 deletion board/early_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
extern void *g_pfnVectors;
extern uint32_t enter_bootloader_mode;

typedef void (*bootloader_fcn)(void);
typedef bootloader_fcn *bootloader_fcn_ptr;

void jump_to_bootloader(void) {
// do enter bootloader
enter_bootloader_mode = 0;
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)BOOTLOADER_ADDRESS));

bootloader_fcn_ptr bootloader_ptr = (bootloader_fcn_ptr)BOOTLOADER_ADDRESS;
bootloader_fcn bootloader = *bootloader_ptr;

// jump to bootloader
enable_interrupts();
Expand Down
3 changes: 3 additions & 0 deletions board/jungle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ def set_ignition(self, enabled):
def set_can_silent(self, silent):
self._handle.controlWrite(PandaJungle.REQUEST_OUT, 0xf5, int(silent), 0, b'')

def set_generated_can(self, enabled):
self._handle.controlWrite(PandaJungle.REQUEST_OUT, 0xa4, int(enabled), 0, b'')

# ******************* serial *******************

def debug_read(self):
Expand Down
39 changes: 34 additions & 5 deletions board/jungle/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ uint32_t loop_counter = 0U;
uint16_t button_press_cnt = 0U;
void tick_handler(void) {
if (TICK_TIMER->SR != 0) {
if (generated_can_traffic) {
for (int i = 0; i < 3; i++) {
if (can_health[i].transmit_error_cnt >= 128) {
(void)llcan_init(CANIF_FROM_CAN_NUM(i));
}
}
}

// tick drivers at 8Hz
usb_tick();

Expand Down Expand Up @@ -148,10 +156,7 @@ int main(void) {
print("\n\n\n************************ MAIN START ************************\n");

// check for non-supported board types
if (hw_type == HW_TYPE_UNKNOWN) {
print("Unsupported board type\n");
while (1) { /* hang */ }
}
assert_fatal(hw_type != HW_TYPE_UNKNOWN, "Unsupported board type\n");

print("Config:\n");
print(" Board type: 0x"); puth(hw_type); print("\n");
Expand Down Expand Up @@ -193,8 +198,32 @@ int main(void) {
#endif

// LED should keep on blinking all the time
uint64_t cnt = 0;
uint32_t cnt = 0;
for (cnt=0;;cnt++) {
if (generated_can_traffic) {
// fill up all the queues
can_ring *qs[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q};
for (int j = 0; j < 3; j++) {
for (uint16_t n = 0U; n < can_slots_empty(qs[j]); n++) {
uint16_t i = cnt % 100U;
CANPacket_t to_send;
to_send.returned = 0U;
to_send.rejected = 0U;
to_send.extended = 0U;
to_send.addr = 0x200U + i;
to_send.bus = i % 3U;
to_send.data_len_code = i % 8U;
(void)memcpy(to_send.data, "\xff\xff\xff\xff\xff\xff\xff\xff", dlc_to_len[to_send.data_len_code]);
can_set_checksum(&to_send);

can_send(&to_send, to_send.bus, true);
}
}

delay(1000);
continue;
}

// useful for debugging, fade breaks = panda is overloaded
for (uint32_t fade = 0U; fade < MAX_LED_FADE; fade += 1U) {
current_board->set_led(LED_RED, true);
Expand Down
8 changes: 7 additions & 1 deletion board/jungle/main_comms.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
extern int _app_start[0xc000]; // Only first 3 sectors of size 0x4000 are used

bool generated_can_traffic = false;

int get_jungle_health_pkt(void *dat) {
COMPILE_TIME_ASSERT(sizeof(struct jungle_health_t) <= USBPACKET_MAX_SIZE);
struct jungle_health_t * health = (struct jungle_health_t*)dat;
Expand Down Expand Up @@ -58,10 +60,14 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
case 0xa2:
current_board->set_ignition((req->param1 == 1U));
break;
// **** 0xa0: Set panda power per channel by bitmask.
// **** 0xa3: Set panda power per channel by bitmask.
case 0xa3:
current_board->set_panda_individual_power(req->param1, (req->param2 > 0U));
break;
// **** 0xa4: Enable generated CAN traffic.
case 0xa4:
generated_can_traffic = (req->param1 > 0U);
break;
// **** 0xa8: get microsecond timer
case 0xa8:
time = microsecond_timer_get();
Expand Down
10 changes: 10 additions & 0 deletions board/libc.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ void delay(uint32_t a) {
for (i = 0; i < a; i++);
}

void assert_fatal(bool condition, const char *msg) {
if (!condition) {
print("ASSERT FAILED\n");
print(msg);
while (1) {
// hang
}
}
}

// cppcheck-suppress misra-c2012-21.2
void *memset(void *str, int c, unsigned int n) {
uint8_t *s = str;
Expand Down
Loading

0 comments on commit 41efb1d

Please sign in to comment.