c - C 中的线程(和 irq)安全动态内存处理程序

标签 c multithreading embedded dynamic-memory-allocation

我正在寻找在多线程系统中安全使用动态内存处理程序的提示。问题详情:

  1. 用 C 语言编写,将在带有 RTOS (CooCox OS) 的 cortex-M3 处理器上运行,
  2. TLSF memory allocator将被使用(如果我发现它们更适合并且它们将是免费和开源的,可能会使用其他分配器),
  3. 我正在寻找的解决方案是使用不受操作系统任务和中断影响的内存分配器。

到目前为止,我想到了 2 种可能的方法,对于我来说,这两种方法的细节都很少:

  1. 在调用分配器函数时禁用和启用中断。问题 - 如果我没记错的话我不能在正常模式下使用中断禁用和启用,只能在特权模式下使用(所以如果我没记错的话,那只是在中断中),我也需要从运行时执行此操作- 防止内存处理程序操作期间的中断和任务切换。
  2. 从 SWI 调用分配器。这个对我来说还是很不清楚。 1st - SWI 是否与 FIQ 相同(如果是这样,FIQ 代码是否需要用 asm 编写 - 因为分配器是用 C 编写的)。然后仍然对从 IRQ 调用 FIQ 有一些疑问(这种情况会发生 - 虽然不经常发生),但很可能这部分不会导致问题。

那么对于这种情况的可能解决方案有什么想法吗?

最佳答案

关于您的建议 1 和 2:

  1. 在 Cortex-M3 上,您可以随时通过 CMSIS intrinsics __disable_irq/_enable_irq特权 级别代码中启用和禁用中断。功能。 特权 级别不限于处理程序模式线程模式 代码也可以在特权级别运行(在许多小型 RTOS 中这是默认设置)。
  2. SWI 和 FIQ 是传统 ARM 架构的概念。它们不存在于 Cortex-M3 中。

理想情况下,您不会希望在中断处理程序中执行内存分配——即使分配器是确定性的,它仍可能需要大量时间;我想不出您想要这样做的几个原因。

最好的方法是修改 tlsf 代码,以便为每个具有外部链接的调用使用 RTOS 互斥锁。 Other libraries我已经使用了库中已有的 stub ,这些 stub 通常什么都不做,但您可以使用自己的实现覆盖它以将其映射到任何 RTOS。

现在你当然不能在 ISR 中使用互斥量,但正如我所说,你也不应该在那里分配内存。如果你真的必须在中断处理程序中执行分配,那么启用/禁用中断是你唯一的选择,但你会混淆 RTOS 提供的所有实时确定性行为。一个更好的解决方案是让您的 ISR 只向线程上下文处理程序发出事件标志或信号量。这允许您使用所有 RTOS 服务和调度,并且与内存分配时间相比,从 ISR 到高优先级线程的上下文切换时间将是微不足道的。

另一种可能性是根本不使用这个分配器,而是使用一个使用 RTOS 队列的固定 block 分配器。您预先分配内存块(静态或动态),将指向每个 block 开始的指针发布到队列中,然后分配您只需从队列中接收一个指针,然后释放您发布回队列。如果内存耗尽(队列为空),您可以阻止或阻塞队列(但不要阻塞在 ISR 中)。您可以为不同大小的 block 创建多个队列,并使用适合您需要的队列(当然要确保您回发到同一个队列!)

关于c - C 中的线程(和 irq)安全动态内存处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30102107/

相关文章:

c - 使用 GENERIC_ALL 访问权限在 ProjectedFS 中打开文件(投影文件系统)

将 int 转换为 uint8_t 数组十六进制值

networking - 使用(免费)嵌入式 TCP/IP 堆栈的经验?

embedded - 重放保护内存块 - eMMC

c - 初学者问题 - 为什么 C 使用 * 来声明指针而不是 &?

c++ - 为什么 malloc() 基于链表?

java - 如何在通过循环修改数据时立即从对象访问数据

c++ - gcc 4.7.1 是否支持线程?

java - spring integration中如何并行同步处理?

linux - 寻找示例嵌入式 Linux HID 设备代码