creating socket based rt component

More
27 Sep 2016 12:42 #80990 by wn007
I have been using Linux CNC for a couple of years now with great success. I am currently attempting to use halcompile to create an RT Component. The only job this component has is to receive a trigger and then read/request data from a socket. I can get it to compile and it does "see" the declared HAL Pins of the component. It just does not respond. I have placed printf statements within the code and nothing shows up in the terminal when running linuxcnc from the command line. I think it has to do with the initialization or permissions?

Not sure how to init, other than using the EXTRA_SETUP option?

I will be posting the code shortly.
More
27 Sep 2016 12:54 #80992 by andypugh
The simplest and easiest explanation for this would be if the component has not been added to a thread.

Unless you are sure that the socket data request is thread-safe and will never wait you might be better off writing your component as a user-space rather than realtime component.
The following user(s) said Thank You: wn007
More
27 Sep 2016 13:15 #80998 by wn007
Here is the code. I really would like to get this working. I have already written and tested with a python based HAL userspace component. The issue is the trigger timing is hit and miss at the feed rate I am using. Sometimes it misses trigger points. I can say that the data is returned within 50 to 100 milliseconds after the trigger. So not sure if that qualifies as thread safe or if there is another way to achieve the same result using RT.



component rtTelnet;
pin in bit trigger_;
pin out float xOffset_;
pin out bit hardTrigger_;

function _;
option extra_setup;
license "GPL"; // indicates GPL v2 or later
;;

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int n, sock,sock2, len;
char buf[50000];
struct sockaddr_in cmts;
struct sockaddr_in server;
char *user = "user1\r\n";
char *pwd = "123\r\n";
char *cmd = "trigger\r\n";
char buffer[256];

EXTRA_SETUP()
{



cmts.sin_family = AF_INET;
cmts.sin_port = htons( 23 );
cmts.sin_addr.s_addr = inet_addr("192.168.2.5");


sock = socket( AF_INET, SOCK_STREAM, 0 );

if ( sock < 0 ) {
perror("Socket creation error!");
exit (EXIT_FAILURE);
}

if ( connect( sock, (struct sockaddr *) &cmts, sizeof( cmts ) ) < 0 ) {
perror("Connect process error!");
exit (EXIT_FAILURE);
}

server.sin_family = AF_INET;
server.sin_port = htons( 20000 );
server.sin_addr.s_addr = inet_addr("192.168.2.5");


sock2 = socket( AF_INET, SOCK_STREAM, 0 );

if ( sock2 < 0 ) {
perror("Socket creation error!");
exit (EXIT_FAILURE);
}

if ( connect( sock2, (struct sockaddr *) &server, sizeof( server ) ) < 0 ) {
perror("Connect to server process error!");
exit (EXIT_FAILURE);
}

n = read(sock,buffer,255);
bzero(buffer,256);

len = strlen(user);
n = send(sock, user, len, 0);
n = read(sock,buffer,255);
bzero(buffer,256);

len = strlen(pwd);
n = send(sock, pwd, len, 0);
n = read(sock,buffer,255);

printf("rtTelnet Init ok...");
return(0);
}


FUNCTION(_) {



if(trigger_){

hardTrigger_ = true;

bzero(buffer,256);

len = strlen(cmd);
n = send(sock, cmd, len, 0);
printf("Trigger sent...");

}


}
More
27 Sep 2016 13:38 #81000 by andypugh
50mS is _way_ too long for a component that is called every 1mS.

What you will need to do is write the code so that every time it is called it basically asks "has the data come in yet" and immediately exits if the answer is "no"

You may not see the result of "printf" in the realtime code. Realtime components can only print to the kernel log (if you are using RTAI rather than uspace).

You should try to only use functions from rtapi. (including rtapi_print)
linuxcnc.org/docs/2.7/html/man/man3/rtapi_print.3rtapi.html

The list of rtapi_* commands is near the bottom of here:
linuxcnc.org/docs/2.7/html/
More
27 Sep 2016 15:09 #81003 by wn007
I am using the PREEMPT-RT version of linuxcnc. I stripped down my code to the basics and like you said earlier it does not look as though is is being added to a thread. I can see the new component in the Hal Config within Axis. Is there something I am missing in the code as far as initializing or something else?

Thanks again for your replies.
More
27 Sep 2016 15:17 #81004 by andypugh
You need the "addf" in the HAL file.
More
27 Sep 2016 15:17 #81005 by wn007
Figured it out. I did forget to add to the servo thread :lol: . Thanks for the advice on how to write the code so it is thread safe.
Time to create page: 0.815 seconds
Powered by Kunena Forum