部分代码是从BES中扣下来的。
指令处理表做的不是很好,本来使用rodata方式,图方便没有使用上。
八.TLV通讯协议代码实现
1. 目录结构
1. demo\main.c
入口函数,没什么特别,引导执行demo而已
#include "tlv_protocol_demo.h"
int main(void)
{
tlv_protocol_main();
return 0;
}
2. demo\tlv_protocol_demo.c
demo入口。先看static void app(protocol_handle_t handle),拿到一个句柄(对象),然后执行protocol_send_data和protocol_receive_data。非常简单。tlv_protocol_main作用就是创建对象,启动app而已。怎么创建对象,提供必要的执行函数和消息和最重要的cmd表。
#include "tlv_protocol_demo.h"
#include "tlv_protocol.h"
#include "stdio.h"
#include "string.h"
#include <sys/time.h>
#include <sys/signal.h>
#include <pthread.h>
/*******************************************************************************
* 主函数复制初始化对象
* app负责使用对象,无论main传来什么,app只负责使用
********************************************************************************/
static void app(protocol_handle_t handle)
{
printf("Start app ... \r\n");
/* 对象发送数据测试 */
printf("---------------protocol send data-------------- \r\n");
/* 命令码 | 长度 | 数据 */
uint8_t ptrData1[] = {
0x01, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03};
protocol_send_data(handle->p_drv, ptrData1);
uint8_t ptrData2[] = {
0x02, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03};
protocol_send_data(handle->p_drv, ptrData2);
uint8_t ptrData3[] = {
0x04, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03};
protocol_send_data(handle->p_drv, ptrData3);
/* 对象接收数据测试 */
printf("---------------protocol receive data-------------- \r\n");
/* 响应 | 长度 | 响应码 | 状态 | 长度 | 数据 */
uint8_t resData1[] = {
0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03};
protocol_receive_data(handle->p_drv, resData1);
/* 响应 | 长度 | 响应码 | 状态 | 长度 | 数据 */
uint8_t resData2[] = {
0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03};
protocol_receive_data(handle->p_drv, resData2);
/* 响应 | 长度 | 响应码 | 状态 | 长度 | 数据 */
uint8_t resData3[] = {
0x00, 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02, 0x03};
protocol_receive_data(handle->p_drv, resData3);
while (1)
;
}
/*********************************提供给对象的函数************************************/
static tlv_protocol_dev_t tlv_protocol_dev;
// 发送
void data_put(uint8_t *ptr_data, uint32_t data_len)
{
for (uint8_t i = 0; i < data_len; i++)
{
printf("%02x", ptr_data[i]);
}
printf("\r\n");
}
// 停止定时
void timer_stop(void)
{
struct itimerval value;
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 0;
value.it_interval = value.it_value;
setitimer(ITIMER_REAL, &value, NULL);
}
// 重新开始定时器
static void timer_cb(int signo)
{
supervision_timer_cb(&tlv_protocol_dev);
}
void timer_start(uint32_t time)
{
timer_stop();
signal(SIGALRM, timer_cb);
struct itimerval new_value;
memset(&new_value, 0, sizeof(new_value));
new_value.it_interval.tv_sec = 0; //设置再次定时时间为1S
new_value.it_interval.tv_usec = 0;
new_value.it_value.tv_sec = time / 1000; //设置首次定时时间为2S
new_value.it_value.tv_usec = (time % 1000) * 1000;
setitimer(ITIMER_REAL, &new_value, NULL);
}
// 系统时间戳ms
uint64_t get_system_time(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
// 互斥开
static pthread_mutex_t mutex;
void mutex_wait(void)
{
pthread_mutex_lock(&mutex);
}
// 互斥关闭
void mutex_release(void)
{
pthread_mutex_unlock(&mutex);
}
/****************************************************************************
* 接收数据处理
****************************************************************************/
void get_response_handler(uint32_t cmdCode, uint8_t *ptrParam, uint32_t paramLen)
{
printf("%s\r\n", __func__)