Open kylongmu opened 1 year ago
在其他系列MCU的drv_usart.c中查看: ` static rt_err_t hpm_uart_configure(struct rt_serial_device serial, struct serial_configure cfg) {
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart_config_t uart_config;
struct hpm_uart *uart = (struct hpm_uart *)serial->parent.user_data;
user_data也被使用了。 再看stm32的drv_usart.c
static rt_err_t stm32_configure(struct rt_serial_device serial, struct serial_configure cfg)
{
struct stm32_uart *uart;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart = rt_container_of(serial, struct stm32_uart, serial);
用了一个奇怪的方式,查到这个宏:
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
` 晦涩难懂,但是没有占用user_data 所以这个user_data被其他系列MCU的驱动使用了,只能在stm32上面正确运行。
好吧,在写这个代码前我还研究过这个驱动user_data到底是给驱动做用户数据还是给应用做用户数据使用。 我误认为是给应用层做数据使用的。 所以这个地方得改一下。
好吧,在写这个代码前我还研究过这个驱动user_data到底是给驱动做用户数据还是给应用做用户数据使用。 我误认为是给应用层做数据使用的。 所以这个地方得改一下。
多谢修复该问题,另外串口驱动现在有了V2版本,还请考虑一下兼容性
这是我以前提问的帖子 https://club.rt-thread.org/ask/question/ead12ad1be79c8f0.html V2版本的串口驱动应该不需要改动吧,直接使用中断接收+轮询发送即可。如果是DMA之类的调整接收的帧超时或者字节超时应该也能适应的。
在官方rt-thread源bsp\wch\risc-v\ch32v307v-r1开发板工程下测试直接死机 msh > hardfult mepc:00013a5c mcause:00000004 mtval:50504251 跟踪后在small_modbus_port_rtthread.c文件中
` static int _modbus_rtdevice_open(small_modbus_t smb) { small_modbus_port_rtdevice_t smb_port_device = (small_modbus_port_rtdevice_t *)smb->port; if (smb_port_device->device) { //屏蔽下面一行可以执行无硬件报错,应该是这里引起问题 //smb_port_device->device->user_data = smb_port_device;
`
把smb_port_device->device->user_data = smb_port_device; 放到rt_device_open后执行,能通过,但是一旦接收到数据,接收数据引用user_data就直接hardfult。看来是user_data的赋值有问题,再引用它的指针时发生了内存越界错误。
进一步检查后发现user_data在Libraries\ch32_drivers\drv_usart.c中被使用了 ` static rt_err_t ch32_configure(struct rt_serial_device serial, struct serial_configure cfg) { struct ch32_uart *uart; GPIO_InitTypeDef GPIO_InitStructure={0};
` 这个变量已经被驱动层代码占用了,应用层再用当然指针出错了,device->user_data不能用。