Mixer structure analysis [uavcan as an example] _ PHP Tutorial

Source: Internet
Author: User
Tags format definition
Mixer structure analysis [uavcan]. Mixer structure analysis [uavcan as an example] mixer commands are system app commands located in the Firmwaresrcsystemcmdsmixer directory, its function is to load valid content in the mix file to the specific device mixer structure analysis [uavcan as an example]
Mixer commands are system app commands located in the Firmware/src/systemcmds/mixer Directory. the function is to load valid content in the mix file to a specific device, then, the specific device's MixerGroups will parse these definitions.
This example uses uvacan as an example. after the system runs, the device name is/dev/uavcan/esc.
Uavcan defines MixerGroup instances and Output instances.

There are three types of MIXER: NullMixer, SimpleMixer, and MultirotorMixer.
NullMixer: Used for output channel points not grouped;
SimpleMixer: Zero or multiple inputs are combined into one output;
MultirotorMixeR: combine the inputs (ROLL, PITCH, RAW, Thrusttle) into a set of outputs based on predefined geometry.



The function used to read the mix file is located in Firmware/src/modules/systemlib/mixwr/mixer_load.c:
 
 
  1. int load_mixer_file(const char *fname, char *buf, unsigned maxlen)
The fname parameter is the position of the mix file in the system. buf is the buffer for reading file data and maxlen is the maximum length of the buf.
This function will remove the rows that match any of the following:
1. rows with a length less than 2 characters
2. the first character of a row is not a line with uppercase letters
3. the second character is not a ':' line
After the data of the illegal content is removed, all the remaining formatted content will be stored in the buf buffer.
Therefore, you must follow the mix and format when writing a mix file.
After the formatted mix content is read from the buffer
 
 
  1. int ret = ioctl(dev, MIXERIOCLOADBUF, (unsigned long)buf);
To specific devices.

Definitions of related structures:


 
 
  1. /** Simple channel scaler */
  2. Struct mixer_scaler_s {
  3. Floatnegative_scale; // negative scaling. in the MIX file, O: The Next 1st integers/10000.0f
  4. Floatpositive_scale; // forward scaling. in the MIX file, O: The Next 2nd integers/limit f
  5. Floatoffset; // Offset. in the MIX file, "O": the first integer after "/until F ".
  6. Floatmin_output; // minimum output value. in the MIX file, "O" indicates the next 4th integers/limit f.
  7. Floatmax_output; // maximum output value. in the MIX file, "O" indicates the next 5th integers/limit f.
  8. }; // This structure defines the structure of a single control.

  9. /** Mixer input */
  10. Struct mixer_control_s {
  11. Uint8_tcontrol_group;/** <group from which the input reads */
  12. Uint8_tcontrol_index;/** <index within the control group */
  13. Struct mixer_scaler_s scaler;/** <scaling applied to the input before use */
  14. }; // Define the input volume structure

  15. /** Simple mixer */
  16. Struct mixer_simple_s {
  17. Uint8_tcontrol_count;/** <number of inputs */
  18. Struct mixer_scaler_soutput_scaler;/** <scaling for the output */
  19. Struct mixer_control_scontrols [0];/** <actual size of the array is set by control_count */
  20. }; // Defines a control entity, including the number of input signals, input signal control set, and output signal control.
  21. // Because a mixer has only one output and can have 0 to multiple inputs, control_count indicates the number of input signals required by this mixer, the specific signals are stored in the array controls [0.
  22. // Output is controlled by output_scaler.
  23. // The definition of these struct can be compared with the syntax definition of the mix file.

Uavcan_main.cpp:
This file parses the buffer data mentioned above.
  1. Int UavcanNode: ioctl (file * filp, int cmd, unsigned long arg)
  2. {
  3. ...
  4. Case MIXERIOCLOADBUF :{
    Const char * buf = (const char *) arg;
    Unsignebuflen = strnlen (buf, 1024 );

    If (_ mixers = nullptr ){
    _ Mixers = new MixerGroup (control_callback, (uintptr_t) _ controls );
    }

    If (_ mixers = nullptr ){
    _ Groups_required = 0;
    Ret =-ENOMEM;

    } Else {

    Ret = _ mixers-> load_from_buf (buf, buflen); // Parse data here

    If (ret! = 0 ){
    Warnx ("mixer load failed with % d", ret );
    Delete _ mixers;
    _ Mixers = nullptr;
    _ Groups_required = 0;
    Ret =-EINVAL;

    } Else {

    _ Mixers-> groups_required (_ groups_required );
    }
    }

    Break;
    }
    ...
  5. }


 
 
  1. Int MixerGroup: load_from_buf (const char * buf, unsigned & buflen)
  2. {
  3. Int ret =-1;
  4. Const char * end = buf + buflen;

  5. /*
  6. * Loop until either we have emptied the buffer, or we have failed
  7. * Allocate something when we expected.
  8. */
  9. While (buflen> 0 ){
  10. Mixer * m = nullptr;
  11. Const char * p = end-buflen;
  12. Unsigned resid = buflen;

  13. /*
  14. * Use the next character as a hint to decide which mixer class to construct.
  15. */
  16. Switch (* p) {// first check the first letter of the row to determine the data category.
  17. Case 'Z ':
  18. M = NullMixer: from_text (p, resid );
  19. Break;

  20. Case'm ':
  21. M = SimpleMixer: from_text (_ control_cb, _ cb_handle, p, resid );
  22. Break;

  23. Case 'r ':
  24. M = MultirotorMixer: from_text (_ control_cb, _ cb_handle, p, resid );
  25. Break;

  26. Default:
  27. /* It's probably junk or whitespace, skip a byte and retry */
  28. Buflen --;
  29. Continue;
  30. }

  31. /*
  32. * If we constructed something, add it to the group.
  33. */
  34. If (m! = Nullptr ){
  35. Add_mixer (m );

  36. /* We constructed something */
  37. Ret = 0;

  38. /* Only adjust buflen if parsing was successful */
  39. Buflen = resid;
  40. Debug ("SUCCESS-buflen: % d", buflen );

  41. } Else {

  42. /*
  43. * There is data in the buffer that we expected to parse, but it didn't,
  44. * So give up for now.
  45. */
  46. Break;
  47. }
  48. }

  49. /* Nothing more in the buffer for us now */
  50. Return ret;
  51. }

The following function is used to process the definition starting with "M". the format specifies that only one number is followed by the character to specify the number of input signal sources, that is, the number of S-type numbers, the number of struct mixer_control_s associated with the struct definition.
 
 
  1. SimpleMixer *
  2. SimpleMixer: from_text (Mixer: ControlCallback control_cb, uintptr_t cb_handle, const char * buf, unsigned & buflen)
  3. {
  4. SimpleMixer * sm = nullptr;
  5. Mixer_simple_s * mixinfo = nullptr;
  6. Unsigned inputs;
  7. Int used;
  8. Const char * end = buf + buflen;

  9. /* Get the base info for the mixer */
  10. If (sscanf (buf, "M: % u % n", & inputs, & used )! = 1 ){
  11. Debug ("simple parse failed on '% s'", buf );
  12. Goto out;
  13. } // Copy M: The first value to the unsigned integer data to the variable inputs, and assign the number of processed notes to used.

  14. Buf = skipline (buf, buflen); // you can specify the next row for the buf.

  15. If (buf = nullptr ){
  16. Debug ("no line ending, line is incomplete ");
  17. Goto out;
  18. }

  19. Mixinfo = (mixer_simple_s *) malloc (MIXER_SIMPLE_SIZE (inputs ));
  20. // M: the following number is the number of the struct mixer_control_s structure. the MIXER_SIMPLE_SIZE field is sizeof (mixer_simple_s) + inputs * sizeof (mixer_control_s ),
  21. // It is a complete definition of mixer_simple_s. controls [0] has a total of inputs.

  22. If (mixinfo = nullptr ){
  23. Debug ("cocould not allocate memory for mixer info ");
  24. Goto out;
  25. }

  26. Mixinfo-> control_count = inputs; // number of input signals

  27. If (parse_output_scaler (end-buflen, buflen, mixinfo-> output_scaler )){
  28. Debug ("simple mixer parser failed parsing out scaler tag, ret: '% s'", buf );
  29. Goto out;
  30. } // This function parses the output field and fills the period in the output_scaler field of mixinfo.

        
        
    1. Int SimpleMixer: parse_output_scaler (const char * buf, unsigned & buflen, mixer_scaler_s & scaler)
    2. {
    3. Int ret;
    4. Int s [5];
    5. Int n =-1;

    6. Buf = findtag (buf, buflen, 'o'); // search for a controller like "O:". return the pointer pointing to the first character 'o' defined in the output format domain '.
        
        
    1. If (buf = nullptr) | (buflen <12 )){
    2. Debug ("output parser failed finding tag, ret: '% s'", buf );
    3. Return-1;
    4. } // 12, indicating that the O: line must have at least 12 characters (O: and five 1-digit long integers). For example, the shortest is defined as: O: 0 0 0 0 0

    5. If (ret = sscanf (buf, "O: % d % n", // O: five integers must be followed, and the integers are separated by at least one space. Here we take out O: The next five integers.
    6. & S [0], & s [1], & s [2], & s [3], & s [4], & n ))! = 5 ){
    7. Debug ("out scaler parse failed on '% s' (got % d, consumed % d)", buf, ret, n );
    8. Return-1;
    9. }

    10. Buf = skipline (buf, buflen );

    11. If (buf = nullptr ){
    12. Debug ("no line ending, line is incomplete ");
    13. Return-1;
    14. }
    15. // From the following assignment operation, we can obtain O: The meaning of the next five values, which are [negative_scale] [positive_scale] [offset] [min_output] [max_output]
    16. // And each operation except 10000 is performed, so the values in the MIX format definition are all values after 10000 times.
    17. Scaler. negative_scale = s [0]/1_f;
    18. Scaler. positive_scale = s [1]/1_f;
    19. Scaler. offset = s [2]/limit F;
    20. Scaler. min_output = s [3]/limit F;
    21. Scaler. max_output = s [4]/10000.0f;

    22. Return 0;
    23. }

    // The output of MIXER is parsed above, and the input is parsed below, because we have read the number of input signals (the value defined by n in "M: n ), so it takes n cycles.
  31. // First, remember the parameters input by the parse_control_scaler function.
  32. For (unsigned I = 0; I <inputs; I ++ ){
  33. If (parse_control_scaler (end-buflen, buflen,
  34. Mixinfo-> controls [I]. scaler,
  35. Mixinfo-> controls [I]. control_group,
  36. Mixinfo-> controls [I]. control_index )){
  37. Debug ("simple mixer parser failed parsing ctrl scaler tag, ret: '% s'", buf );
  38. Goto out;
  39. }

  40. }

        
        
    1. Int SimpleMixer: parse_control_scaler (const char * buf, unsigned & buflen, mixer_scaler_s & scaler, uint8_t & control_group,
    2. Uint8_t & control_index)
    3. {
    4. Unsigned u [2];
    5. Int s [5];

    6. Buf = findtag (buf, buflen,'s '); // locate the first 's' in the remaining buffer and point the buf to the first row of the row;
    7. //
    8. // 16 indicates the value of S: The row must contain at least 16 characters, that is, at least 7 integers (because integers are separated by at least one space)
    9. If (buf = nullptr) | (buflen <16 )){
    10. Debug ("control parser failed finding tag, ret: '% s'", buf );
    11. Return-1;
    12. }
    13. // Read S: the next 7 integers.
    14. If (sscanf (buf, "S: % u % d ",
    15. & U [0], & u [1], & s [0], & s [1], & s [2], & s [3], & s [4])! = 7 ){
    16. Debug ("control parse failed on '% s'", buf );
    17. Return-1;
    18. }

    19. Buf = skipline (buf, buflen );

    20. If (buf = nullptr ){
    21. Debug ("no line ending, line is incomplete ");
    22. Return-1;
    23. }

    24. // From the following assignment, we can see that the MIXER File S: defined format, and S: the integers following them are
    25. // [Control_group] [ontrol_index] [negative_scale] [positive_scale] [offset] [min_output] [max_output]
    26. // It can be seen that the definition of the input signal is two integers more than the definition of the input and output signals, indicating the group where the current input signal is located and the number of the group. 1st and 2nd are used.
    27. // Indicates the group number and the group number. the definitions of the last five integers are the same as those of the input signal, and must be divided by 10000.
    28. Control_group = u [0];
    29. Control_index = u [1];
    30. Scaler. negative_scale = s [0]/1_f;
    31. Scaler. positive_scale = s [1]/1_f;
    32. Scaler. offset = s [2]/limit F;
    33. Scaler. min_output = s [3]/limit F;
    34. Scaler. max_output = s [4]/10000.0f;

    35. Return 0;
    36. }



  41. Sm = new SimpleMixer (control_cb, cb_handle, mixinfo );

  42. If (sm! = Nullptr ){
  43. Mixinfo = nullptr;
  44. Debug ("loaded mixer with % d input (s)", inputs );

  45. } Else {
  46. Debug ("cocould not allocate memory for mixer ");
  47. }

  48. Out:

  49. If (mixinfo! = Nullptr ){
  50. Free (mixinfo );
  51. }

  52. Return sm;
  53. }




Http://www.bkjia.com/PHPjc/1117247.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1117247.htmlTechArticlemixer structure analysis [uavcan for example] mixer command is the system app command, in the Firmware/src/systemcmds/mixer Directory, its function is to load valid content in the mix file to a specific device...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.