题
* 更新 *
这是我发现的。每当我在那里具有该功能时,它实际上不会使代码锁定。实际上,这会使读取RTCI²C函数的执行速度非常慢,但是代码仍然可以正确运行,但是我必须等待很长时间才能每次阅读RTC时都可以超越。
因此,RTC有一个警报中断,这是在ISR内部触发其他I²C交互,因此看起来它似乎正在尝试同时进行两个I²C通信,从而减慢了过程。我删除了ISR中的功能,现在正在工作。我将继续调查。
当使用IAR 5.40编程STM32F103微控制器时,我遇到了这个问题。我有一个功能,如果我尝试打印一个局部变量,它会导致代码在其他方面甚至在有问题的函数之前冻结。
有什么可能导致这个?
这是功能:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[3] = {0};
itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string
printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
我也尝试过,这不会导致我经历的锁:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[3] = {0};
itoa(bSmsIndex, bTmpSms, 10);
printf("index = 2\n");
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
没有任何优化启用,并且在尝试从I²CRTC中读取字节时,代码会被卡住 printf("index = %s\n", bTmpSms);
或改用这个 printf("index = 2\n");
然后一切都很高兴。有任何想法吗?
BSMSINDEX实际上永远不会超过30岁,即使如此,在调用此功能之前,锁定也会发生。
解决方案 4
看来,如果我不将变量btmpsms初始化为问题。
我还意识到问题不是printf。它是ITOA函数。它使我能够检查一下即使我认为这不是问题,当我评论ITOA函数时,整个代码都可以。
所以我最终这样做了:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[4] = "aaa"; // I still need to find out why this is !!!
itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string
printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
这是我得到的ITOA函数:
char itoa(int value, char* result, int base)
{
// Check that the base if valid
if (base < 2 || base > 36) {
*result = '\0';
return 0;
}
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do
{
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsr
QPONMLKJIHGFEDCBA9876543210123456789BCDEFGHIJKLMNOPQRSTUVWXYZ“ [35 +(tmp_value -value * base);};} while(value);
// Apply negative sign
if (tmp_value < 0)
*ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr)
{
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return 1;
}
其他提示
char bTmpSms[3]
只有“ 99”的空间。如果您的BSMSINDEX为100或更高,您将尝试写入不属于您的内存。
更新后编辑
我没有提及 itoa
在我本地的机器上,但我发现了这台 http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ )。根据该参考,目的地数组 必须足够长的时间才能获得任何可能的价值. 。检查您的文档:特定的 itoa
可能是不同的。
或使用 sprintf
, snprintf
, ,或标准描述的一些功能。
一些想法:
如果 itoa()
无法正确地终止字符串,那么对printf的调用可能会导致机器永远寻找nul。
PMG有一个很好的观点。
另外,考虑哪种类型的第一个参数 itoa()
是。如果它已签名并且您正在使用一个未签名的整数,那么您可能会在BTMPSMS中获得意外的减号。尝试使用 sprintf()
反而。
代码的更改是将您的其余代码移动到内存中。我的猜测是,此处未列出的代码的其他部分正在抨击一些随机位置。在第一种情况下,位置包含一些关键的东西,在第二种情况下,它没有。
这些是追踪*的最糟糕的问题。祝你好运。
*也许不是最糟糕的 - 如果多个线程之间的种族条件,每周一次仅表现出一次。仍然不是我最喜欢的错误。
什么价值 bSmsIndex
您要打印吗?
如果它大于99,那么您就会超越 bTmpSms
大批。
如果那无济 printf()
被称为单步,直到杂草陷入困境。这可能会明确问题是什么。
或作为快速n-Dirty故障排除,尝试将数组尺寸尺寸为大的东西(也许8),看看会发生什么。
BSMSINDEX的价值是多少?
如果超过99个,将转换为字符串时将是三位数字。当零终止时,它将是四个字符,但是您仅分配了三个字符,以便将null覆盖,并且printf将尝试打印BTMPSMS之后的所有内容,直到下一个null。真的可以访问任何东西。
尝试用索引拆卸该区域= 2
vs. index = %s
.