run a C program at startup [Red Pitaya] - c

I have a C program that needs to run when I turn on my machine (Red Pitaya).
the beginning of the program presented here:
//my_test program
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redpitaya/rp.h"
int main(int argc, char **argv){
int jj=1;
while(1) {
printf("Ready for experiment number %i\n",jj);
int i, D;
int32_t TrigDly;
and so on...
the program is executable with a run.sh file called uri_test.sh, that contains the following:
cat /opt/redpitaya/fpga/fpga_0.94.bit>/dev/xdevcfg
LD_LIBRARY_PATH=/opt/redpitaya/lib ./my_test
both files are located in a directory under /root. the program is working perfectly when run manually on PuTTY terminal-
/RedPitaya/Examples/C/Uri# ./my_test
or
/RedPitaya/Examples/C/Uri# ./uri_test.sh
I tried to follow the solution presented here :
https://askubuntu.com/questions/9853/how-can-i-make-rc-local-run-on-startup
without success.
any suggestions? Thank you.

There are several ways to have a program running at startup, and it depends upon your init subsystem (are you using systemd or a SysV-style init?).
BTW, a source program in C is not a script and you generally compile it (using gcc -Wall -Wextra -g) into some executable. In your case, you probably want to set up its rpath at build time (in particular to avoid the LD_LIBRARY_PATH madness), perhaps by passing something like -Wl,-rpath,/opt/redpitaya/lib to your linking gcc command.
Perhaps a crontab(5) entry with #reboot could be enough.
Whatever way you are starting your program at startup time, it generally is the case that its stdin, stdout, stderr streams are redirected (e.g. to /dev/null, see null(4)) or not available. So it is likely that your printf output go nowhere. You might redirect stdout in your script, and I would recommend using syslog(3) in your C program, and logger(1) in your shell script (then look also into some *.log file under /var/log/). BTW, its environment is not the same as in some interactive shell (see environ(7)...), so your program is probably failing very early (perhaps at dynamic linking time, see ld-linux.so(8), since LD_LIBRARY_PATH might not be set to what you want it to be...).
You should consider handing program arguments in your C program (perhaps with getopt_long(3)) and might perhaps have some option (e.g. --daemonize) which would call daemon(3).
You certainly should read Advanced Linux Programming or something similar.
I recommend to first be able to successfully build then run some "hello-world" like program at startup which uses syslog(3). Later on, you could improve that program to make it work with your Red Pitaya thing.

Related

How to execute a C file in notepadqq for Linux?

I'm trying to run a C file using Notepadqq in Manjaro Gnome edition, but when I try running my script by going to the Run command it opt up a windows that says Special Placeholders
enter image description here
This should be corrected fairly easily via the graphical user interface. No command or file modification should be necessary.
In Nautilus you can right click on the file to open.
I'm trying to run a C file using Notepadqq in Manjaro Gnome edition, but when I try running my script by going to the Run command it opt up a windows that says Special Placeholders enter image description here
To run a C program you need to compile it first, generate an executable and then run it as a normal system command. You cannot run it directly from Notepad++ because as such, it is not still executable. This is generally done with a program called a C compiler (which you don't mention if you have one or not) I figure that you are on a Windows computer, so the variety and availability of C compilers makes it impossible to continue giving you advice. You need to install a compiler, learn how to use it, and then you'll know how to make your C program executable in the system.
I recommend you to read a good programming book in C, like "The C Programming Language" from Brian Kernighan & Dennis Ritchie, to know how to compile a program and your operating system's manual to know how to execute a program.
Edit
Oh, sorry, you said on linux. You have to save your source file (with some name ended in .c) then compile it with something like
$ cc my_hello.c -Wall -o my_hello
where my_hello.c is the name you gave to the C source file, -Wall makes the compiler to be more verbose in explaining your C programming errors and -o my_hello specifies the compiler to output the executable command in a file called my_hello.
(I have represented the system prompt as $ and the screen cursor as _, you don't need to key those symbols) and then
$ my_hello
Hello$ _
(as you didn't end the line with \n, the next system prompt will appear next to your program's last message) to get it printed correctly, just modify your program to appear as
#include <stdio.h>
int main()
{
printf("Hello\n");
/* ^^-- insert the '\n' there */
}

How to pass run time arguments to a function in c through a shell script

I have a shell script which has to take arguments from the command line and pass it to a function in C. I tried to search but didn't find understandable solutions. Kindly help me out.
Should the arguments be passed via an option as a command in the shell script?
I have a main function like this:
int main(int argc, char *argv[])
{
if(argc>1)
{
if(!strcmp(argv[1], "ABC"))
{
}
else if(!strcmp(argv[1], "XYZ"))
{
}
}
}
How to pass the parameters ABC/XYZ from the command line through a shell script which in turn uses a makefile to compile the code?
You cannot meaningfully compare strings with == which is a pointer equality test. You could use strcmp as something like argc>1 && !strcmp(argv[1], "XYZ"). The arguments of main have certain properties, see here.
BTW, main's argc is at least 1. So your test argc==0 is never true. Generally argv[0] is the program name.
However, if you use GNU glibc (e.g. on Linux), it provides several ways for parsing program arguments.
There are conventions and habits regarding program arguments, and you'll better follow them. POSIX specifies getopt(3), but on GNU systems, getopt_long is even more handy.
Be also aware that globbing is done by the shell on Unix-like systems. See glob(7).
(On Windows, things are different, and the command line might be parsed by some startup routine à la crt0)
In practice, you'll better use some system functions for parsing program arguments. Some libraries provide a way for that, e.g. GTK has gtk_init_with_args. Otherwise, if you have it, use getopt_long ...
Look also, for inspiration, into the source code of some free software program. You'll find many of them on github or elsewhere.
How to pass the parameters ABC/XYZ from the command line through a shell script
If you compile your C++ program into an executable, e.g. /some/path/to/yourexecutable, you just have to run a command like
/some/path/to/yourexecutable ABC
and if the directory /some/path/to/ containing yourexecutable is in your PATH variable, you can simply run yourexecutable ABC. How to set that PATH variable (which you can query using echo $PATH in your Unix shell) is a different question (you could edit some shell startup file, perhaps your $HOME/.bashrc, with a source code editor such as GNU emacs, vim, gedit, etc...; you could run some export PATH=.... command with an appropriate, colon-separated, sequence of directories).
which in turn uses a makefile to compile the code?
Then you should look into that Makefile and you'll know what is the executable file.
You are using and coding on/for Linux, so you should read something about Linux programming (e.g. ALP or something newer; see also intro(2) & syscalls(2)...) and you need to understand more about operating systems (so read Operating Systems: Three Easy Pieces).
See following simple example:
$ cat foo.c
#include <stdio.h>
int main(int argc, char ** argv)
{
int i;
for (i = 0; i < argc; ++i) {
printf("[%d] %s\n", i, argv[i]);
}
return 0;
}
$ gcc foo.c
$ ./a.out foo bar
[0] ./a.out
[1] foo
[2] bar
$

Syntax error near unexpected token '('

As a beginner, I am trying to write a simple c program to learn and execute the "write" function.
I am trying to execute a simple c program simple_write.c
#include <unistd.h>
#include <stdlib.h>
int main()
{
if ((write(1, “Here is some data\n”, 18)) != 18)
write(2, “A write error has occurred on file descriptor 1\n”,46);
exit(0);
}
I also execute chmod +x simple_write.c
But when i execute ./simple_write.c, it gives me syntax error near unexpected token '('
Couldn't figure out why this happens ??
P.S: The expected output is:-
$ ./simple_write
Here is some data
$
You did
$ chmod +x simple_write.c
$ ./simple_write.c
when you should have done
$ cc simple_write.c -o simple_write
$ chmod +x simple_write # On second thought, you probably don’t need this.
$ ./simple_write
In words: compile the program to create an executable simple_write
(without .c) file, and then run that. 
What you did was attempt to execute your C source code file
as a shell script.
Notes:
The simple_write file will be a binary file. 
Do not look at it with tools meant for text files
(e.g., cat, less, or text editors such as gedit).
cc is the historical name for the C compiler. 
If you get cc: not found (or something equivalent),
try the command again with gcc (GNU C compiler). 
If that doesn’t work,
If you’re on a shared system (e.g., school or library),
ask a system administrator how to compile a C program.
If you’re on your personal computer (i.e., you’re the administrator),
you will need to install the compiler yourself (or get a friend to do it). 
There’s lots of guidance written about this; just search for it.
When you get to writing more complicated programs,
you are going to want to use
make simple_write
which has the advantages of
being able to orchestrate a multi-step build,
which is typical for complex programs, and
it knows the standard ways of compiling programs on that system
(for example, it will probably “know” whether to use cc or gcc).
And, in fact, you should be able to use the above command now. 
This may (or may not) simplify your life.
P.S. Now that this question is on Stack Overflow,
I’m allowed to talk about the programming aspect of it. 
It looks to me like it should compile, but
The first write line has more parentheses than it needs.
if (write(1, "Here is some data\n", 18) != 18)
should work.
In the second write line,
I count the string as being 48 characters long, not 46.
By the way, do you know how to make the first write fail,
so the second one will execute?  Try
./simple_write >&-
You cannot execute C source code in Linux (or other systems) directly.
C is a language that requires compilation to binary format.
You need to install C compiler (the actual procedure differs depending on your system), compile your program and only then you can execute it.
Currently it was interpreted by shell. The first two lines starting with # were ignored as comments. The third line caused a syntax error.
Ok,
I got what i was doing wrong.
These are the steps that I took to get my problem corrected:-
$ gedit simple_write.c
Write the code into this file and save it (with .c extension).
$ make simple_write
$ ./simple_write
And I got the desired output.
Thanks!!

Merging two programs in linux while preserving functionality

In Linux, is it possible to merge two binary programs into a single executable while still allowing both programs to execute?
I have several program binaries without source code and I wish to append them with my small program to display additional data for the user. Here is a small example:
prog1.c displays time information:
#include <stdio.h>
#include <time.h>
int main(){
time_t t = time(NULL);
struct tm time_stamp = *localtime(&t);
printf("Date: %d-%d-%d (mm/dd/yyyy) \n",time_stamp.tm_mon+1,time_stamp.tm_mday, time_stamp.tm_year+1900);
printf("Time: %d:%d \n", time_stamp.tm_hour, time_stamp.tm_min);
return 0;
}
prog2.c displays author info:
#include <stdio.h>
void main(){
printf("INFO: Originally developed by Jake.");
}
I wish to append prog1 with my prog2 such that calling prog1 will execute the prog2 and display author info as well. Output would look like:
Date: 11-19-2015 (mm/dd/yyyy)
Time: 11:46
INFO: Originally developed by Jake.
The idea sounds similar to self-extracting archives but have not seen a working example. Simply appending prog2 to the end of prog1 using cat, dd etc. attaches the prog2 but will not execute it.
In Linux, is it possible to merge two binary programs into a single executable while still allowing both programs to execute?
Of course that is impossible in general, and such an impossibility is not specific to Linux. AFAIK all the major OSes also have it. Read about executables, object files, ELF, linkers and Levine's book Linkers & loaders.
If you have access to the source code of both prog1 and prog2 (and you apparently don't) you might transform each of them to become a shared library, then code a wrapper which would dynamically loads one of them, e.g. with dlopen(3)
You could also change the source code to remove any potential name conflict (hence avoid having the same name defined in both), rename prog1's main to prog1_main, rename prog2's main to prog2_main, and have a simple wrapper like
extern int prog1_main(int, char**);
extern int prog2_main(int, char**);
int main(int argc, char**argv) {
if (!strcmp(basename(argv[0]), "prog1")
return prog1_main(argc, argv);
else if (!strcmp(basename(argv[0]), "prog2")
return prog2_main(argc, argv);
else { fprintf(stderr, "bad program name %s\n", argv[0]);
exit(EXIT_FAILURE); }
}
IIRC, SunOS3 did such tricks in 1987... (at that time, shared libraries did not exist as we have them today)
(Such a trick might not always work for C++, because it can have static data with constructors to be called before main, etc...)
Without source code, you might embed the binary executable of both prog1 and prog2 as data of another mixprog.c, compare argv[0] like above, and extract either prog1 or prog2 in some directory (perhaps a temporary one), then execute it (perhaps with execveat(2) on that directory). There might be both technical and legal issues with such an approach.
Alternatively, if prog2 only shows some message (which is unlikely), you might extract it with strings(1)
BTW, if both prog1 and prog2 are from your Linux distribution, they are likely to be free software, and you should work on their source code. If one of them is proprietary, be sure that its license permits you (legally) to do what you imagine.
If prog1 doesn't need to execute anymore once prog2 is launched, then you can make prog1 invoke prog2 through one function of the execv() family.
Another question with same prespective>
Yes, you can run this together, while searching for same I came up with this solution.
gcc prog1 prog2 -o prog_combined
After the execution you will get the executable file "prog_combined" in the same folder . Keep the two files in the same folder before execution.
./prog_combined
It worked for me.
In both the programs you have mentioned main functions, you can call one function as sub function to other using the command I have mentioned.

Daemon on embedded Linux device using Busybox be written in C or as a script

Should a daemon on an embedded device using Busybox be written in C or as a script?
All the examples I have seen use #! /bin/ash at the top of the file and that is for scripting? But in the device I'm writing to has only complied C files (I think) and symbolic links in /usr/bin.
Every way I try to compile a C file with #include </bin/ash> (e.g. gcc -Wall -o daemon_busybox daemon_busybox.c) I get error after error report in /bin/ash:
/bin/ash:174:1: error: stray ‘\213’ in program
/bin/ash:174:1: error: stray ‘\10’ in program
/bin/ash:174:1: error: stray ‘\273’ in program
/bin/ash:174:1: error: stray ‘\204’ in program
/bin/ash:174:1: error: stray ‘\342’ in program
Note I have set this: /bin/ash -> busybox
Any ideas which way I should go?
Update:
I've been given the task trying to see if a daemon can be run on a small device that runs Linux (2.6.35-at-alpha4) and Java (SE Embedded Runtime Environment) with very limited memory (i.e. a 10 second wait to get java -version to report back).
Two weeks ago I didn't know much about daemons — only knew the word. So, this is all new to me.
On my development machine I have built two different daemon files, one in C and one as a script. Both run very nicely on my Linux machine.
But because of the very small size of the target device there is only busybox (no /lib/lsb/init-functions). So I'm trying to build a 3rd daemon file. I believe it should be written in C for this device, but all examples for busybox point to scripting.
Once your question is edited so that the file name you're trying to #include is visible, the problem becomes self-evident:
#include </bin/ash>
This tries to make the C compiler include the binary of busybox (via the symlink /bin/ash) into the code to be compiled. The average binary is not a valid C source file; this is doomed to failure.
Perhaps you simply need to drop that line — the C compiler stands a better chance of working if it is given header files and source files to compile. Maybe there's more work needed; we don't have enough information to help there.
Many daemons are written as C programs, but a carefully written shell script could be used instead.
Personally, I would like to do this as a script (I've never liked C). But on the device everything in the /usr/sbin folder looks like a C file. So, the conservative coder in me says C is the way to go. I know: ask the guys developed the device — but they're long gone. Right now my daemon is just a test (i.e. printf("Hello World\n"); ). I'm trying to get printf passed to Busybox. But so far I cannot get this file to compile. I just need a simple daemon in C to start.
OK; your C code for that should be just:
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
return 0;
}
Save it in hw_daemon.c. Compile it using:
gcc -o hw_daemon hw_daemon.c
If that won't compile, then you've not got a workable C development environment for the target machine. If that will compile, you should be able to run it with:
./hw_daemon
and you should see the infamous 'Hello World' message appear.
If that does not work, then you can go with the script version instead, in a file hw_script.sh:
#!/bin/ash
printf "Hello World\n"
You should be able to run that with:
Predicted output — not output observed on a machine.
$ ash hw_script.sh
Hello World
$ chmod +x hw_script.sh
$ ./hw_script.sh
Hello World
$
If neither of those works at all, then you've got major problems on the system (maybe Busybox doesn't provide a printf command workalike, for example, and you need to use echo "Hello World" instead of the printf).

Resources