Merge branch 'issue/18-Backup-RAM' into issue/15-safety-controller-hardening

This commit is contained in:
Mario Hüttel 2020-09-07 21:58:25 +02:00
commit a877ef5f28
9 changed files with 244 additions and 52 deletions

View File

@ -36,18 +36,18 @@ DEFINES += -DSHELLMATTA_HELP_ALIAS=\"?\"
# RCC Manager # RCC Manager
CFILES += stm-periph/clock-enable-manager.c CFILES += stm-periph/clock-enable-manager.c
CFILES += stm-periph/uart.c stm-periph/dma-ring-buffer.c stm-periph/backup-ram.c CFILES += stm-periph/uart.c stm-periph/dma-ring-buffer.c stm-periph/backup-ram.c
CFILES += stm-periph/rng.c
CFILES += digio.c CFILES += digio.c
CFILES += stm-periph/unique-id.c CFILES += stm-periph/unique-id.c
CFILES += calibration.c CFILES += calibration.c
CFILES += temp-converter.c CFILES += temp-converter.c
CFILES += rotary-encoder.c button.c CFILES += rotary-encoder.c button.c
CFILES += stack-check.c
CFILES += ui/lcd.c ui/menu.c reflow-menu.c CFILES += ui/lcd.c ui/menu.c reflow-menu.c
CFILES += fatfs/diskio.c fatfs/ff.c fatfs/ffsystem.c fatfs/ffunicode.c fatfs/shimatta_sdio_driver/shimatta_sdio.c CFILES += fatfs/diskio.c fatfs/ff.c fatfs/ffsystem.c fatfs/ffunicode.c fatfs/shimatta_sdio_driver/shimatta_sdio.c
CFILES += pid-controller.c oven-driver.c CFILES += pid-controller.c oven-driver.c
CFILES += settings/settings.c settings/settings-sd-card.c CFILES += settings/settings.c settings/settings-sd-card.c
CFILES += stm-periph/crc-unit.c CFILES += stm-periph/crc-unit.c
CFILES += safety/safety-adc.c safety/safety-controller.c safety/watchdog.c safety/fault.c safety/safety-memory.c CFILES += safety/safety-adc.c safety/safety-controller.c safety/watchdog.c safety/fault.c safety/safety-memory.c safety/stack-check.c
DEBUG_DEFINES = -DDEBUGBUILD DEBUG_DEFINES = -DDEBUGBUILD
RELEASE_DEFINES = RELEASE_DEFINES =

View File

@ -50,4 +50,8 @@ static inline uint32_t read_stack_pointer()
return stack_pointer; return stack_pointer;
} }
int stack_check_init_corruption_detect_area(void);
int stack_check_corruption_detect_area(void);
#endif /* __STACK_CHECK_H__ */ #endif /* __STACK_CHECK_H__ */

View File

@ -0,0 +1,42 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __STM_RNG_H__
#define __STM_RNG_H__
#include <stdint.h>
#include <stdbool.h>
enum random_number_error {
RNG_ERROR_OK = 0,
RNG_ERROR_INACT,
RNG_ERROR_INTERNAL_ERROR,
RNG_ERROR_NOT_READY
};
void random_number_gen_init(bool int_enable);
void random_number_gen_deinit();
void random_number_gen_reset(bool int_en);
enum random_number_error random_number_gen_get_number(uint32_t *random_number, bool wait_for_valid_value);
#endif /* __STM_RNG_H__ */

View File

@ -27,7 +27,7 @@
#include <reflow-controller/safety/safety-config.h> #include <reflow-controller/safety/safety-config.h>
#include <reflow-controller/safety/watchdog.h> #include <reflow-controller/safety/watchdog.h>
#include <reflow-controller/safety/safety-adc.h> #include <reflow-controller/safety/safety-adc.h>
#include <reflow-controller/stack-check.h> #include <reflow-controller/safety/stack-check.h>
#include <helper-macros/helper-macros.h> #include <helper-macros/helper-macros.h>
#include <stm-periph/crc-unit.h> #include <stm-periph/crc-unit.h>
#include <reflow-controller/systick.h> #include <reflow-controller/systick.h>
@ -347,6 +347,8 @@ void safety_controller_init()
/* This is usually done by the safety memory already. But, since this module also uses the CRC... */ /* This is usually done by the safety memory already. But, since this module also uses the CRC... */
crc_unit_init(); crc_unit_init();
stack_check_init_corruption_detect_area();
init_safety_flag_weight_table_from_default(); init_safety_flag_weight_table_from_default();
if (found_memory_state == SAFETY_MEMORY_INIT_CORRUPTED) if (found_memory_state == SAFETY_MEMORY_INIT_CORRUPTED)
@ -374,6 +376,10 @@ static void safety_controller_check_stack()
free_stack = stack_check_get_free(); free_stack = stack_check_get_free();
if (free_stack < SAFETY_MIN_STACK_FREE) if (free_stack < SAFETY_MIN_STACK_FREE)
safety_controller_report_error(ERR_FLAG_STACK); safety_controller_report_error(ERR_FLAG_STACK);
if (stack_check_corruption_detect_area()) {
safety_controller_report_error(ERR_FLAG_STACK);
}
} }
static void safety_controller_handle_safety_adc() static void safety_controller_handle_safety_adc()
@ -430,7 +436,7 @@ static int safety_controller_handle_memory_checks(void)
enum safety_memory_state found_state; enum safety_memory_state found_state;
int panic_request = 0; int panic_request = 0;
if (systick_ticks_have_passed(ts, 1000)) { if (systick_ticks_have_passed(ts, 250)) {
ts = systick_get_global_tick(); ts = systick_get_global_tick();
/* Check the safety memory */ /* Check the safety memory */

View File

@ -0,0 +1,110 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/safety/stack-check.h>
#include <stdint.h>
#include <stm-periph/rng.h>
#include <stm-periph/crc-unit.h>
extern char __ld_top_of_stack;
extern char __ld_end_stack;
int32_t stack_check_get_usage()
{
uint32_t stack_top;
uint32_t stack_ptr;
stack_ptr = read_stack_pointer();
stack_top = (uint32_t)&__ld_top_of_stack;
return stack_top - stack_ptr;
}
int32_t stack_check_get_free()
{
uint32_t upper_heap_boundary;
uint32_t stack_ptr;
stack_ptr = read_stack_pointer();
upper_heap_boundary = (uint32_t)&__ld_end_stack;
return stack_ptr - upper_heap_boundary;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
extern uint32_t __ld_start_stack_corruption_detect_area;
extern uint32_t __ld_end_stack_corruption_detect_area;
int stack_check_init_corruption_detect_area(void)
{
uint32_t *ptr = &__ld_start_stack_corruption_detect_area;
uint32_t *end_ptr = &__ld_end_stack_corruption_detect_area;
const uint32_t area_size_in_words = &__ld_end_stack_corruption_detect_area -
&__ld_start_stack_corruption_detect_area;
enum random_number_error rng_stat;
uint32_t rng_number;
uint32_t crc_val;
int ret = 0;
random_number_gen_init(false);
while (ptr < &end_ptr[-1]) {
rng_stat = random_number_gen_get_number(&rng_number, true);
if (rng_stat != RNG_ERROR_OK) {
ret = -1;
goto exit_deinit_rng;
}
*ptr = rng_number;
ptr++;
}
/* Init CRC unit and leave it on */
crc_unit_init();
crc_unit_reset();
crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words - 1);
crc_val = crc_unit_get_crc();
end_ptr[-1] = crc_val;
exit_deinit_rng:
random_number_gen_deinit();
return ret;
}
#pragma GCC diagnostic pop
int stack_check_corruption_detect_area(void)
{
const uint32_t area_size_in_words = &__ld_end_stack_corruption_detect_area -
&__ld_start_stack_corruption_detect_area;
crc_unit_reset();
crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words);
if (crc_unit_get_crc() == 0UL) {
return 0;
} else {
return -1;
}
}

View File

@ -33,7 +33,7 @@
#include <reflow-controller/calibration.h> #include <reflow-controller/calibration.h>
#include <reflow-controller/temp-converter.h> #include <reflow-controller/temp-converter.h>
#include <fatfs/ff.h> #include <fatfs/ff.h>
#include <reflow-controller/stack-check.h> #include <reflow-controller/safety/stack-check.h>
#include <reflow-controller/rotary-encoder.h> #include <reflow-controller/rotary-encoder.h>
#include <reflow-controller/safety/safety-controller.h> #include <reflow-controller/safety/safety-controller.h>
#include <reflow-controller/settings/settings.h> #include <reflow-controller/settings/settings.h>

View File

@ -1,47 +0,0 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/stack-check.h>
#include <stdint.h>
extern char __ld_top_of_stack;
extern char __ld_eheap;
int32_t stack_check_get_usage()
{
uint32_t stack_top;
uint32_t stack_ptr;
stack_ptr = read_stack_pointer();
stack_top = (uint32_t)&__ld_top_of_stack;
return stack_top - stack_ptr;
}
int32_t stack_check_get_free()
{
uint32_t upper_heap_boundary;
uint32_t stack_ptr;
stack_ptr = read_stack_pointer();
upper_heap_boundary = (uint32_t)&__ld_eheap;
return stack_ptr - upper_heap_boundary;
}

View File

@ -0,0 +1,70 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control Firmware is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stm-periph/rng.h>
#include <stm-periph/clock-enable-manager.h>
#include <stm32/stm32f4xx.h>
void random_number_gen_init(bool int_enable)
{
rcc_manager_enable_clock(&RCC->AHB2ENR, BITMASK_TO_BITNO(RCC_AHB2ENR_RNGEN));
__DSB();
random_number_gen_reset(int_enable);
}
void random_number_gen_deinit()
{
RNG->CR = 0;
__DSB();
rcc_manager_disable_clock(&RCC->AHB2ENR, BITMASK_TO_BITNO(RCC_AHB2ENR_RNGEN));
}
void random_number_gen_reset(bool int_en)
{
RNG->CR = 0;
__DSB();
RNG->CR = RNG_CR_RNGEN | (int_en ? RNG_CR_IE : 0U);
}
enum random_number_error random_number_gen_get_number(uint32_t *random_number, bool wait_for_valid_value)
{
bool value_ready;
if (!(RNG->CR & RNG_CR_RNGEN))
return RNG_ERROR_INACT;
if (RNG->SR & RNG_SR_SEIS || RNG->SR & RNG_SR_CEIS) {
/* Error detected */
return RNG_ERROR_INTERNAL_ERROR;
}
/* Check if the value is ready. Wait if wait_for_valid_value is true */
do {
value_ready = !!(RNG->SR & RNG_SR_DRDY);
} while (!value_ready && wait_for_valid_value);
/* If the value is valid, return it */
if (value_ready && random_number)
*random_number = RNG->DR;
/* Return from function with proper status */
return (value_ready ? RNG_ERROR_OK : RNG_ERROR_NOT_READY);
}

View File

@ -25,6 +25,7 @@
/* USER PARAMETERS */ /* USER PARAMETERS */
__ld_stack_size = 0x3000; __ld_stack_size = 0x3000;
__ld_heap_size = 0x2100; __ld_heap_size = 0x2100;
__stack_corruption_area_size = 128;
/* END OF USER PARAMETERS */ /* END OF USER PARAMETERS */
ENTRY(Reset_Handler) ENTRY(Reset_Handler)
@ -150,6 +151,12 @@ SECTIONS
__ld_sheap = .; __ld_sheap = .;
. = . + __ld_heap_size; . = . + __ld_heap_size;
__ld_eheap = .; __ld_eheap = .;
. = ALIGN(4);
__ld_start_stack_corruption_detect_area = .;
. = . + __stack_corruption_area_size;
. = ALIGN(4);
__ld_end_stack_corruption_detect_area = .;
__ld_end_stack = .;
. = . + __ld_stack_size; . = . + __ld_stack_size;
. = ALIGN(4); . = ALIGN(4);
} >RAM } >RAM