当前位置: 首页 > news >正文

FX10/20 (CYUSB401X)开发笔记5 固件架构

之前调试fx10的时候遇到了很多困难,走了不少弯路。看了很多的文档和代码,后来才发现要想调试好这颗芯片。最重要的还是要了解好固件架构,知道什么该做,什么不该做,什么是我们应该关注的,什么是我们不应该关注的,下面就分享一下我的心得。

首先我们来看一下这颗芯片固件的分层结构:

芯片分为以下几个层次,这几个层次不是在物理意义上真正存在的。只是为了好开:而人为的分了这么几个层次。I

USB Device contriller: 芯片物理层,就是由晶体管构成的那个。

USB Controller Abstraction Later (CAL)USB 控制抽象层代码,把硬件的各个寄存器控制实现为一个个的API, 这样上层再次实现某个功能的时候,不需要直接操作寄存器了

USDB layer:实现具体的协议的部分,比如实现USB的复杂的协议,实现 和FPGA通信接口的LINK协议具体部分,具体功能比如有:

自动应答标准请求 (GET_DESCRIPTOR等)

管理端点 & 数据通道

速率协商、描述符切换

APP Layer:用户层,用户具体实现自己的业务

为什么要分这么多层级呢?原因是对于芯片开发来说这么多层级好处多多。

  • 抽象化和模块化:每个层次可以处理特定的功能或任务,使得各层之间的耦合度降低。这样可以更容易地替换某一层的实现而不影响其他层。例如,USB协议层可以在不改变硬件抽象层的情况下进行更新或优化。

  • 易于移植:通过将硬件抽象成独立的层(如USB控制器抽象层CAL),可以更容易地在不同的硬件平台之间迁移代码。不同的硬件平台可能只需要重新实现硬件相关层,而无需修改整个应用程序或协议层的代码。

  • 代码重用:在不同的项目中可以重用已经开发好的层次,减少重复劳动。例如,USB设备控制器的驱动可以在多个应用中共用,只需要为特定硬件编写底层的硬件接口部分。

  • 层级隔离:每一层只负责自己的职责,避免不同模块之间的复杂交互,降低错误发生的概率。这种隔离使得每一层可以单独进行测试和调试。

  • 开发效率:分层结构帮助开发人员聚焦在特定的功能上,而不需要同时处理硬件、协议等多个复杂问题。

我只是用起来这个芯片,因此只需要关心用户层和 USBD 层级就好了,再往下的不去探究了

这一点非常重要,因为我们在看固件代码的时候,他会套好几层,一层一层的,如果我们一直往下看,那么这个代码看好几年也看不完。因此我们只需要关心到USBd这一层,再往下是驱动工程师做的事情,里面涉及到的都是一些芯片寄存器操作了,我们没有寄存器手册,看了也没用。

在用户代码这一层,我们需要关心的功能由以下几个类型的函数构成:(后续的文章也是根据这几部分挨个记录)

1 freeRtos 任务:这个芯片是有实时操作系统的。这个操作系统实现了很多个任务:

A :打印日志task

打印日志的函数会把数据加入到一个缓存中,然后这个任务会把缓存中的信息定期执行

B:Cy_USBD_TaskHandler任务

实现USB协议的task "UsbdTask"

C:Cy_HBDma_Mgr_TaskHandler任务

实现数据DMA的task,HbDmaTask

这个任务内部由高带宽DMA消息队列处理任务

所有高带宽DMA套接字接收的中断通过此消息队列传递给HBDma管理器任务。

D:Cy_UVC_AppDeviceTaskHandler任务是

实现 用户功能的task,这里是UVC功能

UvcDeviceTask ,在Cy_USB_AppInit函数中创建

这个任务内部有 USB设备堆栈消息队列:从USBHS接收的中断以及USBSS IP块通过该消息队列传递给USB堆栈任务

E:reertos 内核创建的task:

以下任务我们无需关注。只是了解有这个就可以了。

• Idle task created by FreeRTOS Kernel:

Idle task 是 FreeRTOS 的“兜底任务”,当系统没有其它任务运行时,它接管 CPU,做资源回收、低功耗、Idle Hook 调用等后台工作。

• Timer task created by FreeRTOS Kernel: 定制器任务,总管一切软件定制器

主要作用:

统一调度软件定时器

所有通过 xTimerCreate()、xTimerStart() 等 API 创建的 FreeRTOS 软件定时器,不会自己生成单独的任务,而是将超时事件放入一个定时器命令队列中,由 Timer task 轮询处理并调用用户注册的回调函数。

     集中管理,减少任务开销

软件定时器共享一个 Timer task,避免每个定时功能都开独立任务,降低了任务切换开销。

代码中有以下两个timer:

usbdTimer:

  • 在 USB 链路从低功耗恢复到活跃状态后,延迟 10ms(USB 2.x)或 50ms(USB 3.x)才允许再次进入低功耗模式,确保数据传输完成。

usb3ConnTimer:

  • 检测到 USB 2.x 总线复位后,延迟 400ms 再尝试 USB 3.x 重连,保证主机控制器的增强模式就绪。

这些定时器的回调最终都是在 Timer task 里被调用的。

执行流程举例说明这个:

  1. 硬件 SysTick 每 1ms 触发一次 tick 中断
  2. FreeRTOS tick handler 检测到 500ms 到期 → 向 Timer task 队列发送“执行 LedToggleCallback”命令
  3. Timer task 从队列取出命令 → 调用 LedToggleCallback() → 切换 LED 状态

2 回调函数

所有回调函数都是中断回调实现的,这里中断实现的回调函数分为两类:

A 中断回调函数当场执行,也就是说直接在中断中解决了,主要是一些LVDS DMA的中断需要及时处理,这类对实时性要求非常高的。

B中断后只是把需要执行的消息通过freertos发送给任务,让任务后续再慢慢执行,一些比较耗时的任务在这里执行。

通过这些任务和回调函数,可以实现我们需要的各种功能,我们要设置的一些功能包括:(后续的文章也是根据这几部分挨个记录)

1 HBDMA:

实现Fpga的数据到了fx10以后。这些数据传输到USB的端点上的路径应该如何配置,内部有一些socket,thread,描述符等等:

  1. Thread
    • LVDS 物理链路和 DMA Adapter 之间的专用硬件连接
    • 可以理解为一个数据通道(比如一根数据线)
  1. DMA Adapter
    • 把 Thread 上的数据搬到 DMA Buffer(或反向)
    • 类似数据格式转换和搬运的“接驳器”
  1. Socket
    • 外设和 DMA Buffer 之间的接口
    • 每个外设通过 socket 与 DMA 交互
  1. Descriptor
    • 描述当前和下一个 DMA Buffer 区域的结构体
    • 用于 DMA 控制器知道下一步要搬运哪一段数据(支持链式传输)

Thread → Adapter → Socket 关系:LVDS/LVCMOS数据通道有2个DMA Adapter,对应4个thread,每个thread 有8个socket,

socket是抽象好的最小的数据传输线路,代码中给每个socket编了号,不同的socket就是对应不同的硬件数据传输路线,比如地址为17的socket是第三个thread,对应DMA adapter1

每个 Socket 有唯一的 全局编号,这样一来,代码里给 Socket 编号,其实就是在选用哪一条硬件传输通道。

这些大概看看,先记录下手册提到的,有个映像。

2 USB 协议

实现USB的各个协议功能,比如说set up的解析自动回复。Cc检测等

3 LVDS/LVCMOS接口

Fpga的数据如何输入到fx10,LVds,LVCMOS接口如何训练等,数据发送的时序是什么等等

 

4 APP 应用业务

自己的一些业务,比如说uVC协议中的一些规定可以在行任务中做实现,又或者说自己的一些特定功能。

这些功能大部分demo都改好了,我们只需要修改一部分。重点其实还是APP自己的业务那块。

后面的笔记记录挨个记录下提到的这些功能如何实现的,尤其是如何对接FPGA的。

http://www.dtcms.com/a/336697.html

相关文章:

  • 【个人项目】跑者天地—测试报告
  • 深入解析二维数组传参的本质
  • 运动场和光流-动手学计算机视觉17
  • 正则表达式实用面试题与代码解析专栏
  • 【Nginx】限流设置
  • 二三层交换转发业务~基础汇总
  • Mysql笔记-错误条件\处理程序
  • SSM从入门到实践:1.1 Spring框架概述与IoC容器入门
  • 堆(Heap):高效的优先级队列实现
  • duiLib 解决点击标题栏中按钮无响应问题
  • ROS2基础
  • C语言零基础第19讲:自定义类型—联合体和枚举
  • 解锁Java开发神器:XXL-Job从入门到精通
  • BT_LE_ADV_CONN_ONE_TIME 参数详解
  • Spring 创建 Bean 的 8 种主要方式
  • [创业之路-556]:创新的本质是赚不确定性带来的潜在价值,把不确定性逐步转化确定性,周而复始。
  • 产品设计.Ai产品经理
  • 48.Seata认识、部署TC服务、微服务集成
  • 网络中的一些基本概念
  • Conda 环境 在AI 私有化部署 有怎么用?
  • 微信小程序 小白gps工具v0.01 使用说明
  • react echarts图表监听窗口变化window.addEventListener(‘resize’)与ResizeObserver()
  • python -基础(5)组合数据类型
  • 每日两道算法题:DAY3
  • java常见的数据加密
  • 当 AI 开始 “理解” 情感:情感计算技术正在改写人机交互规则
  • Linux 服务:iSCSI 存储服务配置全流程指南
  • 廖雪峰-Java教程-Part02
  • C#高级语法_委托
  • 力扣第463场周赛