.TH "D:/gitt/MicrochipFor32/bsp_MPU6050/inv_mpu_dmp_motion_driver.c" 3 "2022年 十一月 22日 星期二" "Version 1.0.0" "Bscpp" \" -*- nroff -*- .ad l .nh .SH NAME D:/gitt/MicrochipFor32/bsp_MPU6050/inv_mpu_dmp_motion_driver.c \- DMP image and interface functions\&. .SH SYNOPSIS .br .PP \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include 'inv_mpu\&.h'\fP .br \fC#include 'inv_mpu_dmp_motion_driver\&.h'\fP .br \fC#include 'dmpKey\&.h'\fP .br \fC#include 'dmpmap\&.h'\fP .br \fC#include 'usart\&.h'\fP .br .SS "类" .in +1c .ti -1c .RI "struct \fBdmp_s\fP" .br .in -1c .SS "宏定义" .in +1c .ti -1c .RI "#define \fBMOTION_DRIVER_TARGET_MSP430\fP" .br .ti -1c .RI "#define \fBdelay_ms\fP HAL_Delay" .br .ti -1c .RI "#define \fBget_ms\fP \fBmget_ms\fP" .br .ti -1c .RI "#define \fBlog_i\fP printf" .br .ti -1c .RI "#define \fBlog_e\fP printf" .br .ti -1c .RI "#define \fBCFG_LP_QUAT\fP (2712)" .br .ti -1c .RI "#define \fBEND_ORIENT_TEMP\fP (1866)" .br .ti -1c .RI "#define \fBCFG_27\fP (2742)" .br .ti -1c .RI "#define \fBCFG_20\fP (2224)" .br .ti -1c .RI "#define \fBCFG_23\fP (2745)" .br .ti -1c .RI "#define \fBCFG_FIFO_ON_EVENT\fP (2690)" .br .ti -1c .RI "#define \fBEND_PREDICTION_UPDATE\fP (1761)" .br .ti -1c .RI "#define \fBCGNOTICE_INTR\fP (2620)" .br .ti -1c .RI "#define \fBX_GRT_Y_TMP\fP (1358)" .br .ti -1c .RI "#define \fBCFG_DR_INT\fP (1029)" .br .ti -1c .RI "#define \fBCFG_AUTH\fP (1035)" .br .ti -1c .RI "#define \fBUPDATE_PROP_ROT\fP (1835)" .br .ti -1c .RI "#define \fBEND_COMPARE_Y_X_TMP2\fP (1455)" .br .ti -1c .RI "#define \fBSKIP_X_GRT_Y_TMP\fP (1359)" .br .ti -1c .RI "#define \fBSKIP_END_COMPARE\fP (1435)" .br .ti -1c .RI "#define \fBFCFG_3\fP (1088)" .br .ti -1c .RI "#define \fBFCFG_2\fP (1066)" .br .ti -1c .RI "#define \fBFCFG_1\fP (1062)" .br .ti -1c .RI "#define \fBEND_COMPARE_Y_X_TMP3\fP (1434)" .br .ti -1c .RI "#define \fBFCFG_7\fP (1073)" .br .ti -1c .RI "#define \fBFCFG_6\fP (1106)" .br .ti -1c .RI "#define \fBFLAT_STATE_END\fP (1713)" .br .ti -1c .RI "#define \fBSWING_END_4\fP (1616)" .br .ti -1c .RI "#define \fBSWING_END_2\fP (1565)" .br .ti -1c .RI "#define \fBSWING_END_3\fP (1587)" .br .ti -1c .RI "#define \fBSWING_END_1\fP (1550)" .br .ti -1c .RI "#define \fBCFG_8\fP (2718)" .br .ti -1c .RI "#define \fBCFG_15\fP (2727)" .br .ti -1c .RI "#define \fBCFG_16\fP (2746)" .br .ti -1c .RI "#define \fBCFG_EXT_GYRO_BIAS\fP (1189)" .br .ti -1c .RI "#define \fBEND_COMPARE_Y_X_TMP\fP (1407)" .br .ti -1c .RI "#define \fBDO_NOT_UPDATE_PROP_ROT\fP (1839)" .br .ti -1c .RI "#define \fBCFG_7\fP (1205)" .br .ti -1c .RI "#define \fBFLAT_STATE_END_TEMP\fP (1683)" .br .ti -1c .RI "#define \fBEND_COMPARE_Y_X\fP (1484)" .br .ti -1c .RI "#define \fBSKIP_SWING_END_1\fP (1551)" .br .ti -1c .RI "#define \fBSKIP_SWING_END_3\fP (1588)" .br .ti -1c .RI "#define \fBSKIP_SWING_END_2\fP (1566)" .br .ti -1c .RI "#define \fBTILTG75_START\fP (1672)" .br .ti -1c .RI "#define \fBCFG_6\fP (2753)" .br .ti -1c .RI "#define \fBTILTL75_END\fP (1669)" .br .ti -1c .RI "#define \fBEND_ORIENT\fP (1884)" .br .ti -1c .RI "#define \fBCFG_FLICK_IN\fP (2573)" .br .ti -1c .RI "#define \fBTILTL75_START\fP (1643)" .br .ti -1c .RI "#define \fBCFG_MOTION_BIAS\fP (1208)" .br .ti -1c .RI "#define \fBX_GRT_Y\fP (1408)" .br .ti -1c .RI "#define \fBTEMPLABEL\fP (2324)" .br .ti -1c .RI "#define \fBCFG_ANDROID_ORIENT_INT\fP (1853)" .br .ti -1c .RI "#define \fBCFG_GYRO_RAW_DATA\fP (2722)" .br .ti -1c .RI "#define \fBX_GRT_Y_TMP2\fP (1379)" .br .ti -1c .RI "#define \fBD_0_22\fP (22+512)" .br .ti -1c .RI "#define \fBD_0_24\fP (24+512)" .br .ti -1c .RI "#define \fBD_0_36\fP (36)" .br .ti -1c .RI "#define \fBD_0_52\fP (52)" .br .ti -1c .RI "#define \fBD_0_96\fP (96)" .br .ti -1c .RI "#define \fBD_0_104\fP (104)" .br .ti -1c .RI "#define \fBD_0_108\fP (108)" .br .ti -1c .RI "#define \fBD_0_163\fP (163)" .br .ti -1c .RI "#define \fBD_0_188\fP (188)" .br .ti -1c .RI "#define \fBD_0_192\fP (192)" .br .ti -1c .RI "#define \fBD_0_224\fP (224)" .br .ti -1c .RI "#define \fBD_0_228\fP (228)" .br .ti -1c .RI "#define \fBD_0_232\fP (232)" .br .ti -1c .RI "#define \fBD_0_236\fP (236)" .br .ti -1c .RI "#define \fBD_1_2\fP (256 + 2)" .br .ti -1c .RI "#define \fBD_1_4\fP (256 + 4)" .br .ti -1c .RI "#define \fBD_1_8\fP (256 + 8)" .br .ti -1c .RI "#define \fBD_1_10\fP (256 + 10)" .br .ti -1c .RI "#define \fBD_1_24\fP (256 + 24)" .br .ti -1c .RI "#define \fBD_1_28\fP (256 + 28)" .br .ti -1c .RI "#define \fBD_1_36\fP (256 + 36)" .br .ti -1c .RI "#define \fBD_1_40\fP (256 + 40)" .br .ti -1c .RI "#define \fBD_1_44\fP (256 + 44)" .br .ti -1c .RI "#define \fBD_1_72\fP (256 + 72)" .br .ti -1c .RI "#define \fBD_1_74\fP (256 + 74)" .br .ti -1c .RI "#define \fBD_1_79\fP (256 + 79)" .br .ti -1c .RI "#define \fBD_1_88\fP (256 + 88)" .br .ti -1c .RI "#define \fBD_1_90\fP (256 + 90)" .br .ti -1c .RI "#define \fBD_1_92\fP (256 + 92)" .br .ti -1c .RI "#define \fBD_1_96\fP (256 + 96)" .br .ti -1c .RI "#define \fBD_1_98\fP (256 + 98)" .br .ti -1c .RI "#define \fBD_1_106\fP (256 + 106)" .br .ti -1c .RI "#define \fBD_1_108\fP (256 + 108)" .br .ti -1c .RI "#define \fBD_1_112\fP (256 + 112)" .br .ti -1c .RI "#define \fBD_1_128\fP (256 + 144)" .br .ti -1c .RI "#define \fBD_1_152\fP (256 + 12)" .br .ti -1c .RI "#define \fBD_1_160\fP (256 + 160)" .br .ti -1c .RI "#define \fBD_1_176\fP (256 + 176)" .br .ti -1c .RI "#define \fBD_1_178\fP (256 + 178)" .br .ti -1c .RI "#define \fBD_1_218\fP (256 + 218)" .br .ti -1c .RI "#define \fBD_1_232\fP (256 + 232)" .br .ti -1c .RI "#define \fBD_1_236\fP (256 + 236)" .br .ti -1c .RI "#define \fBD_1_240\fP (256 + 240)" .br .ti -1c .RI "#define \fBD_1_244\fP (256 + 244)" .br .ti -1c .RI "#define \fBD_1_250\fP (256 + 250)" .br .ti -1c .RI "#define \fBD_1_252\fP (256 + 252)" .br .ti -1c .RI "#define \fBD_2_12\fP (512 + 12)" .br .ti -1c .RI "#define \fBD_2_96\fP (512 + 96)" .br .ti -1c .RI "#define \fBD_2_108\fP (512 + 108)" .br .ti -1c .RI "#define \fBD_2_208\fP (512 + 208)" .br .ti -1c .RI "#define \fBD_2_224\fP (512 + 224)" .br .ti -1c .RI "#define \fBD_2_236\fP (512 + 236)" .br .ti -1c .RI "#define \fBD_2_244\fP (512 + 244)" .br .ti -1c .RI "#define \fBD_2_248\fP (512 + 248)" .br .ti -1c .RI "#define \fBD_2_252\fP (512 + 252)" .br .ti -1c .RI "#define \fBCPASS_BIAS_X\fP (35 * 16 + 4)" .br .ti -1c .RI "#define \fBCPASS_BIAS_Y\fP (35 * 16 + 8)" .br .ti -1c .RI "#define \fBCPASS_BIAS_Z\fP (35 * 16 + 12)" .br .ti -1c .RI "#define \fBCPASS_MTX_00\fP (36 * 16)" .br .ti -1c .RI "#define \fBCPASS_MTX_01\fP (36 * 16 + 4)" .br .ti -1c .RI "#define \fBCPASS_MTX_02\fP (36 * 16 + 8)" .br .ti -1c .RI "#define \fBCPASS_MTX_10\fP (36 * 16 + 12)" .br .ti -1c .RI "#define \fBCPASS_MTX_11\fP (37 * 16)" .br .ti -1c .RI "#define \fBCPASS_MTX_12\fP (37 * 16 + 4)" .br .ti -1c .RI "#define \fBCPASS_MTX_20\fP (37 * 16 + 8)" .br .ti -1c .RI "#define \fBCPASS_MTX_21\fP (37 * 16 + 12)" .br .ti -1c .RI "#define \fBCPASS_MTX_22\fP (43 * 16 + 12)" .br .ti -1c .RI "#define \fBD_EXT_GYRO_BIAS_X\fP (61 * 16)" .br .ti -1c .RI "#define \fBD_EXT_GYRO_BIAS_Y\fP (61 * 16) + 4" .br .ti -1c .RI "#define \fBD_EXT_GYRO_BIAS_Z\fP (61 * 16) + 8" .br .ti -1c .RI "#define \fBD_ACT0\fP (40 * 16)" .br .ti -1c .RI "#define \fBD_ACSX\fP (40 * 16 + 4)" .br .ti -1c .RI "#define \fBD_ACSY\fP (40 * 16 + 8)" .br .ti -1c .RI "#define \fBD_ACSZ\fP (40 * 16 + 12)" .br .ti -1c .RI "#define \fBFLICK_MSG\fP (45 * 16 + 4)" .br .ti -1c .RI "#define \fBFLICK_COUNTER\fP (45 * 16 + 8)" .br .ti -1c .RI "#define \fBFLICK_LOWER\fP (45 * 16 + 12)" .br .ti -1c .RI "#define \fBFLICK_UPPER\fP (46 * 16 + 12)" .br .ti -1c .RI "#define \fBD_AUTH_OUT\fP (992)" .br .ti -1c .RI "#define \fBD_AUTH_IN\fP (996)" .br .ti -1c .RI "#define \fBD_AUTH_A\fP (1000)" .br .ti -1c .RI "#define \fBD_AUTH_B\fP (1004)" .br .ti -1c .RI "#define \fBD_PEDSTD_BP_B\fP (768 + 0x1C)" .br .ti -1c .RI "#define \fBD_PEDSTD_HP_A\fP (768 + 0x78)" .br .ti -1c .RI "#define \fBD_PEDSTD_HP_B\fP (768 + 0x7C)" .br .ti -1c .RI "#define \fBD_PEDSTD_BP_A4\fP (768 + 0x40)" .br .ti -1c .RI "#define \fBD_PEDSTD_BP_A3\fP (768 + 0x44)" .br .ti -1c .RI "#define \fBD_PEDSTD_BP_A2\fP (768 + 0x48)" .br .ti -1c .RI "#define \fBD_PEDSTD_BP_A1\fP (768 + 0x4C)" .br .ti -1c .RI "#define \fBD_PEDSTD_INT_THRSH\fP (768 + 0x68)" .br .ti -1c .RI "#define \fBD_PEDSTD_CLIP\fP (768 + 0x6C)" .br .ti -1c .RI "#define \fBD_PEDSTD_SB\fP (768 + 0x28)" .br .ti -1c .RI "#define \fBD_PEDSTD_SB_TIME\fP (768 + 0x2C)" .br .ti -1c .RI "#define \fBD_PEDSTD_PEAKTHRSH\fP (768 + 0x98)" .br .ti -1c .RI "#define \fBD_PEDSTD_TIML\fP (768 + 0x2A)" .br .ti -1c .RI "#define \fBD_PEDSTD_TIMH\fP (768 + 0x2E)" .br .ti -1c .RI "#define \fBD_PEDSTD_PEAK\fP (768 + 0X94)" .br .ti -1c .RI "#define \fBD_PEDSTD_STEPCTR\fP (768 + 0x60)" .br .ti -1c .RI "#define \fBD_PEDSTD_TIMECTR\fP (964)" .br .ti -1c .RI "#define \fBD_PEDSTD_DECI\fP (768 + 0xA0)" .br .ti -1c .RI "#define \fBD_HOST_NO_MOT\fP (976)" .br .ti -1c .RI "#define \fBD_ACCEL_BIAS\fP (660)" .br .ti -1c .RI "#define \fBD_ORIENT_GAP\fP (76)" .br .ti -1c .RI "#define \fBD_TILT0_H\fP (48)" .br .ti -1c .RI "#define \fBD_TILT0_L\fP (50)" .br .ti -1c .RI "#define \fBD_TILT1_H\fP (52)" .br .ti -1c .RI "#define \fBD_TILT1_L\fP (54)" .br .ti -1c .RI "#define \fBD_TILT2_H\fP (56)" .br .ti -1c .RI "#define \fBD_TILT2_L\fP (58)" .br .ti -1c .RI "#define \fBD_TILT3_H\fP (60)" .br .ti -1c .RI "#define \fBD_TILT3_L\fP (62)" .br .ti -1c .RI "#define \fBDMP_CODE_SIZE\fP (3062)" .br .ti -1c .RI "#define \fBINT_SRC_TAP\fP (0x01)" .br .ti -1c .RI "#define \fBINT_SRC_ANDROID_ORIENT\fP (0x08)" .br .ti -1c .RI "#define \fBDMP_FEATURE_SEND_ANY_GYRO\fP" .br .ti -1c .RI "#define \fBMAX_PACKET_LENGTH\fP (32)" .br .ti -1c .RI "#define \fBDMP_SAMPLE_RATE\fP (200)" .br .ti -1c .RI "#define \fBGYRO_SF\fP (46850825LL * 200 / \fBDMP_SAMPLE_RATE\fP)" .br .ti -1c .RI "#define \fBFIFO_CORRUPTION_CHECK\fP" .br .ti -1c .RI "#define \fBQUAT_ERROR_THRESH\fP (1L<<24)" .br .ti -1c .RI "#define \fBQUAT_MAG_SQ_NORMALIZED\fP (1L<<28)" .br .ti -1c .RI "#define \fBQUAT_MAG_SQ_MIN\fP (\fBQUAT_MAG_SQ_NORMALIZED\fP \- \fBQUAT_ERROR_THRESH\fP)" .br .ti -1c .RI "#define \fBQUAT_MAG_SQ_MAX\fP (\fBQUAT_MAG_SQ_NORMALIZED\fP + \fBQUAT_ERROR_THRESH\fP)" .br .in -1c .SS "函数" .in +1c .ti -1c .RI "int \fBdmp_load_motion_driver_firmware\fP (void)" .br .RI "Load the DMP with this image\&. " .ti -1c .RI "int \fBdmp_set_orientation\fP (unsigned short orient)" .br .RI "Push gyro and accel orientation to the DMP\&. The orientation is represented here as the output of \fIinv_orientation_matrix_to_scalar\fP\&. " .ti -1c .RI "int \fBdmp_set_gyro_bias\fP (long *bias)" .br .RI "Push gyro biases to the DMP\&. Because the gyro integration is handled in the DMP, any gyro biases calculated by the MPL should be pushed down to DMP memory to remove 3-axis quaternion drift\&. .br NOTE: If the DMP-based gyro calibration is enabled, the DMP will overwrite the biases written to this location once a new one is computed\&. " .ti -1c .RI "int \fBdmp_set_accel_bias\fP (long *bias)" .br .RI "Push accel biases to the DMP\&. These biases will be removed from the DMP 6-axis quaternion\&. " .ti -1c .RI "int \fBdmp_set_fifo_rate\fP (unsigned short rate)" .br .RI "Set DMP output rate\&. Only used when DMP is on\&. " .ti -1c .RI "int \fBdmp_get_fifo_rate\fP (unsigned short *rate)" .br .RI "Get DMP output rate\&. " .ti -1c .RI "int \fBdmp_set_tap_thresh\fP (unsigned char axis, unsigned short thresh)" .br .RI "Set tap threshold for a specific axis\&. " .ti -1c .RI "int \fBdmp_set_tap_axes\fP (unsigned char axis)" .br .RI "Set which axes will register a tap\&. " .ti -1c .RI "int \fBdmp_set_tap_count\fP (unsigned char min_taps)" .br .RI "Set minimum number of taps needed for an interrupt\&. " .ti -1c .RI "int \fBdmp_set_tap_time\fP (unsigned short time)" .br .RI "Set length between valid taps\&. " .ti -1c .RI "int \fBdmp_set_tap_time_multi\fP (unsigned short time)" .br .RI "Set max time between taps to register as a multi-tap\&. " .ti -1c .RI "int \fBdmp_set_shake_reject_thresh\fP (long sf, unsigned short thresh)" .br .RI "Set shake rejection threshold\&. If the DMP detects a gyro sample larger than \fIthresh\fP, taps are rejected\&. " .ti -1c .RI "int \fBdmp_set_shake_reject_time\fP (unsigned short time)" .br .RI "Set shake rejection time\&. Sets the length of time that the gyro must be outside of the threshold set by \fIgyro_set_shake_reject_thresh\fP before taps are rejected\&. A mandatory 60 ms is added to this parameter\&. " .ti -1c .RI "int \fBdmp_set_shake_reject_timeout\fP (unsigned short time)" .br .RI "Set shake rejection timeout\&. Sets the length of time after a shake rejection that the gyro must stay inside of the threshold before taps can be detected again\&. A mandatory 60 ms is added to this parameter\&. " .ti -1c .RI "int \fBdmp_get_pedometer_step_count\fP (unsigned long *count)" .br .RI "Get current step count\&. " .ti -1c .RI "int \fBdmp_set_pedometer_step_count\fP (unsigned long count)" .br .RI "Overwrite current step count\&. WARNING: This function writes to DMP memory and could potentially encounter a race condition if called while the pedometer is enabled\&. " .ti -1c .RI "int \fBdmp_get_pedometer_walk_time\fP (unsigned long *time)" .br .RI "Get duration of walking time\&. " .ti -1c .RI "int \fBdmp_set_pedometer_walk_time\fP (unsigned long time)" .br .RI "Overwrite current walk time\&. WARNING: This function writes to DMP memory and could potentially encounter a race condition if called while the pedometer is enabled\&. " .ti -1c .RI "int \fBdmp_enable_feature\fP (unsigned short mask)" .br .RI "Enable DMP features\&. The following #define's are used in the input mask: .br DMP_FEATURE_TAP .br DMP_FEATURE_ANDROID_ORIENT .br DMP_FEATURE_LP_QUAT .br DMP_FEATURE_6X_LP_QUAT .br DMP_FEATURE_GYRO_CAL .br DMP_FEATURE_SEND_RAW_ACCEL .br DMP_FEATURE_SEND_RAW_GYRO .br NOTE: DMP_FEATURE_LP_QUAT and DMP_FEATURE_6X_LP_QUAT are mutually exclusive\&. .br NOTE: DMP_FEATURE_SEND_RAW_GYRO and DMP_FEATURE_SEND_CAL_GYRO are also mutually exclusive\&. " .ti -1c .RI "int \fBdmp_get_enabled_features\fP (unsigned short *mask)" .br .RI "Get list of currently enabled DMP features\&. " .ti -1c .RI "int \fBdmp_enable_gyro_cal\fP (unsigned char enable)" .br .RI "Calibrate the gyro data in the DMP\&. After eight seconds of no motion, the DMP will compute gyro biases and subtract them from the quaternion output\&. If \fIdmp_enable_feature\fP is called with \fIDMP_FEATURE_SEND_CAL_GYRO\fP, the biases will also be subtracted from the gyro output\&. " .ti -1c .RI "int \fBdmp_enable_lp_quat\fP (unsigned char enable)" .br .RI "Generate 3-axis quaternions from the DMP\&. In this driver, the 3-axis and 6-axis DMP quaternion features are mutually exclusive\&. " .ti -1c .RI "int \fBdmp_enable_6x_lp_quat\fP (unsigned char enable)" .br .RI "Generate 6-axis quaternions from the DMP\&. In this driver, the 3-axis and 6-axis DMP quaternion features are mutually exclusive\&. " .ti -1c .RI "static int \fBdecode_gesture\fP (unsigned char *gesture)" .br .RI "Decode the four-byte gesture data and execute any callbacks\&. " .ti -1c .RI "int \fBdmp_set_interrupt_mode\fP (unsigned char mode)" .br .RI "Specify when a DMP interrupt should occur\&. A DMP interrupt can be configured to trigger on either of the two conditions below: .br a\&. One FIFO period has elapsed (set by \fImpu_set_sample_rate\fP)\&. .br b\&. A tap event has been detected\&. " .ti -1c .RI "int \fBdmp_read_fifo\fP (short *gyro, short *accel, long *quat, unsigned long *timestamp, short *sensors, unsigned char *more)" .br .RI "Get one packet from the FIFO\&. If \fIsensors\fP does not contain a particular sensor, disregard the data returned to that pointer\&. .br \fIsensors\fP can contain a combination of the following flags: .br INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO .br INV_XYZ_GYRO .br INV_XYZ_ACCEL .br INV_WXYZ_QUAT .br If the FIFO has no new data, \fIsensors\fP will be zero\&. .br If the FIFO is disabled, \fIsensors\fP will be zero and this function will return a non-zero error code\&. " .ti -1c .RI "int \fBdmp_register_tap_cb\fP (void(*func)(unsigned char, unsigned char))" .br .RI "Register a function to be executed on a tap event\&. The tap direction is represented by one of the following: .br TAP_X_UP .br TAP_X_DOWN .br TAP_Y_UP .br TAP_Y_DOWN .br TAP_Z_UP .br TAP_Z_DOWN " .ti -1c .RI "int \fBdmp_register_android_orient_cb\fP (void(*func)(unsigned char))" .br .RI "Register a function to be executed on a android orientation event\&. " .in -1c .SS "变量" .in +1c .ti -1c .RI "static const unsigned char \fBdmp_memory\fP [\fBDMP_CODE_SIZE\fP]" .br .ti -1c .RI "static const unsigned short \fBsStartAddress\fP = 0x0400" .br .ti -1c .RI "static struct \fBdmp_s\fP \fBdmp\fP" .br .in -1c .SH "详细描述" .PP DMP image and interface functions\&. All functions are preceded by the dmp_ prefix to differentiate among MPL and general driver function calls\&. .PP 在文件 \fBinv_mpu_dmp_motion_driver\&.c\fP 中定义\&. .SH "作者" .PP 由 Doyxgen 通过分析 Bscpp 的 源代码自动生成\&.