转载:/thread-51423-1-1.html
作者:追风
一、USB的“JoyStickMouse”例程结构分析
1、例程的结构
(1)底层结构
包括5个文件:usb_core.c(USB总线数据处理的核心文件),usb_init.cusb_int.c(用于端点数据输入输入中断处理),usb_mem.c(用于缓冲区操作),usb_regs.c(用于寄存器操作)。它们都包含了头文件“usb_lib.h”。在这个头文件中,又有以下定义:
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_def.h"
#include "usb_core.h"
#include "usb_init.h"
#include "usb_mem.h"
#include "usb_int.h"
usb_lib.h中又包含了七个头文件,其中usb_type.h中主要是用typedef为stm32支持的数据类型取一些新的名称。usb_def.h中主要是定义一些相关的数据类型。
还有一个未包含在usb_lib.h中的头文件,usb_conf.h用于USB设备的配置
(2)上层结构
上层结构总共5个文件:hw_config.c(用于USB硬件配置)、usb_pwr.c(用于USB连接、断开操作)、usb_istr.c(直接处理USB中断)、usb_prop.c(用于上层协议处理,比如HID协议,大容量存储设备协议)、usb_desc.c(具体设备的相关描述符定义和处理)。
可见,ST的USB操作库结构十分清晰明了,我先不准备直接阅读源代码。而是先利用MDK的软件模拟器仿真执行,先了解一下设备初始化的流程。
2、设备初始化所做的工作
(1)Set_System(void)
字符串函数应用详解
这个是main函数中首先调用的函数,它位于hw_config.c文件中。它的主要功能是初始化时钟系统、使能相关的外围设备电源
配置了JoyStickMouse所用到的5个按键,并且配置了两个EXTI中断,一个是用于把USB从挂起模式唤醒,还有一个用途未知。
(2)USB_Interrupts_Config();
这个是main函数中调用的第二个函数,它也位于hw_config.c文件中。主要功能是配置USB所用到的中断
跟踪到代码中,主要设配置了USB低优先级中断和唤醒中断,又有一个EXTI中断功能未知。
(3)Set_USBClock()
这个是main函数中调用的第三个函数,它也位于hw_config.c文件中。它的功能是配置和使能USB时钟
(4)USB_Init(void)
这个是main函数中调用的第四个函数,它也位于usb_init.c文件中。它初始化了三个全局指针,指向DEVICE_INFO、USER_STANDARD_REQUESTS和DEVICE_PROP结构体。
后面两个是函数指针结构体,里面都是USB请求实现、功能实现的函数指针。
void USB_Init(void)
{
pInformation = &Device_Info;
pInformation->ControlState = 2;
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;
/* Initialize devices one by one */
pProperty->Init();
}
这三个结构体都是与具体设备枚举和功能实现相关的,定义在usb_prop.c和usb_desc.c文件中。
DEVICE_PROP Device_Property =
{
Joystick_init,
Joystick_Reset,
Joystick_Status_In,
Joystick_Status_Out,
Joystick_Data_Setup,
Joystick_NoData_Setup,
Joystick_Get_Interface_Setting,
Joystick_GetDeviceDescriptor,
Joystick_GetConfigDescriptor,
Joystick_GetStringDescriptor,
0,
0x40 /*MAX PACKET SIZE*/
};
USER_STANDARD_REQUESTS User_Standard_Requests =
{
Joystick_GetConfiguration,
Joystick_SetConfiguration,
Joystick_GetInterface,
Joystick_SetInterface,
Joystick_GetStatus,
Joystick_ClearFeature,
Joystick_SetEndPointFeature,
Joystick_SetDeviceFeature,
Joystick_SetDeviceAddress
};
Usb_init()函数调用pProperty->Init()(实质上就是Joystick_init)完成设备的初始化。
上层程序调用下次函数是常规性的操作。而下层函数(usb_init相对于usb_prop是输入底层操作文件)调用上层文件函数我们称之为回调。
回调函数的意义在于同一种操作模式、提供不同的回调函数则可以实现不同的功能。Windows中处理消息,好像也用到了这种模式。
回调函数的实现方法是函数指针数组。这是指针的高级应用。
这是函数的代码:
void Joystick_init(void)
{/* Update the serial number string descriptor with the data from the unique
ID*/
Get_SerialNum();
//获取设备序列号,转变为unicode字符串
pInformation->Current_Configuration = 0;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。