设计模式之举例说 设计原则

Nuttx环境搭建

  返回  

20、通道分配任务实现

2021/8/21 16:17:46 浏览:

\qquad 下面是HD-GR GNSS导航软件的通道分配任务实现代码:

// main_allocate.c -- Allocate channels.

/* 
 * Copyright (C) 2005 Andrew Greenberg
 * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991).
 * See the "COPYING" file distributed with this software for more information.
 */

/* Namuru GPS receiver project
 * Original: allocate.c
 * Modes   : Some code has been modified for adaption to the Namuru HW by Peter Mumford
 * version : V1.0
 * date    : 21st/Dec/2006
 */

/* 
 * HD-GR GNSS receiver project
 * Modes    : Inherited the code of allocate.c in the Namuru GPS receiver project 
 *            V1.0 and made necessary adjustments to adapt to the new HW, RTOS and 
 *            functions.
 * version  : V1.0
 * date     : xx/xx/2015
 */

#include <io.h>
#include <stdio.h>
#include <math.h>
#include "includes.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "constants.h"
#include "gnsstime.h"
#include "main_allocate.h"
#include "main_position.h"
#include "gps_accum_task.h"
#include "gps_message.h"
#include "gps_ephemeris.h"
#include "b1i_accum_task.h"
#include "b1i_message.h"
#include "b1i_ephemeris.h"


/*******************************************************************************
 * Global variables
 ******************************************************************************/

OS_FLAG_GRP* m_AllocateFlag;

static unsigned short GPS_PrnCode[GPS_MAX_SATELLITES+1] =
{	0x000,
	0x3ec,0x3d8,0x3b0,0x04b,0x096,0x2cb,0x196,0x32c,
	0x3ba,0x374,0x1d0,0x3a0,0x340,0x280,0x100,0x113,
	0x226,0x04c,0x098,0x130,0x260,0x267,0x338,0x270,
	0x0e0,0x1c0,0x380,0x22b,0x056,0x0ac,0x158,0x058
	};

static unsigned short B1I_PrnCode[B1I_MAX_SATELLITES+1] =
{	0x000,
	0x70c,0x4e3,0x33c,0x483,0x503,0x0fc,0x303,0x4fc,
	0x107,0x3ef,0x430,0x38f,0x20f,0x7f0,0x40f,0x3f0,
	0x7df,0x060,0x1e0,0x41f,0x7e0,0x01f,0x7bf,0x63f,
	0x3c0,0x03f,0x7c0,0x180,0x47f,0x780,0x07f,0x5ff
	};


/******************************************************************************
 * Initialize a channel into acquition mode

 ******************************************************************************/

static void initialize_gps_channel( unsigned short ch, unsigned short prn, signed short nfreq)
{
	// Allocate the free satellite and get ready to check/allocate the next
	m_GPS_CH[ch].prn = prn;

	// Set SATCNTL register for C/A code
	write_to_correlator( (GPS_CH00_BASE + ch * CH_BASE_STEP + PRN_KEY), GPS_PrnCode[prn]);

	// Set carrier DCO
	// This is wrong. FIXME
	// carrier_corr is used to correct the "set_carrier_dco_rate()" (carrier DCO) settings.
	// If the system clock is in error by (x)[Hz] the correction to the carrier DCO
	// setting is -(IF_FREQ/(CARR_FREQ_RES * SYSTEM_CLOCK))
	// This is assuming that (x) is the error in the SYSTEM_CLOCK, which is not
	// clear (and should be checked), anyway, L1/CARR_FREQ_RES is wrong.
	// ADG: should it be: chan[ch].carrier_freq = carrier_ref + chan[ch].
	// carrier_corr + d_freq * chan[ch].n_freq;   // set carrier
	// ADG: removed static double ClockOffset = 0.0; and
	//   m_GPS_CH[ch].carrier_corr = (long)(-ClockOffset * 1575.42 / 42.57475e-3);
	m_GPS_CH[ch].carrier_corr = 0;
	m_GPS_CH[ch].carrier_freq = GPS_CARRIER_REF + m_GPS_CH[ch].carrier_corr;
	gps_set_carrier_dco_rate(ch, m_GPS_CH[ch].carrier_freq);

	// Initialize the code and frequency search variables
	m_GPS_CH[ch].codes = 0;
	m_GPS_CH[ch].n_freq = nfreq;
	m_GPS_CH[ch].ms_count = 0;

	// Set code DCO
	m_GPS_CH[ch].code_freq = GPS_CODE_REF;
	gps_set_code_dco_rate(ch, m_GPS_CH[ch].code_freq);

	// Bit sync and frame sync flags
	m_GPS_CH[ch].bit_sync = 0;

	// Clear prompt and dither vector magnitudes
	m_GPS_CH[ch].e_mag = 0;
	m_GPS_CH[ch].p_mag = 0;
	m_GPS_CH[ch].l_mag = 0;

	// Epoch counter set flags
	m_GPS_CH[ch].load_1ms_epoch_count = 0;
	m_GPS_CH[ch].sync_20ms_epoch_count = 0;
	m_GPS_CH[ch].backto_pull_in = 0;

	// Clear the number of bits since the week began
	m_GPS_CH[ch].time_in_bits = 0;

	// Clear the sat navigation message for this channel,
	// including the ephemeris since we're switching sats
	gps_clear_messages(ch);
	gps_clear_ephemeris(ch);

	m_GPS_CH[ch].state = CHANNEL_ACQUISITION;
}

static void initialize_b1i_channel( unsigned short ch, unsigned short prn, signed short nfreq)
{
	// Allocate the free satellite and get ready to check/allocate the next
	m_B1I_CH[ch].prn = prn;

	// Set SATCNTL register for C/A code
	write_to_correlator( (B1I_CH00_BASE + ch * CH_BASE_STEP + PRN_KEY), B1I_PrnCode[prn]);

	// Set carrier DCO
	// This is wrong. FIXME
	// carrier_corr is used to correct the "set_carrier_dco_rate()" (carrier DCO) settings.
	// If the system clock is in error by (x)[Hz] the correction to the carrier DCO
	// setting is -(IF_FREQ/(CARR_FREQ_RES * SYSTEM_CLOCK))
	// This is assuming that (x) is the error in the SYSTEM_CLOCK, which is not
	// clear (and should be checked), anyway, L1/CARR_FREQ_RES is wrong.
	// ADG: should it be: chan[ch].carrier_freq = carrier_ref + chan[ch].
	// carrier_corr + d_freq * chan[ch].n_freq;   // set carrier
	// ADG: removed static double ClockOffset = 0.0; and
	//   m_B1I_CH[ch].carrier_corr = (long)(-ClockOffset * 1575.42 / 42.57475e-3);
	m_B1I_CH[ch].carrier_corr = 0;
	m_B1I_CH[ch].carrier_freq = B1I_CARRIER_REF + m_B1I_CH[ch].carrier_corr;
	b1i_set_carrier_dco_rate(ch, m_B1I_CH[ch].carrier_freq);

	// Initialize the code and frequency search variables
	m_B1I_CH[ch].codes = 0;
	m_B1I_CH[ch].n_freq = nfreq;

	m_B1I_CH[ch].ms_maxval = IS_D1_NAVMESSAGE(prn) ? 19:1;
	m_B1I_CH[ch].ms_count = 0;

	// Set code DCO
	m_B1I_CH[ch].code_freq = B1I_CODE_REF;
	b1i_set_code_dco_rate(ch, m_B1I_CH[ch].code_freq);

	// Bit sync and frame sync flags
	m_B1I_CH[ch].bit_sync = 0;

	// Clear prompt and dither vector magnitudes
	m_B1I_CH[ch].e_mag = 0;
	m_B1I_CH[ch].p_mag = 0;
	m_B1I_CH[ch].l_mag = 0;

	// Epoch counter set flags
	m_B1I_CH[ch].load_1ms_epoch_count = 0;
	m_B1I_CH[ch].sync_20ms_epoch_count = 0;
	m_B1I_CH[ch].backto_pull_in = 0;

	// Clear the number of bits since the week began
	m_B1I_CH[ch].time_in_bits = 0;

	// Clear the sat navigation message for this channel,
	// including the ephemeris since we're switching sats
	b1i_clear_messages(ch);
	b1i_clear_ephemeris(ch);

	m_B1I_CH[ch].state = CHANNEL_ACQUISITION;
}

/******************************************************************************
 * We don't know anything about any satellite (cold power on with no memory)
 * so blindly go through satellites, one at a now through channels.
 ******************************************************************************/
void cold_allocate_gps_channel( unsigned short ch)
{
	// Search satellites 1st to last
	static unsigned short next_satellite = 0;

	unsigned short i;
	unsigned short already_allocated;

	do {
		next_satellite++;
		// check satellites 1 to 32
		if (next_satellite > GPS_MAX_SATELLITES) {
			next_satellite = 1;
		}

		already_allocated = 0;
		for (i = 0; i < GPS_MAX_CHANNELS; i++) {
			// Modified to fix an allocation bug (AA)
			if (m_GPS_CH[i].prn == next_satellite) // && m_GPS_CH[i].state != CHANNEL_OFF) (AA)
			{
				already_allocated = 1;
				break;
			}
		}
	} while (already_allocated);

    initialize_gps_channel( ch, next_satellite, 1);
}

void cold_allocate_b1i_channel( unsigned short ch)
{
	// Search satellites 1st to last
	static unsigned short next_satellite = 0;

	unsigned short i;
	unsigned short already_allocated;

	do {
		next_satellite++;
		// check satellites 1 to 32
		if (next_satellite > B1I_MAX_SATELLITES) {
			next_satellite = 1;
		}

		already_allocated = 0;
		for (i = 0; i < B1I_MAX_SATELLITES; i++) {
			// Modified to fix an allocation bug (AA)
			if (m_B1I_CH[i].prn == next_satellite) // && m_B1I_CH[i].state != CHANNEL_OFF) (AA)
			{
				already_allocated = 1;
				break;
			}
		}
	} while (already_allocated);

    initialize_b1i_channel( ch, next_satellite, 1);
}


void initialize_allocation( void)
{
	unsigned short ch;

	if (m_sys_posconst & POS_CONSTELL_GPS) {
		for (ch = 0; ch < GPS_MAX_CHANNELS; ch ++) {
			cold_allocate_gps_channel(ch);
		}
	}
	if (m_sys_posconst & POS_CONSTELL_BDS) {
		for (ch = 0; ch < B1I_MAX_CHANNELS; ch ++) {
			cold_allocate_b1i_channel(ch);
		}
	}
}

void allocate_task(void* pdata) // input 'pdata' not used
{
	INT8U err;
	unsigned short ch;

	// There SHOULDN'T be a race condition here because initialize_allocate()
	// should keep this from being called for a while on startup.
	m_AllocateFlag = OSFlagCreate((OS_FLAGS)0, &err);

	while(1) {
		// Block. If tracking() in tracking.c turns off any channels, then it 
		// will set the flag bits and wake this thread up.
		OSFlagPend(m_AllocateFlag,
			(1 << TOT_MAX_CHANNELS) - 1,
			OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME, 
			0, &err);

		if (m_sys_posconst & POS_CONSTELL_GPS) {
			for (ch = 0; ch < GPS_MAX_CHANNELS; ch++) {
				if (m_GPS_CH[ch].state == CHANNEL_OFF)
					cold_allocate_gps_channel(ch);
			}
		}

		if (m_sys_posconst & POS_CONSTELL_BDS) {
			for (ch = 0; ch < B1I_MAX_CHANNELS; ch++) {
				if (m_B1I_CH[ch].state == CHANNEL_OFF)
					cold_allocate_b1i_channel(ch);
			}
		}
    }
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号