OpenAVB详解(1)-Linux应用端

最近在研究OpenAVB代码,主要分两个方面进行梳理:

   Linux应用端

   内核驱动部分

目录

OpenAVB详解(1)-Linux应用端

主要文件说明

几个时间的区别

AVB应用(Talker/Listener)获取gPTP时间流程

Talker 端:

Listener端:


主要文件说明

  common:

ap_message.cpp

common_port.cpp

gptp_cfg.cpp: 处理解析gptp_cfg.ini配置文件

ieee1588clock.cpp

wireless_port.cpp

avbts_osnet.cpp

ether_port.cpp

gptp_log.cpp: 输出log相关信息

ptp_message.cpp

wireless_tstamper.cpp

 

几个时间的区别

    OPENAVB_CLOCK_REALTIME: 系统时间

    OPENAVB_CLOCK_MONOTONIC:系统启动上电到目前的时间

    OPENAVB_TIMER_CLOCK:目前等同于OPENAVB_CLOCK_MONOTONIC

    OPENAVB_CLOCK_WALLTIME:gPTP时间,也就是TSN网络对时之后的时间,其获取方式可参考如下代码:

bool osalClockGettime64(openavb_clockId_t openavbClockId, U64 *timeNsec) {
	if (openavbClockId < OPENAVB_CLOCK_WALLTIME)
	{
		clockid_t clockId = CLOCK_MONOTONIC;
		switch (openavbClockId) {
		case OPENAVB_CLOCK_REALTIME:
			clockId = CLOCK_REALTIME;
			break;
		case OPENAVB_CLOCK_MONOTONIC:
			clockId = CLOCK_MONOTONIC;
			break;
		case OPENAVB_TIMER_CLOCK:
			clockId = CLOCK_MONOTONIC;
			break;
		case OPENAVB_CLOCK_WALLTIME:
			break;
		}
		struct timespec getTime;
		if (!clock_gettime(clockId, &getTime)) {
			*timeNsec = ((U64)getTime.tv_sec * (U64)NANOSECONDS_PER_SECOND) + (U64)getTime.tv_nsec;
			AVB_TRACE_EXIT(AVB_TRACE_TIME);
			return TRUE;
		}
	}
	else if (openavbClockId == OPENAVB_CLOCK_WALLTIME) {
		AVB_TRACE_EXIT(AVB_TRACE_TIME);
		return x_getPTPTime(timeNsec);
	}
	AVB_TRACE_EXIT(AVB_TRACE_TIME);
	return FALSE;
}

gptp相关时间解析

gptp的时间相关参数可以通过其提供的shm_test来查看,相关log输出如下:

Frequency 3537550000 Hz
ml phoffset 2065469072503
ml freq offset 1.000155
ls phoffset 1608168703330912468
ls freq offset 1.000005
local time 3428994432467

gptp grandmaster id 00:00:00:00:00:00:00:00
gptp domain number 0

clock identity a0:36:9f:ff:fe:72:8f:20
priority1 248
clock_class 248
offset_scaled_log_variance 17258
clock_accuracy 34
priority2 248
domain_number 0
log_sync_interval 0
log_announce_interval 0
log_pdelay_interval 0
port_number 1

sync count 226
pdelay count 88
asCapable True
Port State 9
process_id 2655

其中

  local time: 是通过网卡取得的本地网卡时间,其调用流程如下:

    port->getDeviceTime=>setMasterOffset=>ipc->update=>LinuxSharedMemoryIPC::update

    这里port->getDeviceTime通过调用_hw_timestamper->HWTimestamper_gettime,最终进入到ptp内核驱动并获取了网卡时间。

  ml phoffset: 是master到Local的时间延迟,是通过sync_arrival-preciseOriginTimestamp计算得来的

               其中sync_arrival是sync数据包到达的设备时间,preciseOriginTimestamp为精准的原始时间戳。

 

AVB应用(Talker/Listener)获取gPTP时间流程

Talker 端:

  Talker会通过配置项spin_wait的不同,获取不同的时间戳,

    如果是0,则直接获取OPENAVB_TIMER_CLOCK->osalClockGettime->CLOCK_MONOTONIC->clock_gettime

    如果是1,则:

       1. talkerStartStream->CLOCK_GETTIME->osalClockGettime->x_getPTPTime

       2. talkerDoStream->CLOCK_GETTIME->osalClockGettime->x_getPTPTime

x_getPTPTime代码如下:

static bool x_getPTPTime(U64 *timeNsec) {
	AVB_TRACE_ENTRY(AVB_TRACE_TIME);

	if (gptpgetdata(gPtpMmap, &gPtpTD) < 0) {
		AVB_LOG_ERROR("GPTP data fetch failed");
		AVB_TRACE_EXIT(AVB_TRACE_TIME);
		return FALSE;
	}

	uint64_t now_local;
	uint64_t update_8021as;
	int64_t delta_8021as;
	int64_t delta_local;

	if (gptplocaltime(&gPtpTD, &now_local)) {
		update_8021as = gPtpTD.local_time - gPtpTD.ml_phoffset;
		delta_local = now_local - gPtpTD.local_time;
		delta_8021as = gPtpTD.ml_freqoffset * delta_local;
		*timeNsec = update_8021as + delta_8021as;

		AVB_TRACE_EXIT(AVB_TRACE_TIME);
		return TRUE;
	}

	AVB_TRACE_EXIT(AVB_TRACE_TIME);
	return FALSE;
}

  其大体流程如下:

   1. 获取gptp数据

   2. 获取本地系统时间 (CLOCK_REALTIME)

           3. 通过本地系统时间计算as的now_time,计算过程代码如下:

bool gptplocaltime(const gPtpTimeData * td, uint64_t* now_local)
{
	struct timespec sys_time;
	uint64_t now_system;
	uint64_t system_time;
	int64_t delta_local;
	int64_t delta_system;

	if (!td || !now_local)
		return false;

	if (clock_gettime(CLOCK_REALTIME, &sys_time) != 0)
		return false;

	now_system = (uint64_t)sys_time.tv_sec * 1000000000ULL + (uint64_t)sys_time.tv_nsec;

	system_time = td->local_time + td->ls_phoffset;
	delta_system = now_system - system_time;
	delta_local = td->ls_freqoffset * delta_system;
	*now_local = td->local_time + delta_local;

	return true;
}

   4. 通过本地上次的now_time时间和gptp时间的偏移计算当前now_local,即为目前的as wall time时间

   5. 输出校准后的时间

Listener端:

  1. listenerStartStream->CLOCK_GETTIME(OPENAVB_TIMER_CLOCK)->osalClockGettime->CLOCK_MONOTONIC->clock_gettime

       2. listenerDoStream->CLOCK_GETTIME(OPENAVB_TIMER_CLOCK)->osalClockGettime->CLOCK_MONOTONIC->clock_gettime

Listener直接使用了系统单调时间作为时间戳

 

OpenAVB h264 gst流程(AVB 1722 协议)

Callback 接口:

    intf_cfg_cb: 配置接口回调

    intf_gen_init_cb:

    intf_tx_init_cb: A call to this callback indicates that this interface module will be a talker. Any talker initialization can be done in this function.

    intf_tx_cb: This callback will be called for each AVB transmit interval. Commonly this will be 4000 or 8000 times  per second.

    intf_rx_init_cb: A call to this callback indicates that this interface module will be a listener. Any listener initialization can be done in this function.

    intf_rx_cb: This callback is called when acting as a listener

    intf_end_cb: This callback will be called when the interface needs to be closed. All shutdown should occur in this function

    intf_gen_end_cb:

    intf_set_stream_uid_cb:

Talker端:

   intf_tx_cb (openavbIntfH264RtpGstTxCB)流程:

   =>openavbMediaQHeadLock(pMediaQ);

           =>gst_al_pull_rtp_buffer

           =>gst_al_rtp_buffer_get_marker

           =>openavbAvtpTimeSetToWallTime(pMediaQItem->pAvtpTime); //其中设置该包的walltime时间,该时间即为通过gptp对时后的网络时间

           =>openavbMediaQHeadPush(pMediaQ);

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《嵌入式Linux应用程序开发详解》是一本非常实用的Linux应用程序开发指导书,其主要讲解了嵌入式Linux系统应用程序的开发过程、技术、工具和优化方法。 本书涵盖了Linux应用程序开发的基础知识和实际案例,详细介绍了Linux系统的组成原理,以及如何开发应用程序。书中内容涉及嵌入式Linux系统的内核、文件系统、网络等方面,通过实践案例,为读者解决了开发过程中遇到的各种问题。 本书结构清晰,内容实用,读者可以从中学习到很多Linux开发的技巧和经验。其中,本书还对Linux应用程序性能优化方面进行了详细讲解,介绍了如何优化系统调用、内存管理、文件系统等性能方面的技术和方法。 总之,《嵌入式Linux应用程序开发详解》是一本非常好的嵌入式Linux应用程序开发入门书,对于想要从事Linux应用程序开发的工程师或编程爱好者来说,都是一本值得推荐的书籍。 ### 回答2: “嵌入式linux应用程序开发详解”是一本深入介绍嵌入式linux应用程序开发的书籍,它详细讲解了嵌入式Linux系统的基本原理、应用开发、系统调试等方面,适合想要学习嵌入式Linux应用程序开发的人阅读。 该书籍首先介绍了嵌入式系统的概念以及嵌入式Linux系统的基本架构和启动流程,随后详细讲解了Linux系统下的应用程序开发,如进程管理、文件系统、网络编程、驱动程序等。此外,该书还介绍了如何在开发过程中使用调试器进行系统调试和性能分析。 在讲解应用程序开发的过程中,该书重点介绍了如何使用GCC编译器和GDB调试器,以及如何使用BusyBox和uClibc等开源软件库实现系统开发,读者可以通过这些工具和库知道如何实现嵌入式Linux系统的开发过程。 总的来说,“嵌入式linux应用程序开发详解”是一本非常适合想要深入学习嵌入式Linux应用程序开发的人阅读的书籍,它全面深入地讲解了嵌入式Linux系统的各个方面,不仅是一本理论性的书籍,还能带领读者一步步实际操作。 ### 回答3: 嵌入式Linux应用程序开发详解PDF一书详细介绍了嵌入式系统以及嵌入式Linux系统的相关知识。本书首先介绍了嵌入式系统中的硬件结构和软件结构,然后介绍了嵌入式Linux系统以及Linux操作系统的基本工作原理和操作方法。 本书旨在帮助开发人员了解嵌入式系统的基本原理以及如何使用Linux系统进行应用程序开发。本书以上传统的C语言为基础,通过介绍Linux下的文件系统、进程管理、内存管理、设备驱动等基础知识,使读者能够深入了解如何开发嵌入式Linux应用程序,如网络应用程序、多媒体应用程序等。 本书特设了大量实例和应用场景,通过实例讲解的方式帮助读者理解和掌握开发嵌入式Linux应用程序的方法和技巧。此外,本书还介绍了嵌入式Linux系统的调试、测试和优化等相关内容,让读者能够全面掌握嵌入式Linux应用程序的开发过程。 总之,本书是一本深入浅出、实用性强的嵌入式Linux应用程序开发详解。通过详细介绍嵌入式系统和Linux操作系统的基础知识,以及丰富的实例和应用场景,本书可帮助读者快速掌握开发嵌入式Linux应用程序的方法和技巧,从而提高其开发效率和成功率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值