在程序中进行函数调用后,控制跳转到未指定的内存位置
After making function call in the programme ,control is jumping into the unspecified memory location
我正在开发一个 gps 代码,它从 gps 获取原始数据并对数据进行解码并将其保存到相关变量(数组)中。问题是每当我进行函数调用时,它都在执行函数语句直到函数结束,即“}”,之后控件将进入一些未指定的内存位置,而不是将控件移交给主函数。
为什么会这样?在不使用微控制器的情况下,代码在编译器中运行良好,为什么?我需要处理微控制器寄存器的任何步骤吗?
void gps_Gpgga_data_pro_funct(void)
{
int loop1 , loop2 , loop3 ;
unsigned char commapos = 0; //to hold the comma position
unsigned char tempbuff[100]; //temparary buffer
str_cpy(tempbuff,aa_GPS_GPGGA_RxBuffer); //received data taking into tempbuff
if(tempbuff[3] == 'G' && tempbuff[4] == 'G' && tempbuff[5] == 'A')
{
loop1 = 0;
loop2 = 7;
while(tempbuff[loop2] != COMMA) //getting the time
{
gga_time[loop1] = tempbuff[loop2];
loop1 ++;
loop2 ++;
}
//storing the comma position in a variable.
gga_time[loop1] = '[=10=]'; //GPGGA time
commapos = loop2 ;
loop1 = 0;
loop2 = 0;
loop2 = commapos + 1; //setting the position for latitude
while(tempbuff[loop2] != COMMA) //receiving the latitude value
{
gga_lat[loop1] = tempbuff[loop2] ;
loop2 ++;
loop1 ++;
}
commapos = loop2; //saving the commaposition
gga_lat[loop1] = '[=10=]'; //GPGGA latitude
loop1 = 0;
loop2 = 0;
loop2 = commapos + 3;
while(tempbuff[loop2] != COMMA) // receiving the longitude value
{
gga_long[loop1] = tempbuff[loop2] ;
loop1 ++;
loop2 ++;
}
commapos = loop2 ;
gga_long[loop1] = '[=10=]'; //GPGGA longitude
}
else
{
/*do nothing*/
}
}
对我来说听起来像是腐败。很可能是堆栈溢出或堆栈损坏。我会在代码中的不同点停止调试器,并查看已被压入堆栈的 link 寄存器,看看它是否在执行期间的任何时候发生变化。它也可能因中断或其他功能而损坏。这需要了解 ARM/C 调用约定,因此您可能需要做一些研究。
这听起来像是覆盖 return 地址的经典缓冲区溢出。检查 tempbuff。 str_cpy()
可能是一个好的开始(如果它像 strcpy()
,它将溢出缓冲区,因为源不是 NUL
-终止)。您可以将缓冲区大小传递给它以防止在所有情况下溢出(即使源格式错误)。
剩余的代码也很漂亮 "optimistic",因为如果输入损坏,它将表现出 未定义的行为 (UB)。如果没有适当的范围检查,我不会接受这样的代码!请记住,所有外部(非自生成)数据都可能已损坏。根据墨菲定律,将。
另外,不清楚为什么要先将数据复制到缓冲区。直接从输入缓冲区解析它会更快更容易。
正如安德鲁所说,这听起来像是堆栈损坏。一种可能是您正在写超出 tmpbuff 末尾的部分,在我看来好像是在 str_cpy 中。您可以尝试改用 strncpy,或者(大量)增加 tmpbuff 的大小;如果这解决了问题,那么要解决的问题是 rx 缓冲区不会像您的代码所假设的那样为您提供长度最多为 99 的字符串。
我猜你正在使用 NMEA 0183 GPS 标准协议。
消息 <CR> <LF>
终止而不是 NULL 终止。
然后检查您是否没有使用字符串函数来完成工作。
我的意思是 str_cpy 必须如下所示:
str_cpy(char *tempbuff, char *aa_GPS_GPGGA_RxBuffer, uint8_t bufferlength)
{
for (int i=0; i<bufferLength; i++)
{
*(tempbuff+i) = *(aa_GPS_GPGGA_RxBuffer+i);
}
}
我认为您的应用程序可能存在的另一个问题是 aa_GPS_GPGGA_RxBuffer
的填充方式。这是因为您正在处理临时缓冲区中的 RX 消息。
我猜想促使您将收到的消息复制到临时缓冲区的原因是 RX 缓冲区必须由另一个 task/interrupt.
在那种情况下,是否确保在复制到 tempbuffer 期间不会覆盖 RX 缓冲区?
无论如何,在执行此操作之前,您必须始终检查消息的完整性:我希望您在验证 RX 缓冲区之前对接收到的消息进行校验和。
最后一点,这段代码没有意义:
commapos = loop2 ;
loop1 = 0;
loop2 = 0;
loop2 = commapos + 1;
您可以将其更改为:
loop1 = 0;
loop2++;
编辑:
据@Weather Vane 报道:在 unsigned char
和 int
变量之间切换从来都不是一个好主意。
我正在开发一个 gps 代码,它从 gps 获取原始数据并对数据进行解码并将其保存到相关变量(数组)中。问题是每当我进行函数调用时,它都在执行函数语句直到函数结束,即“}”,之后控件将进入一些未指定的内存位置,而不是将控件移交给主函数。
为什么会这样?在不使用微控制器的情况下,代码在编译器中运行良好,为什么?我需要处理微控制器寄存器的任何步骤吗?
void gps_Gpgga_data_pro_funct(void)
{
int loop1 , loop2 , loop3 ;
unsigned char commapos = 0; //to hold the comma position
unsigned char tempbuff[100]; //temparary buffer
str_cpy(tempbuff,aa_GPS_GPGGA_RxBuffer); //received data taking into tempbuff
if(tempbuff[3] == 'G' && tempbuff[4] == 'G' && tempbuff[5] == 'A')
{
loop1 = 0;
loop2 = 7;
while(tempbuff[loop2] != COMMA) //getting the time
{
gga_time[loop1] = tempbuff[loop2];
loop1 ++;
loop2 ++;
}
//storing the comma position in a variable.
gga_time[loop1] = '[=10=]'; //GPGGA time
commapos = loop2 ;
loop1 = 0;
loop2 = 0;
loop2 = commapos + 1; //setting the position for latitude
while(tempbuff[loop2] != COMMA) //receiving the latitude value
{
gga_lat[loop1] = tempbuff[loop2] ;
loop2 ++;
loop1 ++;
}
commapos = loop2; //saving the commaposition
gga_lat[loop1] = '[=10=]'; //GPGGA latitude
loop1 = 0;
loop2 = 0;
loop2 = commapos + 3;
while(tempbuff[loop2] != COMMA) // receiving the longitude value
{
gga_long[loop1] = tempbuff[loop2] ;
loop1 ++;
loop2 ++;
}
commapos = loop2 ;
gga_long[loop1] = '[=10=]'; //GPGGA longitude
}
else
{
/*do nothing*/
}
}
对我来说听起来像是腐败。很可能是堆栈溢出或堆栈损坏。我会在代码中的不同点停止调试器,并查看已被压入堆栈的 link 寄存器,看看它是否在执行期间的任何时候发生变化。它也可能因中断或其他功能而损坏。这需要了解 ARM/C 调用约定,因此您可能需要做一些研究。
这听起来像是覆盖 return 地址的经典缓冲区溢出。检查 tempbuff。 str_cpy()
可能是一个好的开始(如果它像 strcpy()
,它将溢出缓冲区,因为源不是 NUL
-终止)。您可以将缓冲区大小传递给它以防止在所有情况下溢出(即使源格式错误)。
剩余的代码也很漂亮 "optimistic",因为如果输入损坏,它将表现出 未定义的行为 (UB)。如果没有适当的范围检查,我不会接受这样的代码!请记住,所有外部(非自生成)数据都可能已损坏。根据墨菲定律,将。
另外,不清楚为什么要先将数据复制到缓冲区。直接从输入缓冲区解析它会更快更容易。
正如安德鲁所说,这听起来像是堆栈损坏。一种可能是您正在写超出 tmpbuff 末尾的部分,在我看来好像是在 str_cpy 中。您可以尝试改用 strncpy,或者(大量)增加 tmpbuff 的大小;如果这解决了问题,那么要解决的问题是 rx 缓冲区不会像您的代码所假设的那样为您提供长度最多为 99 的字符串。
我猜你正在使用 NMEA 0183 GPS 标准协议。
消息 <CR> <LF>
终止而不是 NULL 终止。
然后检查您是否没有使用字符串函数来完成工作。
我的意思是 str_cpy 必须如下所示:
str_cpy(char *tempbuff, char *aa_GPS_GPGGA_RxBuffer, uint8_t bufferlength)
{
for (int i=0; i<bufferLength; i++)
{
*(tempbuff+i) = *(aa_GPS_GPGGA_RxBuffer+i);
}
}
我认为您的应用程序可能存在的另一个问题是 aa_GPS_GPGGA_RxBuffer
的填充方式。这是因为您正在处理临时缓冲区中的 RX 消息。
我猜想促使您将收到的消息复制到临时缓冲区的原因是 RX 缓冲区必须由另一个 task/interrupt.
在那种情况下,是否确保在复制到 tempbuffer 期间不会覆盖 RX 缓冲区?
无论如何,在执行此操作之前,您必须始终检查消息的完整性:我希望您在验证 RX 缓冲区之前对接收到的消息进行校验和。
最后一点,这段代码没有意义:
commapos = loop2 ;
loop1 = 0;
loop2 = 0;
loop2 = commapos + 1;
您可以将其更改为:
loop1 = 0;
loop2++;
编辑:
据@Weather Vane 报道:在 unsigned char
和 int
变量之间切换从来都不是一个好主意。