Reputation: 31
I've been searching for some answer to this problem but can't figure it out.
I have a structure:
typedef struct {
BYTE hour;
BYTE minute;
BYTE second;
BYTE dom;
BYTE month;
BYTE year;
} t_time_date ;
And a serial port receive function:
g_curr_td.year = g_rx_buffer[3];
g_curr_td.month = g_rx_buffer[4];
g_curr_td.dom = g_rx_buffer[5];
g_curr_td.hour = g_rx_buffer[6];
g_curr_td.minute = g_rx_buffer[7];
g_curr_td.second = g_rx_buffer[8];
I have verified the g_rx_buffer
is correct and contains data. If I hard code a number in to the variable it works:
g_curr_td.year = 10; /* this works */
However, running live data it crashes and seems to be writing data somewhere else in memory. Can anyone see something wrong in my setup?
Thanks.
Upvotes: 2
Views: 250
Reputation: 3969
Although I may not answer your question directly, this may help you have cleaner code:
Have a struct for the incoming data format:
typedef struct {
BYTE year;
BYTE month;
BYTE dom;
BYTE hour;
BYTE minute;
BYTE second;
} t_time_input_date __attribute__((packed));
// First you can make sure the data is received in its whole
assert(g_rx_length >= sizeof(t_time_input_date) + 3);
t_time_input_date *in_date = (t_time_input_date *)(g_rx_buffer+3);
g_curr_td.year = in_date->year;
g_curr_td.month = in_date->month;
g_curr_td.dom = in_date->dom;
g_curr_td.hour = in_date->hour;
g_curr_td.minute = in_date->minute;
g_curr_td.second = in_date->second;
This way your code will be cleaner, and it will help you in 3 months.
Upvotes: 1
Reputation: 1694
For debugging purposes, you can try creating a function that takes arguments for all the struct members, something like:
/* Assumes g_curr_td is a global variable. */
void FillStruct( BYTE hour, BYTE minute, BYTE second, BYTE dom, BYTE month, BYTE year )
{
g_curr_td.year = year;
g_curr_td.month = month;
g_curr_td.dom = dom;
g_curr_td.hour = hour;
g_curr_td.minute = minute;
g_curr_td.second = second;
}
Using a function like this should make the assembly code the same whether you're using values from the buffer or constant expressions. If it still crashes, it's probably something with your buffer, even though you do seem to have checked all the angles I could think of dealing with the buffer.
You can call this function as FillStruct( g_rx_buffer[3], g_rx_buffer[4], g_rx_buffer[5], g_rx_buffer[6], g_rx_buffer[7], g_rx_buffer[8] )
, and if that crashes, call it as FillStruct( a, b, c, d, e, f )
, where a, b, c, d, e, and f are either the original arguments or new constant arguments. Try replacing the arguments one at a time and see if it's just one particular field that's failing, or if it's any field that fails.
EDIT: Also, exactly what is your typedef
or #define
for the BYTE
type, what compiler and OS are you using, and are you using any pragmas, e.g. to pack the structure to byte alignment?
Upvotes: 1
Reputation: 37382
What is g_rx_buffer ? If it is not an array of BYTE and not a pointer to BYTE, g_rx_buffer[3]
is not the same as ((BYTE*)g_rx_buffer)[3]
.
Upvotes: 0
Reputation: 12538
The only error source I can see here is the access on the g_rx_buffer. Is the array from g_rx_buffer big enough?
Maybe you can loop over the g_rx_buffer and show us the content of this array.
Upvotes: 0
Reputation: 304
Did you have any system so sincronize data over the serial? How do you guarantee that g_rx_buffer[3] is really g_curr_td.year?
Upvotes: 0