IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 高通 slpi tcs3701_als_init -> 正文阅读

[网络协议]高通 slpi tcs3701_als_init

// set_client_request 设置 来自客服端的请求. 这个客户端是谁? 暂时理解为 hal 层吧…

publish_attributes 调用后,说明 ,sensor 已经准备好了,可以使用了.
此时 ,AP 测 可以查询到并且使用.

看下 tcs3701_als_init
在这里插入图片描述

	tcs3701_common_init(this);
{
	tcs3701_state *state = (tcs3701_state*)this->state->state;

//   1: 获取 服务.  SNS_DIAG_SERVICE 和  SNS_SYNC_COM_PORT_SERVICE 
//  SNS_SYNC_COM_PORT_SERVICE 这个好像是上电的..
	struct sns_service_manager *smgr= this->cb->get_service_manager(this);
	state->diag_service = (sns_diag_service *)smgr->get_service(smgr, SNS_DIAG_SERVICE);
	state->scp_service = (sns_sync_com_port_service *)smgr->get_service(smgr, SNS_SYNC_COM_PORT_SERVICE);

	sns_memzero(&state->common, sizeof(tcs3701_common_state));

//   2: 发送 请求 注册 interrupt timer 和  registry 这些平台 sensor .  
	/* TCS3701 sensor fetches all common dependent sensor SUIDs. */
	if (TCS3701_ALS == state->sensor)
	{
		state->common.start_hw_detect = false;
		tcs3701_send_suid_req(this, "interrupt", sizeof("interrupt"));
		tcs3701_send_suid_req(this, "timer", sizeof("timer"));
	}
	/* Send registry suid request at last */
	tcs3701_send_suid_req(this, "registry", sizeof("registry"));
}

看下 这个 tcs3701_send_suid_req 是怎么实现的
首先 看下 sensor 之间是怎么交流的.?
从图片可以看到 有个stream
requset 和 event 都是通过 stream
在这里插入图片描述

tcs3701_send_suid_req
{
{
	tcs3701_state *state = (tcs3701_state*)this->state->state;
	sns_service_manager *smgr = this->cb->get_service_manager(this);
	// 1: 获得 SNS_STREAM_SERVICE 
	sns_stream_service *stream_service = (sns_stream_service*)smgr->get_service(smgr, SNS_STREAM_SERVICE);
	pb_buffer_arg data = (pb_buffer_arg){.buf = data_type, .buf_len = data_type_len};
	size_t encoded_len;
	uint8_t buffer[50];

	sns_memset(buffer, 0, sizeof(buffer));

	sns_suid_req suid_req = sns_suid_req_init_default;
	suid_req.has_register_updates = true;
	suid_req.register_updates = true;
	suid_req.data_type.funcs.encode = &pb_encode_string_cb;
	suid_req.data_type.arg = &data;

	if (NULL == state->fw_stream)
	{
//  2: 创建 sensor  stream .我们创建了一个 流		stream_service->api->create_sensor_stream(stream_service,
				this, sns_get_suid_lookup(), &state->fw_stream);
	}
//  序列化 ,存放在 buff 里面..
	encoded_len = pb_encode_request(buffer, sizeof(buffer), &suid_req, sns_suid_req_fields, NULL);
	if (0 < encoded_len)
	{
//  发送前的一些设置. 设置 msg_id 设置为  	SNS_SUID_MSGID_SNS_SUID_REQ . 
		sns_request request = (sns_request){.request_len = encoded_len,
			.request = buffer, .message_id = SNS_SUID_MSGID_SNS_SUID_REQ};
//  send_request : 发送请求. 有个问题,发送给谁?? 	
看下注释:
看这样子像是 发送到其他  sensor 或者服务上的. 这里是发送到了SNS_STREAM_SERVICE 这个 server 上去了?? 
/*
* Send a request to some other service/Sensor.  This request may
   * update or replace the existing stream, depending on the Sensor
   * specification
   * 	
	*/
state->fw_stream->api->send_request(state->fw_stream, &request);
	}
}
}

总结下:这个函数做啥了:
1:创建 sensor_stream
2:设置 message id :SNS_SUID_MSGID_SNS_SUID_REQ
3: 发送.

在 tcs3701_common_init 注册了三个 platform sensor 的请求
interrupt , timer ,registry. 在高通中 ,把这种 叫做 datatype
说明 tcs3701 会用到 这三个 platform sensor
继续往下走的话,就是
tcs3701_als_publish_attributes(this);

static void tcs3701_als_publish_attributes(sns_sensor *const this)
{
// 就以  publish name 举例.其他的流程都是一样的..
// 最重要的 就是这个 函数.sns_publish_attribute
	tcs3701_state *state = (tcs3701_state*)this->state->state;
	{
		char const name[] = "tcs3701";
		sns_std_attr_value_data value = sns_std_attr_value_data_init_default;
		value.str.funcs.encode = pb_encode_string_cb;
		value.str.arg = &((pb_buffer_arg)
			{.buf = name, .buf_len = sizeof(name)});

		sns_publish_attribute(this, SNS_STD_SENSOR_ATTRID_NAME,
			&value, 1, false);
	}
}

看下 注释:
用 Attribute Service 来发布一个 sensor 的属性…
在这里插入图片描述
看下是怎么写的 这个函数. 这里我不得不吐槽下 SI ,函数前面加个限定竟然无法识别到这是个函数.气死!!!

在这里插入图片描述

SNS_SECTION(".text.sns")void
sns_publish_attribute(sns_sensor *const sensor,
    uint32_t attribute_id, sns_std_attr_value_data const *values,
    uint32_t values_len, bool completed)
{
  size_t attribute_len = 0;
  sns_std_attr std_attr = (sns_std_attr)
    { .attr_id = attribute_id, .value.values.funcs.encode = &sns_pb_encode_attr_cb,
      .value.values.arg = &((pb_buffer_arg){ .buf = values, .buf_len = values_len }) };

  if(pb_get_encoded_size(&attribute_len, sns_std_attr_fields, &std_attr))
  {
    sns_service_manager *manager = sensor->cb->get_service_manager(sensor);
//  1: 获得  这个 server SNS_ATTRIBUTE_SERVICE
    sns_attribute_service *attribute_service =
      (sns_attribute_service*)manager->get_service(manager, SNS_ATTRIBUTE_SERVICE);

    uint8_t attribute[attribute_len];
    pb_ostream_t stream = pb_ostream_from_buffer(attribute, attribute_len);

//  service api 中的 publish_attribute 把  tcs3701 的 name 属性 注册上去了.( 是注册到了 server 里面去了?)

    if(pb_encode(&stream, sns_std_attr_fields, &std_attr))
   attribute_service->api->publish_attribute(attribute_service, sensor,
        attribute, attribute_len, attribute_id, completed);

    // PEND: Print a message upon errors
  }

pb_get_encoded_size :数据的长度是
pb_ostream_from_buffer就是把编码后的数据写到buffer里

publish 完毕后, 这个 sensor 初始化就完毕,可以使用了.

// --------------------分界线---------------------------------------------------------------
看下 是怎么 接收事件的
上面 通过 tcs3701_send_suid_req 发送了几个请求
messig_id :SNS_SUID_MSGID_SNS_SUID_REQ
看下是怎么处理这个 事件的

void tcs3701_process_suid_events(sns_sensor *const this)
{
//1:  mesg_id 为 SNS_SUID_MSGID_SNS_SUID_EVENT
if (SNS_SUID_MSGID_SNS_SUID_EVENT == event->message_id)
// 2: 后面主要是 从 pb buffer 解码
比如: 这种:
/* If no suids found, ignore the event */
			if (suid_search.num_of_suids == 0)
			{
				SNS_PRINTF(ERROR, this, "TCS3701 no SUID found");
				continue;
			}

}
//  uid 赋值  给  state ,后面会用到
/* Save suid based on incoming data type name */
			if (0 == strncmp(data_type_arg.buf, "interrupt", data_type_arg.buf_len))
			{
				SNS_PRINTF(ERROR, this, "TCS3701 save IRQ SUID");
				state->common.irq_suid = uid_list;
			}

我们 在回到
tcs3701_sensor_notify_event

sns_rc tcs3701_sensor_notify_event(sns_sensor *const this)
{
//  1: 接收服务上发过来的信息
  tcs3701_process_suid_events(this);
//2: request_registry 
if (!sns_sensor_uid_compare(&state->common.reg_suid, &((sns_sensor_uid){{0}})))
			{
				tcs3701_request_registry(this);
			}
}			

在来看下

void tcs3701_request_registry(sns_sensor *const this)
{
//1: 获得 SNS_STREAM_SERVICE 服务
	sns_service_manager *service_mgr = this->cb->get_service_manager(this);
	sns_stream_service *stream_svc =
		(sns_stream_service*)service_mgr->get_service(service_mgr, SNS_STREAM_SERVICE);
//2:create_sensor_stream
stream_svc->api->create_sensor_stream(stream_svc,
			this, state->common.reg_suid, &state->reg_data_stream);
//3: 注册的是  ALS  
		if (TCS3701_ALS == state->sensor)
		{
			
	.....
			tcs3701_sensor_send_registry_request(this, TCS3701_CONFIG_ALS);
		}
}

看下 这个是怎么写的

static void tcs3701_sensor_send_registry_request(sns_sensor *const this,
{
  // 就是 向  server 发送了 SNS_REGISTRY_MSGID_SNS_REGISTRY_READ_REQ 消息
 
}

我曹,真麻烦,还没完. 有点扛不住了. 哎,继续往下看吧…’

// 处理  SNS_REGISTRY_MSGID_SNS_REGISTRY_READ_REQ 
void tcs3701_sensor_process_registry_event(sns_sensor *const this, sns_sensor_event *event)
{
// 1: 解析 server 发送过来的数据.
if (SNS_REGISTRY_MSGID_SNS_REGISTRY_READ_EVENT == event->message_id)
	{
		sns_registry_read_event read_event = sns_registry_read_event_init_default;
		pb_buffer_arg group_name = {0,0};
		read_event.name.arg = &group_name;
		read_event.name.funcs.decode = pb_decode_string_cb;

// 2:我们当时申请 注册的就是 这个  TCS3701_CONFIG_ALS 
stream = pb_istream_from_buffer((void*)event->event, event->event_len);

			if (0 == strncmp((char*)group_name.buf, TCS3701_CONFIG_ALS, group_name.buf_len))
			{

//  3:  填充数据.快完了. 看下是怎么填充的..
// 4: item_group_name 注册的 name 比如:TCS3701_CONFIG_ALS
// 5:  
sns_registry_decode_arg arg = {
						.item_group_name = &group_name,
						.parse_info_len = 1,
						.parse_info[0] = {
							.group_name = "config",
//  5: 匹配就要调用这个							
							.parse_func = sns_registry_parse_phy_sensor_cfg,
//  6: 保存 上面 	parse_func的数据..						
							.parsed_buffer = &state->common.als_registry_cfg
						}
					};

}

再来看下 sns_registry_parse_phy_sensor_cfg
函数的 作用就是解析  一些 item

SNS_SECTION(".text.sns") bool
sns_registry_parse_phy_sensor_cfg(sns_registry_data_item *reg_item,
                                  pb_buffer_arg  *item_name,
                                  pb_buffer_arg  *item_str_val,
                                  void *parsed_buffer)
{
  bool rv = true;

  .....
  else if(reg_item->has_sint)
  {
    sns_registry_phy_sensor_cfg *cfg =
      (sns_registry_phy_sensor_cfg *)parsed_buffer;
// 解析出来的是 is_dri 
    if(0 == strncmp((char*)item_name->buf, "is_dri", item_name->buf_len))
    {
      cfg->is_dri = reg_item->sint;
    }
    //  hw_id 
    else if(0 == strncmp((char*)item_name->buf,
                         "hw_id",
                         item_name->buf_len))
    {
      cfg->hw_id = reg_item->sint;
    }
    else if(0 == strncmp((char*)item_name->buf,
                         "res_idx",
                         item_name->buf_len))
    {
      cfg->res_idx = reg_item->sint;
    }
    else if(0 == strncmp((char*)item_name->buf,
                         "sync_stream",
                         item_name->buf_len))
    {
      cfg->sync_stream = (reg_item->sint == 1) ?
        true : false;
    }
  }
  ....
}

是从  tcs3701.als.config 这个文件读取出来的

继续往下看 tcs3701_sensor_process_registry_event

//  设置  decode 的 callback 和sns_registry_decode_arg 
read_event.data.items.funcs.decode = &sns_registry_item_decode_cb;
					read_event.data.items.arg = &arg;
// 开始  decond, 信息保存在   read_event 中.
					rv = pb_decode(&stream, sns_registry_read_event_fields, &read_event);

//  这个 调试 也许用的上,先记录下..
// 解析完毕.数据保存在 state->common.als_registry_cfg 中..
if (rv)
				{
					state->common.als_registry_cfg_received = true;

					SNS_PRINTF(LOW, this, "TCS3701 Registry read event for ALS group registry_cfg received "
						"is_dri:%d, hardware_id:%d resolution_idx:%d, supports_sync_stream:%d",
						state->common.als_registry_cfg.is_dri, state->common.als_registry_cfg.hw_id,
						state->common.als_registry_cfg.res_idx, state->common.als_registry_cfg.sync_stream);
				}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-06-20 23:08:51  更:2022-06-20 23:09:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 13:42:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码