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

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

  1. /*******************************************************************************
  2. * Function Name : UserToPMABufferCopy
  3. * Description : 从用于内存区拷贝数据到PMA(数据包内存区)
  4. * Input : pbUsrBuf:指向用户的内存区
  5. * wPMABufAddr:要拷贝到PMA的wPMABufAddr地址处
  6. * wNBytes: 要拷贝的数据长度(单位:字)
  7. * Output : None.
  8. * Return : None .
  9. *******************************************************************************/
  10. void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  11. {
  12. uint32_t n = (wNBytes + 1) >> 1; //n = (wNBytes + 1) / 2,表示多少字
  13. uint32_t i, temp1, temp2;
  14. uint16_t *pdwVal;
  15. pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr); //pdwVal存放要将数据存放的地址
  16. for (i = n; i != 0; i--) //开始考被数据
  17. {
  18. temp1 = (uint16_t) * pbUsrBuf;
  19. pbUsrBuf++;
  20. temp2 = temp1 | (uint16_t) * pbUsrBuf << 8; //整合2个16bit数据
  21. *pdwVal++ = temp2; //把整合的数据拷贝PMA内
  22. pdwVal++; //目的指针指向下一个地址
  23. pbUsrBuf++; //源指针指向下一地址
  24. }
  25. }
  26. /*******************************************************************************
  27. * Function Name : PMAToUserBufferCopy
  28. * Description : Copy a buffer from user memory area to packet memory area (PMA)
  29. * Input : pbUsrBuf指向用户的内存区
  30. * wPMABufAddr PAM的地址
  31. * wNBytes要拷贝的字节数
  32. * Output : None.
  33. * Return : None.
  34. *******************************************************************************/
  35. void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  36. {
  37. uint32_t n = (wNBytes + 1) >> 1; //n = (wNBytes + 1) / 2,表示多少字
  38. uint32_t i;
  39. uint32_t *pdwVal;
  40. pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr); //从PAM区中去读1字数据
  41. for (i = n; i != 0; i--)
  42. {
  43. *(uint16_t*)pbUsrBuf++ = *pdwVal++; //拷贝用户的内存区中
  44. pbUsrBuf++;
  45. }
  46. }

  

接下去是usb_sil.c文件,这个文件主要是简单接口层的初始化,和端点的读写操作函数。总共有3个函数:USB_SIL_Init();USB_SIL_Write();USB_SIL_Read()。
USB_SIL_Init()函数初始化USB设备的IP和端点。该函数在usb_prop.c的CustomHID_init()中被调用,总之,就是初始化了
  1. /*******************************************************************************
  2. * Function Name : USB_SIL_Init
  3. * Description : 初始化USB设备IP和端点
  4. * Input : None.
  5. * Output : None.
  6. * Return : Status.
  7. *******************************************************************************/
  8. uint32_t USB_SIL_Init(void)
  9. {
  10. #ifndef STM32F10X_CL
  11.  
  12. /* USB interrupts initialization */
  13. /* clear pending interrupts */
  14. _SetISTR(0); //禁止所有的中断
  15. wInterrupt_Mask = IMR_MSK;
  16. /* set interrupts mask */
  17. _SetCNTR(wInterrupt_Mask); //使能一些中断
  18.  
  19. #else
  20.  
  21. /* Perform OTG Device initialization procedure (including EP0 init) */
  22. OTG_DEV_Init(); //执行初始化程序OTG设备(包括EP0初始化)
  23.  
  24. #endif /* STM32F10X_CL */
  25.  
  26. return 0;
  27. }

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

  1. /*******************************************************************************
  2. * Function Name : USB_SIL_Write
  3. * Description : 往选中的端点中写入数据
  4. * Input : bEpAddr:非控制端点的地址
  5. * pBufferPointer:指向要写入端点的缓冲数据
  6. * wBufferSize:要写入的数据长度(单位:字节)
  7. * Output : None.
  8. * Return : Status.
  9. *******************************************************************************/
  10. uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize)
  11. {
  12. #ifndef STM32F10X_CL
  13.  
  14. UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize);//把用户数据拷贝到PMA中
  15.  
  16. SetEPTxCount((bEpAddr & 0x7F), wBufferSize); //更新数据长度的控制寄存器
  17.  
  18. #else
  19.  
  20. PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize); //使用使用PCD接口层函数来写入选择的端点
  21.  
  22. #endif /* STM32F10X_CL */
  23.  
  24. return 0;
  25. }
  26.  
  27. /*******************************************************************************
  28. * Function Name : USB_SIL_Read
  29. * Description : 从选中的端点中读出数据
  30. * Input : bEpAddr:非控制端点的地址
  31. * pBufferPointer:指向要保存的数据区地址
  32. * Output : None.
  33. * Return : 返回读出来的数据长度(单位:字节)
  34. *******************************************************************************/
  35. uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
  36. {
  37. uint32_t DataLength = 0;
  38.  
  39. #ifndef STM32F10X_CL
  40.  
  41. DataLength = GetEPRxCount(bEpAddr & 0x7F); //从选中的端点中获取接收的数据长度
  42.  
  43. PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);//从PMA拷贝数据到用户区
  44.  
  45. #else
  46.  
  47. USB_OTG_EP *ep;
  48.  
  49. ep = PCD_GetOutEP(bEpAddr); //获取选中端点的结构体指针
  50.  
  51. DataLength = ep->xfer_len; //获取接收到的数据长度
  52.  
  53. PCD_EP_Read (bEpAddr, pBufferPointer, DataLength); //使用PCD接口层函数读取选中的端口
  54.  
  55. #endif /* STM32F10X_CL */
  56.  
  57. return DataLength; //返回接收到的数据长度
  58. }

  

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

  1. STM32入门系列-库目录及文件介绍

    已经介绍了过了CMSIS标准,ST公司按照这个标准设计了一套基于STM32F10x的固件库,我们可以直接在ST公司的官网进行下载,现在给大家STM32最新固件库v3.5,在网盘上给大家提供了下载包,链 ...

  2. PE文件学习系列笔记四-C++实现PE文件的分析

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com 综述: 首 ...

  3. 教程-Delphi资源文件(全面分析于使用)

    Delphi资源文件(全面分析之位图.光标.图标.AVI.JPEG.Wave)   几乎每个Windows应用程序都使用图标.图片.光标等资源.资源是程序的一部分,但是它是不可执行代码.下面我们就详细 ...

  4. 【JVM】Java中的JavaCore/HeapDump文件及其分析方法

    产生时间 Java程序运行时,有时会产生JavaCore及HeapDump文件,它一般发生于Java程序遇到致命问题的情况下. 有时致命问题发生后,Java应用不会死掉,还能继续运行: 但有时致命问题 ...

  5. 对stm32f373XX的startup.s的文件的分析

    ;******************** (C) COPYRIGHT 2012 STMicroelectronics ********************;* File Name : start ...

  6. Android.mk文件简单分析

    Android.mk文件简单分析 一个Android.mk文件用来向编译系统描写叙述须要编译的源码.详细来说:该文件是GNUMakefile的一小部分.会被编译系统解析一次或多次. 能够在每个Andr ...

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

    /etc/rc.d/init.d/functions文件详细分析 functions这个脚本是给/etc/init.d里边的文件使用的(可理解为全局文件). 提供了一些基础的功能,看看里边究竟有些什么 ...

  8. opencart 单入口文件简单分析

    opencart 单入口文件简单分析   opencart是基于mvcl的商城系统,据说是一个外国有人单独开发.比较牛叉.但是又不大符合国人习惯,目前国内opencart社区也是不少. 简单分析了下单 ...

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

    如今我们分析框架中的docs文件夹.看看这个文档文件夹中,究竟放了那些对我们实用的东西. docs文件夹分析 UPGRADE_TO_2_2_3.md 就是讲升级的变化.详细说明:quick-cocos ...

随机推荐

  1. maven编译报错 -source 1.7 中不支持 lambda 表达式

    Maven项目编译失败: [ERROR] COMPILATION ERROR : [INFO] ---------------------------------------------------- ...

  2. Hyper-V如何应用新的网卡

    最近新装了块网卡,可是在Hyper-V的虚拟机设置里怎么也找不到如何应用这个新网卡.   把我郁闷坏了. 偶尔点点,才发现原来不是在虚拟机的设置里面,而是在上面的一级设置. 新建完后就可以在虚拟机的网 ...

  3. shell中使用if判断时用到的一些参数

    shell 编程中使用到得if语句内判断参数 –b 当file存在并且是块文件时返回真 -c 当file存在并且是字符文件时返回真 -d 当pathname存在并且是一个目录时返回真 -e 当path ...

  4. 如何用7-zip创建自解压文件,7Z软件如何使用

    1 要创建自解压文件,一般都是双击直接解压到C盘的Program Files文件夹里面,或许还需要在桌面创建一个快捷方式之类的.但是一般的绿色软件除了复制到Program Files还需要运行一下绿化 ...

  5. Eclipse开发Android的配置(包括ADT安装,SDK配置)

      1. 下载Android SDK http://code.google.com/android/download.html下载后直接解压就可以使用了. 为了在DOS控制台中直接使用SDK的工具,可 ...

  6. Mysql(一)安装

    一.下载 下载地址:http://www.mysql.com/downloads/ 二.安装 解压 双击安装 下一步,选择NO, 下一步,选择, 按需求选择,这时选择developer default ...

  7. python中的sort、sorted、reverse、reversed详解

    python语言中的列表排序方法有三个:reverse反转/倒序排序.sort正序排序.sorted可以获取排序后的列表.在更高级列表排序中,后两中方法还可以加入条件参数进行排序. reverse() ...

  8. Oracle 删除表中记录 如何释放表及表空间大小

    1.查看一个表所占的空间大小:SELECT bytes/1024/1024 ||'MB' TABLE_SIZE ,u.* FROM USER_SEGMENTS U WHERE U.SEGMENT_NA ...

  9. Hive之简单查询不启用MapReduce

    假设你想查询某个表的某一列.Hive默认是会启用MapReduce Job来完毕这个任务,例如以下: 01 hive> SELECT id, money FROM m limit 10; 02 ...

  10. jQuery ajax - ajax() 方法详解

    一些代码通过jQuery来做ajax异步提交. //验证昵称是否存在 function checkNickNameIsExist(){ var nickName = jQuery("#nic ...