前言
2023年Zephyr开发者大会(ZDS)于6月27日至30日在捷克布拉格隆重举行。与以往两次不同,本次ZDS由Zephyr项目规划和管理,并作为首届嵌入式开源峰会(EOSS)的一部分进行。在这个令人期待已久的盛会中,全球Zephyr开发者们共同探讨了Zephyr实时操作系统(RTOS)的最新技术与发展趋势。作为一款开源、灵活和可扩展的嵌入式实时操作系统,Zephyr项目在2014年由英特尔发起,2016年作为Linux基金会项目正式面向公众启动,得到了全球范围内的广泛关注和采用。
ZDS 2023共70余个技术报告,涵盖了使用指导与展示、新功能与技术、架构修改与操作系统、多核异构与虚拟化、模拟器、测试、工业流程与代码管理、安全性、应用案例、工具与调试等丰富多样的内容。湖大嵌入式实验室的小伙伴们将对本次大会的所有技术报告进行逐一收集、整理与分享,尽最大努力为Zephyr开发者提供ZDS 2023技术报告的开发经验、实践成果以及解决方案的参考。
“在Zephyr中实现自定义USB设备控制器驱动程序”
作者简介

Mohammed Billoo
MAB Labs, LLC
CEO
Mohammed Billoo是MAB Labs, LLC的创始人。他在架构、设计、实施和测试嵌入式软件(从基于MCU的应用程序到基于Linux的嵌入式系统)方面拥有超过14年的经验。他还是库珀科学与艺术促进联盟(The Cooper Union for the Advancement of Science and Art)电气工程兼职教授,教授数字逻辑设计、计算机体系结构和高级计算机体系结构课程。
文章简介
首先对项目进行概述包括系统架构和问题简述,其次是对项目前置USB知识(背景)的简短讲解,随后是针对项目采取的一些初步措施包括面临问题的尝试以及故障排除工具的简要介绍和使用时所遭遇的问题,最后是对于项目的最终解决措施。
System Architecture系统架构
Enclustra XU5 开发板
UART 控制台
Ethernet 以太网
架构图:

目前FreeRTOS的实现
Blinky:一个简单的LED,证明USB CDC是否启动
USB CDC:USB Communications Device Class是一种USB设备类别
Network:网络接口
TinyUSB
一个跨平台且开源的USB设备/主机协议堆栈,具有独立的USB Host/Device Stack,主要面向嵌入式设备。
特点:
内存安全(memory safe):无动态分配
线程安全(thread safe):中延迟处理断
TinyUSB在Zephyr中的实现
架构图:

OS Abstraction Layer(OSAL)操作系统抽象层,针对RTOS实时操作系统的实现:设置宏来启用对应的OS抽象

针对特定微控制器(MCU)的具体实现:

要解决的问题(实现的目标):
利用Zephyr的USB栈实现USB设备和CDC驱动程序(假设 Xilinx USB 设备控制器)
1 设备插入主机总线
2 主机检测到新增设备
3 主机询问设备:
3.1 确定类型及其提供的服务
3.2 加载适当的驱动程序
USB的传输模式
Control控制
Interrupt中断
Bulk批量
Isochronous同步
USB事务组成

Token packet令牌数据包
IN:主机希望从设备读取数据
OUT:主机希望向设备写入数据
Setup:主机希望开始控制传输
Data Packet数据包
可选,所携带的实际信息或有效负载
Handshake Packet握手包
ACK确认:数据包已被接收
NAK否确认:设备忙碌/无数据
STALL停滞:设备需要主机干预
Zero Length Packets(ZLP)零长度数据包
USB通信中的一种特殊类型的数据包,其有效负载长度为零。这些数据包用于执行一些特殊的控制和同步任务而不用于传输实际的数据。

场景一:
1 主机发送OUT令牌将数据发送到EP1的OUT缓冲区
2 主机发送IN令牌来检查是否已收到(使用ZLP):如果设备成功接收到数据包,将以ACK方式回应(设备在EP1 OUT中处理数据);否则,以NAK方式回应
场景二:
1 主机等待EP1 OUT传输的响应
2 主机发送IN令牌,从EP1 IN缓冲区读取数据
3 主机发送OUT令牌(使用ZLP):确定设备是否准备好进行下一次事务,如果设备准备好,以ACK方式回应;否则,设备以NAK方式回应,主机稍后再次尝试
初步尝试/探索
1 使用Windows作为CDC主机驱动程序
2 插入设备: 将设备插入主机是开始测试的第一步
3 使用TeraTerm检查字符是否被回显(echo)
4 使用printks测试功能
结果:

初步结果:存在数据传输问题
1 确定数据没有正确传输到FPGA
2 始终发送NAK
3 主机会尝试再次发送,但最终放弃
4 底层的Xilinx寄存器配置不正确(使用ARM来查询Xilinx寄存器)
最终实现
1 决定将TinyUSB移植到Zephyr:完全绕过Zephyr USB设备协议栈
2 为Zephyr创建了一个新的操作系统端口:为Zephyr创建了OSAL
3 创建了Zephyr线程来管理来自FPGA的事务、管理CDC回显功能
实验结果:成功
