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