Inicialización de estructura de metodos

Buenos dias a todos.
Ante todo dar las gracias por anticipado por la ayuda que se me preste en este foro. Espero aprender mucho del mismo.

Mi problema es el siguiente:

Estoy desarrollando un proyecto donde tengo que leer mediante rfid una serie de tags. El fabricante me proporciono una librería en c para windows y linux que estoy intentando hacer funcionar en arduino.

Por ahora voy solucionando los problemas que me van surgiendo en el proceso, pero me encuentro con un problema al inicializar una variable de un tipo estructura en la que sus elementos son métodos.

Pongo aquí debajo primero la parte de la librería del proveedor:

typedef struct RFIDReader_s {

    int16_t (*connect)(void* *port_handle, int16_t port_type, void* port_params);

    int16_t (*disconnect)(void* port_handle);

    int16_t (*tx)(void* port_handle, uint8_t* data, uint32_t len);

    int16_t (*rx)(void* port_handle, uint8_t* data, uint32_t len, uint32_t ms_timeout);

      s (*clear_rx_data)(void* port_handle);

      void    (*enable_irqs)(void); 

      void    (*disable_irqs)(void);


} RFIDReader;

Este es el código que me proporcionó el proveedor de prueba
lector.h


#ifndef _HOST_H_
#define _HOST_H_

#include <stdint.h>

//communication interface functions/functions needed for CAENRFIDLib_Light
int16_t _connect(void* *port_handle, int16_t port_type, void* port_params);
int16_t _disconnect(void* port_handle);
int16_t _tx(void* port_handle, uint8_t* data, uint32_t len);
int16_t _rx(void* port_handle, uint8_t* data, uint32_t len, uint32_t ms_timeout);
int16_t _clear_rx_data(void* port_handle);
void _enable_irqs(void);
void _disable_irqs(void);

#endif

lector.c

int16_t _connect(void* *port_handle, int16_t port_type, void* port_params)
{
*//Aquí va el código correspondiente*   
}

int16_t _disconnect(void* port_handle)
{
*//Aquí va el código correspondiente*   
}

int16_t _tx(void* port_handle, uint8_t* data, uint32_t len)
{
*//Aquí va el código correspondiente*   
}

int16_t _rx(void* port_handle, uint8_t* data, uint32_t len, uint32_t ms_timeout)
{          
*//Aquí va el código correspondiente*   
}

int16_t _clear_rx_data(void* port_handle)
{
*//Aquí va el código correspondiente*   
 }

void _enable_irqs(void)
{
}

void _disable_irqs(void)
{
}

Inicialización que envía el proveedor de ejemplo.

RFIDReader reader = { 
                             .connect = _connect,
                             .disconnect = _disconnect,
                             .tx = _tx,
                             .rx = _rx,
                             .clear_rx_data = _clear_rx_data,
                             .enable_irqs = _enable_irqs,
                             .disable_irqs = _disable_irqs
                            };

Y es este último trozo de código el que no consigo trasladar para que funcione en arduino pues me dice: sorry, unimplemented: non-trivial designated initializers not supported

Y aquí estoy parado, ya que estuve buscando y haciendo diversas pruebas y no encuentro solución para ello.

Espero que me podáis echar una mano en esto.

De nuevo muchas gracias por adelantado.

Creo que o lo has copiado mal o directamente se te ha colado un error en la definición de la estructura. La línea:

    s (*clear_rx_data)(void* port_handle);

Creo que debería de ser:

    int16_t (*clear_rx_data)(void* port_handle);

La estructura debería de quedar definida tal que así:

typedef struct RFIDReader_s {
    int16_t (*connect)(void* *port_handle, int16_t port_type, void* port_params);
    int16_t (*disconnect)(void* port_handle);
    int16_t (*tx)(void* port_handle, uint8_t* data, uint32_t len);
    int16_t (*rx)(void* port_handle, uint8_t* data, uint32_t len, uint32_t ms_timeout);
    int16_t (*clear_rx_data)(void* port_handle);
    void    (*enable_irqs)(void); 
    void    (*disable_irqs)(void);
} RFIDReader;

Por otro lado, no sé si te has dado cuenta que has de definir el contenido de cada una de las funciones de lector.c y que tal como las tienes ahora no van a compilar y van a dar problemas. En cada línea que pone:

*//Aquí va el código correspondiente*   

El * (asterisco) del principio no está comentado y el compilador piensa que lo ha de compilar y un asterisco suelto no es una instrucción válida, por lo que va a dar error. Supongo que se puso adrede para que no se compilara sin poner el código adecuado. Prueba a quitar ese asterisco y mira a ver si al menos te compila, porque funcionar no debería ya que falta que programes el código adecuado para cada una de esas funciones.

IgnoranteAbsoluto muchas gracias por la respuesta.

Te cuento.
La estructura en principio al compilar no me da problemas, pero haré la prueba con lo que me comentas.

En cuanto a la de
//Aquí va el código correspondiente

En donde pongo esto es donde va el código con lo que hace, pero como era muy largo y no influia para mi problema para ponerlo en el post lo sustitui por este texto. Los * me los puso el foro al indicar que tenia que ir en negrita.

El problema que tengo realmente es que

RFIDReader reader = { 
                             .connect = _connect,
                             .disconnect = _disconnect,
                             .tx = _tx,
                             .rx = _rx,
                             .clear_rx_data = _clear_rx_data,
                             .enable_irqs = _enable_irqs,
                             .disable_irqs = _disable_irqs
                            };

el ide de arduino me dice: sorry, unimplemented: non-trivial designated initializers not supported

Y no se como trasladar esto para que el ide de arduino me lo permita y funcione.

Un saludo

Hola. He logrado replicar el error. Para ello he cambiado el orden de la definición de los campos de la estructura:

RFIDReader reader = { 
                             .connect = _connect,
                             .disconnect = _disconnect,
                             .tx = _tx,
                             .rx = _rx,
                             .clear_rx_data = _clear_rx_data,
                             .enable_irqs = _enable_irqs,
                             .disable_irqs = _disable_irqs
                            };

Tienen que estar definidos en el mismo orden que está definido en:

typedef struct RFIDReader_s {
    int16_t (*connect)(void* *port_handle, int16_t port_type, void* port_params);
    int16_t (*disconnect)(void* port_handle);
    int16_t (*tx)(void* port_handle, uint8_t* data, uint32_t len);
    int16_t (*rx)(void* port_handle, uint8_t* data, uint32_t len, uint32_t ms_timeout);
    int16_t (*clear_rx_data)(void* port_handle);
    void    (*enable_irqs)(void); 
    void    (*disable_irqs)(void);
} RFIDReader;

Mira a ver si por un casual has intercambiado alguna línea en tu programa o te falta una. Han de tener los mismo campos y en el mismo orden, en caso contrario da el error.

Muchas gracias.
Voy a revisar lo que comentas.

Un saludo

Continuando la discusión desde Inicialización de estructura de metodos:

Al final creo que lo tengo resuelto haciéndolo por separado.

rfidReader.connect = _connect;
rfidReader.disconnect = _disconnect;
rfidReader.tx = _tx;
rfidReader.rx = _rx;
rfidReader.clear_rx_data = _clear_rx_data;
rfidReader.enable_irqs = _enable_irqs;
rfidReader.disable_irqs = _disable_irqs;

Para este proyecto estoy intentando hacer funcionar un sdk que me enviaron en c, para un lector Rfid que se conecta por uart al arduino.

Ahora el problema que me encuentro es la comunicación entre ellos, ya que para conectar con el puerto uart2, utlizo la libreria HardwareSerial y abro el puerto con la instrucción begin, al igual que la comunicación con cualquier puerto serial.

Pero el sdk para hacerlo utiliza la instrucción open, ya que esto le devuelve un handle que se utiliza para enviarle los distintos comandos al lector.

Para ello se utiliza una estructura donde se indica el nombre del puerto como char*, y no se si esto se puede hacer en arduino y como seria la transformación.

pongo el código de la función de conexión para ver si me podeis echar una mano.

esta es la estrucutra del tipo RS323

typedef struct {
    char* com;
    uint32_t baudrate;
    uint8_t dataBits;
    uint8_t stopBits;
    uint8_t parity;
    uint8_t flowControl;    
}RS232_params;

Y este el codigo de conexion

#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/time.h>
#include "host.h"

int16_t _connect(void* *port_handle, int16_t port_type, void* port_params)
{   
    RS232_params* params = (RS232_params*)port_params;
    int fd;
    struct termios config;
    speed_t speed;
    
    //This example supports RS232 port type only
    (void) (port_type);
    //This example will ignore flow control
    (void) (params->flowControl);
    //This example will support 8 databits only
    (void) (params->dataBits);
        
    //Open port
    if((fd = open(params->com, O_RDWR | O_NOCTTY)) < 0) return (-1);
    *port_handle = (void *)fd;
    
    //Get current configuration
    tcgetattr(fd, &config);
  
    //Set baudrate 
    switch(params->baudrate)
    {
    case 921600:
            speed = B921600;
            break;
    case 460800:
            speed = B460800;
            break;
    case 230400:
            speed = B230400;
            break;
    case 57600:
            speed = B57600;
            break;
    case 38400:
            speed = B38400;
            break;
    case 19200:
            speed = B19200;
            break;
    case 9600:
            speed = B9600;
            break;
    case 115200:
    default:    
            speed = B115200;
            break;
    }
    if(cfsetispeed(&config, speed) < 0) return (-1);
    if(cfsetospeed(&config, speed) < 0) return (-1);    
    //Set 8 data bits
    config.c_cflag &= ~CSIZE;
    config.c_cflag |= CS8;
    //Set  stop bits 
    switch(params->stopBits)
    {
        case 2:
            config.c_cflag |= CSTOPB;
            break;
        case 1:
        default:
            config.c_cflag &= ~CSTOPB;
            break;
    }   
    //Set parity
    switch(params->parity)
    {
        case 1:
            config.c_cflag |= PARENB;
            config.c_cflag |= PARODD;
            break;
        case 2:
            config.c_cflag |= PARENB;
            config.c_cflag &= ~PARODD;
            break;
        case 0:
        default:
            config.c_cflag &= ~PARENB;
            break;
    }   
  
    //no hardware flow control
    config.c_cflag &= ~CRTSCTS;     
    //Ignore modem control lines, Enable Receiver
    config.c_cflag |= CREAD | CLOCAL;
    //disable input/output flow control, disable restart chars
    config.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL);
    /*disable canonical input, disable echo,  
      disable visually erase char,
      disable terminal-generated signals */
    config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    //disable output processing
    config.c_oflag &= ~OPOST;
    //Set completely non-blocking read
    config.c_cc[VMIN] = 0;
    config.c_cc[VTIME] = 0;
    
    //Flush Input
    if(tcflush(fd, TCIFLUSH) < 0) return (-1);
    //Set configuration
    if(tcsetattr(fd, TCSANOW, &config) < 0) return (-1);
    
    return (0);
}

En este código, se conecta con el lector y le pasa los parámetros de conexión. O eso entiendo.

Mi conocimiento de arduino, no es muy amplio, ya que casi acabo de empezar, pero me cayo este proyecto, y ya sabéis.

Gracias de antemano y un saludo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.