Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中线程(和irq)安全的动态内存处理程序_C_Multithreading_Embedded_Dynamic Memory Allocation - Fatal编程技术网

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

C中线程(和irq)安全的动态内存处理程序,c,multithreading,embedded,dynamic-memory-allocation,C,Multithreading,Embedded,Dynamic Memory Allocation,我正在寻找在多线程系统中使用动态内存处理程序安全的提示。详情如下: 用C编写的将在cortex-M3处理器上运行,带有RTOS(CooCox OS) 将被使用(如果我发现其他分配器更合适,可能会使用它们,并且它们将是免费和开源的) 我正在寻找的解决方案是使用内存分配器来避免操作系统任务和中断 到目前为止,我已经想到了两种可能的方法,这两种方法都有一些未知的细节: 调用分配器函数时禁用和启用中断。问题-如果我没有弄错我不能在正常模式下玩中断禁用和启用,只有在特权模式下(所以如果我没有弄错,那只是在

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

  • 用C编写的将在cortex-M3处理器上运行,带有RTOS(CooCox OS)
  • 将被使用(如果我发现其他分配器更合适,可能会使用它们,并且它们将是免费和开源的)
  • 我正在寻找的解决方案是使用内存分配器来避免操作系统任务和中断
  • 到目前为止,我已经想到了两种可能的方法,这两种方法都有一些未知的细节:

  • 调用分配器函数时禁用和启用中断。问题-如果我没有弄错我不能在正常模式下玩中断禁用和启用,只有在特权模式下(所以如果我没有弄错,那只是在中断中),我也需要从运行时开始这样做-以防止内存处理程序操作期间的中断和任务切换
  • 从SWI调用分配器。这个对我来说还很不清楚。第一个-SWI与FIQ相同(如果是,FIQ代码需要用asm编写是真的吗?因为分配器是用C编写的)。然后,对于从IRQ调用FIQ(这种情况会发生——虽然不经常发生),仍然没有什么疑问,但这一部分很可能不会引起问题

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

    关于您的建议1和2:

  • 在Cortex-M3上,您可以通过函数在特权级别代码中随时启用和禁用中断。特权级别不限于处理程序模式;线程模式代码也可以在特权级别运行(在许多小型RTO中,这是默认情况)
  • SWI和FIQ是传统ARM体系结构的概念。它们不存在于Cortex-M3中
  • 理想情况下,您不希望在中断处理程序中执行内存分配-即使分配器是确定性的,也可能需要大量时间;我想不出你想这么做的理由

    最好的方法是修改tlsf代码,以便为具有外部链接的每个调用使用RTOS互斥体。我曾经在库中使用过存根,这些存根通常不起任何作用,但您可以使用自己的实现覆盖它们,以将其映射到任何RTO

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


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

    我能够处理这一问题的唯一方法是根本不在中断中直接使用分配。相反,我使用两组三个队列,一组用于IRQ,一组用于FIQ。在每组中,一个队列向发送中断提供缓冲区索引/指针,一个队列向接收中断提供“空”缓冲区,第三个队列为已填充的接收缓冲区和“已使用”的发送缓冲区的返回队列。一个线程管理每组队列,并在中断发出信号表示队列“需要注意”时运行。FIQ通过触发在FIQ退出时运行的“SWI”IRQ来发出信号量。@MartinJames:听起来不像Cortex-M,而是旧的ARM7/9/10/11或Cortex-R(不确定-A)。COretx-M有一个完全不同的中断系统,它有一个完整的中断控制器(NVIC),包括真向量、优先级(内部/外部)等。这种机制将挑战整个体系结构。只要我看一眼代码,中断将被阻塞很长一段时间(尽管这可能有一个最大边界)。你应该确保你的系统在任何情况下都能容忍这种情况。SWI不是这样的东西(实际上没有SWI指令,它至少被重命名为SVC)。Cortex-M有一个非常聪明的异常系统;你可以看看SVPend而不是SVC。以及(正如我已经说过的)Cortex-M有一个不同的中断系统,而不仅仅是两个向量。你应该首先非常熟悉Cortex-M例外系统。你在问题中陈述的大多数东西甚至不存在,或者对我来说似乎没有意义(无意冒犯)。您可以从Cortex-M3 TRM和体系结构指南开始,该指南可从ARM免费下载(注意:有两个不同的Arch指南)。此外,您的MCU供应商应提供参考手册(也称为用户指南或类似指南;这不是数据表,但也可能是必需的)。启用/禁用irq的指令受到保护是有充分理由的。它们不能从非特权模式访问。中断处理程序的内存分配是常见的做法,可以简化系统设计。这尤其是在使用优先级的情况下。但是,您是对的,分配器不能超过给定的时间。实际时间取决于可接受的中断时间和延迟。无论如何,标准分配器在大多数情况下都不是正确的。关于
    \uu enable\u irq
    -我的错误,在简单的RTOS环境中,所有软件都以特权模式运行是常见的