硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5052|回复: 7
收起左侧

[有问必答] 用了硬汉的线程安全的printf函数,进入硬件中断?

[复制链接]

1

主题

5

回帖

8

积分

新手上路

积分
8
发表于 2017-2-9 14:43:35 | 显示全部楼层 |阅读模式
正常情况下,调试信息输出不多时,并没有问题。
我在CAN接收中断里,收到一个数据包,向外打印一些信息。如果CAN短时间接收大量数据包时,便会打印非常多的调试信息。这时候单片机进入硬件中断。
代码如下:
  1. /*
  2. *********************************************************************************************************
  3. * Function Name : ECHO_SAFE
  4. * Description    : 线程安全的打印信息
  5. * Input    : None
  6. * Output    : None
  7. * Return    : None
  8. *********************************************************************************************************
  9. */
  10. void ECHO_SAFE(char *format, ...)
  11. {
  12.     CPU_CHAR buf_str[256];
  13.     va_list v_args;
  14.     OS_ERR err;
  15.    
  16.     va_start(v_args, format);
  17.    
  18.     (void)vsnprintf((char *)&buf_str[0],
  19.                     (size_t ) sizeof(buf_str),
  20.                     (char const *) format,
  21.                     v_args);
  22.    
  23.     va_end(v_args);
  24.     OSSemPend((OS_SEM *)&EchoSem,
  25.             (OS_TICK )0,
  26.             (OS_OPT )OS_OPT_PEND_BLOCKING,
  27.             (CPU_TS *)0,
  28.             (OS_ERR *)&err);
  29.     printf("%s\r\n", buf_str);
  30.    
  31.     OSSemPost((OS_SEM *)&EchoSem,
  32.             (OS_OPT )OS_OPT_POST_1,
  33.             (OS_ERR *)&err);
  34. }
  35. 我感觉是因为这个函数使用了数组,如果该函数执行时间过长,没有来得及退出,又调用该函数,将导致上次的堆栈没有释放。
  36. 当堆栈使用量达到设置值时,单片机进入硬件中断。
  37. 请教各位是这样吗?
复制代码
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2017-2-9 15:03:12 | 显示全部楼层
加大这个缓冲

CPU_CHAR buf_str[256];

设置为1024看看,如果要打印的非常多的话。
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2017-2-9 15:20:55 | 显示全部楼层
我不是打印的内容多,而是快速多次频繁打印输出。
很可能上次的 ECHO_SAFE()函数没有执行完毕,没有释放堆栈。
这次的打印又来了,又再次调用 ECHO_SAFE() 函数,又分配256 Byte堆栈。
总的堆栈空间是1024 Byte,用不了4次就会堆栈溢出了。
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2017-2-9 15:21:24 | 显示全部楼层

回 eric2013 的帖子

eric2013:加大这个缓冲

CPU_CHAR buf_str[256];

设置为1024看看,如果要打印的非常多的话。 (2017-02-09 15:03) 
我不是打印的内容多,而是快速多次频繁打印输出。
很可能上次的 ECHO_SAFE()函数没有执行完毕,没有释放堆栈。
这次的打印又来了,又再次调用 ECHO_SAFE() 函数,又分配256 Byte堆栈。
总的堆栈空间是1024 Byte,用不了4次就会堆栈溢出了。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2017-2-9 17:04:23 | 显示全部楼层
函数是在哪里被调用的,中断里面?
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2017-2-9 17:08:38 | 显示全部楼层

回 eric2013 的帖子

eric2013:函数是在哪里被调用的,中断里面? (2017-02-09 17:04) 
对的,CAN的接收中断函数。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2017-2-9 17:11:25 | 显示全部楼层

回 dasuimao 的帖子

dasuimao:对的,CAN的接收中断函数。 (2017-02-09 17:08) 
不支持中断里面调用,仅支持在任务里面调用,因为函数  OSSemPend是禁止在中断里面调用的,

凡是OSXXXPend类的函数,一律禁止在中断里面调用。
回复

使用道具 举报

1

主题

5

回帖

8

积分

新手上路

积分
8
 楼主| 发表于 2017-2-9 17:27:37 | 显示全部楼层

回 eric2013 的帖子

eric2013:不支持中断里面调用,仅支持在任务里面调用,因为函数  OSSemPend是禁止在中断里面调用的,

凡是OSXXXPend类的函数,一律禁止在中断里面调用。 (2017-02-09 17:11) 
多谢。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-16 13:13 , Processed in 0.041088 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表