This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How do I properly launch and retrieve GPS data in another thread

Because the GPS will continue to output data after starting, in order not to block the main thread, I placed it in another thread, but I found that when my main thread did not communicate with the external device(My screen automatically shuts down after 15 seconds when I'm not doing anything. When the screen shuts down, I never see the GPS data again), the GPS thread could not receive the location data. What is the reason?  

This is my code:

static void set_gps_enable(const bool enable)
{
	if(enable == gps_control_is_enabled())
	{
		return;
	}

	if(enable)
	{
		LOG_INF("Starting GPS");
		//k_work_submit_to_queue(app_work_q,
		//		       &send_agps_request_work);
		gps_control_start(K_NO_WAIT);

		gps_start_time = k_uptime_get();
	}
	else
	{
		LOG_INF("Stopping GPS");
		gps_control_stop(K_NO_WAIT);
	}
}

static void send_agps_request(struct k_work *work)
{
	ARG_UNUSED(work);

#if defined(CONFIG_NRF_CLOUD_AGPS)
	int err;
	static s64_t last_request_timestamp;

	if((last_request_timestamp != 0) &&
	    (k_uptime_get() - last_request_timestamp < K_HOURS(1)))
	{
		LOG_WRN("A-GPS request was sent less than 1 hour ago");
		return;
	}

	LOG_INF("Sending A-GPS request");

	err = nrf_cloud_agps_request_all();
	if(err)
	{
		LOG_ERR("A-GPS request failed, error: %d", err);
		return;
	}

	last_request_timestamp = k_uptime_get();

	LOG_INF("A-GPS request sent");
#endif /* defined(CONFIG_NRF_CLOUD_AGPS) */
}

static void gps_handler(struct device *dev, struct gps_event *evt)
{
	u8_t tmpbuf[128] = {0};
	
	switch (evt->type)
	{
	case GPS_EVT_SEARCH_STARTED:
		LOG_INF("GPS_EVT_SEARCH_STARTED");
		gps_control_set_active(true);
		break;
		
	case GPS_EVT_SEARCH_STOPPED:
		LOG_INF("GPS_EVT_SEARCH_STOPPED");
		gps_control_set_active(false);
		break;
		
	case GPS_EVT_SEARCH_TIMEOUT:
		LOG_INF("GPS_EVT_SEARCH_TIMEOUT");
		gps_control_set_active(false);
		break;
		
	case GPS_EVT_PVT:
		/* Don't spam logs */
		LOG_INF("GPS_EVT_PVT");
		
	#ifdef SHOW_LOG_IN_SCREEN
		sprintf(tmpbuf, "Longitude:  %f\nLatitude:   %f\nAltitude:   %f\nSpeed:      %f\nHeading:    %f\nDate:       %02d-%02d-%02d\nTime (UTC): %02d:%02d:%02d", 
					evt->pvt.longitude,
					evt->pvt.latitude,
					evt->pvt.altitude,
					evt->pvt.speed,
					evt->pvt.heading,
					evt->pvt.datetime.year,
					evt->pvt.datetime.month,
					evt->pvt.datetime.day,
					evt->pvt.datetime.hour,
					evt->pvt.datetime.minute,
					evt->pvt.datetime.seconds);	
		show_infor(tmpbuf);
	#else
		sprintf(tmpbuf, "Longitude:%f, Latitude:%f, Altitude:%f, Speed:%f, Heading:%f", 
									evt->pvt.longitude, 
									evt->pvt.latitude,
									evt->pvt.altitude,
									evt->pvt.speed,
									evt->pvt.heading);
		LOG_INF("%s",tmpbuf);

		LOG_INF("Date:       %02u-%02u-%02u", evt->pvt.datetime.year,
					       					  evt->pvt.datetime.month,
					       					  evt->pvt.datetime.day);
		LOG_INF("Time (UTC): %02u:%02u:%02u", evt->pvt.datetime.hour,
					       					  evt->pvt.datetime.minute,
					      					  evt->pvt.datetime.seconds);
	#endif		
		break;
	
	case GPS_EVT_PVT_FIX:
		LOG_INF("GPS_EVT_PVT_FIX");
		sprintf(tmpbuf, "Longitude:%f, Latitude:%f\n", evt->pvt.longitude, evt->pvt.latitude);
		LOG_INF("%s",tmpbuf);
		break;
		
	case GPS_EVT_NMEA:
		/* Don't spam logs */
		LOG_INF("NMEA:%s\n", evt->nmea.buf);
		break;
		
	case GPS_EVT_NMEA_FIX:
		LOG_INF("Position fix with NMEA data, fix time:%d\n", k_uptime_get()-gps_start_time);
		LOG_INF("NMEA:%s\n", evt->nmea.buf);

		memcpy(gps_data.buf, evt->nmea.buf, evt->nmea.len);
		gps_data.len = evt->nmea.len;

		gps_control_set_active(false);
		break;
		
	case GPS_EVT_OPERATION_BLOCKED:
		LOG_INF("GPS_EVT_OPERATION_BLOCKED");
		break;
		
	case GPS_EVT_OPERATION_UNBLOCKED:
		LOG_INF("GPS_EVT_OPERATION_UNBLOCKED");
		break;
		
	case GPS_EVT_AGPS_DATA_NEEDED:
		LOG_INF("GPS_EVT_AGPS_DATA_NEEDED");
		k_work_submit_to_queue(app_work_q,
				       &send_agps_request_work);
		break;
		
	case GPS_EVT_ERROR:
		LOG_INF("GPS_EVT_ERROR\n");
		break;
		
	default:
		break;
	}
}

void GPS_init(struct k_work_q *work_q)
{
	app_work_q = work_q;

	k_work_init(&send_agps_request_work, send_agps_request);

	gps_control_init(app_work_q, gps_handler);
}

void system_init(void)
{
	InitSystemSettings();
	
	pmu_init();
	flash_init();
	LCD_Init();
	
	//ShowBootUpLogo();

	key_init();
	IMU_init(&imu_work_q);
	ble_init();//À¶ÑÀUART_0¸úATÖ¸Áî¹²Óã¬ÐèÒªATÖ¸ÁîʱҪ¹Ø±ÕÕâÌõÓï¾ä
	NB_init(&nb_work_q);
	GPS_init(&nb_work_q);
	EnterIdleScreen();
}

void work_init(void)
{
	k_work_q_start(&nb_work_q, nb_stack_area,
					K_THREAD_STACK_SIZEOF(nb_stack_area),
					CONFIG_APPLICATION_WORKQUEUE_PRIORITY);
	k_work_q_start(&imu_work_q, imu_stack_area,
					K_THREAD_STACK_SIZEOF(imu_stack_area),
					CONFIG_APPLICATION_WORKQUEUE_PRIORITY);
	k_work_q_start(&gps_work_q, gps_stack_area,
					K_THREAD_STACK_SIZEOF(imu_stack_area),
					CONFIG_APPLICATION_WORKQUEUE_PRIORITY);	
}

/***************************************************************************
* Ãè  Êö : mainº¯Êý 
* Èë  ²Î : ÎÞ 
* ·µ»ØÖµ : int ÀàÐÍ
**************************************************************************/
int main(void)
{
	work_init();
	system_init();

//	test_show_string();
//	test_show_image();
//	test_nvs();
//	test_flash();
//	test_uart_ble();
//	test_sensor();
//	test_show_digital_clock();
//	test_sensor();
//	test_pmu();
//	test_crypto();
//	test_imei();
//	test_tp();
//	test_gps();
//	test_nb();
//	test_i2c();
//	test_bat_soc();

	while(1)
	{
		TimeMsgProcess();
		NBMsgProcess();
		GPSMsgProcess();
		PMUMsgProcess();
		IMUMsgProcess();
		LCDMsgProcess();
		//TPMsgProcess();
		AlarmMsgProcess();
		SettingsMsgPorcess();
		SOSMsgProc();
		ScreenMsgProcess();

		k_cpu_idle();
	}
}

void TimeMsgProcess(void)
{
	if(sys_time_count)
	{
		sys_time_count = false;
		UpdateSystemTime();
		
		if(lcd_is_sleeping)
			return;
		
		if(screen_id == SCREEN_ID_IDLE)
			scr_msg[screen_id].act = SCREEN_ACTION_UPDATE;
	}
}

Related