4. 资源管理基础:资源分类与同步机制

各位同学,咱们今天聊聊资源管理。说实话,这是BSW里最容易出问题的地方之一。我见过太多项目,功能逻辑写得漂漂亮亮,结果一跑多任务就崩了——十有八九是资源管理没做好。

4.1 资源分类:CPU、内存、外设

在AUTOSAR系统里,资源说白了就是三类:CPU时间、内存空间、外设接口。咱们一个一个说。

4.1.1 CPU资源

CPU资源,说白了就是“谁能在哪个时刻用处理器”。在单核系统里,同一时刻只能有一个任务在跑。多任务系统靠调度器来分配CPU时间片。

我个人习惯把CPU资源看作“时间片蛋糕”。每个任务分一块,分多了别的任务饿死,分少了这个任务跑不完。嗯,这里要注意:优先级反转就是典型的CPU资源管理问题。

关键点:CPU资源管理主要靠任务优先级和调度策略。AUTOSAR OS支持优先级抢占调度,高优先级任务可以打断低优先级任务。

4.1.2 内存资源

内存资源分两类:堆(Heap)和栈(Stack)。

  • 栈空间:每个任务/ISR有自己的栈。我在项目中遇到过,一个任务栈溢出,把隔壁任务的变量给踩了——查了三天才找到原因。
  • 堆空间:动态内存分配用的。AUTOSAR里其实不推荐动态分配,但有些中间件还是会用。

你想想看,嵌入式系统内存就那么点,谁多用一点,别人就少用一点。所以内存管理说白了就是“分蛋糕”的艺术。

4.1.3 外设资源

外设资源包括:CAN控制器、SPI总线、I2C接口、ADC模块等等。这些硬件模块通常不能同时被多个任务访问。

举个例子:两个任务同时往CAN控制器里写数据,会发生什么?数据会乱掉。所以外设资源需要互斥访问

资源类型 典型例子 管理方式
CPU 任务执行时间 优先级调度、时间片
内存 栈、堆、全局变量 静态分配、栈监控
外设 CAN、SPI、ADC 资源锁、信号量

4.2 资源锁:保护共享资源

资源锁,说白了就是“谁拿到锁谁用”。其他任务想用?等着吧。

AUTOSAR里最常用的资源锁机制是中断锁调度锁

4.2.1 中断锁

中断锁就是暂时关闭中断。这样ISR就不会来抢资源了。但要注意:关中断时间不能太长,否则会影响系统实时性。

/* 获取中断锁 */
SuspendAllInterrupts();

/* 访问共享资源 */
shared_data = new_value;

/* 释放中断锁 */
ResumeAllInterrupts();

警告:我曾经在一个项目里,有人把中断锁关了整整1毫秒——结果CAN报文接收超时,整车控制器报故障。关中断时间一定要控制在微秒级。

4.2.2 调度锁

调度锁不关中断,只禁止任务切换。这样ISR还能响应,但其他任务不会来抢资源。

/* 获取调度锁 */
GetResource(SCHEDULER_LOCK);

/* 访问共享资源 */
shared_buffer[index] = data;

/* 释放调度锁 */
ReleaseResource(SCHEDULER_LOCK);

我个人更推荐用调度锁而不是中断锁。为什么呢?因为调度锁不会影响中断响应,系统实时性更好。

4.3 信号量:任务间的同步工具

信号量和资源锁不一样。资源锁是“互斥”的,信号量是“同步”的。

你想想看:一个任务生产数据,另一个任务消费数据。怎么让消费者知道数据准备好了?用信号量。

4.3.1 二值信号量

二值信号量只有两个值:0和1。0表示资源被占用,1表示资源可用。

/* 任务A:生产者 */
while(1) {
    /* 生产数据 */
    produce_data();
    /* 释放信号量,通知消费者 */
    ReleaseSemaphore(data_ready);
}

/* 任务B:消费者 */
while(1) {
    /* 等待信号量 */
    WaitSemaphore(data_ready);
    /* 消费数据 */
    consume_data();
}

4.3.2 计数信号量

计数信号量可以管理多个同类资源。比如有3个缓冲区,信号量初始值就是3。

小技巧:我建议用信号量时,一定要设置超时。否则任务可能永远等下去——这叫“死锁”。我曾经调试过一个死锁问题,两个任务互相等对方的信号量,系统直接卡死。排查了整整两天。

4.4 资源管理的避坑指南

做资源管理这么多年,我总结了几条经验:

  1. 能静态分配就别动态分配——动态分配容易产生碎片,而且不好预测。
  2. 锁的粒度要适中——锁太大,并发性差;锁太小,容易死锁。
  3. 信号量命名要规范——我见过有人用sema1、sema2这种名字,三个月后自己都看不懂。
  4. 资源使用要成对出现——获取锁就要释放锁,获取信号量就要释放信号量。

核心原则:资源管理的本质是“谁用谁负责,用完就归还”。别想着别人会帮你释放资源——在嵌入式系统里,没人会帮你擦屁股。

好了,这一章的内容就这些。资源分类、资源锁、信号量,这三个概念是后续章节的基础。下一章咱们聊聊堆栈监控的具体实现——那可是我踩过最多坑的地方。