Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9082841
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T20:38:54+00:00 2026-06-16T20:38:54+00:00

I have a USB protocol that I want to implement but I’m a little

  • 0

I have a USB protocol that I want to implement but I’m a little lost on the best way to do it.

The USB protocol involves exchanging data and acknowledgement packets back and forth like so:

Device: data
Host: ACK
Host: reply
Device: ACK

But sometimes, packets might come in asynchronously like this:

Device: data #1
Device: data #2
Host: ACK #1
...

I want to have an API that will abstract away all the details of USB and have the program just work with the actual data and not have to worry about packet headers or acknowledging packets or anything like that. Ideally, there will be a write_to_device function that blocks until the device acknowledges the packet, a read_from_device that will block until a packet is received and a is_data_available function that returns immediately whether there is any data on the queue.

I’m thinking of running a separate thread that handles USB events. This thread will handle all the data encapsulation and acknowledging.

When a packet comes in, the processing thread will send an ACK packet then extract and write the raw data into a pipe. The read_from_device function (called from the main thread) will simply read from this pipe and naturally block until there is data. But if I use this scheme, I won’t have a clean way of implementing a is_data_available function – there’s no way to check if there is data in a pipe without reading it.

Something like this:

[ Main thread    ][ Processing thread   ]
| Read from pipe ||                     |
|                || USB packet comes in |
|                || Send ACK packet     |
|                || Extract data        |
|                || Write data to pipe  |
| Read succeeds  ||                     |
| Return data    ||                     |

The real issue is implementing a write_to_device function.

[ Main thread                ][ Processing thread      ]
| Somehow signal write       ||                        |
| Wait for write to complete ||                        |
|                            || Send the data          |
|                            || Wait for ACK packet    |
|                            || Somehow signal that write completed
| Return                     ||                        |

How can I cleanly implement a way to send the packet, wait for an acknowledgement packet then return?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T20:38:55+00:00Added an answer on June 16, 2026 at 8:38 pm

    I would suggest that you create a custom pipe class or structure or something. For that, you define a write method, which also holds waits for a semaphore to trigger. If you’re on linux, sem_wait (from the semaphore function family, sem_*) is what you want to look at.

    The write function would then write the data to the FIFO and wait for the semaphore to be flagged. However, how does the writing thread know when all the data arrived through the pipe you wanted to send? If the thread has to read blockingly, problems can occur here.

    So I suggest that you use a microformat inside the pipe from the main thread to the processing thread, sending an integer size which defines how many bytes you are going to write. The processing thread will then read that amount of bytes, forward it to the device and flag the semaphore as soon as all data is flagged. The write function will wait for the semaphore, thus non-busy blocking until the processing thread finished.

    This is how a custom pipe struct and the outlined write function could be drafted:

    #include <stdlib.h>
    #include <unistd.h>
    #include <semaphore.h>
    
    typedef struct {
        int write_to_pipe, read_from_pipe;
        sem_t *write_sem;
    } MyPipe;
    
    MyPipe *pipe_new() {
        int fds[2];
        if (pipe(fds)) {
            // handle error here
            return NULL;
        }
    
        sem_t *sem = NULL;
        if (sem_init(sem, 0, 0)) {
            // handle error here
            close(fds[0]);
            close(fds[1]);
            return NULL;
        }
    
        MyPipe *result = malloc(sizeof(MyPipe));
        result->write_to_pipe = fds[1];
        result->read_from_pipe = fds[0];
        result->write_sem = sem;
        return result;
    }
    
    void pipe_write(MyPipe *pipe, const unsigned char *buf, const int size) {
        write(pipe->write_to_pipe, &size, sizeof(int));
        write(pipe->write_to_pipe, buf, size);
        sem_wait(pipe->write_sem);
    }
    

    The processing thread would know the MyPipe instance and read from read_from_pipe whenever it desires. It first reads the amount of bytes the main thread wrote to the pipe and afterwards all the bytes an arbitrary chunks. After all data has been sent to the device and was ACK’d by it, it can sem_post the semaphore, so that pipe_write will return.

    Optionally, one can add another semaphore, which pipe_write posts to make the processing thread only read data when there actually is data available.

    Disclaimer: Have not tested the code, only checked that it compiles. Needs to be built with -pthread, to have sem_* available.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a D-Link DWM-156 3G USB modem that I want to send AT-commands
I want to write an app that receive data from RS232(sometimes using usb connector)
I have developed a USB device that communicates with linux over a simple but
I have a USB device that I'm attempting to communicate to with my Android
I have installed usb driver, selected the android device's debugging mode but i can't
I have 3 usb devices (barcode scanner, same model) I want to do an
Couple of quick questions. I have a DMX king USB lighting controller that I'm
I'm building a thingy that will have a usb interface, I'm pretty keen on
I am trying to read data from a HID device. I have a USB
I am doing some experimenting with robotics and have a USB servo controller that

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.