Mixer structural Analysis [Uavcan for example]_php tutorial

Source: Internet
Author: User
Tags format definition

Mixer structural Analysis [Uavcan for example]


The mixer instruction is a system app command, located under the Firmware/src/systemcmds/mixer directory, where the function is to load the contents of the mix file into a specific device, and then resolve these definitions by mixergroups in the specific device.
This example is taking Uvacan as an example, after the system runs, the name of the device is:/dev/uavcan/esc.
There are mixergroup instances in the definition of Uavcan, and an output instance.

There are three types of mixer: Nullmixer, simplemixer and Multirotormixer.
Nullmixer: Used for non-grouped output channel points;
Simplemixer: 0 or more inputs fused into one output;
MultirotormixeR: The input amount (roll,pitch,raw,thrusttle) is fused into a set of outputs based on pre-defined geometry.



Functions that read the mix file are located in FIRMWARE/SRC/MODULES/SYSTEMLIB/MIXWR/MIXER_LOAD.C:
 
  
  
The parameter fname is the location of the mix file in the system, buf the buffer for reading the file data, maxlen the maximum length of the BUF.
The function rejects a line that conforms to any of the following:
1. Lines with a line length of less than 2 characters
2. The first character of a line is not an uppercase line
3. The second character is not a line of ': '
After removing the data from these illegal contents, all the remaining formatted content will be stored in the BUF buffer.
So this requires the mix and format to be followed when writing the mix file.
Once these formatted mix contents are read in the buffer, the function
 
  
  
To be handed over to specific equipment for processing.

Definitions of related structures:


 
 
  1. /** Simple Channel Scaler */
  2. struct mixer_scaler_s {
  3. floatnegative_scale;//negative scaling, the mix file O: The 1th integer after the/10000.0f
  4. floatpositive_scale;//forward scaling, in the mix file, O: The 2nd integer after the/10000.0f
  5. Floatoffset; Offset, in the mix file, O: The 3rd integer after the/10000.0f
  6. floatmin_output;//minimum output value, in the mix file, O: The 4th integer after the/10000.0f
  7. floatmax_output;//maximum output value, mix file O: The 5th integer followed by/10000.0f
  8. };//This structure defines the structure of a single control quantity

  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 structure of the input amount

  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. The};//defines the control body of a control entity, including the number of inputs, the input signal control set, and the 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 for this mixer, and the specific signals are stored in the array controls[0].
  22. The output is controlled by the Output_scaler.
  23. From the definition of these structures, you can compare the definition of the mix file syntax.

Uavcan_main.cpp:
The file is parsed with 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;
      unsigned buflen = 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);//start parsing 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 had failed to
  7. * Allocate something when we expected to.
  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 look at the first letter of the line to determine the category of the data.
  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 is successful */
  39. Buflen = Resid;
  40. Debug ("Success-buflen:%d", buflen);

  41. } else {

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

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

The following function is used to deal with the definition of the beginning of M: The format specifies that there can be only one number behind the character, which indicates the number of input sources, that is, the number of S type, and the number of struct mixer_control_s that is associated with the definition of the struct.
 
 
  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: After the first value to the unsigned integer data into the variable inputs, and assign the number of notes already processed to used

  14. BUF = SkipLine (buf, Buflen);//Let buf specify the next line

  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 number behind is the amount of struct mixer_control_s structure. Mixer_simple_size is the literal meaning of sizeof (mixer_simple_s) + inputs*sizeof (mixer_control_s),
  21. That is, the definition of a complete mixer_simple_s, controls[0] there are inputs altogether.

  22. if (Mixinfo = = nullptr) {
  23. Debug ("Could not allocate memory for mixer info");
  24. Goto out;
  25. }

  26. Mixinfo->control_count = number of inputs;//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. }//the function resolves the output field and fills the period into the Mixinfo output_scaler field.

     
         
         
    1. int simplemixer::p arse_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 "O:" Such a control, return pointer to the output format field defined by the first character ' O '.
        
        
    1. if ((buf = = nullptr) | | (Buflen < 12)) {
    2. Debug ("Output parser failed finding tag, ret: '%s '", buf);
    3. return-1;
    4. }//12, indicating o: the definition of this line has at least 12 characters (O: and five 1-bit long integers), such as the shortest definition: o:0 0 0 0 0

    5. if (ret = sscanf (buf, "O:%d%d%d,%d%d%n",//o: Must be followed by 5 integers, and the integers are separated by at least one space, here is the 5 integer value after the O: Is removed.)
    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. The following assignment operation allows you to derive the meanings of the 5 values, respectively, [Negative_scale] [Positive_scale] [offset] [min_output] [max_output]
    16. And each of these has been done in addition to 10000 of the operation, so the mix format definition says these values are magnified 10,000 times times after the value.
    17. scaler.negative_scale= S[0]/10000.0f;
    18. scaler.positive_scale= s[1]/10000.0f;
    19. scaler.offset= s[2]/10000.0f;
    20. scaler.min_output= s[3]/10000.0f;
    21. scaler.max_output= s[4]/10000.0f;

    22. return 0;
    23. }

    The above parses the output of the mixer and begins parsing the input as we have read the number of input signals (the value defined in "M:n"), so we loop n times.
  31. First remember the parameters of the Parse_control_scaler function input
  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::p arse_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 ');//Find the first ' s ' in the remaining buffer and let BUF point to the beginning of the line;
    7. //
    8. 16 indicates that the S: line has at least 16 characters, which is at least 7 integers (because there are at least 1 spaces separated between integers)
    9. if ((buf = = nullptr) | | (Buflen < 16)) {
    10. Debug ("Control parser failed finding tag, ret: '%s '", buf);
    11. return-1;
    12. }
    13. Reads s: 7 integers after the second.
    14. if (sscanf (buf, S:%u%u%d%d%d%d,%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 assignment below you can see the mixer file s: The defined format, s: The following integers are
    25. [Control_group] [Ontrol_index] [Negative_scale] [Positive_scale] [offset] [min_output] [max_output]
    26. As can be seen, the definition of the input signal is more than two integers to the definition of the input signal, which is used to indicate the sequence number within the group and group where the current input signal resides. The 1th and 2nd integers are used to
    27. Description group number and group ordinal. The definition of the next 5 integers is the same as the input signal, and is divided by 10000.
    28. control_group= U[0];
    29. control_index= U[1];
    30. scaler.negative_scale= S[0]/10000.0f;
    31. scaler.positive_scale= s[1]/10000.0f;
    32. scaler.offset= s[2]/10000.0f;
    33. scaler.min_output= s[3]/10000.0f;
    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 ("Could 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.html www.bkjia.com true http://www.bkjia.com/PHPjc/1117247.html techarticle mixer Structure Analysis [Uavcan for example] mixer instruction is the System App command, located under the Firmware/src/systemcmds/mixer directory, its function is to load the mix file valid content to the specific device ...

  • Related Article

    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.