C Структурная проблема - PullRequest
       1

C Структурная проблема

2 голосов
/ 03 ноября 2010

Я искал какой-то ответ на эту проблему, но не могу понять.

У меня есть структура:

typedef struct  {
    BYTE  hour;      
    BYTE  minute;    
    BYTE  second;   
    BYTE  dom;     
    BYTE month;
    BYTE year;      
} t_time_date ;

И функция приема последовательного порта:

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];

Я подтвердил, что g_rx_buffer правильный и содержит данные.Если я жестко закодирую число в переменной, оно будет работать:

g_curr_td.year = 10;  /* this works */

Однако, при работе с живыми данными происходит сбой, и кажется, что они записывают данные где-то в памяти.Кто-нибудь может увидеть что-то не так в моей настройке?

Спасибо.

Ответы [ 6 ]

1 голос
/ 04 ноября 2010

В целях отладки вы можете попробовать создать функцию, которая принимает аргументы для всех членов структуры, например:

/* 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;
}

Использование такой функции должно сделать код ассемблера одинаковым независимо от того, используете ли вы значения из буфера или константные выражения. Если он все еще падает, возможно, это что-то с вашим буфером, даже если вы, кажется, проверили все углы, которые я мог придумать, имея дело с буфером.

Вы можете вызывать эту функцию как 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] ), а в случае сбоя вызывать ее как FillStruct( a, b, c, d, e, f ), где a, b, c, d, e и f являются либо исходными аргументами, либо новыми константами. Попробуйте заменять аргументы по одному за раз и посмотрите, не сработает ли только одно конкретное поле или не сработает ли какое-либо поле.

РЕДАКТИРОВАТЬ: Кроме того, именно то, что ваш typedef или #define для типа BYTE, какой компилятор и ОС вы используете, и вы используете какие-либо прагмы, например. упаковать структуру в байтовое выравнивание?

1 голос
/ 03 ноября 2010

Хотя я не могу ответить на ваш вопрос напрямую, это может помочь вам иметь более чистый код:

У вас есть структура для формата входящих данных:

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;

Таким образом ваш кодчище, и это поможет вам через 3 месяца.

1 голос
/ 03 ноября 2010

Имеет ли g_rx_buffer хотя бы 9 байт данных?

0 голосов
/ 03 ноября 2010

Что такое g_rx_buffer?Если это не массив BYTE и не указатель на BYTE, g_rx_buffer[3] не совпадает с ((BYTE*)g_rx_buffer)[3].

0 голосов
/ 03 ноября 2010

Единственный источник ошибок, который я вижу здесь, - это доступ к g_rx_buffer. Достаточно ли велик массив из g_rx_buffer?

Возможно, вы можете перебрать g_rx_buffer и показать нам содержимое этого массива.

0 голосов
/ 03 ноября 2010

Была ли у вас какая-либо система для синхронизации данных по последовательному каналу?Как вы гарантируете, что g_rx_buffer [3] действительно g_curr_td.year?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...