STM32 usb_mem.c和usb_sil.c文件的分析

转:http://blog.csdn.net/u011318735/article/details/17424515

这两个c文件都还算是很简单的,先讲讲usb_mem.c这个文件。从文件名就能知道跟内存有关,这个文件主要定义了两个函数,一个读双缓冲区PMA的数据PMAToUserBufferCopy(),另一个是写数据到双缓冲区PMA,UserToPMABufferCopy。如果,当你的usb设备接收到了数据,当然数据存放在PMA中了,我们要读出数据就要用到PMAToUserBufferCopy()函数了,如果我们想要发送数据给usb主机,就要将你要发送的数据拷贝到PMA缓冲区中了,这样才能发送出去,原理跟串口类似。

/*******************************************************************************
* Function Name  : UserToPMABufferCopy
* Description    : 从用于内存区拷贝数据到PMA(数据包内存区)
* Input          : pbUsrBuf:指向用户的内存区
*                  wPMABufAddr:要拷贝到PMA的wPMABufAddr地址处
*                  wNBytes: 要拷贝的数据长度(单位:字)
* Output         : None.
* Return         : None	.
*******************************************************************************/
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;   				//n = (wNBytes + 1) / 2,表示多少字
  uint32_t i, temp1, temp2;
  uint16_t *pdwVal;
  pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);	//pdwVal存放要将数据存放的地址
  for (i = n; i != 0; i--)							//开始考被数据
  {
    temp1 = (uint16_t) * pbUsrBuf;
    pbUsrBuf++;
    temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;		//整合2个16bit数据
    *pdwVal++ = temp2;								//把整合的数据拷贝PMA内
    pdwVal++;										//目的指针指向下一个地址
    pbUsrBuf++;										//源指针指向下一地址
  }
}
/*******************************************************************************
* Function Name  : PMAToUserBufferCopy
* Description    : Copy a buffer from user memory area to packet memory area (PMA)
* Input          : pbUsrBuf指向用户的内存区
*                  wPMABufAddr PAM的地址
*                  wNBytes要拷贝的字节数
* Output         : None.
* Return         : None.
*******************************************************************************/
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;			//n = (wNBytes + 1) / 2,表示多少字
  uint32_t i;
  uint32_t *pdwVal;
  pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);	//从PAM区中去读1字数据
  for (i = n; i != 0; i--)
  {
    *(uint16_t*)pbUsrBuf++ = *pdwVal++;			//拷贝用户的内存区中
    pbUsrBuf++;
  }
}

  

接下去是usb_sil.c文件,这个文件主要是简单接口层的初始化,和端点的读写操作函数。总共有3个函数:USB_SIL_Init();USB_SIL_Write();USB_SIL_Read()。

USB_SIL_Init()函数初始化USB设备的IP和端点。该函数在usb_prop.c的CustomHID_init()中被调用,总之,就是初始化了

/*******************************************************************************
* Function Name  : USB_SIL_Init
* Description    : 初始化USB设备IP和端点
* Input          : None.
* Output         : None.
* Return         : Status.
*******************************************************************************/
uint32_t USB_SIL_Init(void)
{
#ifndef STM32F10X_CL

  /* USB interrupts initialization */
  /* clear pending interrupts */
  _SetISTR(0);					  //禁止所有的中断
  wInterrupt_Mask = IMR_MSK;
  /* set interrupts mask */
  _SetCNTR(wInterrupt_Mask);	  //使能一些中断

#else

  /* Perform OTG Device initialization procedure (including EP0 init) */
  OTG_DEV_Init();				  //执行初始化程序OTG设备(包括EP0初始化)

#endif /* STM32F10X_CL */

  return 0;
}

  还有的就是两个端点读写数据函数了,端点写函数USB_SIL_Write()共有三个参数:uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize,所以写调用写函数时,要指明端点号、要写数据地址,和要写的数据长度。读函数USB_SIL_Read()只有两个参数:端点号、数要保存的据区地址。

/*******************************************************************************
* Function Name  : USB_SIL_Write
* Description    : 往选中的端点中写入数据
* Input          : bEpAddr:非控制端点的地址
*                  pBufferPointer:指向要写入端点的缓冲数据
*                  wBufferSize:要写入的数据长度(单位:字节)
* Output         : None.
* Return         : Status.
*******************************************************************************/
uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize)
{
#ifndef STM32F10X_CL

  UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize);//把用户数据拷贝到PMA中

  SetEPTxCount((bEpAddr & 0x7F), wBufferSize); 				//更新数据长度的控制寄存器

#else

   PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize); 		//使用使用PCD接口层函数来写入选择的端点

#endif /* STM32F10X_CL */

  return 0;
}

/*******************************************************************************
* Function Name  : USB_SIL_Read
* Description    : 从选中的端点中读出数据
* Input          : bEpAddr:非控制端点的地址
*                  pBufferPointer:指向要保存的数据区地址
* Output         : None.
* Return         : 返回读出来的数据长度(单位:字节)
*******************************************************************************/
uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
{
  uint32_t DataLength = 0;

#ifndef STM32F10X_CL

  DataLength = GetEPRxCount(bEpAddr & 0x7F);	 		//从选中的端点中获取接收的数据长度

  PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);//从PMA拷贝数据到用户区

#else

  USB_OTG_EP *ep;

  ep = PCD_GetOutEP(bEpAddr);					//获取选中端点的结构体指针

  DataLength = ep->xfer_len;					//获取接收到的数据长度

  PCD_EP_Read (bEpAddr, pBufferPointer, DataLength);		//使用PCD接口层函数读取选中的端口

#endif /* STM32F10X_CL */

  return DataLength;						//返回接收到的数据长度
}

  

时间: 2024-08-24 21:44:31

STM32 usb_mem.c和usb_sil.c文件的分析的相关文章

HTTP的上传文件实例分析

HTTP的上传文件实例分析 由于论坛不支持Word写文章发帖. 首先就是附件发送怎么搞,这个必须解决.论坛是php的.我用Chrome类浏览器跟踪请求,但是上传的文件流怎么发过去没找到,估计流可能多或者什么的不好显示,只知道发送了文件名字.需要实际了解下post文件,不能只会后台或界面不了解前台数据处理和协议怎么传送数据. 图中:有些相关文章 HTTP请求中的form data和request payload的区别 AJAX POST请求中参数以form data和request payload

quick-cocos2d-x教程3:程序框架内文件夹分析之docs文件夹

如今我们分析框架中的docs文件夹.看看这个文档文件夹中,究竟放了那些对我们实用的东西. docs文件夹分析 UPGRADE_TO_2_2_3.md 就是讲升级的变化.详细说明:quick-cocos2d-x 2.2.3 须要的注意的事项和代码改动范例. 项目执行时,假设出现 [DEPRECATED] 相关信息,应该将这些已经作废的 API 替换为新 API. 已作废API 请參考 framework/deprecated.lua 文件. HOW_TO_USE_PROJET_MAC_AND_WI

uboot移植之九鼎提供的uboot的文件夹分析

文件夹分析 (1)api:提供了uboot在执行时用到的一些函数,这些函数都是硬件无关的,所以和我们的移植没多大关系 (2)api_examples:api的示例代码 (3)board:开发板相关的文件夹,这个文件夹里面存放的一个文件夹对应一款开发板或者是一个芯片厂商.我们在config配置的时候就是根据这个文件夹下面的子文件夹来选择开发板信息.需要注意一点,由于历史原因,一开始开发板种类比较少,所以board存放的子文件夹就是对应的开发板,但是随着电子信息的发展,开发板越来越多,所以就在ubo

Android.mk文件简单分析

Android.mk文件简单分析 一个Android.mk文件用来向编译系统描述需要编译的源代码.具体来说:该文件是GNUMakefile的一小部分,会被编译系统解析一次或多次.可以在每一个Android.mk中定义一个或多个模块,也可以在几个模块中使用同一个源代码文件. 每个模块属下列类型之一: 1)APK程序,一般的Android程序,编译打包生成apk文件 2)JAVA库,java类库,编译打包生成jar文件 3)  C\C++应用程序,可执行的C\C++应用程序 4)C\C++静态库,编

mysql source命令导入sql文件效率分析

Query OK, 24918 rows affected (0.90 sec)Records: 24918  Duplicates: 0  Warnings: 0Query OK, 24923 rows affected (2.26 sec)Records: 24923  Duplicates: 0  Warnings: 0Query OK, 24924 rows affected (2.74 sec)Records: 24924  Duplicates: 0  Warnings: 0Quer

android 文件系统目录分析(手机系统目录分析)

# pwd && ls -a -l / drwxrwxrwt root     root              2009-06-10 09:53 sqlite_stmt_journals drwxrwx--- system   cache             2008-09-06 22:51 cache d---rwxrwx system   system            1970-01-01 08:00 sdcard lrwxrwxrwx root     root    

/etc/rc.d/init.d/functions文件详细分析

/etc/rc.d/init.d/functions文件详细分析 functions这个脚本是给/etc/init.d里边的文件使用的(可理解为全局文件). 提供了一些基础的功能,看看里边究竟有些什么.首先会设置umask,path,还有语言环境,然后会设置success,failure,warning,normal几种情况下的字体颜色. 下面再看看提供的重要方法:checkpid:检查是否已存在pid,如果有一个存在,返回0(通过查看/proc目录)daemon:启动某个服务./etc/ini

[delphi技术]Delphi资源文件(全面分析于使用)

Delphi资源文件(全面分析之位图.光标.图标.AVI.JPEG.Wave) 几乎每个Windows应用程序都使用图标.图片.光标等资源.资源是程序的一部分,但是它是不可执行代码.下面我们就详细介绍资 源文件在Delphi5中建立和使用方法. 1.把资源放到Exe文件的优点  由于定位资源比在磁盘中定位文件花费时间少,所以应用程序执行会更快.多种资源可以放在一个文件中,减少了图标.图片.光标 等文件数量.保存资源文件时不要和工程名相同,因为Delphi创建工程时会自动创建一个和工程名相同的资源

STM32 HAL固件库编程的文件构架

对于我这种以前只接触过51和AVR单片机编程的小菜来说,现在开始学习STM32的编程,对于函数的功能以及C语言的语法都还好理解,难的是它提供的那一套硬件抽象层(HAL)驱动是怎么和其他的东东搭配在一起组成一个又一个的工程. 首先上两张从ST官方提供的HAL固件库文档截图 从这两张图的话,能对它的构架看出个一二,下面稍稍具体一点分析 HAL固件库编程,它的文件组织大致分三个部分 - HAL驱动 - CMSIS驱动 - 用户编写程序 而假如你使用的是ST官网的开发板,那么你还有一套现成的驱动可供使用