NevermindZZT / letter-shell

letter shell
MIT License
1.2k stars 438 forks source link

关于在shellTask任务中添加延时,释放CPU占用,让空闲任务得到执行 #182

Open github-linux opened 6 months ago

github-linux commented 6 months ago

Hi NevermindZZT 大佬好 在下面这个代码中,如果使用rtos则是一个while(1)的死循环,如果rtos中还有一个空闲任务,优先级比这个任务优先级低,则永远得不到执行 void shellTask(void *param) { Shell *shell = (Shell *)param; char data; #if SHELL_TASK_WHILE == 1 while(1) { #endif if (shell->read && shell->read(&data, 1) == 1) { shellHandler(shell, data); } #if SHELL_TASK_WHILE == 1 } #endif }

大佬是否考虑添加一个delay,用于释放CPU资源; 例如在配置文件中加一个宏定义 #define SHELL_DELAY() vTaskDealy( (5) / portTICK_PERIOD_MS ) void shellTask(void *param) { Shell *shell = (Shell *)param; char data; #if SHELL_TASK_WHILE == 1 while(1) { #endif if (shell->read && shell->read(&data, 1) == 1) { shellHandler(shell, data); } #if SHELL_TASK_WHILE == 1 SHELL_DELAY(); } #endif }

NevermindZZT commented 6 months ago

这个设计是期望实现的 shell->read 接口中,有进行操作系统的任务调度 MCU 上使用串口一般实现是在串口中断中发送信号量,在 read 中等待信号量,当有串口数据过来的时候就会调度进 shellTask,没有数据就会将任务挂起 可以看看 esp-idf 的 demo, 里面实现的 read 接口就是调用了 esp-idf 中阻塞接受的函数,是会有任务调度的

github-linux commented 6 months ago

感谢回复,这个我看了在esp32中是没问题的,但是好多底层驱动设计的和RTOS完全解耦了; 比如串口中断接受的数据写入一个ringbuf中,而RTOS需要数据是调用uart_read()从ringbuf中去取出来的,所以可能uart_read接口只是从ringbuf中获取数据,没有等待信号量等操作,从而导致不会进行任务调度

NevermindZZT commented 6 months ago

感谢回复,这个我看了在esp32中是没问题的,但是好多底层驱动设计的和RTOS完全解耦了; 比如串口中断接受的数据写入一个ringbuf中,而RTOS需要数据是调用uart_read()从ringbuf中去取出来的,所以可能uart_read接口只是从ringbuf中获取数据,没有等待信号量等操作,从而导致不会进行任务调度

这种情况就可以在实现的 shell->read 接口中进行任务调度,就比如说最简单的加 sleep,就可以放在 shell->read 的实现中

github-linux commented 6 months ago

了解了,那我就先在uart_isr和uart_read中添加一个钩子函数吧,一个用于发送信号量和等待信号量操作,尽量降低驱动和rtos耦合吧