Rplidar学习(二)—— SDK库文件学习
SDK头文件介绍
1、头文件简介:
rplidar.h //一般情况下开发的项目中仅需要引入该头文件即可使用 RPLIDAR SDK 的所有功能。
rplidar_driver.h //定义了 SDK 核心驱动接口: RPlidarDriver 的类声明。
rplidar_protocol.h //定义了 RPLIDAR 通讯协议文档中描述的底层相关数据结构和常量定义。
rplidar_cmd.h //定义了 RPLIDAR 通讯协议文档中描述的各类请求/应答相关的数据结构和常量定义。
rptypes.h //平台无关的结构和常量定义
2、头文件解析
(1)rplidar_protocol.h
#pragma once // RP-Lidar Input Packets #define RPLIDAR_CMD_SYNC_BYTE 0xA5 //请求报文开始字节
#define RPLIDAR_CMDFLAG_HAS_PAYLOAD 0x80 //情报报文负载 #define RPLIDAR_ANS_SYNC_BYTE1 0xA5 //应答报文起始标志1
#define RPLIDAR_ANS_SYNC_BYTE2 0x5A //应答报文起始标志2 #define RPLIDAR_ANS_PKTFLAG_LOOP 0x1 //多次应答模式 #define RPLIDAR_ANS_HEADER_SIZE_MASK 0x3FFFFFFF
#define RPLIDAR_ANS_HEADER_SUBTYPE_SHIFT (30) #if defined(_WIN32)
#pragma pack(1)
#endif //请求报文格式
typedef struct _rplidar_cmd_packet_t {
_u8 syncByte; //must be RPLIDAR_CMD_SYNC_BYTE //起始标志
_u8 cmd_flag; //请求命令
_u8 size; //负载长度
_u8 data[0]; //请求负载数据
} __attribute__((packed)) rplidar_cmd_packet_t; //__attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐
//使用之后才会是几字节就是几字节,否则就每个变量的字节长度都跟结构体中变量字节长度最长相同 //应答报文格式
typedef struct _rplidar_ans_header_t {
_u8 syncByte1; // must be RPLIDAR_ANS_SYNC_BYTE1 //起始标志1
_u8 syncByte2; // must be RPLIDAR_ANS_SYNC_BYTE2 //起始标志2
_u32 size_q30_subtype; // see _u32 size:30; _u32 subType:2; //应答报文长度
_u8 type; //应答模式
} __attribute__((packed)) rplidar_ans_header_t; #if defined(_WIN32)
#pragma pack()
#endif
(2)rplidar_cmd.h
#pragma once #include "rplidar_protocol.h" // Commands
//----------------------------------------- // Commands without payload and response
#define RPLIDAR_CMD_STOP 0x25 //离开扫描模式,进入空闲状态
#define RPLIDAR_CMD_SCAN 0x20 //请求进入扫描采样状态
#define RPLIDAR_CMD_FORCE_SCAN 0x21 //请求进入扫描采样状态,强制数据输出
#define RPLIDAR_CMD_RESET 0x40 //测距核心软重启 // Commands without payload but have response
#define RPLIDAR_CMD_GET_DEVICE_INFO 0x50 //获取设备序列号等信息
#define RPLIDAR_CMD_GET_DEVICE_HEALTH 0x52 //获取设备健康状态 #define RPLIDAR_CMD_GET_SAMPLERATE 0x59 //added in fw 1.17 获取单词激光测距的用时 // Commands with payload and have response
#define RPLIDAR_CMD_EXPRESS_SCAN 0x82 //added in fw 1.17 请求进入扫描状态,幷工作在最高采样频率下 //add for A2 to set RPLIDAR motor pwm when using accessory board
#define RPLIDAR_CMD_SET_MOTOR_PWM 0xF0
#define RPLIDAR_CMD_GET_ACC_BOARD_FLAG 0xFF #if defined(_WIN32) //如果是win32下编译则执行
#pragma pack(1) //结构体边界设置为1字节,也就是说储存在内存中是连续的
#endif // Payloads
// ------------------------------------------
#define RPLIDAR_EXPRESS_SCAN_MODE_NORMAL 0
#define RPLIDAR_EXPRESS_SCAN_MODE_FIXANGLE 1 typedef struct _rplidar_payload_express_scan_t { //带有负载的数据包
_u8 working_mode;
_u32 reserved;
} __attribute__((packed)) rplidar_payload_express_scan_t; #define MAX_MOTOR_PWM 1023 //电机PWM最大值
#define DEFAULT_MOTOR_PWM 660 //电机PWM默认值 //电机PWM结构
typedef struct _rplidar_payload_motor_pwm_t {
_u16 pwm_value;
} __attribute__((packed)) rplidar_payload_motor_pwm_t; // ???????????
typedef struct _rplidar_payload_acc_board_flag_t {
_u32 reserved;
} __attribute__((packed)) rplidar_payload_acc_board_flag_t; // Response
// ------------------------------------------
#define RPLIDAR_ANS_TYPE_DEVINFO 0x4 //设备信心获取 起始应答结尾
#define RPLIDAR_ANS_TYPE_DEVHEALTH 0x6 //设备健康状态获取 起始应答结尾 #define RPLIDAR_ANS_TYPE_MEASUREMENT 0x81 //普通采集
// Added in FW ver 1.17
#define RPLIDAR_ANS_TYPE_MEASUREMENT_CAPSULED 0x82 //高速采集 // Added in FW ver 1.17
#define RPLIDAR_ANS_TYPE_SAMPLE_RATE 0x15 // #define RPLIDAR_ANS_TYPE_ACC_BOARD_FLAG 0xFF #define RPLIDAR_RESP_ACC_BOARD_FLAG_MOTOR_CTRL_SUPPORT_MASK (0x1)
typedef struct _rplidar_response_acc_board_flag_t {
_u32 support_flag;
} __attribute__((packed)) rplidar_response_acc_board_flag_t; //设备状态
#define RPLIDAR_STATUS_OK 0x0
#define RPLIDAR_STATUS_WARNING 0x1
#define RPLIDAR_STATUS_ERROR 0x2 #define RPLIDAR_RESP_MEASUREMENT_SYNCBIT (0x1<<0)
#define RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT 2
#define RPLIDAR_RESP_MEASUREMENT_CHECKBIT (0x1<<0)
#define RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT 1 //激光测距勇士获取数据包
typedef struct _rplidar_response_sample_rate_t {
_u16 std_sample_duration_us; //在标准扫描模式下,设备测距核心进行单次激光测距的耗时 单位:微秒
_u16 express_sample_duration_us; //在高速采样模式下,设备测距核心进行单次激光测距的耗时 单位:微妙
} __attribute__((packed)) rplidar_response_sample_rate_t; typedef struct _rplidar_response_measurement_node_t {
_u8 sync_quality; // syncbit:1;syncbit_inverse:1;quality:6; //信号质量
_u16 angle_q6_checkbit; // check_bit:1;angle_q6:15; //测距点相对于RPLIDAR朝向夹角 实际角度 = angle_q6 / 64.0 Deg
_u16 distance_q2; //测距点相对于RPLIDAR的距离 实际距离 = distance_q2 / 4.0 mm
} __attribute__((packed)) rplidar_response_measurement_node_t; //[distance_sync flags]
#define RPLIDAR_RESP_MEASUREMENT_EXP_ANGLE_MASK (0x3)
#define RPLIDAR_RESP_MEASUREMENT_EXP_DISTANCE_MASK (0xFC) typedef struct _rplidar_response_cabin_nodes_t {
_u16 distance_angle_1; // see [distance_sync flags]
_u16 distance_angle_2; // see [distance_sync flags]
_u8 offset_angles_q3;
} __attribute__((packed)) rplidar_response_cabin_nodes_t; #define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_1 0xA
#define RPLIDAR_RESP_MEASUREMENT_EXP_SYNC_2 0x5 #define RPLIDAR_RESP_MEASUREMENT_EXP_SYNCBIT (0x1<<15) typedef struct _rplidar_response_capsule_measurement_nodes_t {
_u8 s_checksum_1; // see [s_checksum_1]
_u8 s_checksum_2; // see [s_checksum_1]
_u16 start_angle_sync_q6;
rplidar_response_cabin_nodes_t cabins[16];
} __attribute__((packed)) rplidar_response_capsule_measurement_nodes_t; //设备信息数据报文
typedef struct _rplidar_response_device_info_t {
_u8 model;
_u16 firmware_version;
_u8 hardware_version;
_u8 serialnum[16];
} __attribute__((packed)) rplidar_response_device_info_t; //设备健康信息数据报文
typedef struct _rplidar_response_device_health_t {
_u8 status;
_u16 error_code;
} __attribute__((packed)) rplidar_response_device_health_t; #if defined(_WIN32)
#pragma pack()
#endif
(3)rplidar_driver.h
#pragma once #ifndef __cplusplus
#error "The RPlidar SDK requires a C++ compiler to be built"
#endif namespace rp { namespace standalone{ namespace rplidar { class RPlidarDriver {
public:
enum {
DEFAULT_TIMEOUT = 2000, //2000 ms
}; enum {
DRIVER_TYPE_SERIALPORT = 0x0,
};
public:
/// Create an RPLIDAR Driver Instance
/// This interface should be invoked first before any other operations
///
/// \param drivertype the connection type used by the driver.
static RPlidarDriver * CreateDriver(_u32 drivertype = DRIVER_TYPE_SERIALPORT); //静态创建对象接口 /// Dispose the RPLIDAR Driver Instance specified by the drv parameter
/// Applications should invoke this interface when the driver instance is no longer used in order to free memory
static void DisposeDriver(RPlidarDriver * drv); //静态接口函数析构RPlidar实例 public:
/// Open the specified serial port and connect to a target RPLIDAR device
///
/// \param port_path the device path of the serial port
/// e.g. on Windows, it may be com3 or \\.\com10
/// on Unix-Like OS, it may be /dev/ttyS1, /dev/ttyUSB2, etc
///
/// \param baudrate the baudrate used
/// For most RPLIDAR models, the baudrate should be set to 115200
///
/// \param flag other flags
/// Reserved for future use, always set to Zero
virtual u_result connect(const char * port_path, _u32 baudrate, _u32 flag = 0) = 0; //设备连接函数,调用时会默认停止电机旋转,测试时需要使用startMotor启动电机旋转 /// Disconnect with the RPLIDAR and close the serial port
virtual void disconnect() = 0; //断开链接 /// Returns TRUE when the connection has been established
virtual bool isConnected() = 0; /// Ask the RPLIDAR core system to reset it self
/// The host system can use the Reset operation to help RPLIDAR escape the self-protection mode.
///
// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result reset(_u32 timeout = DEFAULT_TIMEOUT) = 0; /// Retrieve the health status of the RPLIDAR
/// The host system can use this operation to check whether RPLIDAR is in the self-protection mode.
///
/// \param health The health status info returned from the RPLIDAR
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result getHealth(rplidar_response_device_health_t & health, _u32 timeout = DEFAULT_TIMEOUT) = 0; //获取 RPLIDAR 设备的健康状态 /// Get the device information of the RPLIDAR include the serial number, firmware version, device model etc.
///
/// \param info The device information returned from the RPLIDAR
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result getDeviceInfo(rplidar_response_device_info_t & info, _u32 timeout = DEFAULT_TIMEOUT) = 0; //获取 RPLIDAR 设备序列号、固件版本等信息 /// Get the sample duration information of the RPLIDAR.
///
/// \param rateInfo The sample duration information returned from the RPLIDAR
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result getSampleDuration_uS(rplidar_response_sample_rate_t & rateInfo, _u32 timeout = DEFAULT_TIMEOUT) = 0; //获取 RPLIDAR 分别在标准 Scan 以及 ExpressScan 模
//式下单次激光采样的用时。 单位为微秒(uS)
/// Set the RPLIDAR's motor pwm when using accessory board, currently valid for A2 only.
///
/// \param pwm The motor pwm value would like to set
virtual u_result setMotorPWM(_u16 pwm) = 0; //向开发套件的 USB 附件板发送特定的 PWM 占空比,控制RPLIDAR 扫描电机转速。 /// Start RPLIDAR's motor when using accessory board
virtual u_result startMotor() = 0; //启动电机 /// Stop RPLIDAR's motor when using accessory board
virtual u_result stopMotor() = 0; //停止电机 /// Check whether the device support motor control.
/// Note: this API will disable grab.
///
/// \param support Return the result.
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication.
virtual u_result checkMotorCtrlSupport(bool & support, _u32 timeout = DEFAULT_TIMEOUT) = 0; //检测附件板是否支持电机 PWM 控制。
/// Calcuate RPLIDAR's current scanning frequency from the given scan data
/// Please refer to the application note doc for details
/// Remark: the calcuation will be incorrect if the specified scan data doesn't contains enough data
///
/// \param inExpressMode Indicate whether the RPLIDAR is in express mode
///
/// \param count The number of sample nodes inside the given buffer
///
/// \param frequency The scanning frequency (in HZ) calcuated by the interface.
///
/// \param is4kmode Return whether the RPLIDAR is working on 4k sample rate mode.
virtual u_result getFrequency(bool inExpressMode, size_t count, float & frequency, bool & is4kmode) = 0; //从实现抓取的一圈扫描数据序列计算 RPLIDAR 的转速 /// Ask the RPLIDAR core system to enter the scan mode(Normal/Express, Express mode is 4k mode)
/// A background thread will be created by the RPLIDAR driver to fetch the scan data continuously.
/// User Application can use the grabScanData() interface to retrieved the scan data cached previous by this background thread.
///
/// \param force Force the core system to output scan data regardless whether the scanning motor is rotating or not.
///
/// \param autoExpressMode Force the core system to trying express mode first, if the system does not support express mode, it will use normal mode.
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication.
//开始扫描,(正常模式,还有一个特别模式2.0能用)
virtual u_result startScan(bool force = false, bool autoExpressMode = true) = 0;
virtual u_result startScanNormal(bool force, _u32 timeout = DEFAULT_TIMEOUT) = 0;
virtual u_result startScanExpress(bool fixedAngle, _u32 timeout = DEFAULT_TIMEOUT) = 0; /// Check whether the device support express mode.
///
/// \param support Return the result.
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication. //检测是否能用这个模式
virtual u_result checkExpressScanSupported(bool & support, _u32 timeout = DEFAULT_TIMEOUT) = 0; /// Ask the RPLIDAR core system to stop the current scan operation and enter idle state. The background thread will be terminated
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication //停止
virtual u_result stop(_u32 timeout = DEFAULT_TIMEOUT) = 0; /// Wait and grab a complete 0-360 degree scan data previously received.
/// The grabbed scan data returned by this interface always has the following charactistics:
///
/// 1) The first node of the grabbed data array (nodebuffer[0]) must be the first sample of a scan, i.e. the start_bit == 1
/// 2) All data nodes are belong to exactly ONE complete 360-degrees's scan
/// 3) Note, the angle data in one scan may not be ascending. You can use API ascendScanData to reorder the nodebuffer.
///
/// \param nodebuffer Buffer provided by the caller application to store the scan data
///
/// \param count The caller must initialize this parameter to set the max data count of the provided buffer (in unit of rplidar_response_measurement_node_t).
/// Once the interface returns, this parameter will store the actual received data count.
///
/// \param timeout Max duration allowed to wait for a complete scan data, nothing will be stored to the nodebuffer if a complete 360-degrees' scan data cannot to be ready timely.
///
/// The interface will return RESULT_OPERATION_TIMEOUT to indicate that no complete 360-degrees' scan can be retrieved withing the given timeout duration.
///
/// \The caller application can set the timeout value to Zero(0) to make this interface always returns immediately to achieve non-block operation.
//得到扫描数据
virtual u_result grabScanData(rplidar_response_measurement_node_t * nodebuffer, size_t & count, _u32 timeout = DEFAULT_TIMEOUT) = 0; /// Ascending the scan data according to the angle value in the scan.
///
/// \param nodebuffer Buffer provided by the caller application to do the reorder. Should be retrived from the grabScanData
///
/// \param count The caller must initialize this parameter to set the max data count of the provided buffer (in unit of rplidar_response_measurement_node_t).
/// Once the interface returns, this parameter will store the actual received data count.
/// The interface will return RESULT_OPERATION_FAIL when all the scan data is invalid.
//根据角度值传输扫描数据
virtual u_result ascendScanData(rplidar_response_measurement_node_t * nodebuffer, size_t count) = 0; protected:
RPlidarDriver() {}
virtual ~RPlidarDriver() {}
}; }}}
\param timeout The operation timeout value (in millisecond) for the serial port communication.
virtual u_result startScan(bool force = false, bool autoExpressMode = true) = 0; //请求 RPLIDAR 核心开始进行测距扫描,开始输出数据 //如 RPLIDAR 支持 ExpressScan 模式,且程序使用默认参数调用 //startScan()时,SDK 将自动使用 ExpressScan 模式
virtual u_result startScanNormal(bool force, _u32 timeout = DEFAULT_TIMEOUT) = 0; //强制以标准 Scan 模式进行测距扫描
virtual u_result startScanExpress(bool fixedAngle, _u32 timeout = DEFAULT_TIMEOUT) = 0; //强制进行高速扫描测距(ExpressScan)模式 //如果 RPLIDAR 固件不支持 ExpressScan 模式,该函数将执行失败。 /// Check whether the device support express mode.
///
/// \param support Return the result.
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication.
virtual u_result checkExpressScanSupported(bool & support, _u32 timeout = DEFAULT_TIMEOUT) = 0; //检查 RPLIDAR 是否支持 ExpressScan 模式 /// Ask the RPLIDAR core system to stop the current scan operation and enter idle state. The background thread will be terminated
///
/// \param timeout The operation timeout value (in millisecond) for the serial port communication
virtual u_result stop(_u32 timeout = DEFAULT_TIMEOUT) = 0; //请求 RPLIDAR 核心停止测距扫描 /// Wait and grab a complete 0-360 degree scan data previously received.
/// The grabbed scan data returned by this interface always has the following charactistics:
///
/// 1) The first node of the grabbed data array (nodebuffer[0]) must be the first sample of a scan, i.e. the start_bit == 1
/// 2) All data nodes are belong to exactly ONE complete 360-degrees's scan
/// 3) Note, the angle data in one scan may not be ascending. You can use API ascendScanData to reorder the nodebuffer.
///
/// \param nodebuffer Buffer provided by the caller application to store the scan data
///
/// \param count The caller must initialize this parameter to set the max data count of the provided buffer (in unit of rplidar_response_measurement_node_t).
/// Once the interface returns, this parameter will store the actual received data count.
///
/// \param timeout Max duration allowed to wait for a complete scan data, nothing will be stored to the nodebuffer if a complete 360-degrees' scan data cannot to be ready timely.
///
/// The interface will return RESULT_OPERATION_TIMEOUT to indicate that no complete 360-degrees' scan can be retrieved withing the given timeout duration.
///
/// \The caller application can set the timeout value to Zero(0) to make this interface always returns immediately to achieve non-block operation.
virtual u_result grabScanData(rplidar_response_measurement_node_t * nodebuffer, size_t & count, _u32 timeout = DEFAULT_TIMEOUT) = 0; //抓取一圈扫描测距数据序列 /// Ascending the scan data according to the angle value in the scan.
///
/// \param nodebuffer Buffer provided by the caller application to do the reorder. Should be retrived from the grabScanData
///
/// \param count The caller must initialize this parameter to set the max data count of the provided buffer (in unit of rplidar_response_measurement_node_t).
/// Once the interface returns, this parameter will store the actual received data count.
/// The interface will return RESULT_OPERATION_FAIL when all the scan data is invalid.
virtual u_result ascendScanData(rplidar_response_measurement_node_t * nodebuffer, size_t count) = 0; //对通过 grabScanData()获取的扫描数据按照角度递增排序。 protected:
RPlidarDriver() {}
virtual ~RPlidarDriver() {}
}; }}}
3、ultra_simlpe
Rplidar学习(二)—— SDK库文件学习的更多相关文章
- JavaWeb学习 (二十八)————文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- git学习(二) git的文件状态
git的文件状态 用于查看git的状态 git status 用于git文件的删除操作 git rm 如果只是 git rm --cache 仅删除暂存区里的文件: 如果不加--cache 会删除工作 ...
- 【学习】Windows PE文件学习(一:导出表)
今天做了一个读取PE文件导出表的小程序,用来学习. 参考了<Windows PE权威指南>一书. 首先, PE文件的全称是Portable Executable,可移植的可执行的文件,常见 ...
- java web 学习二(Tomcat服务器学习和使用1)
一.Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件. 如果想修改Tomcat服务器的启动端口,则可以在server.xml ...
- spring cloud 学习(二)关于 Eureka 的学习笔记
关于 Eureka 的学习笔记 个人博客地址 : https://zggdczfr.cn/ ,欢迎光临~ 前言 Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务.Sprin ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Numpy库的学习(三)
今天我们继续学习一下Numpy库的学习 废话不多说 ,开始讲 比如我们现在想创建一个0-14这样一个15位的数组 可以直接写,但是很麻烦,Numpy中就给我们了一个方便创建的方法 numpy中有一个a ...
- 集成学习二: Boosting
目录 集成学习二: Boosting 引言 Adaboost Adaboost 算法 前向分步算法 前向分步算法 Boosting Tree 回归树 提升回归树 Gradient Boosting 参 ...
- gcc编译时头文件和库文件搜索路径
特殊情况:用户自定义的头文件使用#include"mylib"时,gcc编译器会从当前目录查找头文件 一.头文件 gcc 在编译时寻找所需要的头文件 : ※搜寻会从-I开始( ...
随机推荐
- Return array from functions in C++
C++ does not allow to return an entire array as an argument to a function. However, you can return a ...
- 刷完OpenWrt在浏览器无法访问的解决办法
其实问题很明显. 是因为刷了trunk版固件. 并没有集成luci. 那接下来就是装luci.但是装luci需要联网(不过其实不联网其实也是可以安装的.) 我说的联网是让路有联网.而不是网线接路由,路 ...
- maven中的snapshot来源与注意事项
maven中的snapshot来源与注意事项 (2012-04-23 15:37:48) 转载▼ 标签: 杂谈 分类: java maven的依赖管理是基于版本管理的,在maven2之后,把版本管理细 ...
- tomcat中的日志开关文件(logging.properties)介绍
以tomcat-6.0.29为例: http://www.ossez.com/thread-18138-1-1.html #配置tomcat的日志输出方式,这里表示文件输出和控制台输出.handler ...
- IIS 之 IIS 7及以上多域名或端口绑定同一物理目录并设置不同默认文档
今天在 IIS 7 多端口或域名绑定同一物理目录,设置不同的默认文档遇到问题:同一物理目录的多个站点修改任意一个站点默认文档都会一起更改. 原因:在同一个物理目录下只有一个 web.config,并且 ...
- SQL Server 之 修改时不允许保存更改
SQL Server错误提示:不允许保存更改. 您所做的更改要求删除并重新创建以下表.您对无法重新创建的表进行了更改或者启用了“阻止保存要求重新创建表的更改”选项. 修改数据库的数据结构,比如把var ...
- 微信小程序 - template和include详细描述
演示 index.wxml <!-- 内部模板 --> <template name="all"> {{a}} {{b}} </template> ...
- spring boot-mybatis三种动态sql(5)
脚本sql XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现.适用于xml配置转换到注解配置 @Select(" ...
- vs2017莫名自动退出调试状态可以尝试一下如下的方法
- BIEE启动关闭服务(转)
一.环境说明 版本:BIEE11g (BIEE_11.1.1.9.0) OS:CentOS 6.5 64bit (所有的linux服务器都适用) 二.BIEE启动与关闭 BIEE11g 的启动包括三个 ...