Передать указатель структуры в качестве аргумента функции в c

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

, 👍0


1 ответ


Лучший ответ:

0

Удалите приведение и измените параметр 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;
}

И снова вызовите его с указателем, что в любом случае делает первый блок кода.

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

Вы также можете использовать «передачу по ссылке», если хотите, но я считаю, что при частой передаче чего-либо вроде этого лучше придерживаться указателей.

,

Спасибо за ответ, я внес вышеупомянутые изменения и запустил код, который показывает ошибки ниже.... 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