Передать указатель структуры в качестве аргумента функции в c
Я разрабатываю код, в котором мне нужно передать значение указателя структуры функции в качестве параметра. Я вызываю функцию «proto485Compare()» в «RS485TaskSlave()». «rs485Msg» содержит мои данные, для которых мне нужно проверить контрольную сумму, я проверяю их в «RS485TaskSlave()», используя «if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message)))», но в этой строке отображается ошибка .
Пожалуйста, помогите мне получить значения «rs485Msg» & проверьте контрольную сумму в этой строке
Ниже приведен фрагмент моего кода:
typedef struct
{
uint8_t AB; ///< Адресный байт (стартовый байт)
uint8_t CB; ///< Команда (индекс) «ASCII-байт»
uint8_t SI; ///< Действие (субиндекс) «ASCII-байт»
uint8_t PH1; ///< Полезная нагрузка «ASCII-байт» старшего полубайта старшего байта необработанной полезной нагрузки
uint8_t PH0; ///< Полезная нагрузка «ASCII-байт» младшего полубайта старшего байта необработанной полезной нагрузки
uint8_t PL1; ///< Полезная нагрузка «ASCII-байт» старшего полубайта младшего байта необработанной полезной нагрузки
uint8_t PL0; ///< Полезная нагрузка «ASCII-байт» младшего полубайта младшего байта необработанной полезной нагрузки
uint8_t CS1; ///< Контрольная сумма «ASCII-байт» старшего полубайта необработанной контрольной суммы
uint8_t CS0; ///< Контрольная сумма «ASCII-байт» младшего полубайта необработанной контрольной суммы
} rs485_message_t;
uint8_t proto485ValidCheckSum(rs485_message_t message)
{
uint8_t rawChecksum = (message.CB - OFFSET_ASCII) + (message.SI - OFFSET_ASCII) +
(message.PH1 - OFFSET_ASCII) + (message.PH0 - OFFSET_ASCII) +
(message.PL1 - OFFSET_ASCII) + (message.PL0 - OFFSET_ASCII);
uint8_t res = (((rawChecksum & 0xF0) >> 4) + OFFSET_ASCII) == message.CS1 &&
((rawChecksum & 0x0F) + OFFSET_ASCII) == message.CS0;
return res;
}
void RS485TaskSlave(void *p_arg) //b — задача связи RS485
{
uint8_t res;
rs485_message_t rs485Msg;
uint8_t command, action, value;
(void)p_arg;
while(1)
{
res = driver485Read((uint8_t *)&rs485Msg, RS485_MSG_LENGTH);
if(RS485_MSG_LENGTH == 9)
{
res = proto485Compare((uint8_t *)&rs485Msg, command, action, value);
}
}
}
int16_t proto485Compare(uint8_t* message, uint8_t* comparec, uint8_t* comparea, uint8_t* comaprev)
{ int j = 0;
rs485_message_t rs485Msg;
char res;
uint8_t FWmsg[9] = {0x09,0x31,0x30,0x30,0x30,0x30,0x33,0x30,0x34};
uint8_t arduinodata[9] = {0x09,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message))) //
/*GETTING ERRORVON THIS LINE please help how to pass message value to verify checksum at this line*/
{
printf("compare command..........");
for (j=0; j<9; j++)
{
arduinodata[j] = message[j];
printf("%d ",arduinodata[j]);
}
printf("\n");
if(compareArray(FWmsg,arduinodata,7)==0)
{
uint8_t add, fwc, fwa;
uint16_t fwv;
res = GetABFWversion(&add, &fwc, &fwa, &fwv);
res = proto485OnlyWrite(add,fwc, fwa, fwv);
}
}
else
{
printf("Arrays have different elements.\n");
}
return res;
}
@swanand, 👍0
1 ответ
Лучший ответ:
Удалите приведение и измените параметр message
на rs485_message_t *
:
int16_t proto485Compare(rs485_message_t * message, uint8_t* comparec, uint8_t* comparea, uint8_t* comaprev) {
int j = 0;
rs485_message_t rs485Msg;
char res;
uint8_t FWmsg[9] = {0x09,0x31,0x30,0x30,0x30,0x30,0x33,0x30,0x34};
uint8_t arduinodata[9] = {0x09,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
if(proto485ValidCheckSum(message))) { ...
И когда вы его вызываете, просто:
res = proto485Compare(&rs485Msg, command, action, value);
Чтобы получить отдельные байты, вы можете затем создать новую переменную:
uint8_t *messageAsBytes = (uint8_t *)message;
Тогда вы можете использовать:
messageAsBytes[i]
и т. д.
Однако другой более простой способ — создать объединение
в вашей структуре:
struct rs485_message_t {
union {
uint8_t bytes[9];
struct {
uint8_t AB; ///< Адресный байт (стартовый байт)
uint8_t CB; ///< Команда (индекс) «ASCII-байт»
uint8_t SI; ///< Действие (субиндекс) «ASCII-байт»
uint8_t PH1; ///< Полезная нагрузка «ASCII-байт» старшего полубайта старшего байта необработанной полезной нагрузки
uint8_t PH0; ///< Полезная нагрузка «ASCII-байт» младшего полубайта старшего байта необработанной полезной нагрузки
uint8_t PL1; ///< Полезная нагрузка «ASCII-байт» старшего полубайта младшего байта необработанной полезной нагрузки
uint8_t PL0; ///< Полезная нагрузка «ASCII-байт» младшего полубайта младшего байта необработанной полезной нагрузки
uint8_t CS1; ///< Контрольная сумма «ASCII-байт» старшего полубайта необработанной контрольной суммы
uint8_t CS0; ///< Контрольная сумма «ASCII-байт» младшего полубайта необработанной контрольной суммы
};
};
};
Теперь вы можете получить доступ к message->CS0
и т. д., а также к message->bytes[3]
.
Вам также следует передать указатель при вызове proto485ValidCheckSum
— исключительно для экономии памяти.
uint8_t proto485ValidCheckSum(rs485_message_t *message)
{
uint8_t rawChecksum = (message->CB - OFFSET_ASCII) + (message->SI - OFFSET_ASCII) +
(message->PH1 - OFFSET_ASCII) + (message->PH0 - OFFSET_ASCII) +
(message->PL1 - OFFSET_ASCII) + (message->PL0 - OFFSET_ASCII);
uint8_t res = (((rawChecksum & 0xF0) >> 4) + OFFSET_ASCII) == message->CS1 &&
((rawChecksum & 0x0F) + OFFSET_ASCII) == message->CS0;
return res;
}
И снова вызовите его с указателем, что в любом случае делает первый блок кода.
В общем, лучше передавать один указатель на структуру от функции к функции, а не клонировать ее каждый раз.
Вы также можете использовать «передачу по ссылке», если хотите, но я считаю, что при частой передаче чего-либо вроде этого лучше придерживаться указателей.
- устаревшее преобразование из строковой константы в 'char*'
- Как запрограммировать ардуино на чистом C/C++?
- Количество элементов в массиве char
- Регистры ввода-вывода SAM3X8E (Arduino Due)
- как быстро loop() работает в Arduino
- Arduino: как получить тип платы в коде
- Как вызвать функции C из скетча ардуино?
- Как преобразовать полезную нагрузку byte* в строку
Спасибо за ответ, я внес вышеупомянутые изменения и запустил код, который показывает ошибки ниже.... 1) в строке «if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message)))» он дает «имя типа не разрешено» и в строке « arduinodata[j] = message[j];» это показывает, что «значение типа «rs485_message_t» не может быть присвоено объекту tpe «uint8_t»», @swanand
@swanand Прочитайте мой первый блок кода и сравните его со своим., @Majenko
Извините, я виноват, я изменил чтение элемента сообщения, он работает нормально, но я все еще получаю сообщение об ошибке в строке " if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message)))" t дает "имя типа не разрешено". Пожалуйста, сообщите Если я делаю что-то не так...., @swanand
@swanand Прочитайте мой первый блок кода и сравните его со своим., @Majenko
Еще раз огромное спасибо за подсказки....., @swanand