查看: 10817|回复: 9

[原创] [经验分享]usb调用讲解

[复制链接]

该用户从未签到

715

主题

6374

帖子

0

超级版主

Rank: 8Rank: 8

积分
25233
最后登录
2025-8-20
发表于 2020-7-16 10:02:35 | 显示全部楼层 |阅读模式
本帖最后由 小恩GG 于 2020-7-16 10:05 编辑

usb调用图.jpeg
      Usb例程使用的是一种面向对象的编程方式,使得程序读起来非常晦涩,感觉程序一层一层在套娃。所以本文尝试梳理cdc 虚拟串口usb例程,从大框架下,粗略理解程序运行过程。Usb例程的main函数里,只有两个函数,一个用来初始化usb,一个用于usb任务。我们分两个部分来讲usb例程。第一部分讲它到底是如何初始化usb的,另一个讲它到底是怎么工作的。结合上面思维导图以及程序理解。
       APPinit函数里又分为三个函数,如图中所示,第一个用来初始化设备,第二个使能中断,第三个运行usb设备。
       重点就在于第一个函数到底是以怎样一个过程来初始化函数的。
        从参数上来看,第一个CONTROLLER_ID。主要有两类控制器id一个是khci,一个是ehci,前者用于usb的full speed, 后者用于high speed。 本实验的CONTROLLER_ID就是使用khci模块。第二个参数是USB_DeviceCallback,这个是定义的设备回调函数的地址,第三个则是虚拟串口设备的句柄。
       设备回调函数USB_DeviceCallback,到底是怎样的一个函数呢?它是为了处理usb设备事件而定义的,而它处理的事件,有两种,第一种总线复位事件,第二种设置usb的配置。    我们知道,当usb设备插入比如说PC中,在通信前,首先就是主机发起复位信号,复位总线。所以说mcu一旦接收到复位信号后,就需要DeviceCallback处理复位事件。而复位事件中,最重要的就是初始化usb端点0。因为端点0就是用来与主机进行各种传输配置和控制信息的端口。复位以后,主机就会开始枚举操作,发送的获取描述符,获取配置等命令都是发给这个端口,所以必须立刻初始化这个端口0。而这个端口的回调函数是USB_DeviceControlCallback,这个函数是用来组织,配置数据。当mcu接收到获取描述符的命令后,这个端点的回调函数则会调用USB_DeviceCh9GetDescriptor,来组织mcu的描述符,组织完的数据再传回去,给mcu从端点0发送。
       第二个设置usb的配置则是初始化其他端点,该例程初始化了3个端点。端点0是用来传输控制信息的,当通信建立好后,则该端点就不用了,而使用其他端点传输报文和接受报文。除了端点0是双向的以外,每个端口都只能设置一个传输方向,要么是输入的,要么是输出的。
       进入USB_DeviceInit函数,它主要功能就是将之前回调函数赋予传入的句柄。然后将端点的回调函数,回调参数,以及忙碌状态清除,再将khci的各种控制函数赋予该句柄。
       端点的回调函数是用来处理对应端点发生的事件,端点0的回调函数要处理,主机发送过来的获取描述符等等命令,其他端点回调函数,则要处理要么发送数据的事情,要么接受数据,解析数据的任务。Khci的控制函数则包含了各种发送,接受,初始化寄存器等最基本操作。无论mcu是发送数据还是接收数据,最终都需要调用这块函数。
       将这些功能全部集中到一个句柄上来,从而通过操作这个句柄,就可以操作所有函数。
       该函数最后使用了deviceHandle->controllerInterface->deviceInit. 其实就是调用了khci的USB_DeviceKhciInit。跳出USB_DeviceInit以后,最后调用USB_DeviceRun,而运行usb其实就是调用了USB_DeviceKhciControl,也是之前赋予句柄的khci函数之一。



        从运行角度来说,首先PC发出复位信号,MCU接受到复位信号产生一次usb复位中断。进入中断函数中,通过寄存器ISTAT值判断为usb复位中断,调用USB_DeviceNotificationTrigger,而它调用USB_DeviceNotification来提示这是一个复位事件。
USB_DeviceNotification拥有两种功能,一种是处理总线复位事件,那么需要调用DeviceCallback来处理,另一种则是初始化完以后,调用端点回调函数来处理对应端点请求。
        USB_DeviceNotification发现是一个复位事件,就调用了USB_DeviceCallback,USB_DeviceCallback发现是复位事件,则初始化端点0。这样与PC通信的端点0就准备就绪。
        PC开始枚举。PC发来获取描述符请求,mcu发生令牌包中断。USB_DeviceNotificationTrigger调用USB_DeviceNotification,然后调用端点0的回调函数,端点0发现是获取描述符请求,最后调用USB_DeviceCh9GetDescriptor,将mcu描述符组织完成,存放在buffer里,上层函数调用USB_DeviceKhciSend将buffer从端点0发送出去。
        当PC发送设置配置请求时候,mcu发生令牌包中断。调用端点0的回调函数USB_DeviceCh9SetConfiguration,端点0接收PC的配置,存在buffer里,然后端点0调用USB_DeviceSetConfigure,而它会调用USB_DeviceCallback,USB_DeviceCallback发现是设置配置事件,将1,2,3端口配置完成。
其他请求也是相似过程。
        往后收到PC数据就会调用端点2的批量输入回调函数,输出数据给PC则调用端点3的批量输出回调函数。



回复

使用道具 举报

  • TA的每日心情
    慵懒
    2021-12-23 09:57
  • 签到天数: 1587 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    5

    主题

    3048

    帖子

    23

    金牌会员

    Rank: 6Rank: 6

    积分
    8416
    最后登录
    2025-4-23
    发表于 2020-7-16 11:23:15 | 显示全部楼层
    脑图很绕,已经晕菜
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    715

    主题

    6374

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25233
    最后登录
    2025-8-20
     楼主| 发表于 2020-7-16 13:46:27 | 显示全部楼层
    Splore.Liu 发表于 2020-7-16 11:23
    脑图很绕,已经晕菜

    哈哈,这个不是一两下就能整明白的,毕竟套娃不是白套的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    1

    主题

    12

    帖子

    0

    注册会员

    Rank: 2

    积分
    115
    最后登录
    2021-9-17
    发表于 2021-8-31 21:30:57 | 显示全部楼层
    有个疑问哈:最后总结,收到PC数据,应该调用批量输出回调函数吧?---对应到图片里面,xxx_BulkOut的函数应该是调用接口里面的xxx_Recv函数吧?
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    715

    主题

    6374

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25233
    最后登录
    2025-8-20
     楼主| 发表于 2021-9-1 09:43:44 | 显示全部楼层
    ji_dan 发表于 2021-8-31 21:30
    有个疑问哈:最后总结,收到PC数据,应该调用批量输出回调函数吧?---对应到图片里面,xxx_BulkOut的函数应 ...

    哈哈,你说的对,写反了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    1

    主题

    12

    帖子

    0

    注册会员

    Rank: 2

    积分
    115
    最后登录
    2021-9-17
    发表于 2021-9-6 22:38:40 | 显示全部楼层
    小恩GG 发表于 2021-9-1 09:43
    哈哈,你说的对,写反了

    另外有一个问题请教下版主哈:就是LPC54616有没有对应的PC的USB驱动库呢?做它的usb界面开发,找不到对应的dll驱动库呢
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    4 天前
  • 签到天数: 1868 天

    连续签到: 2 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112694
    最后登录
    2025-8-17
    发表于 2021-9-7 09:39:14 | 显示全部楼层
    Splore.Liu 发表于 2020-7-16 11:23
    脑图很绕,已经晕菜

    这水印太丧心病狂了 TS1 - 副本 (3).jpg TS1 - 副本 (2).jpg TS1 - 副本 (4).jpg TS1 - 副本 (5).jpg TS1 - 副本 (6).jpg TS1 - 副本 (7).jpg TS1 - 副本 (10).jpg TS1 - 副本 (9).jpg TS1 - 副本 (8).jpg TS1.jpg
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    715

    主题

    6374

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25233
    最后登录
    2025-8-20
     楼主| 发表于 2021-9-7 10:08:26 | 显示全部楼层
    ji_dan 发表于 2021-9-6 22:38
    另外有一个问题请教下版主哈:就是LPC54616有没有对应的PC的USB驱动库呢?做它的usb界面开发,找不到对应 ...

    你到lpc版块那里直接提这个问题吧
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    1

    主题

    12

    帖子

    0

    注册会员

    Rank: 2

    积分
    115
    最后登录
    2021-9-17
    发表于 2021-9-7 16:47:57 | 显示全部楼层
    小恩GG 发表于 2021-9-7 10:08
    你到lpc版块那里直接提这个问题吧

    好的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    1

    主题

    3

    帖子

    0

    注册会员

    Rank: 2

    积分
    112
    最后登录
    2024-12-17
    发表于 2022-4-21 11:49:27 | 显示全部楼层
    能否做一期USB程序分析的视频,太难了晕菜
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-21 11:37 , Processed in 0.104733 second(s), 29 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表