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
+203
View File
@@ -0,0 +1,203 @@
/**
* @file board.h
* @brief NXP S32K144 EVB board definitions
*/
#ifndef BOARD_H
#define BOARD_H
#include <stdint.h>
#include <stdbool.h>
#include "S32K144.h"
/* ============================================================================
* Board Identification
* ============================================================================ */
#define BOARD_NAME "S32K144EVB-Q100"
#define BOARD_MANUFACTURER "NXP Semiconductors"
#define BOARD_VERSION "1.0"
#define BOARD_MCU "S32K144"
/* ============================================================================
* Clock Configuration
* ============================================================================ */
#define SOSC_FREQUENCY 8000000U /* System oscillator */
#define SPLL_FREQUENCY 160000000U /* System PLL */
#define FIRC_FREQUENCY 48000000U /* Fast IRC */
#define SIRC_FREQUENCY 8000000U /* Slow IRC */
#define SYSTEM_CLOCK 160000000U /* 160 MHz */
#define BUS_CLOCK 40000000U /* 40 MHz */
#define FLASH_CLOCK 20000000U /* 20 MHz */
/* PLL Configuration */
#define PLL_MULT 20
#define PLL_DIV 1
/* ============================================================================
* LED Definitions
* ============================================================================ */
#define LED_COUNT 3
#define LED_RED_PORT PTC
#define LED_RED_PIN 0
#define LED_RED_INDEX 0
#define LED_GREEN_PORT PTC
#define LED_GREEN_PIN 1
#define LED_GREEN_INDEX 1
#define LED_BLUE_PORT PTC
#define LED_BLUE_PIN 2
#define LED_BLUE_INDEX 2
/* LED Active Level */
#define LED_ACTIVE_LEVEL 0 /* Active low */
/* ============================================================================
* Button Definitions
* ============================================================================ */
#define BUTTON_COUNT 2
#define BUTTON1_PORT PTC
#define BUTTON1_PIN 3
#define BUTTON1_INDEX 0
#define BUTTON2_PORT PTC
#define BUTTON2_PIN 4
#define BUTTON2_INDEX 1
/* Button Active Level */
#define BUTTON_ACTIVE_LEVEL 0 /* Active low */
/* ============================================================================
* UART Definitions
* ============================================================================ */
#define UART0_INSTANCE 0
#define UART0_BAUDRATE 115200
#define UART0_TX_PORT PTA
#define UART0_TX_PIN 2
#define UART0_TX_MUX 2
#define UART0_RX_PORT PTA
#define UART0_RX_PIN 3
#define UART0_RX_MUX 2
#define UART1_INSTANCE 1
#define UART1_BAUDRATE 115200
#define UART1_TX_PORT PTC
#define UART1_TX_PIN 7
#define UART1_TX_MUX 2
#define UART1_RX_PORT PTC
#define UART1_RX_PIN 6
#define UART1_RX_MUX 2
/* ============================================================================
* CAN Definitions
* ============================================================================ */
#define CAN0_INSTANCE 0
#define CAN0_BAUDRATE 500000
#define CAN0_TX_PORT PTE
#define CAN0_TX_PIN 5
#define CAN0_TX_MUX 5
#define CAN0_RX_PORT PTE
#define CAN0_RX_PIN 4
#define CAN0_RX_MUX 5
#define CAN1_INSTANCE 1
#define CAN1_BAUDRATE 500000
#define CAN1_TX_PORT PTC
#define CAN1_TX_PIN 17
#define CAN1_TX_MUX 2
#define CAN1_RX_PORT PTC
#define CAN1_RX_PIN 16
#define CAN1_RX_MUX 2
/* ============================================================================
* SPI Definitions
* ============================================================================ */
#define SPI0_INSTANCE 0
#define SPI0_SCK_PORT PTA
#define SPI0_SCK_PIN 6
#define SPI0_SCK_MUX 2
#define SPI0_MISO_PORT PTA
#define SPI0_MISO_PIN 7
#define SPI0_MISO_MUX 2
#define SPI0_MOSI_PORT PTA
#define SPI0_MOSI_PIN 8
#define SPI0_MOSI_MUX 2
/* ============================================================================
* I2C Definitions
* ============================================================================ */
#define I2C0_INSTANCE 0
#define I2C0_SCL_PORT PTA
#define I2C0_SCL_PIN 9
#define I2C0_SCL_MUX 3
#define I2C0_SDA_PORT PTA
#define I2C0_SDA_PIN 10
#define I2C0_SDA_MUX 3
/* ============================================================================
* ADC Definitions
* ============================================================================ */
#define ADC0_INSTANCE 0
#define ADC0_CHANNEL_COUNT 8
#define ADC0_CH0_PORT PTA
#define ADC0_CH0_PIN 0
#define ADC0_CH0_MUX 0
#define ADC0_CH1_PORT PTA
#define ADC0_CH1_PIN 1
#define ADC0_CH1_MUX 0
/* ============================================================================
* PWM Definitions
* ============================================================================ */
#define PWM_INSTANCE 0
#define PWM_TIMER FTM0
#define PWM_TIMER_CHANNEL_COUNT 4
#define PWM_TIMER_FREQUENCY 10000
#define PWM_TIMER_PRESCALER 4
#define PWM_CH0_PORT PTC
#define PWM_CH0_PIN 1
#define PWM_CH0_MUX 4
#define PWM_CH1_PORT PTC
#define PWM_CH1_PIN 2
#define PWM_CH1_MUX 4
#define PWM_CH2_PORT PTC
#define PWM_CH2_PIN 3
#define PWM_CH2_MUX 4
#define PWM_CH3_PORT PTC
#define PWM_CH3_PIN 4
#define PWM_CH3_MUX 4
/* ============================================================================
* Watchdog Configuration
* ============================================================================ */
#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 */
+371
View File
@@ -0,0 +1,371 @@
/**
* @file board_init.c
* @brief NXP S32K144 EVB 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>
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) {
/* Configure system PLL */
SCG->SPLLCSR = 0; /* Reset SPLL */
SCG->SPLLDIV = SCG_SPLLDIV_SPLLDIV1(1) | SCG_SPLLDIV_SPLLDIV2(1);
SCG->SPLLCFG = SCG_SPLLCFG_MULT(20); /* 8MHz * 20 = 160MHz */
/* Enable SPLL */
SCG->SPLLCSR |= SCG_SPLLCSR_SPLLEN_MASK;
/* Wait for PLL lock */
while (!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK));
/* Switch to SPLL */
SCG->RCCR = SCG_RCCR_DIVCORE(1) |
SCG_RCCR_DIVBUS(4) | /* 160/4 = 40MHz */
SCG_RCCR_DIVSLOW(8) | /* 160/8 = 20MHz */
SCG_RCCR_SCS(6); /* SPLL */
/* Wait for clock switch */
while ((SCG->CSR & SCG_CSR_SCS_MASK) != SCG_CSR_SCS(6));
/* Update SystemCoreClock */
SystemCoreClock = SYSTEM_CLOCK;
}
/* ============================================================================
* GPIO Initialization
* ============================================================================ */
void board_gpio_init(void) {
/* Enable GPIO clocks */
PCC->PCCn[PCC_PORTA_INDEX] |= PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTB_INDEX] |= PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTD_INDEX] |= PCC_PCCn_CGC_MASK;
PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK;
/* 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 = 2; /* PTC */
led_config.pin = 0;
gpio_init(&led_config);
led_config.pin = 1;
gpio_init(&led_config);
led_config.pin = 2;
gpio_init(&led_config);
/* Configure buttons */
GpioPinConfig_t button_config = {
.port = 2, /* PTC */
.pin = 3,
.mode = GPIO_MODE_INPUT,
.pull = GPIO_PULL_UP
};
gpio_init(&button_config);
button_config.pin = 4;
gpio_init(&button_config);
/* Turn off all LEDs */
board_led_off(0);
board_led_off(1);
board_led_off(2);
}
/* ============================================================================
* UART Initialization
* ============================================================================ */
void board_uart_init(void) {
/* Configure UART0 */
UartConfig_t uart_config = {
.baudrate = UART0_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(UART0_INSTANCE, &uart_config);
}
/* ============================================================================
* CAN Initialization
* ============================================================================ */
void board_can_init(void) {
/* Configure CAN0 */
CanConfig_t can_config = {
.nominal_baudrate = CAN0_BAUDRATE,
.data_baudrate = CAN0_BAUDRATE,
.frame_type = CAN_FRAME_CLASSIC,
.enable_fd = true, /* S32K144 supports CAN FD */
.enable_automatic_retransmission = true,
.filter_count = 0
};
can_init(CAN0_INSTANCE, &can_config);
}
/* ============================================================================
* SPI Initialization
* ============================================================================ */
void board_spi_init(void) {
/* Configure SPI0 */
SpiConfig_t spi_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 = 1,
.cs_pin = 0
};
spi_init(SPI0_INSTANCE, &spi_config);
}
/* ============================================================================
* I2C Initialization
* ============================================================================ */
void board_i2c_init(void) {
/* Configure I2C0 */
I2cConfig_t i2c_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(I2C0_INSTANCE, &i2c_config);
}
/* ============================================================================
* ADC Initialization
* ============================================================================ */
void board_adc_init(void) {
/* Configure ADC0 */
AdcConfig_t adc_config = {
.resolution = ADC_RESOLUTION_12BIT,
.mode = ADC_MODE_SCAN,
.trigger_source = ADC_TRIGGER_SOFTWARE,
.reference = ADC_REFERENCE_VDD,
.enable_dma = false,
.conversion_frequency = 1000,
.channel_count = 8,
.channels = {
{.channel = 0, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 1, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 2, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 3, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 4, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 5, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 6, .sampling_time = ADC_SAMPLING_13_5_CYCLES},
{.channel = 7, .sampling_time = ADC_SAMPLING_13_5_CYCLES}
}
};
adc_init(ADC0_INSTANCE, &adc_config);
}
/* ============================================================================
* PWM Initialization
* ============================================================================ */
void board_pwm_init(void) {
/* Configure PWM */
PwmConfig_t pwm_config = {
.frequency_hz = PWM_TIMER_FREQUENCY,
.alignment = PWM_ALIGNMENT_EDGE,
.period_ticks = 10000,
.prescaler = PWM_TIMER_PRESCALER,
.channel_count = 4,
.channels = {
{.channel = 0, .duty_cycle = 0},
{.channel = 1, .duty_cycle = 0},
{.channel = 2, .duty_cycle = 0},
{.channel = 3, .duty_cycle = 0}
},
.enable_fault_protection = true,
.fault_action = PWM_FAULT_DISABLE
};
pwm_init(PWM_INSTANCE, &pwm_config);
}
/* ============================================================================
* Watchdog Initialization
* ============================================================================ */
void board_watchdog_init(void) {
/* Configure WDOG */
WDOG->CNT = 0x1000; /* Timeout value */
WDOG->TOVAL = 0x1000;
WDOG->CS = WDOG_CS_EN_MASK |
WDOG_CS_CLK(1) |
WDOG_CS_WIN_MASK |
WDOG_CS_UPDATE_MASK;
}
void board_watchdog_service(void) {
/* Service WDOG */
WDOG->CNT = 0xB480;
WDOG->CNT = 0x4B80;
}
/* ============================================================================
* LED Functions
* ============================================================================ */
void board_led_on(uint8_t led) {
switch (led) {
case 0:
gpio_write(2, 0, false); /* Active low */
break;
case 1:
gpio_write(2, 1, false);
break;
case 2:
gpio_write(2, 2, false);
break;
}
}
void board_led_off(uint8_t led) {
switch (led) {
case 0:
gpio_write(2, 0, true);
break;
case 1:
gpio_write(2, 1, true);
break;
case 2:
gpio_write(2, 2, true);
break;
}
}
void board_led_toggle(uint8_t led) {
switch (led) {
case 0:
gpio_toggle(2, 0);
break;
case 1:
gpio_toggle(2, 1);
break;
case 2:
gpio_toggle(2, 2);
break;
}
}
/* ============================================================================
* Button Functions
* ============================================================================ */
bool board_button_read(uint8_t button) {
switch (button) {
case 0:
return !gpio_read(2, 3); /* Active low */
case 1:
return !gpio_read(2, 4);
default:
return false;
}
}
/* ============================================================================
* Delay Functions
* ============================================================================ */
void board_delay_ms(uint32_t ms) {
kernel_delay(ms);
}
void board_delay_us(uint32_t us) {
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(ADC0_INSTANCE, 26, &adc_value, 10); /* Internal temp sensor */
/* Convert to temperature (S32K144 specific formula) */
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
float temperature = 25.0f - ((voltage - 0.716f) / 0.00162f);
return temperature;
}
float board_get_voltage(void) {
/* Read bandgap reference */
uint16_t adc_value = 0;
adc_read_channel(ADC0_INSTANCE, 27, &adc_value, 10); /* Bandgap */
float voltage = adc_convert_to_voltage(adc_value, ADC_RESOLUTION_12BIT, 3.3f);
return voltage;
}
+141
View File
@@ -0,0 +1,141 @@
/**
* @file linker_script.ld
* @brief Linker script for NXP S32K144
*/
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
SRAM_L (rwx) : ORIGIN = 0x1FFF8000, LENGTH = 32K
SRAM_U (rwx) : ORIGIN = 0x20000000, LENGTH = 28K
}
_estack = ORIGIN(SRAM_U) + LENGTH(SRAM_U);
_min_stack_size = 0x400;
_min_heap_size = 0x200;
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
/* Initialization Arrays */
.preinit_array :
{
PROVIDE_HIDDEN(__preinit_array_start = .);
KEEP(*(.preinit_array*))
PROVIDE_HIDDEN(__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN(__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array*))
PROVIDE_HIDDEN(__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN(__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array*))
PROVIDE_HIDDEN(__fini_array_end = .);
} >FLASH
/* Data Sections */
_sidata = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >SRAM_L AT> FLASH
/* BSS Section */
.bss :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >SRAM_L
/* Heap and Stack */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE(end = .);
PROVIDE(_end = .);
. = . + _min_heap_size;
. = . + _min_stack_size;
. = ALIGN(8);
} >SRAM_U
/* Discard */
/DISCARD/ :
{
libc.a(*)
libm.a(*)
libgcc.a(*)
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}