【问题标题】:FreeRTOS queues for IO before scheduler starts (or after it stops)FreeRTOS 在调度程序启动之前(或在它停止之后)排队等待 IO
【发布时间】:2011-02-15 10:05:17
【问题描述】:

我正在寻找有关如何在操作系统调度程序可能尚未启动、正在运行、暂停或可能尚未启动的环境中最好地实现线程安全 IO(例如,将 printf 转到调试串行端口)的建议已停止或坠毁。我正在使用 Newlib 和 FreeRTOS。

目前,我正在使用(看似标准的)FreeRTOS 方法,将 _write 系统调用(Newlib)队列字符放入 FreeRTOS queue,然后从中断服务例程中清空(填充串行端口硬件 FIFO 然后等待 FIFO 空中断)。

这样做的缺点是(至少在 FreeRTOS 上)队列只能在调度程序运行时安全使用,并且在禁用中断时无法打印调试输出(因为它们在引导期间直到调度程序启动,或者在发生致命错误情况之后(正是调试 printf 输出最有用的地方:-)。

最好让 _write 系统调用查询调度程序和/或中断状态,如果调度程序正在运行则使用队列,并在禁用中断时使用阻塞/轮询串行 IO?有没有更优雅的想法我还没有想到?

谢谢

【问题讨论】:

    标签: c embedded io freertos newlib


    【解决方案1】:

    在 _write 系统调用中使用间接可能会更优雅一些。不用检查状态,而是使用函数指针,根据调度器是否在运行、是否启用中断等来实现所需的功能。然后在程序状态发生变化时设置相应的回调函数。

    int (*writeCallback)(int, const void *, unsigned int);
    
    int
    _write(int fd, const void *buffer, unsigned int count)
    {
        return writeCallback(fd, buffer, count);
    }
    
    ...
    
    writeCallback = polling_write;
    
    ...
    
    writeCallback = rtos_write;
    
    ...
    

    或者,您可以定义一个不同的调试函数来绕过标准库流系统(即 printf),以便在您知道不会有中断/RTOS 设施(例如异常处理程序)的地方使用。

    【讨论】:

    • 在发生致命错误后依赖函数指针的完整性真的是个好主意吗?
    • 好吧,在我看来,如果回调函数指针被任何导致致命错误的东西破坏了,可能 printf() -> _write() -> UART 链中的许多其他东西也被破坏了所以无论如何它都没有实际意义......我最终做了梅加登法官建议的事情,除了 _write 调用明确地轮询调度程序状态并首先更新函数指针。 (新硬件的早期调试证明了我的偏执:-)
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    • 1970-01-01
    相关资源
    最近更新 更多