How to use linux library to interface with hardware

In summary, the conversation discusses the need for a system to program a complex frequency synthesizer IC, where software executes an algorithm to calculate the values needed to program the device. The desired algorithm should be contained in an independent file that can be easily replaced without recompiling the application. It is mentioned that shared libraries (similar to DLLs in Windows) are used in Linux for this purpose, but the implementation details are still unclear. Further clarification is needed on the transformation algorithm, how the values are loaded into the device, and the existing programs that handle these tasks. It is suggested to use .so files for dynamic linking in Linux, but it is also possible to compile separate object files and link them together to avoid recompiling the entire application
  • #1
the_emi_guy
766
79
We have a system that requires software to program a fairly complex frequency synthesizer IC. Given the desired frequency, software executes an algorithm to calculate the values needed to be programmed into the physical device. We would like to have this algorithm contained in an independent file so that any change to the algorithm only requires replacing this file without requiring the application to be recompiled. I understand that the input/output interface must not change. I believe this is what DLLs do in Windows. What would the equivalent way to do this in Linux?
 
Technology news on Phys.org
  • #3
DLL's are compiled code, they just aren't complete programs, rather chunks that fit into other programs (or other DLL's).

You may run across unrelated homacronyms 'Delay Locked Loops' and possibly (though not probably in your application) 'Data Link Layer', neither of which have anything to do with Dynamic Link Libraries.
 
  • #4
Thanks,
I understand conceptually what these are, I am looking for an example of how it is actually implemented.
I have c-code already that takes frequency as input and creates a table of address/data to be written to the hardware. How would I compile this code to have it become a library, and how would I write the code in the app to use it. An example would be great.
 
  • #5
Plenty of Google hits and YouTube vids. "How do I use a dll in Linux".

Building a hardware synth ?
 
  • #6
I did some Googling, seems that in Linux world .so (shared object) is similar to the Windows .dll, but its unclear to me if they are dynamically linked. Should I used .dll or .so? Just want to get headed in right direction before I spend time digging into the dirty details. (Yes, hardware synth).
 
  • #7
I think this is an example of a XY Problem: I am not sure that the answer you need has anything to do with DLLs or shared objects.

Can we clarify some things - please correct any errors and answer these questions:
  1. Given input data (the desired frequency)
    1. Program A should transform the input data into values for loading into a device
    2. Program A should [do what?] with the values for loading into the device
  2. The transformation algorithm used by Program A
    1. should be replaceable at run time
    2. is an an example of the algorithm known?
    3. has the example algorithm been implemented? In what form?
  3. How do the values get loaded into the device?
    1. Is this part of Program A?
  4. Does Program A already exist?
    1. In what form?
    2. How does it currently create the values for loading into the device?
    3. What does it do with the values?
  5. Does the program for loading the data to the device exist?
    1. In what form?
    2. How does it load the data to the device?
The reason I ask all of these questions is that the way these things are often implemented is like this:

Program A is written in a scripting language (e.g. Python) and transforms the input data into a output file in some common text format (e.g. JSON).

Program B is entirely independent of Program A. It transforms the output file from Program A into whatever hardware protocol is required to program the device. Program B is often provided by the manufacturer of the device as an executable object file, or perhaps C(++) source code.

If this is the case then Program A and Program B operate independently and in series, there is no need to dynamically link them for two-way interaction at all.
 
  • #8
Thanks for the detailed response. I like the simplicity of using a file to communicate the data back to the calling program, but I am thinking it would be too slow, the algorithm is called at relatively high speed. Program A is currently implemented in C and is part of program B. I would like to pull it out into its own file, but not degrade performance too much.
1 - Program A accepts frequency as input, and outputs list of address/data to program B. The manner of returning the data is one of the things I am unsure about (pointer?).
2 - Program A should be a file that can be simply replaced in the file structure without any change required to program B. I assume that is what "replaceable at run time" means.
Program A is already written in C. It has already been embedded into program B (which is C++) but would like to pull it out so that it can be easily updated without full application (program B) rebuild.
3 - Program B handles physically programming the device.
4 - Program A is already written in C. It simply runs a series of calculations to generate address/data values that program B will use to program hardware.
5 - Loading data to the device is not a concern.
 
Last edited:
  • #9
the_emi_guy said:
I did some Googling, seems that in Linux world .so (shared object) is similar to the Windows .dll, but its unclear to me if they are dynamically linked. Should I used .dll or .so? Just want to get headed in right direction before I spend time digging into the dirty details. (Yes, hardware synth).

.so files are dynamically linked in Linux.

That said it's unclear from what you've written if dynamically-linked libraries are what you really need. If the problem is simply that "B" takes a long time to compile and you don't want to recompile it every time you make a change to "A" then you can simply compile "B" by itself to object code:
Code:
$ g++ -c B.cc
(which generates a compiled object file "B.o"). Then each time you modify the code in A.c you only recompile that and link it with B.o to make an executable:
Code:
$ gcc A.c B.o
If you're sure that a dynamically-linked library is what you want then you can compile (e.g.) A.c to a shared library (A.so) like this using GCC:
Code:
$ gcc -shared -fPIC -o A.so A.c
Then in B.cc you can use the POSIX library function dlopen() to open the library and dlsym() to load the specific functions and/or objects you want from it. You just need to make sure you include the dl library among those you link into B:
Code:
$ g++ -ldl B.cc
There's an example of how to use dlopen() and related functions in the dlopen man page. Google can no doubt turn up more details and examples.
 
  • #10
Thanks for the detailed response.
There's more to it than just the compile time of "B". Touching B triggers a whole lot of regression testing and version control hassles. I think the dynamic link lib is what I need, and what you provided looks like it will help me get started. Just curious, how does A.so typically transfer an array or structure to calling program, does the calling program pass a pointer?
 
  • #11
the_emi_guy said:
Thanks for the detailed response.
NP - and thanks for the answers.

the_emi_guy said:
I like the simplicity of using a file to communicate the data back to the calling program, but I am thinking it would be too slow, the algorithm is called at relatively high speed.
A file is just a stream so it can easily be replaced with a socket if you need more speed. How is this the case though, usually programming a device is a slow off-line process?

Anyway I think @wle has narrowed it down to the best solution:
wle said:
That said it's unclear from what you've written if dynamically-linked libraries are what you really need. If the problem is simply that "B" takes a long time to compile and you don't want to recompile it every time you make a change to "A" then you can simply compile "B" by itself to object code:
 
  • #12
wle,
Thanks for the response.
Definitely something I should consider, but I am concerned about burdening "B" with operating system calls every microsecond, we are bandwidth limited. I was hoping that the library could be done in a way that it gets loaded at runtime, then behaves more or less the same as if it were a resident part of "B" (as it is now), unless this is really complicated or unconventional.
Also, once done I need to be able to modify "A" without touching "B", even re-linking, since this would trigger lots of regression testing and configuration management hassles.
 
  • #14
Tom,
This looks like documentation for including code "A" when building code "B". I want to be able to change "A" without touching "B", like updating a Windows DLL without having to rebuild the Windows operating system.
Also, I am looking for this in Linux.
 
  • #15
the_emi_guy said:
Thanks,
I understand conceptually what these are, I am looking for an example of how it is actually implemented.
I have c-code already that takes frequency as input and creates a table of address/data to be written to the hardware. How would I compile this code to have it become a library, and how would I write the code in the app to use it. An example would be great.
Here's a reference to help you to get started: https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
 
  • #16
  • Like
Likes sysprog
  • #17
the_emi_guy said:
Thanks for the response.
Definitely something I should consider, but I am concerned about burdening "B" with operating system calls every microsecond, we are bandwidth limited. I was hoping that the library could be done in a way that it gets loaded at runtime, then behaves more or less the same as if it were a resident part of "B" (as it is now), unless this is really complicated or unconventional.

I should fix something I said in my previous post: you do not necessarily have to use dlopen() and related functions to load a shared library. You can simply link it when you compile "B", as pointed out in @sysprog's link. (B will have to include declarations and function prototypes for any variables or functions provided by A for this to work; usually you would put these in a header file which you #include in both B and A.) E.g., with GCC you could do this:
Code:
$ gcc -shared -fPIC -o libA.so A.c
$ g++ -L/folder/containing/libA -lA B.cc
After this, you can change and recompile A and B should use the new version (without needing to be recompiled or relinked) the next time you run it.

Using dlopen() and dlsym() is a bit more flexible since you can control when functions or objects are loaded from a shared library. So, e.g., you could write code in B that periodically checks if the shared library file "libA.so" has changed on disk and loads the new version if it has. This is obviously cumbersome and costly but it's unavoidable since in order to use code in a shared library it needs to be loaded from the file on disk into main memory at some point before it can be run. It is not clear from what you've written if you need this, i.e., you want to be able to change A and have B use the new version while B is still running as opposed to just the next time you run B.
the_emi_guy said:
Just curious, how does A.so typically transfer an array or structure to calling program, does the calling program pass a pointer?

Functions in B and A can transfer data to each other in the same ways you usually pass data between functions. Just, if you want A to pass a lot of data to B then space needs to be reserved for it and you need to decide whether B or A will manage this. So B could create a structure or array to contain the results and pass a pointer to it to A, or A could create the structure or array and return a pointer to it to B. In the second case, A would have to put the data somewhere that will persist after A has finished running, either in a global variable or in memory allocated with malloc() that B is responsible for later free()ing.
 
  • #18
wle: thanks for the help with this.
Definitely don't need to have B monitor for changes to A. When A is replaced with new version, system restart will be expected.
 

What is the purpose of using a linux library to interface with hardware?

The purpose of using a linux library to interface with hardware is to provide a standardized and efficient way for software applications to communicate with hardware devices. This allows for easier development and compatibility across different hardware platforms.

How do I find and install the appropriate linux library for my hardware device?

You can typically find the appropriate linux library for your hardware device by searching online for the device's name and "linux library". Many hardware manufacturers also provide their own linux libraries for their devices. Once you have found the library, you can install it using your distribution's package manager or by compiling the source code.

What are the basic steps for using a linux library to interface with hardware?

The basic steps for using a linux library to interface with hardware are:

  1. Find and install the appropriate linux library for your hardware device.
  2. Include the library in your software application's code.
  3. Open a connection to the hardware device using the library's functions.
  4. Send and receive data to and from the hardware device using the library's functions.
  5. Close the connection to the hardware device when finished.

Can I use a linux library to interface with any type of hardware device?

It depends on the library and the hardware device. Some libraries are designed to work with specific types of hardware, while others may be more general and support a wider range of devices. It is important to research and choose a library that is compatible with your specific hardware device.

Are there any special considerations or precautions when using a linux library to interface with hardware?

Yes, there are a few things to keep in mind when using a linux library to interface with hardware:

  • Make sure to carefully read the documentation for the library and follow any guidelines or requirements.
  • Handle errors and exceptions properly to ensure the stability and safety of your system.
  • Be aware of any potential conflicts or compatibility issues with other libraries or software on your system.
  • Regularly update and maintain both the library and your hardware device's drivers to ensure optimal performance.

Similar threads

Replies
6
Views
1K
  • Programming and Computer Science
Replies
29
Views
2K
  • Programming and Computer Science
Replies
7
Views
670
  • Programming and Computer Science
Replies
3
Views
1K
  • Computing and Technology
Replies
2
Views
646
  • Programming and Computer Science
Replies
29
Views
3K
  • Programming and Computer Science
Replies
21
Views
3K
Replies
2
Views
886
  • Computing and Technology
Replies
12
Views
1K
Back
Top