protobuf-c, also available for embedded platforms!

What is protobuf-c

The previous article: "Protobuf: A Smaller, Faster, and More Efficient Protocol" introduced protobuf and protobuf-c in detail. Here is a brief mention:

Protocol Buffers, Is a data format developed by Google, similar to XML, which can serialize structured data and can be used for data storage, communication protocols, etc. protobuf supports some mainstream languages, but does not support C, so the third-party protobuf-c was born.

The previous article introduced the installation and use of protobuf and protobuf-c on the PC platform. In this note, we will use it on our embedded ARM platform.

Cross compile protobuf-c

In the previous article, we have installed protobuf and protobuf-c in our PC environment:

Let's briefly review the general content of our last article:

From this, we know that the main function of protobuf here is to generate the protoc tool, and the function of the protoc tool is to generate the corresponding C source and header files from the .proto file. This process is platform-independent, so we can continue to use it here.

And protobuf-c generates the dynamic library needed for compilation, here we need to compile the dynamic library of the ARM architecture. That is, what we need to do in this note is:

(1) Cross compile protobuf-c

First use the make cleancommand in the protobuf-c directory to clear the things we compiled before:

Enter the following command to generate a cross-compiled Makefile:

Swipe left and right to view all codes >>>

./configure --host=arm-linux-gnueabihf CC=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-gcc CXX=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-g++ --disable-protoc --prefix=$PWD/tmp

This command seems very long, but it is not difficult, just add a few configuration parameters. What do you think about these configuration parameters? We can enter the ./configure --helpcommand to view the supported configurations:

Let's analyze the long command above in turn:

  • --host=arm-linux-gnueabihf: indicates the environment in which our final executable file runs.

  • CC=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-gcc: This is to specify our cross-compilation tool arm-linux-gnueabihf-gcc, and give it directly here The absolute path.

  • CXX=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-g++: This is to specify our cross-compilation tool arm-linux-gnueabihf-g++, here we give it directly The absolute path.

  • --disable-protoc: Do not use protoc. We also said that the process of generating the corresponding C source and header files from the .proto file by the protoc tool is platform-independent, so there is no need to use it here, unless we want to develop Protoc is used on the board, but this increases the trouble. It is not recommended to use it directly on the development board.

  • --prefix=$PWD/tmp: Specify the installation path. Indicates that the installation path is in the tmp folder under the current path.

After executing this command, you will get the cross-compiled Makefile, and then enter the following commands to compile and install:

make
make install

At this time, the relevant library files of the arm version are generated in the tmp folder of the current directory:

Among them, our most important is libprotobuf-c.sothis dynamic library. We can use the file or readelf tool to check whether it is in arm format:

Obviously, this is the dynamic library of our ARM platform. Related articles about the use of readelf: "A simple understanding of ELF files"

Let's start our demo demonstration:

(2) protobuf-c example demonstration

We customize one .prototo create our protocol data, and then use protoc-c工具compilation to generate C code. There are two files: a header file and a source file.

For example, we create a student.protofile:

syntax = "proto2";
 
message Student
{
    required string name    = 1;
    required uint32 num     = 2;
    required uint32 c_score = 3;
}

Use protoc-c工具tools to compile student.protofiles:

protoc --c_out=. student.proto

Write our student.c test demo:

Swipe left and right to view all codes >>>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student.pb-c.h"
 
int main(void)
{
    Student pack_stu = {0};
    uint8_t buffer[512] = {0};
    Student *unpack_stu = NULL;
    size_t len = 0;
 
    student__init(&pack_stu);
 
    /* 组包 */
    pack_stu.name = "ZhengN";
    pack_stu.num = 88;
    pack_stu.c_score = 90;
    len = student__pack(&pack_stu, buffer);
    printf("len = %ld\n",len);
 
    /* 解包 */
    unpack_stu = student__unpack(NULL, len, buffer);
    printf("unpack_stu.name = %s\n", unpack_stu->name);
    printf("unpack_stu.num = %d\n", unpack_stu->num);
    printf("unpack_stu.c_score = %d\n", unpack_stu->c_score);
 
    student__free_unpacked(unpack_stu, NULL);
    return 0;
}

The demo is very simple. Packing is to construct a protocol data structure, calling the pack grouping interface to throw data into the buffer; unpacking is just the other way around, taking data from the buffer and putting it into the structure.

The files of our project at this time are:

Cross compilation:

Swipe left and right to view all codes >>>

arm-linux-gnueabihf-gcc student.c student.pb-c.c -o student -I /home/book/git_clone/protobuf-c/tmp/include -L /home/book/git_clone/protobuf-c/tmp/lib -lprotobuf-c

This command also seems to be very long, but it is actually very simple:

  • arm-linux-gnueabihf-gcc: cross compiler.

  • student.c student.pb-cc: input source file.

  • student: The generated executable file.

  • -I /home/book/git_clone/protobuf-c/tmp/include: Specify the header file path.

  • -L /home/book/git_clone/protobuf-c/tmp/lib: Specify the library path.

  • -lprotobuf-c: Link the dynamic library libprotobuf-c.so.

What needs to be mentioned here is that we can copy the files in tmp/include we compiled above to our cross compiler header file search path, and copy the files in tmp/lib to the cross compiler library file search path. This way we don't need to specify such a long string of paths.

But in order to keep the originality of my cross-compiler, I will not add anything to it. For more detailed content about these links and dynamic libraries, you can read previous articles: "Static Link and Dynamic Link Supplement (Linux)" , "What is Dynamic Link and Static Link?

If the compilation is OK, we can generate our executable student student:

Similarly, we can look at the running environment of the student executable file:

It can be seen that it can run on our arm development board.

Next, copy the student to our development board and run it. I am using the IMX6ULL development board of Teacher Wei Dongshan here.

The following error occurred during operation:

This is because the shared library file libprotobuf-c.so1 cannot be found, and the loading fails. We have explained this problem in detail in the article "Static Link and Dynamic Link Supplement (Linux)" .

There are two solutions: the first is to copy the library file to the default search path of the system library; the first is to add the current path to the search path of the dynamic library.

Here we choose the second method: we also upload libprotobuf-c.so and libprotobuf-c.so1 to the board and put them in the same directory as the student. Then enter the following command to add the current path to the search path of the dynamic library:

export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

Then run:

Run successfully!

The above is the use of the protobuf-c we introduced on the embedded Linux platform (if you are learning a single-chip microcomputer, you can also try to transplant it.) If there are errors, please point out, thank you. In addition,

According to the steps in the above two articles, there is a high probability of success. The key is to have patience.

Experience sharing: In learning Linux, we are often hindered by the development environment. Often follow other people's methods and steps, but can't do it, and it's easy to collapse. This is all normal. Because the environment is different, sometimes various dependencies are needed. But we must have enough patience, see what happens!

Before that, I also encountered a lot of problems and searched a lot of blog posts, either not working or writing too messy. So take advantage of this to learn and write an article.

This article is probably the first article on the entire network about cross-compilation of protobuf-c on the embedded Linux platform, the most complete steps, and the most explanations. If the article is helpful to you, please forward it, thank you everyone.


1. If you understand the error frame and missed detection of CAN, the car factory can't perfuse you!

2. Gartner releases important strategic technology trends in 2021!

3. When designing the circuit, what stupid things cry our youth...

4. What is the difference between Linux x86 and ARM?

5. Explore several issues in the STM32 startup file~

6. Famous companies that use Rust in production and their reasons for choosing!

Disclaimer: This article is reproduced online, and the copyright belongs to the original author. If you are involved in the copyright of the work, please contact us, we will confirm the copyright based on the copyright certification materials you provide and pay the author's remuneration or delete the content.

Guess you like

Origin blog.csdn.net/DP29syM41zyGndVF/article/details/110943882