Files
root ca13734bf0 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.
2026-08-23 03:35:29 -04:00

166 lines
4.5 KiB
C

/**
* @file memory_protection.c
* @brief Memory Protection for safety-critical applications
*/
#include "kernel.h"
#include "task.h"
#include <string.h>
/* Memory Protection Configuration */
#define MPU_MAX_REGIONS 8
#define MEMORY_PROTECTION_ALIGNMENT 32 /* 32 bytes minimum */
/* Memory Region Attributes */
typedef struct {
uint32_t base_address;
uint32_t size;
uint8_t permissions;
bool executable;
bool cacheable;
bool bufferable;
} MemoryRegion_t;
/* Memory Protection State */
typedef struct {
bool initialized;
bool enabled;
MemoryRegion_t regions[MPU_MAX_REGIONS];
uint8_t region_count;
TaskHandle_t current_task;
Mutex_t mutex;
} MemoryProtectionState_t;
static MemoryProtectionState_t memory_protection;
/* Initialize Memory Protection */
KernelStatus_t memory_protection_init(void) {
if (memory_protection.initialized) {
return KERNEL_ERROR;
}
memset(&memory_protection, 0, sizeof(MemoryProtectionState_t));
memory_protection.enabled = false;
memory_protection.region_count = 0;
mutex_create(&memory_protection.mutex, false);
memory_protection.initialized = true;
return KERNEL_OK;
}
/* Configure Memory Region */
KernelStatus_t memory_protection_configure_region(uint32_t base_address,
uint32_t size,
uint8_t permissions,
bool executable) {
if (!memory_protection.initialized) {
return KERNEL_ERROR;
}
if (memory_protection.region_count >= MPU_MAX_REGIONS) {
return KERNEL_OUT_OF_MEMORY;
}
/* Validate alignment */
if ((base_address % MEMORY_PROTECTION_ALIGNMENT) != 0 ||
(size % MEMORY_PROTECTION_ALIGNMENT) != 0) {
return KERNEL_INVALID_PARAMETER;
}
mutex_lock(&memory_protection.mutex, 100);
MemoryRegion_t* region = &memory_protection.regions[memory_protection.region_count];
region->base_address = base_address;
region->size = size;
region->permissions = permissions;
region->executable = executable;
memory_protection.region_count++;
mutex_unlock(&memory_protection.mutex);
return KERNEL_OK;
}
/* Enable Memory Protection */
KernelStatus_t memory_protection_enable(void) {
if (!memory_protection.initialized) {
return KERNEL_ERROR;
}
/* Configure MPU hardware */
hal_mpu_enable();
/* Configure regions */
for (uint8_t i = 0; i < memory_protection.region_count; i++) {
MemoryRegion_t* region = &memory_protection.regions[i];
hal_mpu_configure_region(i, region->base_address, region->size,
region->permissions, region->executable);
}
memory_protection.enabled = true;
return KERNEL_OK;
}
/* Disable Memory Protection */
KernelStatus_t memory_protection_disable(void) {
if (!memory_protection.initialized) {
return KERNEL_ERROR;
}
hal_mpu_disable();
memory_protection.enabled = false;
return KERNEL_OK;
}
/* Set Task Memory Region */
KernelStatus_t memory_protection_set_task_region(TaskHandle_t task,
uint32_t base_address,
uint32_t size) {
if (!memory_protection.initialized || task == NULL) {
return KERNEL_ERROR;
}
/* Configure task-specific memory region */
hal_mpu_configure_task_region(task, base_address, size);
return KERNEL_OK;
}
/* Check Memory Access */
bool memory_protection_check_access(uint32_t address, uint8_t access_type) {
if (!memory_protection.initialized || !memory_protection.enabled) {
return true; /* Protection disabled */
}
/* Check if address is within any protected region */
for (uint8_t i = 0; i < memory_protection.region_count; i++) {
MemoryRegion_t* region = &memory_protection.regions[i];
if (address >= region->base_address &&
address < (region->base_address + region->size)) {
/* Check permissions */
if ((region->permissions & access_type) == 0) {
return false; /* Access denied */
}
return true; /* Access allowed */
}
}
return false; /* Address not in any region */
}
/* Memory Protection Fault Handler */
void memory_protection_fault_handler(uint32_t fault_address) {
/* Log fault */
fault_handler_process(2, fault_address, 0);
/* Enter safe state */
while (1) {
/* Wait for watchdog reset */
}
}