*更新*
这是我发现的。每当我在那里使用该功能时,它实际上不会使代码锁定。它实际上会使读取RTCI²C函数执行起来很慢,但代码仍然可以正常运行,但每次读取RTC时我都要等很长时间才能过去。
因此,RTC有一个报警中断,这触发了ISR内部的其他I²C交互,所以看起来它试图同时进行两次I²C通信,因此减慢了进程。我删除了ISR中的功能,现在正在运行。我会继续调查。
使用IAR 5.40编程STM32F103微控制器时出现此问题。我有这个函数,如果我尝试printf一个局部变量,它会导致代码在它到达有问题的函数之前以另一种方式冻结。
可能导致这种情况的原因是什么?
这是功能:
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,即使这样,在调用此函数之前锁定也会发生。
答案 0 :(得分:2)
char bTmpSms[3]
只有“99”的空间。如果您的bSmsIndex为100或更高,您将尝试写入不属于您的内存。
更新后编辑
我的本地计算机上没有itoa
的引用,但我找到了这个(http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/)。根据该参考文献,目标阵列必须足够长,以获得任何可能的价值。查看您的文档:您的具体itoa
可能不同。
或使用sprintf
,snprintf
或标准所描述的某些功能。
答案 1 :(得分:1)
一些想法:
如果itoa()
没有正确地终止字符串,那么对printf的调用可能会导致机器永远寻找NUL。
另外,请考虑itoa()
的第一个参数是什么类型。如果它已经签名并且您传入的是无符号整数,那么您可能会在bTmpSms中获得意外减号。请尝试使用sprintf()
。
答案 2 :(得分:1)
代码的更改是将剩下的代码移到内存中。我的猜测是,这里没有列出的代码的其他部分正在抨击一些随机位置;在第一种情况下,该位置包含一些关键的东西,在第二种情况下它不包含。
这些是追踪*的最糟糕的问题。祝你好运。
*也许不是最糟糕的 - 如果它是多线程之间的竞争条件,每周只能表现一次,可能会更糟。仍然不是我最喜欢的那种虫。
答案 3 :(得分:1)
似乎如果我没有将变量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
qponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz“[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;
}
答案 4 :(得分:0)
bSmsIndex的价值是什么?
如果超过99,转换为字符串时将为三位数。当零终止时,它将是四个字符,但是你只为bTmpSms分配了三个,所以null可能会被覆盖,printf将尝试打印bTmpSms之后的任何内容,直到下一个null。那可以访问任何东西,真的。
答案 5 :(得分:0)
您尝试打印的bSmsIndex
的价值是多少?
如果它大于99,那么你将超越bTmpSms
数组。
如果这没有帮助,那么使用IAR非常好的调试器 - 我会在调用printf()
的位置进入汇编窗口,然后单步执行,直到事情进入杂草状态。这可能会弄清问题是什么。
或者作为快速排除故障的方法,尝试将数组调整为大型(可能是8个),看看会发生什么。
答案 6 :(得分:0)
尝试使用index = 2
与index = %s
对此区域进行反汇编。