Marcus Barnet
Marcus Barnet

Reputation: 2103

How to unplug a USB device under Ubuntu and C/C++ without rebooting

I'm using a C program with termios to exchange information and commands between my pc with Ubuntu and a USB motor controller.

It works great and i'm able to successfully send messages over the serial port; however, sometimes it happens that if i close the program in the wrong way or something else happens, i'm not able any more to reconnect to my usb device.

To be able to connect again to the device, i have to reboot my pc and start again ubuntu.

I'd like to avoid this problem and to find a solution to enable again the usb port without have to reboot my system each time.

At the first time, i tried to kill all the processes (sudo killall -9 program_name) that were using the usb port, but the port still remains blocked and i have to reboot it.

Can you suggest me some solutions to avoid the reboot, please? And why it happens?

I connect to the usb port (/dev/ttyACM0) in this way:

handle = open(port.c_str(), O_RDWR |O_NOCTTY | O_NDELAY);

    if(handle == RQ_INVALID_HANDLE)

    {

        cout<<"failed."<<endl;

        return RQ_ERR_OPEN_PORT;

    }

Upvotes: 2

Views: 1079

Answers (1)

Benjamin Maurer
Benjamin Maurer

Reputation: 3753

To avoid making your USB-Controller unusable, you can harden your program to better deal with program termination.

Create a routine, that does your cleaning up, i.e., closing the USB connection. Let's call it void cleanup(void) {}

You can use the atexit function from stdlib.h to register a function, that will be called when the program terminates normally. That means through either exit or return in main. See atexit man page E.g.: int res = atexit(cleanup);

For cases, where your program is terminated irregularly, like through a signal (e.g., SIGINT when you hit Ctrl+c), you have to implement signal handlers to deal with this. Basically you can create one signal handler function, that only calls your cleanup routine and register it to all the signals you want to deal with. More details on how to do that: signal handler tutorial

If your program was terminated in a way, that can not be handled, e.g., with SIGKILL, you'll either have to reboot or look at the methods in the post that pmg has linked to in his comment - they look promising.

Upvotes: 3

Related Questions