Add full automotive RTOS project

Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers,
middleware (CAN stack, diagnostics, safety), applications, board
support, build/test tooling, and documentation.
This commit is contained in:
root
2026-08-23 03:35:29 -04:00
parent f113bf0a05
commit ca13734bf0
151 changed files with 23945 additions and 0 deletions
+227
View File
@@ -0,0 +1,227 @@
/**
* @file board.h
* @brief STM32F407 Discovery board definitions
*/
#ifndef BOARD_H
#define BOARD_H
#include <stdint.h>
#include <stdbool.h>
#include "stm32f4xx.h"
/* ============================================================================
* Board Identification
* ============================================================================ */
#define BOARD_NAME "STM32F407G-DISC1"
#define BOARD_MANUFACTURER "STMicroelectronics"
#define BOARD_VERSION "1.0"
#define BOARD_MCU "STM32F407VG"
/* ============================================================================
* Clock Configuration
* ============================================================================ */
#define HSE_VALUE 8000000U /* External crystal */
#define HSI_VALUE 16000000U /* Internal oscillator */
#define LSE_VALUE 32768U /* Low speed external */
#define LSI_VALUE 32000U /* Low speed internal */
#define SYSTEM_CLOCK 168000000U /* 168 MHz */
#define AHB_CLOCK 168000000U
#define APB1_CLOCK 42000000U
#define APB2_CLOCK 84000000U
#define USB_CLOCK 48000000U
/* PLL Configuration */
#define PLL_M 8
#define PLL_N 336
#define PLL_P 2
#define PLL_Q 7
/* ============================================================================
* LED Definitions
* ============================================================================ */
#define LED_COUNT 4
#define LED1_PORT GPIOD
#define LED1_PIN GPIO_PIN_12
#define LED1_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
#define LED2_PORT GPIOD
#define LED2_PIN GPIO_PIN_13
#define LED2_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
#define LED3_PORT GPIOD
#define LED3_PIN GPIO_PIN_14
#define LED3_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
#define LED4_PORT GPIOD
#define LED4_PIN GPIO_PIN_15
#define LED4_CLOCK __HAL_RCC_GPIOD_CLK_ENABLE()
/* LED Active Level */
#define LED_ACTIVE_LEVEL GPIO_PIN_SET
/* ============================================================================
* Button Definitions
* ============================================================================ */
#define BUTTON_COUNT 1
#define BUTTON1_PORT GPIOA
#define BUTTON1_PIN GPIO_PIN_0
#define BUTTON1_CLOCK __HAL_RCC_GPIOA_CLK_ENABLE()
#define BUTTON1_EXTI_IRQ EXTI0_IRQn
/* Button Active Level */
#define BUTTON_ACTIVE_LEVEL GPIO_PIN_SET
/* ============================================================================
* UART Definitions
* ============================================================================ */
#define UART1_INSTANCE 0
#define UART1_BAUDRATE 115200
#define UART1_WORDLENGTH UART_WORDLENGTH_8B
#define UART1_STOPBITS UART_STOPBITS_1
#define UART1_PARITY UART_PARITY_NONE
#define UART1_HWFLOWCTL UART_HWCONTROL_NONE
#define UART1_TX_PORT GPIOA
#define UART1_TX_PIN GPIO_PIN_9
#define UART1_TX_AF GPIO_AF7_USART1
#define UART1_RX_PORT GPIOA
#define UART1_RX_PIN GPIO_PIN_10
#define UART1_RX_AF GPIO_AF7_USART1
#define UART1_CLOCK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
#define UART1_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define UART2_INSTANCE 1
#define UART2_BAUDRATE 115200
#define UART2_TX_PORT GPIOA
#define UART2_TX_PIN GPIO_PIN_2
#define UART2_TX_AF GPIO_AF7_USART2
#define UART2_RX_PORT GPIOA
#define UART2_RX_PIN GPIO_PIN_3
#define UART2_RX_AF GPIO_AF7_USART2
#define UART2_CLOCK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE()
/* ============================================================================
* CAN Definitions
* ============================================================================ */
#define CAN1_INSTANCE 0
#define CAN1_BAUDRATE 500000
#define CAN1_TX_PORT GPIOB
#define CAN1_TX_PIN GPIO_PIN_9
#define CAN1_TX_AF GPIO_AF9_CAN1
#define CAN1_RX_PORT GPIOB
#define CAN1_RX_PIN GPIO_PIN_8
#define CAN1_RX_AF GPIO_AF9_CAN1
#define CAN1_CLOCK_ENABLE() __HAL_RCC_CAN1_CLK_ENABLE()
#define CAN1_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define CAN2_INSTANCE 1
#define CAN2_BAUDRATE 500000
#define CAN2_TX_PORT GPIOB
#define CAN2_TX_PIN GPIO_PIN_13
#define CAN2_TX_AF GPIO_AF9_CAN2
#define CAN2_RX_PORT GPIOB
#define CAN2_RX_PIN GPIO_PIN_12
#define CAN2_RX_AF GPIO_AF9_CAN2
#define CAN2_CLOCK_ENABLE() __HAL_RCC_CAN2_CLK_ENABLE()
/* ============================================================================
* SPI Definitions
* ============================================================================ */
#define SPI1_INSTANCE 0
#define SPI1_SCK_PORT GPIOA
#define SPI1_SCK_PIN GPIO_PIN_5
#define SPI1_SCK_AF GPIO_AF5_SPI1
#define SPI1_MISO_PORT GPIOA
#define SPI1_MISO_PIN GPIO_PIN_6
#define SPI1_MISO_AF GPIO_AF5_SPI1
#define SPI1_MOSI_PORT GPIOA
#define SPI1_MOSI_PIN GPIO_PIN_7
#define SPI1_MOSI_AF GPIO_AF5_SPI1
#define SPI1_CLOCK_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE()
/* ============================================================================
* I2C Definitions
* ============================================================================ */
#define I2C1_INSTANCE 0
#define I2C1_SCL_PORT GPIOB
#define I2C1_SCL_PIN GPIO_PIN_6
#define I2C1_SCL_AF GPIO_AF4_I2C1
#define I2C1_SDA_PORT GPIOB
#define I2C1_SDA_PIN GPIO_PIN_7
#define I2C1_SDA_AF GPIO_AF4_I2C1
#define I2C1_CLOCK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
/* ============================================================================
* ADC Definitions
* ============================================================================ */
#define ADC1_INSTANCE 0
#define ADC1_CHANNEL_COUNT 6
#define ADC1_CH0_PORT GPIOA
#define ADC1_CH0_PIN GPIO_PIN_0
#define ADC1_CH1_PORT GPIOA
#define ADC1_CH1_PIN GPIO_PIN_1
#define ADC1_CH2_PORT GPIOA
#define ADC1_CH2_PIN GPIO_PIN_2
#define ADC1_CH3_PORT GPIOA
#define ADC1_CH3_PIN GPIO_PIN_3
#define ADC1_CLOCK_ENABLE() __HAL_RCC_ADC1_CLK_ENABLE()
/* ============================================================================
* PWM/Timer Definitions
* ============================================================================ */
#define PWM_TIMER_INSTANCE 0
#define PWM_TIMER TIM1
#define PWM_TIMER_CLOCK_ENABLE() __HAL_RCC_TIM1_CLK_ENABLE()
#define PWM_TIMER_CHANNEL_COUNT 4
#define PWM_TIMER_PRESCALER 168 /* 1 MHz */
#define PWM_TIMER_PERIOD 1000 /* 1 kHz */
#define PWM_TIMER_IRQ TIM1_UP_TIM10_IRQn
#define PWM_CH1_PORT GPIOA
#define PWM_CH1_PIN GPIO_PIN_8
#define PWM_CH1_AF GPIO_AF1_TIM1
#define PWM_CH2_PORT GPIOA
#define PWM_CH2_PIN GPIO_PIN_9
#define PWM_CH2_AF GPIO_AF1_TIM1
#define PWM_CH3_PORT GPIOA
#define PWM_CH3_PIN GPIO_PIN_10
#define PWM_CH3_AF GPIO_AF1_TIM1
#define PWM_CH4_PORT GPIOA
#define PWM_CH4_PIN GPIO_PIN_11
#define PWM_CH4_AF GPIO_AF1_TIM1
/* ============================================================================
* Watchdog Configuration
* ============================================================================ */
#define WATCHDOG_INSTANCE 0
#define WATCHDOG_TIMEOUT_MS 100
#define WATCHDOG_WINDOW_MS 50
/* ============================================================================
* Board Functions
* ============================================================================ */
void board_init(void);
void board_clock_init(void);
void board_gpio_init(void);
void board_uart_init(void);
void board_can_init(void);
void board_spi_init(void);
void board_i2c_init(void);
void board_adc_init(void);
void board_pwm_init(void);
void board_watchdog_init(void);
void board_watchdog_service(void);
void board_led_on(uint8_t led);
void board_led_off(uint8_t led);
void board_led_toggle(uint8_t led);
bool board_button_read(uint8_t button);
void board_delay_ms(uint32_t ms);
void board_delay_us(uint32_t us);
float board_get_temperature(void);
float board_get_voltage(void);
#endif /* BOARD_H */
+388
View File
@@ -0,0 +1,388 @@
/**
* @file board_init.c
* @brief STM32F407 Discovery board initialization
*/
#include "board.h"
#include "kernel.h"
#include "gpio_driver.h"
#include "uart_driver.h"
#include "can_driver.h"
#include "spi_driver.h"
#include "i2c_driver.h"
#include "adc_driver.h"
#include "pwm_driver.h"
#include <string.h>
/* Board state */
static bool board_initialized = false;
/* ============================================================================
* Board Initialization
* ============================================================================ */
void board_init(void) {
if (board_initialized) {
return;
}
/* Initialize clock */
board_clock_init();
/* Initialize GPIO */
board_gpio_init();
/* Initialize UART */
board_uart_init();
/* Initialize CAN */
board_can_init();
/* Initialize SPI */
board_spi_init();
/* Initialize I2C */
board_i2c_init();
/* Initialize ADC */
board_adc_init();
/* Initialize PWM */
board_pwm_init();
/* Initialize watchdog */
board_watchdog_init();
board_initialized = true;
}
/* ============================================================================
* Clock Initialization
* ============================================================================ */
void board_clock_init(void) {
/* Reset RCC */
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY));
/* Configure PLL */
RCC->PLLCFGR = (PLL_M << RCC_PLLCFGR_PLLM_Pos) |
(PLL_N << RCC_PLLCFGR_PLLN_Pos) |
(((PLL_P >> 1) - 1) << RCC_PLLCFGR_PLLP_Pos) |
(PLL_Q << RCC_PLLCFGR_PLLQ_Pos);
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
/* Configure flash latency */
FLASH->ACR = FLASH_ACR_LATENCY_5WS | FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN;
/* Configure AHB, APB1, APB2 prescalers */
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV2;
/* Switch to PLL */
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
/* Update SystemCoreClock variable */
SystemCoreClockUpdate();
}
/* ============================================================================
* GPIO Initialization
* ============================================================================ */
void board_gpio_init(void) {
/* Enable GPIO clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/* Configure LEDs */
GpioPinConfig_t led_config = {
.mode = GPIO_MODE_OUTPUT,
.output_type = GPIO_OUTPUT_PUSH_PULL,
.pull = GPIO_PULL_NONE,
.speed = GPIO_SPEED_HIGH
};
led_config.port = 3; /* GPIOD */
led_config.pin = 12;
gpio_init(&led_config);
led_config.pin = 13;
gpio_init(&led_config);
led_config.pin = 14;
gpio_init(&led_config);
led_config.pin = 15;
gpio_init(&led_config);
/* Configure button */
GpioPinConfig_t button_config = {
.port = 0, /* GPIOA */
.pin = 0,
.mode = GPIO_MODE_INPUT,
.pull = GPIO_PULL_DOWN
};
gpio_init(&button_config);
/* Turn off all LEDs */
board_led_off(0);
board_led_off(1);
board_led_off(2);
board_led_off(3);
}
/* ============================================================================
* UART Initialization
* ============================================================================ */
void board_uart_init(void) {
/* Configure UART1 */
UartConfig_t uart1_config = {
.baudrate = UART1_BAUDRATE,
.data_bits = UART_DATA_BITS_8,
.stop_bits = UART_STOP_BITS_1,
.parity = UART_PARITY_NONE,
.flow_control = UART_FLOW_CONTROL_NONE,
.enable_rx = true,
.enable_tx = true,
.use_dma = false
};
uart_init(UART1_INSTANCE, &uart1_config);
/* Configure UART2 */
UartConfig_t uart2_config = uart1_config;
uart_init(UART2_INSTANCE, &uart2_config);
}
/* ============================================================================
* CAN Initialization
* ============================================================================ */
void board_can_init(void) {
/* Configure CAN1 */
CanConfig_t can1_config = {
.nominal_baudrate = CAN1_BAUDRATE,
.data_baudrate = CAN1_BAUDRATE,
.frame_type = CAN_FRAME_CLASSIC,
.enable_fd = false,
.enable_automatic_retransmission = true,
.filter_count = 0
};
can_init(&can1_config);
/* Configure CAN2 */
CanConfig_t can2_config = can1_config;
can_init(&can2_config);
}
/* ============================================================================
* SPI Initialization
* ============================================================================ */
void board_spi_init(void) {
/* Configure SPI1 */
SpiConfig_t spi1_config = {
.mode = SPI_MODE_0,
.clock_speed = SPI_CLOCK_8MHZ,
.data_order = SPI_DATA_ORDER_MSB_FIRST,
.data_size = 8,
.use_dma = false,
.enable_hardware_cs = false,
.cs_polarity = SPI_CS_ACTIVE_LOW,
.cs_port = 0,
.cs_pin = 4
};
spi_init(SPI1_INSTANCE, &spi1_config);
}
/* ============================================================================
* I2C Initialization
* ============================================================================ */
void board_i2c_init(void) {
/* Configure I2C1 */
I2cConfig_t i2c1_config = {
.speed = I2C_SPEED_FAST,
.addressing_mode = I2C_ADDRESSING_7BIT,
.own_address = 0x50,
.enable_general_call = false,
.enable_clock_stretching = true,
.use_dma = false
};
i2c_init(I2C1_INSTANCE, &i2c1_config);
}
/* ============================================================================
* ADC Initialization
* ============================================================================ */
void board_adc_init(void) {
/* Configure ADC1 */
AdcConfig_t adc1_config = {
.resolution = ADC_RESOLUTION_12BIT,
.mode = ADC_MODE_SCAN,
.trigger_source = ADC_TRIGGER_TIMER,
.reference = ADC_REFERENCE_VDD,
.enable_dma = false,
.conversion_frequency = 1000,
.channel_count = 6,
.channels = {
{.channel = 0, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
{.channel = 1, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
{.channel = 2, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
{.channel = 3, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
{.channel = 4, .sampling_time = ADC_SAMPLING_28_5_CYCLES},
{.channel = 5, .sampling_time = ADC_SAMPLING_28_5_CYCLES}
}
};
adc_init(ADC1_INSTANCE, &adc1_config);
}
/* ============================================================================
* PWM Initialization
* ============================================================================ */
void board_pwm_init(void) {
/* Configure PWM timer */
PwmConfig_t pwm_config = {
.frequency_hz = 1000,
.alignment = PWM_ALIGNMENT_EDGE,
.period_ticks = 1000,
.prescaler = 168,
.channel_count = 4,
.channels = {
{.channel = 0, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH},
{.channel = 1, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH},
{.channel = 2, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH},
{.channel = 3, .duty_cycle = 0, .polarity = PWM_POLARITY_ACTIVE_HIGH}
},
.enable_fault_protection = true,
.fault_action = PWM_FAULT_DISABLE
};
pwm_init(PWM_TIMER_INSTANCE, &pwm_config);
}
/* ============================================================================
* Watchdog Initialization
* ============================================================================ */
void board_watchdog_init(void) {
/* Enable IWDG */
IWDG->KR = 0x5555; /* Enable write access */
IWDG->PR = 0x06; /* Prescaler: 256 */
IWDG->RLR = 0x0FFF; /* Reload value */
IWDG->KR = 0xCCCC; /* Start watchdog */
}
void board_watchdog_service(void) {
/* Service IWDG */
IWDG->KR = 0xAAAA;
}
/* ============================================================================
* LED Functions
* ============================================================================ */
void board_led_on(uint8_t led) {
switch (led) {
case 0:
gpio_write(3, 12, true);
break;
case 1:
gpio_write(3, 13, true);
break;
case 2:
gpio_write(3, 14, true);
break;
case 3:
gpio_write(3, 15, true);
break;
}
}
void board_led_off(uint8_t led) {
switch (led) {
case 0:
gpio_write(3, 12, false);
break;
case 1:
gpio_write(3, 13, false);
break;
case 2:
gpio_write(3, 14, false);
break;
case 3:
gpio_write(3, 15, false);
break;
}
}
void board_led_toggle(uint8_t led) {
switch (led) {
case 0:
gpio_toggle(3, 12);
break;
case 1:
gpio_toggle(3, 13);
break;
case 2:
gpio_toggle(3, 14);
break;
case 3:
gpio_toggle(3, 15);
break;
}
}
/* ============================================================================
* Button Functions
* ============================================================================ */
bool board_button_read(uint8_t button) {
if (button == 0) {
return gpio_read(0, 0);
}
return false;
}
/* ============================================================================
* Delay Functions
* ============================================================================ */
void board_delay_ms(uint32_t ms) {
kernel_delay(ms);
}
void board_delay_us(uint32_t us) {
/* Simple busy-wait delay */
uint32_t count = us * (SystemCoreClock / 1000000) / 5;
while (count--) {
__NOP();
}
}
/* ============================================================================
* Sensor Functions
* ============================================================================ */
float board_get_temperature(void) {
/* Read internal temperature sensor */
uint16_t adc_value = 0;
adc_read_channel(ADC1_INSTANCE, 16, &adc_value, 10);
/* Convert to temperature */
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
float temperature = ((voltage - 0.76f) / 0.0025f) + 25.0f;
return temperature;
}
float board_get_voltage(void) {
/* Read VREFINT */
uint16_t adc_value = 0;
adc_read_channel(ADC1_INSTANCE, 17, &adc_value, 10);
/* Convert to voltage */
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
return voltage;
}
+160
View File
@@ -0,0 +1,160 @@
/**
* @file linker_script.ld
* @brief Linker script for STM32F407VG
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Memory Map */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
/* Stack Configuration */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* End of RAM */
_min_stack_size = 0x400; /* 1KB minimum stack */
_min_heap_size = 0x200; /* 512B minimum heap */
/* Sections */
SECTIONS
{
/* Interrupt Vector Table */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
/* Program Code */
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
/* Constant Data */
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} >FLASH
/* ARM Extensions */
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
/* Pre-initialization Array */
.preinit_array :
{
PROVIDE_HIDDEN(__preinit_array_start = .);
KEEP(*(.preinit_array*))
PROVIDE_HIDDEN(__preinit_array_end = .);
} >FLASH
/* Initialization Array */
.init_array :
{
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array*))
PROVIDE_HIDDEN(__init_array_end = .);
} >FLASH
/* Finalization Array */
.fini_array :
{
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array*))
PROVIDE_HIDDEN(__fini_array_end = .);
} >FLASH
/* Used by startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized Data */
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >RAM AT> FLASH
/* Uninitialized Data */
.bss :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
/* CCMRAM Section */
.ccmram :
{
. = ALIGN(4);
_sccmram = .;
*(.ccmram)
*(.ccmram*)
. = ALIGN(4);
_eccmram = .;
} >CCMRAM
/* Heap Section */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE(end = .);
PROVIDE(_end = .);
. = . + _min_heap_size;
. = . + _min_stack_size;
. = ALIGN(8);
} >RAM
/* Remove information from standard libraries */
/DISCARD/ :
{
libc.a(*)
libm.a(*)
libgcc.a(*)
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}