Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
FinSH
ringbuffer_环形缓冲区
卡死
5
再用ringbuffer方法移植Finsh的时候出现程序卡死
发布于 2024-11-15 22:04:18 浏览:15
订阅该版
在跟着rtt官方用中断方式移植FinSH组件的时候在进入rt_sem_take(&shell_rx_sem, RT_WAITING_FOREVER);的时候程序卡死,一旦这句话注释掉,程序正常运行,有大佬解答一下吗 这是串口的完整函数 ```c #include "bsp_usart.h" #if USART1_EN == 1 unsigned char g_USART1_RxBuf[USART1_RX_BUF_SIZE];//串口接收缓冲区 unsigned short int g_USART1_RecPos = 0;//存放当前串口接收数据存放的位置 #endif #if USART2_EN == 1 unsigned char g_USART2_RxBuf[USART2_RX_BUF_SIZE];//串口接收缓冲区 unsigned short int g_USART2_RecPos = 0;//存放当前串口接收数据存放的位置 #endif #if USART3_EN == 1 unsigned char g_USART3_RxBuf[USART3_RX_BUF_SIZE];//串口接收缓冲区 unsigned short int g_USART3_RecPos = 0;//存放当前串口接收数据存放的位置 #endif rt_uint8_t uart_rx_buf[512] = {0}; struct rt_ringbuffer uart_rxcb; /* 定义一个 ringbuffer cb */ static struct rt_semaphore shell_rx_sem; /* 定义一个静态信号量 */ void UsartInit(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; #if USART1_EN == 1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; //TX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ; //RX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = USART1_BAUD; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART1, &USART_InitStructure);//初始化串口1 //#if 0 //由于FinSH中rt_hw_console_getchar使用查询方式实现,故串口1中断初始化需注释掉 //串口1中断初始化 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //#endif USART_Cmd(USART1, ENABLE);//使能串口1 USART_ClearFlag(USART1, USART_FLAG_TC );//清发送完成标志位 #endif #if USART2_EN == 1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ; //TX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ; //RX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = USART2_BAUD; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART2, &USART_InitStructure);//初始化串口2 //串口2中断初始化 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_Cmd(USART2, ENABLE);//使能串口2 USART_ClearFlag(USART2, USART_FLAG_TC );//清发送完成标志位 #endif #if USART3_EN == 1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ; //TX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; //RX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = USART3_BAUD; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART3, &USART_InitStructure);//初始化串口3 //串口3中断初始化 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); USART_Cmd(USART3, ENABLE);//使能串口3 USART_ClearFlag(USART3, USART_FLAG_TC );//清发送完成标志位 #endif } //为能够调用printf函数从选定的串口打印输出,重定义fputc函数,本例子使用串口1 int fputc(int ch,FILE *f) { USART_SendData(USART1, (unsigned char)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC)== RESET); return (ch); } static void UsartSendByte(USART_TypeDef* USARTx,unsigned char ch) { USART_SendData(USARTx, (unsigned char)ch); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)== RESET); } void UsartSendString(USART_TypeDef* USARTx,unsigned char *str) { unsigned int pos = 0; while(*(str+pos)!='\0') { UsartSendByte(USARTx,*(str+pos)); pos ++; } } //#if 0 //由于FinSH中rt_hw_console_getchar使用查询方式实现,故串口1中断回调需注释掉 //USART1_IRQHandler,串口1中断回调函数 void USART1_IRQHandler(void) { #if USART1_EN == 1 /*----------------------------------------------------------------------------------*/ int ch = -1; /* enter interrupt */ rt_interrupt_enter(); //在中断中一定要调用这对函数,进入中断 /*----------------------------------------------------------------------------------*/ #endif if( USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=RESET ) // 串口接收数据 { #if USART1_EN == 1 /*---------------------------------------------------------------------------------- */ while (1) { ch = -1; if (USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=RESET) { ch = USART_ReceiveData(USART1); }else ch = -1; if (ch == -1) { break; } /* 读取到数据,将数据存入 ringbuffer */ rt_ringbuffer_putchar(&uart_rxcb, ch); } rt_sem_release(&shell_rx_sem); /*----------------------------------------------------------------------------------*/ #endif USART_ClearFlag(USART1, USART_FLAG_RXNE); } if( USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET ) // 串口溢出错误 { USART_ClearFlag(USART1, USART_FLAG_ORE); } /* leave interrupt */ rt_interrupt_leave(); //在中断中一定要调用这对函数,离开中断 } //#endif //USART2_IRQHandler,串口2中断回调函数 void USART2_IRQHandler(void) { #if USART2_EN == 1 //用户代码 #endif if( USART_GetFlagStatus(USART2,USART_FLAG_RXNE)!=RESET ) // 串口接收数据 { #if USART2_EN == 1 //用户代码 #endif USART_ClearFlag(USART2, USART_FLAG_RXNE); } if( USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET ) // 串口溢出错误 { USART_ClearFlag(USART2, USART_FLAG_ORE); } } //USART3_IRQHandler,串口3中断回调函数 void USART3_IRQHandler(void) { #if USART3_EN == 1 //用户代码 #endif if( USART_GetFlagStatus(USART3,USART_FLAG_RXNE)!=RESET ) // 串口接收数据 { #if USART3_EN == 1 //用户代码 #endif USART_ClearFlag(USART3, USART_FLAG_RXNE); } if( USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET ) // 串口溢出错误 { USART_ClearFlag(USART3, USART_FLAG_ORE); } } void rt_hw_console_output(const char *str) //实现该函数,才能使用rt_kprintf { /* 进入临界段 */ rt_enter_critical(); while(*str !='\0') { /* 换行 */ if (*str == '\n')//RT-Thread 系统中已有的打印均以 \n 结尾,而并非 \r\n,所以在字符输出时,需要在输出 \n 之前输出 \r,完成回车与换行,否则系统打印出来的信息将只有换行 { USART_SendData(USART1, '\r'); while(USART_GetFlagStatus(USART1, USART_FLAG_TC)== RESET); } USART_SendData(USART1, *(str++)); while(USART_GetFlagStatus(USART1, USART_FLAG_TC)== RESET); } /* 退出临界段 */ rt_exit_critical(); //注意:使用进入临界段语句rt_enter_critical(); 一定要使用退出临界段语句 rt_exit_critical();否则调度器锁住,无法进行调度 } //char rt_hw_console_getchar(void)//使用Finsh组件三步骤:1.实现该函数及rt_hw_console_output函数;2.rtconfig.h中开启RT_USING_FINSH宏;3.添加Finsh组件(cmd.c、msh.c、shell.c), //{ //查询方式实现,记得将Usart1初始化中的中断接收配置相关代码注释掉 // int ch = -1; // /*等待串口1输入数据*/ // if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) // { // ch = (int)USART_ReceiveData(USART1); // USART_ClearFlag(USART1, USART_FLAG_RXNE); // } // else // { // // if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) // { // USART_ClearFlag(USART1, USART_FLAG_ORE); // } // //rt_thread_mdelay(10); // // } // return ch; //} char rt_hw_console_getchar(void) { char ch = 0; /* 从 ringbuffer 中拿出数据 */ while (rt_ringbuffer_getchar(&uart_rxcb, (rt_uint8_t *)&ch) != 1) { rt_sem_take(&shell_rx_sem, RT_WAITING_FOREVER); } return ch; } ``` 这是FInSH组件显示内容,求大佬解答 ![1.png](https://oss-club.rt-thread.org/uploads/20241115/a9689f51d4461e69ab52e6aab004cade.png) 程序主要问题应该在这段程序 ```c char rt_hw_console_getchar(void) { char ch = 0; /* 从 ringbuffer 中拿出数据 */ while (rt_ringbuffer_getchar(&uart_rxcb, (rt_uint8_t *)&ch) != 1) { rt_sem_take(&shell_rx_sem, RT_WAITING_FOREVER); } return ch; } ``` 中的rt_sem_take(&shell_rx_sem, RT_WAITING_FOREVER); 注释掉程序运行良好。
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
15
关于作者
wwwwake
这家伙很懒,什么也没写!
提问
2
回答
0
被采纳
0
关注TA
发私信
相关问题
1
RT-THREAD shell无反应呢?
2
RT-thread2.0beta下用类似linux风格MSH,参数如何输入和导出
3
rt-thread finsh windows下的那个终端软件叫什么来着
4
板子上只有485接口,能把FINSH改造成485的么?
5
finsh最大字符问题
6
finsh命令个数是不是有限制啊
7
finsh支持转义字符吗
8
不用finsh如何知道堆栈使用量
9
强烈建议 RT-Thread下finsh原理深入分析
10
finsh输入命令全部返回null node
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
rt-thread官方usb驱动之虚拟串口
2
RTduino物联网应用零基础入门
3
TinyUSB Demo运行教程
4
RT-Thread学习大礼包一键带走!
5
freemodbus从机调试说明
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
ART-Pi
FinSH
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
cubemx
freemodbus
PWM
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
5
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
3
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
5
个答案
1
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
4
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部