4.7 多任务数据共享和软件速度优化

\qquad 本文讨论HD-GR导航软件中的多任务数据共享和软件速度优化。

4.7.1 多任务数据共享

\qquad AGRS_GP_1软件只有一个中断,软件初始化后,所有任务(线程)的执行都由这个中断触发。本小节讨论AGRS_GP_1软件是如何保证多个任务之间安全共享最少量数据的。

1、accum_task和message_task间的数据共享

\qquad 相关数据累积任务(accum_task)和电文处理任务message_task之间共享了以下数据:

  • m_GPS_CH – GPS信号跟踪通道数据结构
  • m_B1I_CH – BDS信号跟踪通道数据结构
  • g_channel_bits – 通道电文数据位集变量

当任一通道(每20ms或2ms)出现1-位电文时,accum_task就会唤醒message_task进行处理,因此message_task的执行频度很高,几ms量级,仅次于accum_task的0.5~1ms。为此,对在这两个任务中存取这些数据的代码,需要施加互斥机制。

\qquad 在所有任务中,accum_task优先级最高,它的执行不会被任何其它任务挂起。任务message_task的优先级排第三,只会由于出现累积中断和调度accum_task任务而挂起。因此,为保证安全存取上述共享数据,在message_task中采取了以下互斥措施:

  • 将关键代码紧致地集中在若干处;
  • 在执行关键代码前后,分别禁用和启用中断。

当然,频繁禁用和启用中断会影响CPU处理效率。鉴于此,AGRS_GP_1软件通过检查定义在头文件constants.h中的宏开关GNSS_ENABLE_CRITICAL,来决定是否施加上述互斥机制。如果CPU性能足够高,卫星信号跟踪很稳定,电文处理出错率很低,就可在代码中不定义宏开关GNSS_ENABLE_CRITICAL。详情可参阅源文件中宏调用GNSS_ENTER_CRITICAL()和GNSS_EXIT_CRITICAL()之间的代码段。

2、message_task和ephemeris_task间的数据共享

\qquad 卫星电文(m_gps_messages, m_b1i_messages)是电文处理任务(message_task)和星历处理任务(ephemeris_task)之间的共享数据结构,前者对它们解码,后者将它们转换为星历(历书)。

\qquad 一个通道的电文 (m_gps_messages[ch], m_b1i_messages[ch])能够保存一颗卫星的一帧数据。更新一帧数据需要花费30秒,它由message_task连续、逐位地写入。message_task每解码一个完整6秒子帧,就向ephemeris_task发出一个有数据等待处理的信号,让后者将它转换为星历(历书)。因此,单就处理一个通道而言,只要ephemeris_task能在子帧更新后的24秒内完成这个子帧的星历转换,就不会与message_task发生数据读/写冲突。不过,由于HD-GR导航软件最多能锁定约16颗卫星,基本的要求是:一个子帧的星历转换时间不应大于1.5秒。

\qquad 考虑到卫星最快每小时上传一次星历电文,而ephemeris_task对于相同龄期的电文只处理一次,再考虑到不同卫星信号的锁定不会同时,因此可以合理地将上述要求放宽为1.5×120秒=180秒。对于这一处理要求,可以认为message_task和ephemeris_task能够安全地存取共享的卫星电文(m_gps_messages, m_b1i_messages),而无需施加额外的互斥机制。

3、accum_task和meas_task间的数据共享

\qquad 相关数据累积任务(accum_task)和观测量读取任务(meas_task)间共享了以下数据:

  • m_GPS_CH – GPS信号跟踪通道数据结构
  • m_B1I_CH – BDS信号跟踪通道数据结构

当accum_task检测到一个新TIC信号时,就会唤醒meas_task进行处理(缺省为每100 ms调用1次)。为存取安全起见,应在读/写这些数据的代码段,施加互斥机制。

\qquad 在所有任务中,accum_task优先级最高,它的执行不会被任何其它任务挂起。任务meas_task的优先级排第二,只会由于出现累积中断和调度accum_task任务而挂起。因此,为保证安全存取上述共享数据,可在meas_task中采取以下互斥措施:

  • 将关键代码紧致地集中在若干处;
  • 在执行关键代码前后,分别禁用和启用中断。

\qquad AGRS_GP_1软件通过检查定义在头文件constants.h中的宏开关GNSS_ENABLE_CRITICAL,来决定是否施加上述互斥机制。如果CPU性能足够高,卫星信号跟踪很稳定,观测量数据读取和定位解算结果出错率很低,就可以在代码中不定义宏开关GNSS_ENABLE_CRITICAL。详情可参阅源文件中宏调用GNSS_ENTER_CRITICAL()和GNSS_EXIT_CRITICAL()之间的代码段。

4、position_task中的数据共享

\qquad 定位计算任务(position_task)使用了以下共享数据:

  • 与观测量读取任务(meas_task) 共享了:
    • m_ppr_pos – 指向卫星伪距结构(pseudorange_t)数组的指针
    • m_pvt_share – PVT解状态和时钟偏差
  • 与星历处理任务(ephemeris_task)共享了
    • m_gps_ephetable – GPS星历表
    • m_b1i_ephetable – BDS星历表

\qquad AGRS_GP_1软件通过检查头文件constants.h来决定是否使用互斥量(mutex)来保证不同任务操作共享数据的完整性。如果constants.h中存在GNSS_ENABLE_MUTEX宏定义,则使用互斥量,具体而言:

  • 在position_task中,创建互斥量m_PrCbsMutex,用于与meas_task互斥地存取共享数据m_ppr_pos和m_pvt_share;
  • 在ephemeris_task中,创建互斥量m_EphTabMutex,用于与position_task互斥地存取共享数据m_gps_ephetable和m_b1i_ephetable。

5、allocate_task中的数据共享

\qquad 通道分配任务(allocate_task)与相关数据累积任务(accum_task)共享了跟踪通道数据结构m_GPS_CH, m_B1I_CH:

  • 在accum_task的一个处理环中,首先检查每个通道ch的处理状态:当状态处于CHANNEL_OFF时,只会简单地向allocate_task发出重新分配通道ch的信号;否则,才会读写它的共享数据m_GPS_CH[ch]或m_B1I_CH[ch];
  • 任务allocate_task比任务accum_task的优先级低,不会抢占accum_task的执行,即使accum_task修改了通道ch状态,也不会引起与allocate_task的共享数据读写冲突。
  • 只有在通道ch处于CHANNEL_OFF状态时,allocate_task才会分配它,且在初始化通道数据m_GPS_CH[ch]或m_B1I_CH[ch]的最后一步,才会将通道设置为非CHANNEL_OFF状态。

由此可见,只有在allocate_task写通道为非CHANNEL_OFF状态未完成且恰好accum_task读取通道状态时,两个任务才可能存在共享数据存取冲突。这种情况下,最坏结果是损失通道ch的一个相关累积数据,即在下一个累积中断唤醒的accum_task处理环中,再按allocate_task更新后的状态进行处理。这是可以接受的。

\qquad 另外,任务allocate_task在分配一个通道时,调用了电文处理任务(message_task)和星历处理任务(ephemeris_task)中的以下函数:

  • gps_clear_messages(ch)
  • gps_clear_ephemeris(ch)
  • b1i_clear_messages(ch)
  • b1i_clear_ephemeris(ch)

鉴于以下理由,可以认为allocate_task能够与message_task和ephemeris_task安全地共享上述函数涉及的数据:

  • 任务accum_task不会设置标志位,让message_task处理一个处于CHANNEL_OFF状态的通道;
  • 任务message_task和ephemeris_task比任务allocate_task的优先级高,对于刚刚设置为CHANNEL_OFF状态的通道,只有在message_task和ephemeris_task空闲时,allocate_task才有时机重新分配它。
  • 在allocate_task分配这个完成之前,message_task和ephemeris_task不会再处理与这个通道相关的任务数据。

4.7.2 软件速度优化

\qquad GNSS接收机为满足实时处理要求,除了要用硬件逻辑来实现基带模块外,还要求导航软件和运行它们的CPU满足速度要求。为此,AGRS_GP_1项目选择快速模型(NIOS II/f)构建了NIOS II CPU,并为它优化了速度选项,参见2.2.1。另外,为了加速导航软件代码执行和数据存取速度,在FPGA上分配了两个挂接在CPU上的紧耦合片上存储器组件,分别用于存取具有关键速度要求的代码和数据,参见2.3.1。本节主要介绍HD-GR导航软件如何通过配置BSP速度选项,以及如何利用这两个紧耦合存储器,来提高导航软件运行速度。当然,优化具体算法是软件速度优化的另一有效办法,这在HD-GR导航软件实现的许多地方都有所体现,在“定位解算方程”一节(第4.6.2节)中给出了一例,其它烦请耐心阅读和分析源代码及其注释。

1、配置BSP项目以优化速度

\qquad HD-GR导航软件项目(AGRS_GP_1)是使用软件生成工具(Nios II IDE)创建的。Nios II IDE创建AGRS_GP_1项目同时,使用AGRS_GP_1_SYS.sopcinfo文件和选择μC/OS-II RTOS操作系统,创建了BSP项目AGRS_GP_1_bsp。这个BSP项目是c源文件、头文件和初始化文件的集合,用于为系统中的硬件构建自定义库。此自定义库与应用程序项目链接,为系统创建可执行的二进制文件,称为应用程序映像。

\qquad BSP项目可用BSP Editor进行配置,具体选项是操作系统相关的。在我们的BSP项目AGRS_GP_1_bsp中,如下地配置了与速度优化有关的选项:

  • 将CPU的异常矢量(.exceptions)设置在片上紧耦合指令存储器(tightly_coupled_instruction_memory)中;
  • 将软件中的中断服务代码(.isrcode)设置在片上紧耦合指令存储器(tightly_coupled_instruction_memory)中;
  • 将软件中的中断服务数据(.isrdata)设置在片上紧耦合数据存储器(tightl_coupled_data_memory)中。

以便在生成可执行文件时,能够将与这些段相关联的软件代码和数据,分别链接到上述紧耦合指令存储器和紧耦合数据存储器中。

2、用紧耦合存储器加速软件

\qquad 由前一小节知道,AGRS_GP_1项目为了增强导航软件性能,除将在处理中断时使用的异常矢量实现在紧耦合存储器中外,还用紧耦合存储器实现了快速代码段(.isrcode)和快速数据段(.isrdata)。为了将导航软件中的指定函数和数据与这些段相关联,需要在编写源代码时予以相应声明。

\qquad 例如,在源文件agrs_gp_1_ucos.c中,将累积中断处理例程accum_int_handler的函数原型声明为:

static void accum_int_handler(void *context) __attribute__ ((section(".isrcode.txt")));

对此,编译器在编译/连接时,将把accum_int_handler的函数代码放在.isrcode段。而这个.isrcode段将被放在紧耦合指令存储器(tightly_coupled_instruction_memory)中。

\qquad 另如,在源文件agrs_gp_1_ucos.c中,还如下地定义了相关数据累积任务栈accum_task_stk:

OS_STK accum_task_stk[TASK_STACKSIZE] __attribute__ ((section(".isrdata.rwdata")));

对此,编译器在编译/连接时,将把数据缓冲区accum_task_stk[TASK_STACKSIZE]放在.isrdata段。而这个.isrdata段将被放在紧耦合数据存储器(tightl_coupled_data_memory)中。

\qquad 实际上,AGRS_GP_1项目将以下例程和任务的全部代码,以及它们存取的几乎全部数据都放置在了紧耦合存储器中:

  • 累积中断处理例程accum_int_handler(…)
  • 相关数据累积任务accum_task
  • 电文处理任务message_task

涉及的源文件包括:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值