Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] gpio_poll() hangs master #448

Open
2 tasks
ag88889 opened this issue Jan 17, 2025 · 3 comments
Open
2 tasks

[BUG] gpio_poll() hangs master #448

ag88889 opened this issue Jan 17, 2025 · 3 comments
Labels

Comments

@ag88889
Copy link

ag88889 commented Jan 17, 2025

Description of problem: gpio_poll() hangs master

Using gpio_poll() as that

void erpc::spiWaitForSlaveReadyGpio(int gpioHandle)
{
    for (;;)
    {
         if (gpio_poll(gpioHandle, -1))
         {
             break;
         }
    }
}

hangs master.

To Reproduce

I got that behaviour when
erpc_c/transports/erpc_spidev_master_transport.cpp
was tested with gpio synchronization turned on.

Expected behavior

No hangs.

Screenshots

Desktop (please complete the following information)

  • OS Linux orangepizero3 6.1.31-sun50iw9 1.0.4 SMP Thu Jul 11 16:37:41 CST 2024 aarch64 GNU/Linux
  • eRPC Version 1.13.0

Steps you didn't forgot to do

  • I checked if there is no related issue opened/closed.
  • I checked that there doesn't exist opened PR which is solving this issue.

Additional context

That's modification works fine:

int gpio_poll(int fd, int timeout)  // 0/1 - new pin state, -2 - error, -1 - timeout
{
    int pollr;
    struct pollfd fds;
    int ret;
    char val;

    fds.fd = fd;
    fds.events = POLLIN | POLLPRI | POLLERR;
    ;
    pollr = poll(&fds, 1, timeout);

    if (pollr < 0)
    {
        (void)fprintf(stderr, "Could not poll gpio (%d).\r\n", errno);
        ret = -2;
    }
    else
    {
        if ((fds.revents & (POLLPRI | POLLIN) ) > 0)
        {
            lseek(fds.fd, 0, SEEK_SET);
            read(fds.fd, &val, 1);
            ret = val-'0';
        }
        else if ((fds.revents & POLLERR) > 0)
        {
            (void)fprintf(stderr, "Error while polling gpio (%d).\r\n", errno);
            ret = -2;
        }
        else
        {
            ret = -1;
        }
    }

    return ret;
}

/***********************/

void erpc::spiWaitForSlaveReadyGpio(int gpioHandle)
{
    for (;;)
    {
         if (gpio_poll(gpioHandle, -1) == 0)
         {
             break;
         }
    }
}

@ag88889 ag88889 added the bug label Jan 17, 2025
@ag88889 ag88889 changed the title [BUG] [BUG] gpio_poll() hangs master Jan 18, 2025
@ag88889
Copy link
Author

ag88889 commented Jan 19, 2025

It seems reasonable to change the synchronization to character-device interface similarly how it done in the gpio-tools/

@ag88889
Copy link
Author

ag88889 commented Jan 24, 2025

here is a working functional equivalent of the original gpio_poll(), the latter should be considered broken
(in the context of the operating system version used, may be...)

int gpio_poll_val(int fd)  // returns 0/1 - new pin state,
                           // -2 - error occured (see errno), for compatibility ret with gpio_poll()
{
    char val;
    int ret;

    lseek(fd, 0, SEEK_SET);
    if (read(fd, &val, 1) < 1)
        return -2;
    ret = val-'0';

    return ret;
}

@ag88889
Copy link
Author

ag88889 commented Jan 24, 2025

the reason this code (original gpio_poll()) doesn't work is that between the return from poll() and reading the value, events can happen that will be cancelled when reading the value
(has this code never been tested in real work??)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

1 participant