打印
[STM32F4]

[求助] stm32 USB CDC中诡异的堆栈设置问题

[复制链接]
1866|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pkuzhx|  楼主 | 2017-10-27 17:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 pkuzhx 于 2017-10-30 16:37 编辑

芯片:STM32F401CB,有64kB ram
软件:cubemx生成的IAR工程
功能:mcu控制单片机采集i2c传感器数据,通过usb的virtual com port回传到PC(后期会在mcu本地处理)

问题1:接usb到pc后,可以在设备管理器中看到com口,但是串口助手无法打开。
尝试1:尝试修改iar堆栈大小
结果1:基本解决,可以传数据到PC,串口可以打开

为什么说基本解决呢,因为里边产生了更诡异的问题。
同样硬件3个样品,在A配置下,只有12能打开串口,3不能,在B配置下,3可以打开,12不能。

3个样品是同样的PCBA,芯片都是同一批次在mouser购买的,不存在假货的问题。买来放了大概2年。
由于芯片有64kB RAM,这么小的堆栈,绝对不存在撑爆ram的问题。
问题2:为什么3个芯片需要不同的配置?
问题3:为什么堆栈设置大了反而打开不串口了?设置小了打不开倒可以理解,大了打不开完全没道理啊?

之后又有了一个新的问题,别人拿我的程序做了改动,逻辑更复杂了,然后发现串口无法打开。
我这改堆栈已经轻车熟路了,心想可能随随便便就搞定了,结果又出了幺蛾子。
他的程序逻辑也就复杂了一点,结果堆栈都要设置到0x5000才可以打开串口。

除此以外,还发现了更奇怪的问题。我查看map文件中的stack usage,stack用的其实很少:

就是stack比较要设置的跟heap一样大才行,基本stack只用了那么点,也不能设置小了,哪怕是设置成0x4F00都不会,都会导致串口无法打开。
问题4:为什么stack使用很小的情况下,却必须设置很大?要跟heap一样大才可以工作?


问题解决,安装最新的virtual com port驱动后一切恢复正常!
沙发
天灵灵地灵灵| | 2017-10-27 21:47 | 只看该作者
用串口才能显示串口吧,用USB应该是USB啊。

使用特权

评论回复
板凳
antusheng| | 2017-10-27 22:25 | 只看该作者
三个芯片下载了同样的固件,结果效果不同?是不是其中一个是次品,或者有坏块。

使用特权

评论回复
地板
airwill| | 2017-10-28 08:57 | 只看该作者
确实挺怪的问题, 不要停在表象, 用调试器跟踪一下, 说不定让你找到一个库里的 BUG 呢

使用特权

评论回复
5
pkuzhx|  楼主 | 2017-10-28 09:38 | 只看该作者
天灵灵地灵灵 发表于 2017-10-27 21:47
用串口才能显示串口吧,用USB应该是USB啊。

接的是USB端口,但是性质是virtual com port。
谢谢你,但不是这个原因。参数设置合适是可以用串口助手打开的。

使用特权

评论回复
6
pkuzhx|  楼主 | 2017-10-28 09:40 | 只看该作者
antusheng 发表于 2017-10-27 22:25
三个芯片下载了同样的固件,结果效果不同?是不是其中一个是次品,或者有坏块。 ...

嗯,这只是其中一个问题。按照你这么说也能解释的通,我本来也是这么想的。但是ST的片子放两年就不行了,我又有点不敢相信。
还有问题3,堆栈必须设置到一个合适的值才可以,设置大了反而不行,而且我保证还有大了的ram剩余。这个我百思不得其解。

使用特权

评论回复
7
pkuzhx|  楼主 | 2017-10-28 09:44 | 只看该作者
airwill 发表于 2017-10-28 08:57
确实挺怪的问题, 不要停在表象, 用调试器跟踪一下, 说不定让你找到一个库里的 BUG 呢 ...

主要是对usb底层也不熟悉,本来用cube就是想只关注算法,不关注底层硬件的。
我debug了一下,usb主结构体中有一个指针变量在debug过程中始终是null,一直没有给分配空间,按理说是不能发送数据的。但在脱离编译器后,又可以发送数据。所以debug过程中usb的相关变量是不正常的,我也不能在debug模式下传送数据到pc。
不知道这是iar的bug,还是我的山寨烧录器不给力。

使用特权

评论回复
8
airwill| | 2017-10-28 16:11 | 只看该作者
在 DEBUG 模式下不能发数据, 应该是因为 DEBUG 模式打乱了 USB 的数据传递的时间关系.

使用特权

评论回复
9
icecut| | 2017-10-30 10:08 | 只看该作者
因为动态申请内存.所以建议先usb初始化,再干其他事情.
可以考虑看我open.21ic.com的usb视频课程.因为我也买过一些开发demo板,没出过此问题.
另外我是stm32f405,不同芯片usb库会有大不同.但是代码思路一致

使用特权

评论回复
10
pkuzhx|  楼主 | 2017-10-30 10:47 | 只看该作者
icecut 发表于 2017-10-30 10:08
因为动态申请内存.所以建议先usb初始化,再干其他事情.
可以考虑看我open.21ic.com的usb视频课程.因为我也买 ...

多谢i神。我main部分代码如下:
int main(void)
{

  /* USER CODE BEGIN 1 */
  char test[] = "test\n";
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
    CDC_Transmit_FS((uint8_t*)test, 5);
    HAL_Delay(500);
  }
  /* USER CODE END 3 */

}

HAL初始化,时钟初始化,GPIO初始化,这三个应该是必须要在USB初始化之前的吧?好像除此以外我也没在USB初始化之前干一些不必要的事情了。
我很久以前用USB的时候也没出过这些诡异的问题,但是USB使用也确实只是浮于表面,没有理解深层次的东西,这次碰到问题就抓瞎了

使用特权

评论回复
11
icecut| | 2017-10-30 13:04 | 只看该作者
你确定39行发送的时候,usb串口初始化好了么?
我估计就是这问题了.

使用特权

评论回复
12
pkuzhx|  楼主 | 2017-10-30 14:31 | 只看该作者
icecut 发表于 2017-10-30 13:04
你确定39行发送的时候,usb串口初始化好了么?
我估计就是这问题了.

应该是好了的,因为堆栈设置到“合适”值的时候,是可以正确发送数据的。
我刚才在USB初始化后加了1000ms的延时,发现问题还是存在:堆栈必须设置到某一个值附近,太大了都不行。而且堆和栈设置必须相等,否则也不行。
我怀疑是不是有一个什么非常隐蔽的参数被不小心改动了。2年前我用这套代码几乎没出过问题的,头大……

使用特权

评论回复
13
pkuzhx|  楼主 | 2017-10-30 14:33 | 只看该作者
icecut 发表于 2017-10-30 13:04
你确定39行发送的时候,usb串口初始化好了么?
我估计就是这问题了.

又把延时加大了些,加到3000,还是老样子
int main(void)
{

  /* USER CODE BEGIN 1 */
  char test[] = "test\n";
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();

  /* USER CODE BEGIN 2 */
  HAL_Delay(3000);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
    CDC_Transmit_FS((uint8_t*)test, 5);
    HAL_Delay(500);
  }
  /* USER CODE END 3 */

}

使用特权

评论回复
14
pkuzhx|  楼主 | 2017-10-30 15:04 | 只看该作者
icecut 发表于 2017-10-30 13:04
你确定39行发送的时候,usb串口初始化好了么?
我估计就是这问题了.

刚才又发现,同样的代码,在win7下可以打开串口并传输数据,在win10下就打不开串口……

使用特权

评论回复
15
pkuzhx|  楼主 | 2017-10-30 15:16 | 只看该作者
刚才又试了几个不同的程序,在thinkpad win7 32位环境下,正常设置堆栈,工作正常;在台式机win10 64位环境下,堆栈必须设置一样大,而且太大太小不不能工作。
搞不懂是Windows版本问题?还是USB接口问题?

使用特权

评论回复
16
icecut| | 2017-10-30 15:40 | 只看该作者
pkuzhx 发表于 2017-10-30 15:16
刚才又试了几个不同的程序,在thinkpad win7 32位环境下,正常设置堆栈,工作正常;在台式机win10 64位环境 ...

bushund抓,肯定是不同请求序列,你程序执行不一样的顺序弄挂了.    我遇到过虚拟机xp有时候不行的.

使用特权

评论回复
17
pkuzhx|  楼主 | 2017-10-30 16:26 | 只看该作者
icecut 发表于 2017-10-30 15:40
bushund抓,肯定是不同请求序列,你程序执行不一样的顺序弄挂了.    我遇到过虚拟机xp有时候不行的. ...

更新了官网最新的驱动以后,一切正常了……

使用特权

评论回复
18
pkuzhx|  楼主 | 2017-10-30 16:27 | 只看该作者
icecut 发表于 2017-10-30 15:40
bushund抓,肯定是不同请求序列,你程序执行不一样的顺序弄挂了.    我遇到过虚拟机xp有时候不行的. ...

购买了你的《小 i 教你 usb,从入门到实践》,回头学习一下

使用特权

评论回复
19
icecut| | 2017-10-30 17:50 | 只看该作者
pkuzhx 发表于 2017-10-30 16:27
购买了你的《小 i 教你 usb,从入门到实践》,回头学习一下

书到用时方恨少.
我的视频适合提前学.别等遇到问题在学.那时候,可能很难帮到你.而提前学,会帮你绕过一些坑

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:原来可以设置签名档啊!

45

主题

730

帖子

6

粉丝