• Announcements

    • bluehash

      Forum Upgrade   03/11/2017

      Hello Everyone, Thanks for being patient while the forums were being fixed and upgraded. Please see details and report issues in this thread. Thanks!
Sign in to follow this  
Followers 0
yyrkoon

Error recovery in C

5 posts in this topic

So, I'm not even sure what to call this - So I titled this post the best I could.

 

Here goes . . . developing an application running Linux, and with a myriad of *possible* devices / device names. I'm trying to figure out how to best, programmatically attempt to use a device that may / may not exist.

 

In my case this is in relation to socketcan, and virtual / physical devices. "vcanx", "can0", and "can1" are all possibilities. execv() run with lsmod did come to mind, but I'm not sure if that is a safe way to determine which device to use. Not to mention, what *if* multiple devices ?

 

Attempting to initialize a socket on a device that does not exist will yield a "device does not exist" error. Then I think I could easily create an if/ if else, else block to deal with a simple "there can only be one" device solution. But is this ideal ? Or is this what assert() is meant for ?

 

For multiple devices on the same system, the above probably would not work very well. Especially if different types of socketcan networks exist. Or is there something else I am not considering ?

 

Currently, I'm using a command line option to do this right now. However, I have no option ( *argv[] ) checking. Which I know is a bad idea in production code. But when thinking how to test for what is valid, and what is not. The above questions came to mind. Also, what about the posibility of things I have not considered due to lack of knowledge / experience.

 

As usual any / all comments welcome.

Share this post


Link to post
Share on other sites

Given that Linux maps everything into a file, couldn't you use opendir() and readdir() on /dev to determine what devices exist? Then only try to talk to devices that show up in there.

 

Of course you still need some error handling logic to react to communication errors.

Share this post


Link to post
Share on other sites

Given that Linux maps everything into a file, couldn't you use opendir() and readdir() on /dev to determine what devices exist? Then only try to talk to devices that show up in there.

 

Of course you still need some error handling logic to react to communication errors.

 

Yeah, I thought of that. The problem with this approach, is that /dev/<can device> does not exist. Nor does /dev/net/<can device>. Maybe the device does show somewhere in the /dev/ structure, but if it does, I can not locate it.

 

So what I have so far, and this is really simplistic . . .

int main ( int argc, char *argv[])
{    
    if(argc != 3)
        exit(1);

    /* Simple argv check for device name - Intentional lack of error msg */
    const char *dev = argv[1];
    if((strcmp(dev, "vcan0") != 0) && strcmp(dev, "can0") != 0 && strcmp(dev, "can1") != 0)
        exit(1);

    const int s = init_can(dev);

    . . .

     return 0;
}

Passed that, when attempting to use init_can() with an improper device will cause a trapped exception, which I do deal with. Anyway, this will work, but it is very simplistic. On a beaglebone black, this will work fine. But when testing on x86 / x86-64 - You can create just about any virtual CAN device that you like. Within reason of course. So, I always use vcan0, but what if there is need by someone else to use another virtual CAN device ? Not that I expect anyone else to be using this code, but eventually it will be on github . . .

 

EDIT:

 

Oh, and argv[2] is an integer which I use atoi() to get out of the arg string value. Not quite sure how to deal with that either. As the integer could arguably be 0-65535. But is based on how many XanBus devices are on a CANBus network. e.g. source ID.

Share this post


Link to post
Share on other sites

You wish to search for CAN ports available on a system and have the user choose them, correct?

Normally for serial interfaces you can do a search for tty interfaces( you may know this) as list those with device drivers:

The /sys/class/tty dir contains all TTY devices but you might want to exclude those pesky virtual terminals and pseudo terminals. I suggest you examine only those which have a device/driver entry:

via: http://stackoverflow.com/a/9914339/1364349

 

Your issue is that there is none for CAN.hmmm..

Maybe do the simple CAN0/1/2/ search first. As more people start using the application, you can add up the prefixes in your code later.

 

Does this app have a front end? Maybe let the user specify the CAN port, rather the app taking over and selecting a wrong one.

Share this post


Link to post
Share on other sites

@@bluehash @@chicken

 

So . . .

 

Beaglebone black

william@xanbustester:~$ sudo find / -name can0
 /sys/devices/platform/ocp/481d0000.can/net/can0
 /sys/class/net/can0
 /proc/irq/182/can0
 /proc/sys/net/ipv4/conf/can0
 /proc/sys/net/ipv4/neigh/can0

i386 virtual machine

william@debian-can:~$ sudo find / -name vcan0
/sys/devices/virtual/net/vcan0
/sys/class/net/vcan0
/proc/sys/net/ipv4/neigh/vcan0
/proc/sys/net/ipv4/conf/vcan0

So now the question becomes - Which directory / file to test ? /proc/sys/net/ipv4/conf/ seems to me to be the most consistent. But can you stat a virtual file system ? Hmmmm. Well I suppose they both have /sys/class/net too.

 

@@bluehash

 

So the front end is currently a web browser, html, with some javascript( needed for websockets ). But really so far nothing for configuration. Right now it displays onl a few things - For visual feedback as I develop. Ideally, I'd like this set of executables to run automatically on the beaglebone black, and the user just navigates to the beaglebone IP address. That part, I really have not thought about much, except that I may wish at some point to "subscribe" to various canid's / PGN's from the webpage. Perhaps drop down combo boxes.

 

So . . .I need to give this some more thought. Using stat on a directory structure may be too complex, but also could be very complete too.

 

As for the rest, I may end up implementing a config file too on the binary application side of things. But still not convinced this would be the proper way to go about configuring the socketcan interface. As right now, I have an executable that is a process manager. Each PGN has it's own executable. Then each PGN executable takes 2 cmd line arguments. Interface, and source ID. This post came about, because I was concerned about potential stackoverfow for improperly handled cmd line arguments.

 

So I think if I handle interface names automatically - This would be ideal. Still I have one more cmd argument to deal with. Source id. Short of just tracking all source ID's per PGN executable( which really  also is not ideal ) I do not know how to do that automatically.

 

Example. a source ID is given to each device on a XanBus network. We have 4 devices on our XanBus network. Some ID's transmit some PGN's more than others, while some id's do not transmit some PGN's at all. So, ideally it is best with my current model to use source ID's as a parameter for the various PGN executables. Now the reason why I'm using separate executables for each PGN is that I can use a separate socket for each PGN and source ID. This makes the application in whole faster, and also gives me the option of opting in, or out of various PGN's / source ID's.

 

Thoughts ?

 

EDIT:

 

Ah . . . But using the directory structure for can interfaces still could be a problem where multiple canbus devices might be on a single system . . .hmmm

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0