想在stm32上做个boot程序,之前用的是gitee上的一个开源推荐项目,但是有些功能还是不需要,例如ymodem,也不想做成多分区的结构。自己写个简单的吧。
之前用串口接收都是中断+定时器,或者有头有尾的帧,基本上都是一个字节一个字节的处理。后来在rt-thread的官方文档上才知道有dma+idle模式,基本不需要去干预。针对json格式的通讯是个不错的选择。调试过程中遇到的小问题记录下来。
1.在跑rtt时,新增的serial线程总是跑不起来,后来发现是优先级太低了。
thread pri status sp stack size max used left tick error
-------- --- ------- ---------- ---------- ------ ---------- ---
tshell 21 ready 0x00000060 0x00000200 90% 0x00000003 000
serial 21 suspend 0x00000064 0x00000400 16% 0x00000004 000
tidle 31 ready 0x00000044 0x00000100 26% 0x00000020 000
main 10 close 0x00000044 0x00000400 21% 0x00000001 000
tshell线程是cubeMX生成时,默认的优先级,里面不停的读取获得的键盘输入字符,也没有延时。srial是创建的,里面的打印显示10ms一次,老是显示不出来,调成一样的就好了。
2.dma+idle模式 中的缓存总是只有最后一个字节的顺序。
后发现是dma初始化问题
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}
MX_DMA_Init函数默认生成的是static修饰,如果不改main默认生产的设置是没有问题的,因为要打印rtt的启动信息,就放在了rtt的borad.c中,不然放在main中,串口还没有初始化有些信息打印不了。
/**
* This function will initial your board.
*/
void rt_hw_board_init()
{
/* System Clock Update */
SystemCoreClockUpdate();
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
MX_USART1_UART_Init();
MX_SPI1_Init();
extern int uart_init(void);
uart_init();
}
MX_DMA_Init();
MX_USART3_UART_Init();的顺序导致了问题。
dma+idle模式参考如下
https://www.stmcu.org.cn/document/detail/index/id-219493
该帖子采用了修改标准库的方式,感觉不太好
https://blog.youkuaiyun.com/as480133937/article/details/105013368
可以用标准库使用宏,更好些。