Thread: Data handling and structure advice for Embedded C UAV project

  1. #1
    Registered User
    Join Date
    Apr 2014
    Posts
    3

    Data handling and structure advice for Embedded C UAV project

    Good day all

    I was wanting some advice on data handling for a UAV project I am trying. My background is in Microcontrollers but I have never had exposure to "sound" programming practice, so please be forgiving :P

    I have got 2 microcontrollers to drive a UAV craft I've made. One "firmware" micro collects all the sensor data and then passes it to the other "application" micro for control processing. Once decisions have been made this is sent back to the "firmware" micro so that actions are taken.

    So in essence I am sharing a raw data chunk periodically between the 2 processors that has outputs and feedback data. For the moment this is captured as one big buffer array on either micro after receiving. For easier structure I thought of bouncing this buffer that contains all sensor information and control variables between the 2 processors (visualize a ping pong game with all the possible variables from both micros - bandwidth between the micros is not a limitation) There are quite a few modules that want to access information from this buffer and write control actions back to it.

    I was thinking of constructing a struct on both micros to access this "raw data" from the buffer and set it up with variable names so that it is easier for functions to read info and write controls back.

    But this would mean that the data is accessible to every function, and there is the fear that some functions will write to the input data or write to control variables that they should not have access to. I also need to reduce memory copies and the like due to limited memory on each micro.

    Apologies for the verbose description. I would like to get a discussion going. Any feedback and suggestions would be greatly appreciated

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    It sounds like you just want to create a struct (or two) in your code. If you're already successfully reading bytes, storing them in the buffer, and processing them, then you're halfway there.

    But this would mean that the data is accessible to every function, and there is the fear that some functions will write to the input data or write to control variables that they should not have access to.
    Not necessarily - simply avoid making the struct global. The structure can be declared in "main()" and a pointer to it passed to functions that read or manipulate it.

    I also need to reduce memory copies and the like due to limited memory on each micro.
    Again, you can pass a pointer to the struct to the functions of interest, so that local copies of that structure won't be created. If you're only reading from, and not modifying, the structure, then declare the struct pointer as "const" in the arguments to those functions. This should make the compiler throw warnings if you accidentally modify something you're not supposed to.

    When you finish receiving a string of data, pass the buffer and a struct pointer to a function that parses the data in the buffer and updates the corresponding struct members. Now you can pass this structure around as you see fit, and perform the necessary calculations. You can either store the results in other members of the same structure, or create a second structure that contains "response" data.

    When calculations are complete, pass a pointer to the structure (or the second "response" struct) and the buffer to another function that extracts data from the struct and builds the response string in the buffer. Now you can transmit the buffer, which contains the response string. And now you're done - just repeat this process every time you receive a new string of data.

    If you don't expect more than one string of data at a time, then you can use the same buffer for reception and transmission (which will reduce memory usage). If you have some sort of data queue, you would be better off making separate transmit and receive buffers.

    Here is a bit of sample code that illustrates the point - note the actual implementation details are not covered (for instance, the logic that is responsible for detecting received input and acting accordingly). This is just to show how such code might roughly look.

    Code:
    struct control_s
    {
        unsigned char var1;
        unsigned char var2;
        unsigned char var3;
    };
    
    void control_initialize(struct control_s *control);
    void buffer_receive(char *buffer);
    void control_set(char *buffer, struct control_s *control);
    void control_calculate(struct control_s *control);
    void buffer_update(char *buffer, struct control_s *control);
    void buffer_transmit(const char *buffer);
    
    void main(void)
    {
        // declare variables
        char buffer[SIZE] = {0};
        struct control_s control;
    
        // initialize control structure
        control_initialize(&control);
    
        // main loop
        while(1)
        {
            buffer_receive(buffer);  // when data is received, call this
                                     // function to read all data and store
                                     // in your buffer
    
            control_set(buffer, &control);   // this function takes the received
                                             // buffer and stores the data into the
                                             // appropriate control struct members
    
            control_calculate(&control);  // this function uses control data received
                                          // from the buffer to calculate other values
                                          // in the control structure (optionally, two
                                          // structures can be used; one for received data,
                                          // another for results to be transmitted)
            
            buffer_update(buffer, &control);  // this function takes the results to be
                                              // transmitted, and updates the buffer
                                              // accordingly so that it can be sent
            
            buffer_transmit(buffer);  // this function now transmits the string of bytes
                                      // that is the expected response
            
        }
    
        // end of program
    }

  3. #3
    Registered User
    Join Date
    Apr 2014
    Posts
    3
    Thank you kindly Matticus!

    I think I will separate the send and receive data into two different structs, and then pass Struct members to each function that will use that information eg.

    control_calculate(&control.var1);

    Would changing the function declaration to voidcontrol_calculate(structcontrol_s *control.var1); allow this sort of passing information?

    Thanks for the help! Structs are a bit new to me still.

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I strongly suggest you do some reading and practice with structures before implementing them in your code. Practicing with console programs is a good idea, in my opinion. This lets you quickly and easily write test code and simply print results to the screen, which will make the learning part easier.

    Tutorials are okay (such as here), though nothing beats a good book.

    Structures are pretty easy once you get the hang of them. Struct pointers also have a "short hand" notation you should get used to (see "Example 3" here).

    control_calculate(&control.var1);

    Would changing the function declaration to voidcontrol_calculate(structcontrol_s *control.var1); allow this sort of passing information?
    If instead of passing the whole struct, you just want to pass one member, then just declare the function to receive a variable of that data type.

    Code:
    void control_calculate(unsigned char *var1);
    As long as you're dealing with a single member of a structure, that function does not need to know that the struct even exists.

  5. #5
    Registered User
    Join Date
    Apr 2014
    Posts
    3
    Thanks again Matticus,

    Your advice has been really helpful.

    Happy coding!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pages handling in a embedded source
    By Massimo Moltoni in forum C Programming
    Replies: 1
    Last Post: 07-09-2013, 06:51 AM
  2. Need Advice on File Handling
    By Gaurav Singh in forum C Programming
    Replies: 3
    Last Post: 10-24-2011, 11:14 PM
  3. what to do in a data structure project c++
    By MyRedz in forum C++ Programming
    Replies: 0
    Last Post: 12-22-2009, 02:45 AM
  4. advice on a data structure
    By ventolin in forum C++ Programming
    Replies: 7
    Last Post: 03-23-2004, 10:34 PM
  5. Window priority handling for a GUI - data structure
    By rmullen3 in forum C++ Programming
    Replies: 0
    Last Post: 04-15-2003, 07:06 PM

Tags for this Thread