原创 USB的“JoyStickMouse”源代码分析01

2010-4-22 21:30 4457 13 14 分类: MCU/ 嵌入式

USB的“JoyStickMouse”源代码分析01<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


 


一、c源文件和头文件


1c文件的组织


我们一般用C语言编程的时候都比较讲究模块化、层次化,以及数据和操作分开的原则


模块化最明显的表现是我们把常用的、某一个具体功能实现封装在一个函数中,我们所要操作的数据以参数的方式提供给函数,函数通过代码处理过后,再把结果回馈个调用者。


层次化表现在比较复杂的功能实现都要分几层来实现,有时候也是为了提高可移植性。比如文件系统的代码实现大致要分这么几层:


磁盘操作层实现磁盘扇区的读取、写入、控制;


文件分配管理函数和目录项操作函数;


文件的打开、读取、写入函数,目录的建立、删除函数等;


用户应用操作函数,如文件的查找、具体数据的写入等等。


 


一个具体USB功能的实现也能分成几层,比如我们的Stm32 JoyStickMouse,我们也可以这样分层:


硬件操作层:寄存器操作和内存操作。


协议通用层:设备枚举的控制传输实现,对所有类协议都一样。


具体协议层:比如HID协议的描述符,类特定请求实现。


 


这样一划分,一个具体的功能实现就需要比较多的C源文件。


2c文件和h文件


一个c文件一般是几个函数组成,这几个函数可能一部分存在依存关系,而有一些函数要对外引出,而同时它还可能要引用外部函数。解决这个相互关联的是“包含头文件”。


一个c文件很多时候都存在一个与它同名的“h文件”,对c文件的意义主要有以下几个:


1提供常量定义,#define


2)提供一些类型定义,为了实现c文件数据类型的编译器无关性,一般都要将该编译器提供的数据类型重新定义,tpyedef来实现


3结构体、联合体、枚举类型的定义


4带参数的宏定义


5外部函数声明


6外部变量声明


7本身实现函数的声明:起始这个声明对c文件本身意义不大,主要是其它c文件要使用本c文件实现的函数时,包含同名“h文件”,意义更清楚一些。


 


3h文件的相互包含


头文件对c源文件的意义比较清晰。但实际有时候“头文件”也会存在依存关系,相互包含。


比如有个头文件使用数据类型“u8”,那么它必须先包含定义这个数据类型的头文件。


有时候为了让c文件包含的头文件数目不至于过多,一般采用这样的方法:用一个h文件包含所有相关的头文件,然后每个c文件包含这个头文件就行了。这个以usb的库函数组织最为典型。


编程时,用到库函数的源文件只要包含“stm<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />32f10x_lib.h”就行了USB操作库函数也采用了类似的方式。


 


二、USB函数库分析


1usb_regs.h


1)寄存器定义


#define CNTR    ((volatile unsigned *)(RegBase + 0x40))


我觉得这是c语言指针的魅力所在,通过这样的定义可以直接操作寄存器。*CNTR = Value。特别是含有多个寄存器的设备,可以将首地址结构体指针化,通过指针间接访问结构体,实际上就访问了各个寄存器。


2)标志位、屏蔽位定义


#define ISTR_CTR    (0x8000) /* Correct TRansfer (clear-only bit) */


#define CLR_CTR    (~ISTR_CTR)   /* clear Correct TRansfer bit */


有了这个定义,我们可以以比较明了的方式对相关位进行操作。


 


3)寄存器操作宏定义


#define _SetCNTR(wRegValue)  (*CNTR   = (u16)wRegValue)


这样定义以后,用户对寄存器的操作调用宏就行了,意义清晰。


 


#define _SetEPTxStatus(bEpNum,wState) {\


    register u16 _wRegVal;       \


    _wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\


    /* toggle first bit ? */     \


    if((EPTX_DTOG1 & wState)!= 0)      \


      _wRegVal ^= EPTX_DTOG1;        \


    /* toggle second bit ?  */         \


    if((EPTX_DTOG2 & wState)!= 0)      \


      _wRegVal ^= EPTX_DTOG2;        \


    _SetENDPOINT(bEpNum, _wRegVal);    \


  } /* _SetEPTxStatus */


宏可以代表一个变量,也可以是一个表达式,也可以是一个代码块。


 


4)声明外部变量


extern volatile u16 wIstr;  /* ISTR register last read value */


 


5)对外声明同名c文件实现的函数


u16 GetCNTR(void);


它在这里使用了“u16”类型定义,所以必须先定义。


 


2usb_regs.c


主要是调用宏,实现寄存器操作,但我看上层函数也很少调用这些函数,直接就使用宏了。


 


 


 

文章评论1条评论)

登录后参与讨论

tengjingshu_112148725 2010-4-23 09:19

沙发
相关推荐阅读
nthq2004 2010-05-08 20:04
USB自定义设备驱动02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  本来还想编写应用程序测试一下自定...
nthq2004 2010-05-07 21:35
USB自定义设备驱动01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、USB设备驱动入门1、学习目...
nthq2004 2010-05-04 21:01
智林开发板上实现自定义的USB HID设备
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、自定义HID设备的相关概念1...
nthq2004 2010-05-01 21:58
U盘例程在智林开发板上的移植
 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 一、移植前的准备工作1、有哪些操...
nthq2004 2010-04-30 19:19
U盘实现流程跟踪分析02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   二、追踪USB大容量设备的实现...
nthq2004 2010-04-27 21:51
U盘实现流程跟踪分析01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   一、追踪USB大容量设备的实现...
我要评论
1
13
关闭 站长推荐上一条 /2 下一条