使用STM32的USB模块中后对USB缓冲区的认识

最近在使用STM32的USB模块开发个项目,还以为挺简单,结果搞了快两天才把USB的包缓冲区的访问搞定,在此做个小总结吧。

  STM32的USB模块包缓冲区有512B,但是在STM32的参考手册中的存储器映像中却表明0x40006000-0x400063ff,整整多了512B,怎么会这样呢,同时在尝试着编程时也遇到了一个问题:

在usb_core.c文件的Setup0_Process(void)这个函数中,有这么一段:

uint16_t offset = 1; 
if (pInformation->ControlState != PAUSE)
  {
    pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
    pInformation->USBbRequest = *pBuf.b++; /* bRequest */
    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwLength = *pBuf.w; /* wLength */
  }  

这其中又不太明白为什么需要pBuf.w += offset;而且后面的解释也不太懂 /* word not accessed because of 32 bits addressing */
,我于是在这段之前加入调试以显示收到什么数
        #ifdef DEBUG
        UARTSend_String("***  端点0收到SETUP数据  ***\r\n");
        for(offset=0;offset<16;offset++)
        {
                UARTSend_Hex(*pBuf.b++);
        }
        #endif
结果串口调试显示如下:
***  USB总线复位  ***
***  USB总线CTR置位  ***
***  进入端点0  ***
***  端点0收到SETUP包  ***
***  端点0收到SETUP数据  ***
0x80 0x06 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x40 0x00 0x00 0x00

本来应该显示0x80 0x06 0x00 0x01 0x00 0x000x40 0x00才对,不太明白怎么0x80 0x06和0x00 0x01 后面多了两个 0x00 ,难道USB模块还会将收到的数据跳着放吗?

 后来反复看参考手册,问了些人,才知道原来STM32的USB缓冲区是一个双端口的RAM,CPU一端需要使用32位方式访问,但USB模块一端使用16位方式访问。也就是说每个USB模块中的地址*2才能对应到控制器中的实际地址,这样每四个字节地址空间后两个字节地址空间是空的。所以上面串口调试显示的数据每正确两个字节就会多出两个字节的0x00。

这里也对STM32的USB库函数中对缓冲区的操作函数做个说明:

在usb_men.c文件有这么一个函数

void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)

  uint32_t n = (wNBytes + 1) >> 1;/* /2*/
  uint32_t i;
  uint32_t *pdwVal;
  pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
  for (i = n; i != 0; i--)
  {
    *(uint16_t*)pbUsrBuf++ = *pdwVal++;
    pbUsrBuf++;
  }

它的作用是将缓冲区中的数据拷贝到你所定义的uint8_t Receive_Buffer[];数组中。其它地方都好理解,这里说说

  pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
  for (i = n; i != 0; i--)
  {
    *(uint16_t*)pbUsrBuf++ = *pdwVal++;
    pbUsrBuf++;
  }
首先是pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);这里wPMABufAddr * 2之所以要*2就是前面所述的USB模块中的地址*2才能对应到控制器中的实际地址,在取得对应端点的缓冲区首地址后,将其(uint32_t*)强制指向uint32_t型,这样每次*pdwVal++,pdwVal的地址都增加4个字节,并且每次都会有四个字节的数据读出。

在for循环中,*(uint16_t*)pbUsrBuf++ = *pdwVal++;这句重点说说,++与指针*同优先级,结合顺序为至右向左结合,因此相当于*((uint16_t*)pbUsrBuf++),先*(uint16_t*)pbUsrBuf赋值只取*pdwVal++的32位数据的前16位,然后再将pbUsrBuf加上1个字节。到这里,前面定义的uint8_tReceive_Buffer[];数组中就有两个数组变量被赋值了,但这时地址还指增加一个字节,因此还需要pbUsrBuf++;让其指向Receive_Buffer[];的下下个数组变量。一次循环,知道读出所有数据。

转自http://blog.csdn.net/ringstart/article/details/6822377


转载于:https://www.cnblogs.com/findstr/archive/2012/03/14/2803693.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404353.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

md /mdd /ml /mt/mtd

From: http://www.cnblogs.com/eddyshn/archive/2009/11/23/1608823.html VC编译选项 多线程(/MT) 多线程调试(/MTd) 多线程 DLL (/MD) 多线程调试 DLL (/MDd) C 运行时库 库文件 Single thread(static link) ML libc.lib Debug single …

[react] 在react中怎样改变组件状态,以及状态改变的过程是什么?

[react] 在react中怎样改变组件状态&#xff0c;以及状态改变的过程是什么&#xff1f; 使用this.setState改变组件的状态改变的过程中&#xff0c;React Fiber Reconciler遍历了整个Fiber Tree&#xff0c;得到了最新的DOM diff结果&#xff0c;并把这个结果应用到真实的DOM上…

web前端实战系列[1]——三列布局

1.代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta http-equiv"Cont…

[react] react是什么?它的主要特点是什么?

[react] react是什么&#xff1f;它的主要特点是什么&#xff1f; React是用于构建用户界面的库。 特点&#xff1a; 组件化,增强复用性数据到视图的单向绑定,更安全数据的单项传递流高性能个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff…

Unix整理笔记-vi简介-里程碑M8

1 vi是Unix/Linx工程师必备的 2 ~表示是未使用的行&#xff0c;如果某行不是以~开头&#xff0c;并且仍然是空白的&#xff0c;那么一定存在空格&#xff0c;制表符&#xff0c;换行符等 3 vi区别大小写 4 在vi中搜索文件&#xff0c;命令模式下&#xff1a;/yourword 5 如果进…

android Sqlite小记

1、android.database.sqlite.SQLiteException: near "": syntax error (code 1): 语法错误&#xff0c;如果你的报了这个错误,就好好看下你的sql语句吧 比如,下边这句&#xff1a;&#xff0c;如果你不注意&#xff0c;可能会觉得没错 1 ss "ss:42--56,10--11…

[react] 你用过react版本有哪些?

[react] 你用过react版本有哪些&#xff1f; react17.0.2 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

Ext JS 4.1 RC1发布

下载地址&#xff1a;http://cdn.sencha.com/ext-4.1-rc1.zip Bugs Fixed for RC1Button EXTJSIV-5129 - Button does not adhere to width setting in IE9Charts EXTJSIV-4416 - Chart label misaligned on numeric x axisEXTJSIV-5459 - Setting markers to be hidden in ren…

修改linux默认启动级别(包括Ubuntu)

From: http://xinchibaobei.blog.163.com/blog/static/126392509200910101356215/ 说明&#xff1a;本文后半篇引用crazy365的文章&#xff0c;可能是大部分linux版本的设置方式&#xff0c;但在Ubuntu下不适用。 所以搜寻了Ubuntu下的修改方式&#xff0c;稍作整理放在前面…

iSensor APP 之 摄像头调试 OV3640 OV2640 MT9d112

iSensor app 非常适合调试各种摄像头&#xff0c;已测试通过的sensor有&#xff1a; l OV7670、OV7725、OV9650、OV9655、OV9653、OV5642、OV5640 l MT9T001、MT9M001、MT9P031 今天又测试了上述几款新的型号&#xff0c;之前并未用过。 OV3640 OV2640 MT9d112 先看OV2640&am…

[react-router] React-Router怎么获取URL的参数?

[react-router] React-Router怎么获取URL的参数&#xff1f; 通过params 类组件&#xff1a;在保证props能获取到路由信息的前提下&#xff08;如果不是直接嵌套在<Route/>下&#xff0c;需要使用withRouter的HOC&#xff09;&#xff0c;通过this.props.match.params获…

LINUX下查看CPU使用率的命令

From: http://www.cnblogs.com/Wen-Man/archive/2011/04/04/2373771.html 1.top 使用权限&#xff1a;所有使用者 使用方式&#xff1a;top [-] [d delay] [q] [c] [S] [s] [i] [n] [b] 说明&#xff1a;即时显示process的动态 d :改变显示的更新速度&#xff0c;或是在交…

ZFS 常见问题解答 及 ZFS Boot 问题探讨

首先我们来看一下上月Snow Leopard Server活动上Apple 对SUN ZFS发表的评论&#xff1a; 综观计算机业界的整个历史&#xff0c;这个行业往往推崇“奇思妙想”&#xff0c;原因在于它似乎喜欢给最新技术赋予近乎神奇的功效。ZFS&#xff08;Zettabyte File System&#xff09;常…

说一下output子句

Output子句日常灰常有用&#xff0c;而且用的地方也挺多&#xff0c;但是确好多时候被我们忽视&#xff0c;今天我就也简单扫盲一下这个语句的用法。 Output子句 返回受 INSERT、UPDATE、DELETE 或 MERGE 语句影响的各行中的信息&#xff0c;或返回基于受这些语句影响的各行的表…

[react] 在使用react过程中你都踩过哪些坑?你是怎么填坑的?

[react] 在使用react过程中你都踩过哪些坑&#xff1f;你是怎么填坑的&#xff1f; 组件不像Vue一样有(beforeRouteLeave, beforeRouteEnter)路由守卫Hooks中的闭包渲染问题 import { useState } from react;const Demo () > {const [count, setCount] useState(0);const…

查询优化器内核剖析第四篇:从一个实例看执行计划

查询优化器内核剖析第四篇&#xff1a;从一个实例看执行计划系列文章索引&#xff1a; 查询优化器内核剖析第一篇 查询优化器内核剖析第二篇&#xff1a;产生候选执行计划&执行计划成本估算 查询优化器内核剖析第三篇&#xff1a;查询的执行与计划的缓存 &…

linux 查看端口使用情况

From: http://blog.csdn.net/zwhfyy/article/details/3971523 -bash-3.00# netstat -tln netstat -tln 命令是用来查看linux的端口使用情况     /etc/init.d/vsftp start 是用来启动ftp端口~&#xff01;     看文件/etc/services     netstat     查看已经连接的…

POJ3764 The xor-longest Path(Trie树)

题目给一棵有边权的树&#xff0c;问树上任意两点路径上的边异或值最多是多少。 记录每个点u到根路径的异或值xor[u]&#xff0c;那么任意两点u、v路径的异或值就是xor[u]^xor[v]。 于是这个问题就变成了从n个数中任取两个数异或&#xff0c;求最大异或值&#xff0c;这是个经典…

[react] 说说react的生命周期有哪些?

[react] 说说react的生命周期有哪些&#xff1f; 装载阶段 组件第一次被渲染时的阶段&#xff0c;这一阶段相关的生命周期函数有&#xff1a; constructor componentWillMount render componentDidMount 更新阶段 如果组件中的 state 或者 props 发生了改变&#xff0c;React…