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
+115
View File
@@ -0,0 +1,115 @@
# GDB initialization script for Automotive RTOS debugging
# Set target architecture
set architecture arm
set endian little
# Configure remote target
# target remote localhost:3333
# target remote :2331
# Set program counter
set $pc = Reset_Handler
# Break at main
break main
continue
# RTOS-specific commands
define rtos_tasks
echo === RTOS Tasks ===\n
set $task = task_list_head
while $task != 0
printf "Task: %s\n", $task->name
printf " ID: %d\n", $task->task_id
printf " Priority: %d\n", $task->priority
printf " State: %d\n", $task->state
printf " Stack: 0x%08x\n", $task->stack_pointer
printf " Stack Base: 0x%08x\n", $task->stack_base
printf " Stack Size: %d\n", $task->stack_size
printf "\n"
set $task = $task->next
end
end
define rtos_task_info
if $argc != 1
echo Usage: rtos_task_info <task_name>\n
else
set $task = task_list_head
while $task != 0
if $_streq($task->name, $arg0)
printf "Task Information:\n"
printf " Name: %s\n", $task->name
printf " ID: %d\n", $task->task_id
printf " Priority: %d\n", $task->priority
printf " State: %d\n", $task->state
printf " Stack Pointer: 0x%08x\n", $task->stack_pointer
printf " Stack Base: 0x%08x\n", $task->stack_base
printf " Stack Size: %d\n", $task->stack_size
printf " Stack Used: %d\n", $task->stack_high_water_mark
printf " Execution Count: %d\n", $task->statistics.execution_count
printf " Last Execution: %d\n", $task->statistics.last_execution_time
break
end
set $task = $task->next
end
if $task == 0
echo Task not found\n
end
end
end
define rtos_scheduler_stats
echo === Scheduler Statistics ===\n
printf "Context Switches: %d\n", scheduler_state.statistics.context_switches
printf "Preemptions: %d\n", scheduler_state.statistics.preemptions
printf "Max Latency: %d\n", scheduler_state.statistics.max_scheduling_latency
printf "Total Idle Time: %d\n", scheduler_state.statistics.total_idle_time
end
define rtos_semaphores
echo === Semaphores ===\n
# Iterate through semaphore list
echo Semaphore information not available in this build\n
end
define rtos_mutexes
echo === Mutexes ===\n
# Iterate through mutex list
echo Mutex information not available in this build\n
end
define rtos_queues
echo === Message Queues ===\n
# Iterate through queue list
echo Queue information not available in this build\n
end
define rtos_stack_check
echo === Stack Usage ===\n
set $task = task_list_head
while $task != 0
printf "%s: %d/%d bytes used\n", $task->name, $task->stack_high_water_mark, $task->stack_size
set $task = $task->next
end
end
# Pretty printing
set print pretty on
set print array on
set print elements 20
set print demangle on
# History
set history save on
set history size 1000
set history filename .gdb_history
# Convenience
set pagination off
set confirm off
set verbose off
# Display on stop
display/10i $pc
+213
View File
@@ -0,0 +1,213 @@
#!/usr/bin/env python3
"""
@file trace_analyzer.py
@brief Trace analyzer for Automotive RTOS debugging
"""
import os
import re
import sys
import argparse
import json
from collections import defaultdict
from datetime import datetime
from pathlib import Path
class TraceAnalyzer:
"""Analyze RTOS trace data"""
def __init__(self, trace_file):
self.trace_file = Path(trace_file)
self.events = []
self.task_timeline = defaultdict(list)
self.context_switches = []
self.interrupts = []
def parse_trace_file(self):
"""Parse trace file"""
print(f"Parsing trace file: {self.trace_file}")
if not self.trace_file.exists():
print(f"Error: Trace file not found")
return False
event_pattern = re.compile(
r'\[(\d+\.?\d*)\]\s+(\w+):\s+(.*)'
)
with open(self.trace_file, 'r') as f:
for line in f:
match = event_pattern.match(line)
if match:
timestamp = float(match.group(1))
event_type = match.group(2)
event_data = match.group(3)
event = {
'timestamp': timestamp,
'type': event_type,
'data': event_data
}
self.events.append(event)
# Categorize events
if event_type == 'TASK_SWITCH':
self.context_switches.append(event)
elif event_type == 'IRQ_ENTER':
self.interrupts.append(event)
elif event_type == 'TASK_START':
task_name = event_data.split(':')[0].strip()
self.task_timeline[task_name].append({
'type': 'start',
'timestamp': timestamp
})
elif event_type == 'TASK_END':
task_name = event_data.split(':')[0].strip()
self.task_timeline[task_name].append({
'type': 'end',
'timestamp': timestamp
})
print(f"Parsed {len(self.events)} events")
return True
def analyze_context_switches(self):
"""Analyze context switches"""
print("\nContext Switch Analysis:")
print("-" * 60)
if not self.context_switches:
print("No context switches found")
return
# Calculate intervals
intervals = []
for i in range(1, len(self.context_switches)):
interval = (self.context_switches[i]['timestamp'] -
self.context_switches[i-1]['timestamp'])
intervals.append(interval)
if intervals:
avg_interval = sum(intervals) / len(intervals)
min_interval = min(intervals)
max_interval = max(intervals)
print(f"Total context switches: {len(self.context_switches)}")
print(f"Average interval: {avg_interval:.3f} ms")
print(f"Minimum interval: {min_interval:.3f} ms")
print(f"Maximum interval: {max_interval:.3f} ms")
def analyze_task_execution(self):
"""Analyze task execution times"""
print("\nTask Execution Analysis:")
print("-" * 60)
print(f"{'Task Name':25s} {'Executions':>10s} {'Total Time':>10s} {'Avg Time':>10s}")
print("-" * 60)
for task_name, events in self.task_timeline.items():
executions = 0
total_time = 0
for i in range(0, len(events) - 1, 2):
if i + 1 < len(events):
if events[i]['type'] == 'start' and events[i+1]['type'] == 'end':
duration = events[i+1]['timestamp'] - events[i]['timestamp']
total_time += duration
executions += 1
if executions > 0:
avg_time = total_time / executions
print(f"{task_name:25s} {executions:10d} {total_time:10.3f} {avg_time:10.3f}")
def analyze_interrupts(self):
"""Analyze interrupt handling"""
print("\nInterrupt Analysis:")
print("-" * 40)
if not self.interrupts:
print("No interrupts found")
return
irq_count = defaultdict(int)
for irq in self.interrupts:
irq_name = irq['data'].strip()
irq_count[irq_name] += 1
for irq_name, count in irq_count.items():
print(f"{irq_name:20s} {count:5d} occurrences")
def generate_timeline(self, output_file):
"""Generate task timeline visualization"""
print(f"\nGenerating timeline: {output_file}")
with open(output_file, 'w') as f:
f.write("RTOS Task Timeline\n")
f.write("=" * 80 + "\n\n")
# Find time range
if not self.events:
return
start_time = self.events[0]['timestamp']
end_time = self.events[-1]['timestamp']
duration = end_time - start_time
f.write(f"Time range: {start_time:.3f} to {end_time:.3f} ms\n")
f.write(f"Duration: {duration:.3f} ms\n\n")
# Generate ASCII timeline
timeline_width = 80
time_per_char = duration / timeline_width if duration > 0 else 1
for task_name, events in self.task_timeline.items():
f.write(f"\n{task_name}:\n")
# Create timeline
timeline = [' '] * timeline_width
for i in range(0, len(events) - 1, 2):
if i + 1 < len(events):
start_pos = int((events[i]['timestamp'] - start_time) / time_per_char)
end_pos = int((events[i+1]['timestamp'] - start_time) / time_per_char)
for pos in range(start_pos, min(end_pos, timeline_width)):
if 0 <= pos < timeline_width:
timeline[pos] = '#'
f.write(''.join(timeline) + '\n')
f.write("\nLegend: '#' = task running, ' ' = task not running\n")
def analyze(self):
"""Run complete analysis"""
print("=" * 60)
print("Trace Analyzer")
print("=" * 60)
if not self.parse_trace_file():
return
self.analyze_context_switches()
self.analyze_task_execution()
self.analyze_interrupts()
# Generate timeline
output_dir = self.trace_file.parent
timeline_file = output_dir / 'timeline.txt'
self.generate_timeline(timeline_file)
print(f"\nTimeline saved to: {timeline_file}")
def main():
parser = argparse.ArgumentParser(description='Trace analyzer')
parser.add_argument('trace_file', help='Trace file to analyze')
parser.add_argument('--output', help='Output directory')
args = parser.parse_args()
analyzer = TraceAnalyzer(args.trace_file)
analyzer.analyze()
if __name__ == '__main__':
main()