STM32 USB转串口驱动移植到SylixOS中遇到的问题总结

2019-07-22来源: eefocus关键字:STM32  USB转串口驱动  移植  SylixOS
  1. 简介 


由于客户项目需求,需要在STM32的硬件平台上实现USB转串口的功能,由于ST公司基于STM32硬件平台实现了相应的USB库以方便开发者进行开发,因此,在SylixOS下实现USB转串口功能时对该USB库进行了移植。由于该USB库的实现是基于STM32的裸机代码实现,因此在移植的过程中,不需要做过多的修改。 


下面章节主要介绍在移植STM32的USB转串口驱动到SylixOS下遇到的问题以及对应的解决方法。对于其中的有些解决方法在移植STM32其他外设驱动的过程中也依然适用。 


2. 移植遇到的问题及解决方法 

2.1 非对齐内存访问错误 


在移植完USB转串口驱动后,烧写SylixOS到STM32后,在运行过程中提示非法非对齐内存访问的错误,并且在产生该问题后会导致系统一直重启。调试过程中发现代码运行到数据拷贝的语句发生错误,具体代码如下所示。


USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, 

                                uint8_t             *src, 

                                uint8_t              ch_ep_num, 

                                uint16_t             len)

{

    USB_OTG_STS status = USB_OTG_OK;

    if (pdev->cfg.dma_enable == 0) {

        uint32_t count32b = 0, i= 0;

        __IO uint32_t *fifo;


        count32b =  (len + 3) / 4;

        fifo = pdev->regs.DFIFO[ch_ep_num];

        for (i = 0; i < count32b; i++) {

            USB_OTG_WRITE_REG32(fifo, *((__packed uint32_t *)src));

            src += 4;

        }

    }


    return  status;

}


运行过程中发现src的地址在会出现非四字节对齐的情况,并且在该情况发生后系统便会宕机重启,对于该种问题可增加一个临时变量解决,具体解决方法如下所示。


USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE   *pdev, 

                                      uint8_t         *src, 

                                      uint8_t          ch_ep_num, 

                                      uint16_t         len)

{

    USB_OTG_STS status = USB_OTG_OK;

    if (pdev->cfg.dma_enable == 0) {

        uint32_t count32b = 0, i = 0;

        __IO uint32_t *fifo;

        uint32_t data = 0;


        count32b = (len + 3) / 4;

        fifo = pdev->regs.DFIFO[ch_ep_num];

        for (i = 0; i < count32b; i++) {

            if (((uint32_t) src) % 4 == 0) {

                USB_OTG_WRITE_REG32(fifo, *((__packed uint32_t *)src));

            } else {

                lib_memcpy(&data, src, 4);

                USB_OTG_WRITE_REG32(fifo, data);

            }

            src += 4;

        }

    }


    return  status;

}


2.2 中断优先级设置不当导致进入”Hard Fault”中断 

STM32采用的中断控制器是NVIC,全称为Nested Vector Interrupt Controller,人们一般称之为“嵌套中断向量控制器”,是用来管理中断嵌套的,核心任务就是在于其优先级的管理。NVIC给每个中断赋予先占优先级和次占优先级。具体关系描述如下: 

1) 拥有较高先占优先级的中断可以打断先占优先级较低的中断; 

2) 若两个先占优先级的中断同时挂起,则优先执行次占优先级较高的中断; 

3) 若两个挂起的中断两个优先级都一致,则优先执行位于中断向量表中位置较高的中断; 

4) 无论任何时刻,次占优先级都不会造成中断嵌套,即中断嵌套完全是由先占优先级决定的。 

在调试USB转串口的过程中,由于系统tick中断的先占优先级被设置为0(最高优先级)导致系统不停的重启。需要注意的是,在对外设初始化的过程中,需要对外设中断优先级进行手动设置,否则该外设中断的先占优先级将默认为0。对于STM32的外设中断优先级可以使用ST公司提供的库函数进行设置,函数原型如下所示。


Void  HAL_NVIC_SetPriority(IRQn_Type    IRQn,

                           uint32_t     PreemptPriority, 

                           uint32_t     SubPriority)


函数HAL_NVIC_SetPriority原型分析: 

参数IRQn是中断号; 

参数PreemptPriority是先占优先级; 

参数SubPriority是子优先级。 

通常情况下,将外设中断的先占优先级设置为0xF(最低优先级)。


关键字:STM32  USB转串口驱动  移植  SylixOS

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic468708.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 UART串口驱动程序
下一篇:STM32F407串口配置

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32 USART1对PWM的影响,串口影响PWM

注意,USART1和TIM1是复用的,如果用TIM1产生PWM(PA9 / PA10),则USART1不应该用该管脚,可以用PB6/PB7。
发表于 2019-08-22

stm32103R8C6 捕捉2路pwm 串口打印捕捉数据

第一路使用定时器2的通道1,先捕捉一个上升沿,清楚所有数据开始捕捉下降沿,捕捉到下降沿后再捕捉一个上升沿。 第二路使用定时器4的通道4,使用其他通道的时候要注意,定时器的中断时CC4,设置上升沿和下降沿的时候也要改为通道4。//定时器2通道1输入捕获配置TIM_ICInitTypeDef TIM2_ICInitStructure;void TIM2_Cap_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
发表于 2019-08-22
stm32103R8C6 捕捉2路pwm 串口打印捕捉数据

STM32——使用PWM+DMA实现脉冲发送精确控制

之前用stm32写过脉冲发送的代码,用来控制步进电机,但是缺点明显,之前是用定时器中断做的,所以一但控制的电机多起来,MCU资源占用就很大,这在大多数情况下是不可接受的,更不用说多轴联动了。最近做的步进电机CAN总线控制系统,就想顺便重新写驱动。希望做到占用很少的MCU资源,实现脉冲发送的精确控制。既然是用来控制步进电机,那么脉冲的数量和频率一定要可控,要不然怎么实现电机的加减速曲线。于是就想到了DMA。DMA (直接存储器访问)DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料
发表于 2019-08-22
STM32——使用PWM+DMA实现脉冲发送精确控制

stm32入门——PWM输出控制直流电机变速

,ARR大于CCRx时输出为“有效”电平。注意,我这里用的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。以下面的代码来讲解TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz我们使用定时器1的通道1来输出一路PWM波,想详细了解定时器参数的设置的朋友可以参考(stm32入门——定时器中断),我这里简单介绍一下,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。void
发表于 2019-08-22
stm32入门——PWM输出控制直流电机变速

STM32学习笔记(PWM输出)

本人采用Cube 进行的STM32库函数编程,PWM波的输出配置以及代码如下所示:(经过实际实验证明非常好用)以下为定时器PWM输出函数,注意:使用时一定要把原来输出函数注释掉。注释代码如下:// sConfigOC.OCMode = TIM_OCMODE_PWM1;// sConfigOC.Pulse = 0;// sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;// sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;// if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC
发表于 2019-08-22

STM32死机 调试时进入HardFault_Handler定位错误的方法

STM32在运行不正常的时候我们一般会进行调试看看问题出在了哪里。但是当STM32卡死后进行调试的时候会发现进入到了一个HardFault_Handler函数里,这是一个硬件错误处理函数。通过它和MDK配合可以定位程序最后卡死的原因。STM32卡死的原因有以下几种:数组越界操作;内存溢出,访问越界;堆栈过小;中断处理错误;电压供电异常。现在实验一个堆栈过小的错误,让MDK来检测这个问题然后定位错误。这个程序基于UCOSII 系统 #define TFTLCD_STK_PRIO  8 //任务的优先级#define TFTLCD_STK_SIZE  2 //任务的堆栈大小OS_ST
发表于 2019-08-22
STM32死机 调试时进入HardFault_Handler定位错误的方法

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved