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;
	}
}

Parents
  • Hi!

    When your screen shuts down, you don't see the GPS data in the log output? Or does it disappear from the application, as in the information being read from the socket disappears?

    The logging can stop when the screen shuts down, so that isn't that strange, but if it's disappearing from the application that's a bigger problem.

  • Thanks for your reply!  The current situation is that when GPS is activated in another thread, the system main thread must have a call to the external device in order to receive the GPS data. Once the screen goes off and the main thread does not send any data to the screen, the GPS data will no longer be received. In fact, the main program can still output other LOG information.  

    When I press the button, I can receive the data output of the GPS for a short time. It feels like the main program stops for a while before the GPS thread can continue to run, otherwise it will be suspended  

Reply
  • Thanks for your reply!  The current situation is that when GPS is activated in another thread, the system main thread must have a call to the external device in order to receive the GPS data. Once the screen goes off and the main thread does not send any data to the screen, the GPS data will no longer be received. In fact, the main program can still output other LOG information.  

    When I press the button, I can receive the data output of the GPS for a short time. It feels like the main program stops for a while before the GPS thread can continue to run, otherwise it will be suspended  

Children
Related