martinling / libserialport

Unofficial personal repository for libserialport - see git://sigrok.org/libserialport for official repo
http://sigrok.org/wiki/Libserialport
GNU Lesser General Public License v3.0
65 stars 34 forks source link

Windows 10 #9

Closed MoizesFerreira closed 7 years ago

MoizesFerreira commented 9 years ago

I'm trying to read and write data from an Arduino microcontroller. My computer runs Windows 10. The code below worked on Windows 7, but no more after the upgrade. As there are many examples of libserialport, I wonder if there are any errors in my code:

uint8_t Arduino :: LocalizarSimulador(){ int vid = 0, pid = 0;

if (sp_list_ports(&lista_portas) == SP_OK){
    numero_portas = sizeof(lista_portas)/sizeof(struct sp_port *);

    for (uint8_t i = 0; i < numero_portas; i++){
        sp_copy_port(lista_portas[i], &porta);
        if (sp_get_port_usb_vid_pid(porta, &vid, &pid) == SP_OK){
            /*     usb_vid = 0x2341;
                   usb_pid = 0x42; 
            */
            if (vid == usb_vid && pid == usb_pid){
                if (lista_portas != NULL){
                    sp_free_port_list(lista_portas);
                    lista_portas = NULL;
                }
                nome_porta = std::string(sp_get_port_name(porta));
                return SIMULATOR_FOUND;
            }

... }

uint8_t Arduino :: Conectar(){ if (uint8_t retorno = LocalizarSimulador() != SIMULATOR_FOUND){ return retorno; }

if(sp_open(porta, (sp_mode) (SP_MODE_WRITE | SP_MODE_READ)) == SP_OK){
    if ((sp_set_baudrate(porta, 921600) == SP_OK) &&
        (sp_set_bits(porta, 8) == SP_OK) &&
        (sp_set_stopbits(porta, 1) == SP_OK) &&
        (sp_set_flowcontrol(porta, SP_FLOWCONTROL_NONE) == SP_OK)){
            conectado = true;
            return CONNECT_SUCCESS;
    }

... }

Although I can locate the Arduino and connect to it, the following code always returns an error:

int retorno = sp_nonblocking_read(porta, &buffer_entrada[posicao_buffer], sizeof(AquisicaoEquipamentos_t) - posicao_buffer); /* always return -1 (SP_ERR_ARG). I'm sure there is no NULL pointer */

I tried to modify the code, using sp_blocking_read with the same results. Is there any error in my code? Thanks

martinling commented 9 years ago

This code was incorrect to start with.

Presumably you are allocating lista_portas somewhere as:

struct sp_port **lista_portas;

When you take sizeof(lista_portas), you're just taking the size of that pointer. That's a constant determined by the compiler at compile time, not something that changes depending on the result of your sp_list_ports() call.

So this line:

numero_portas = sizeof(lista_portas)/sizeof(struct sp_port *);

will always set numero_portas = 1, because all pointers have the same size.

What sp_list_ports(&lista_portas) does is to update lista_portas to point to a NULL-terminated array of struct sp_port pointers. If you want to get the number of ports, you need to iterate over that array until you get to the NULL. You can do that in one line like this:

for (int numero_portas = 0; lista_portas[numero_portas] != NULL; numero_portas++);

This may not be the only problem, but I suggest you fix it before debugging further.

You're the first person I know of to try libserialport on Windows 10, so there might be other things that need fixing. That said, libserialport follows the pre-W10 Windows API very strictly and the new OS should be fully backwards compatible.