历史上的今天

今天是:2024年09月17日(星期二)

2020年09月17日 | STM32 usb_mem.c和usb_sil.c文件的分析

发布者:mmsg3814 来源: eefocus关键字:STM32  usb_mem  usb_sil  c文件 手机看文章 扫描二维码
随时随地手机看文章

这两个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;                        //返回接收到的数据长度

}


关键字:STM32  usb_mem  usb_sil  c文件 引用地址:STM32 usb_mem.c和usb_sil.c文件的分析

上一篇:STM32 SPI接口的NSS引脚
下一篇:USB的中断说明

推荐阅读

对于没玩过DMA 的朋友,这里简单说一下DMA,用自己的语言说吧,那就是,从某个位置传输数据到某个位置,如果不用DMA,那要CPU参与操作,一个字节一个字节地搬,效率高点的,就一个字一个字地搬.但当你用了DMA 后,那就是只需要设置:A.从哪里开始搬; B,搬到哪里去;C以字节方式搬还是半字还是字;D:一共搬多少个.之后,启动DMA.CPU内部就会开始搬数据了,整个搬数据的...
iPhone SE是部分用户非常喜欢的产品,不仅价格相对会便宜一些,最主要是在配置够用,而且小巧的屏幕操控起来十分顺手,基于IOS系统体验也非常不错。就在iPhone 11发布之后,有不少用户还在关注iPhone SE2究竟何时才能到来。据外媒报道,苹果正在研发新一代iPhone SE手机,并会搭载夏普提供的5英寸LCD屏幕。除此之外,iPhone SE2将会采用A13处理器,非...
//DM430开发板控制带字库型12864液晶模块显示测试程序//显示模式为汉字模式,直接将12864插入12864接口即可//注意选择液晶的电源,位于电位器附近,可选5V或3.3V,根据液晶电压进行选择//调试环境:EW430 V5.30MSP430单片机对12864液晶模块显示的测试设计//********************************************************************/#include#define CPU_F...
二氧化碳气体或固体越来越多的应用于工业或生活中,因此配备二氧化碳报警器,二氧化碳检测仪,保障人身安全是必备的。二氧化碳密度为1.977g/mL,熔点-56.6℃(226.89千帕——5.2大气压),沸点-78.5℃(升华)。临界温度31.1℃。常温下7092.75千帕(70大气压)液化成无色液体。液体二氧化碳密度1.1克/厘米3。编辑搜图便捷式二氧化碳气体检测仪HNAG900-CO2液体二...

史海拾趣

问答坊 | AI 解惑

设计者必看,因为你可以搞明白很多

学设计第一个要认识到的就是设计不是艺术。我就是一开始没有分清这个概念,在第一次上设计课时可苦大了。设计是沟通,是传达,而艺术是表现,是创作。这并不是说设计里没有表现的成份,更不是说艺术是不在乎沟通的。但是两者放在这两项上的重视是有 ...…

查看全部问答∨

检测绝缘栅极双极型晶体管(IGBT)好坏的简易方法

1、判断极性首先将万用表拨在R×1KΩ挡,用万用表测量时,若某一极与其它两极阻值为无穷大,调换表笔后该极与其它两极的阻值仍为无穷大,则判断此极为栅极(G)。其余两极再用万用表测量,若测得阻值为无穷大,调换表笔后测量阻值较小。在测量阻值 ...…

查看全部问答∨

请教PB->Platform->Settings->Enable full Kernel Mode

如题:PB->Platform->Settings->Enable full Kernel Mode(no IMGNOTALLKMODE=1) 以前的工程一直选择这个选项,从来没想过是做什么的 前两天新做个工程,忘记加这个选项,编译后系统不报错,但是下到板子上,系统好象缺少explore.exe一样 ...…

查看全部问答∨

很奇怪的问题 wince 串口测试应用程序 writefile(...)函数没有执行完就失败了,然后程序死掉了。

串口测试的writefile(...)函数没有执行完就失败了,没有任何返回结果。writefile的下一个语句做断点,没有执行到。 if(hComm!=INVALID_HANDLE_VALUE&&dwCharToWrite!=0)         {           ...…

查看全部问答∨

关于nk.bin :error opening file -no such file or directory问题

大家好。我现在在虚拟机上建立Wince系统。建立了虚拟机以后。使用USBoot将U盘以HDD(ZIP也试过)模式格式化为引导盘,将C:\\Program Files\\Microsoft Platform Builder\\6.00\\cepb\\utilities下的CepcBoot.144文件放入WinImage软件中并选择U盘,利 ...…

查看全部问答∨

终于研发成功

终于研发成功,cpu是s3c2410,64M   SDRAM,网口为cs8900 flash(k9f1208 64m)   实现了只用nand flash 就可以启动引导vxworks. 公司送bsp及全套开发文档 ,另可配公司的开发板 有意着QQ联系641328010 请注明 arm…

查看全部问答∨

RT_THREAD中的异常与中断

  异常是导致处理器脱离正常运行转向执行特殊代码的任何事件,如果系统不及时处理,系统轻则出错,重着导致系统毁灭性的瘫痪。所以正确地处理异常避免错误的发生是提高软件的鲁棒性重要的一方面,对于嵌入式系统更加如此。 异常可以分成两类 ...…

查看全部问答∨

uboot-2009.08.tar.bz2移植到TQ2440

依据上几次搭建的环境进行uboot的移植,出现了一些错误,我特此做出一些总结,已经将编译器转换到旧一点的arm-linux-gcc-4.3.2,具体的原因是为什么,我查找了天嵌的网站说需要转换到3.4版本的编译器,因此我改用了友善之臂的uboot-2009.08.tar.bz2 ...…

查看全部问答∨

11.06【每周讨论】软文——春风化雨、润物无声

您知道“软文”的含义吗?什么,不知道。赶紧百度一下吧,别被OUT了 [ 本帖最后由 longxtianya 于 2011-11-6 20:19 编辑 ]…

查看全部问答∨

分享一些收集的msp430方面的书籍

最近接触了一下msp430的单片机从网上搜集了一些书籍希望对大家有帮助。…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved