6767#include < uORB/topics/sensor_gps.h>
6868#include < uORB/topics/sensor_gnss_relative.h>
6969
70- #include < lib/gnss/rtcm.h>
71-
7270#ifndef CONSTRAINED_FLASH
7371# include " devices/src/ashtech.h"
7472# include " devices/src/emlid_reach.h"
@@ -217,8 +215,6 @@ class GPS : public ModuleBase<GPS>, public device::Device
217215 gps_dump_s *_dump_from_device{nullptr };
218216 gps_dump_comm_mode_t _dump_communication_mode{gps_dump_comm_mode_t ::Disabled};
219217
220- gnss::Rtcm3Parser _rtcm_parser{};
221-
222218 static px4::atomic_bool _is_gps_main_advertised; // /< for the second gps we want to make sure that it gets instance 1
223219 // / and thus we wait until the first one publishes at least one message.
224220
@@ -268,7 +264,7 @@ class GPS : public ModuleBase<GPS>, public device::Device
268264 * @param data
269265 * @param len
270266 */
271- inline bool injectData (const uint8_t *data, size_t len);
267+ inline bool injectData (uint8_t *data, size_t len);
272268
273269 /* *
274270 * set the Baudrate
@@ -289,7 +285,7 @@ class GPS : public ModuleBase<GPS>, public device::Device
289285 * @param mode calling source
290286 * @param msg_to_gps_device if true, this is a message sent to the gps device, otherwise it's from the device
291287 */
292- void dumpGpsData (const uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device);
288+ void dumpGpsData (uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device);
293289
294290 void initializeCommunicationDump ();
295291
@@ -476,16 +472,28 @@ int GPS::pollOrRead(uint8_t *buf, size_t buf_length, int timeout)
476472 const int max_timeout = 50 ;
477473 int timeout_adjusted = math::min (max_timeout, timeout);
478474
479- handleInjectDataTopic ();
480-
481475 if (_interface == GPSHelper::Interface::UART) {
482- ret = _uart.readAtLeast (buf, buf_length, math::min (character_count, buf_length), timeout_adjusted);
476+
477+ const ssize_t read_at_least = math::min (character_count, buf_length);
478+
479+ // handle injection data before read if caught up
480+ if (_uart.bytesAvailable () < read_at_least) {
481+ handleInjectDataTopic ();
482+ }
483+
484+ ret = _uart.readAtLeast (buf, buf_length, read_at_least, timeout_adjusted);
485+
486+ if (ret > 0 ) {
487+ _num_bytes_read += ret;
488+ }
483489
484490// SPI is only supported on LInux
485491#if defined(__PX4_LINUX)
486492
487493 } else if ((_interface == GPSHelper::Interface::SPI) && (_spi_fd >= 0 )) {
488494
495+ handleInjectDataTopic ();
496+
489497 // Poll only for the SPI data. In the same thread we also need to handle orb messages,
490498 // so ideally we would poll on both, the SPI fd and orb subscription. Unfortunately the
491499 // two pollings use different underlying mechanisms (at least under posix), which makes this
@@ -575,7 +583,6 @@ void GPS::handleInjectDataTopic()
575583 // Looking at 8 packets thus guarantees, that at least a full injection
576584 // data set is evaluated.
577585 // Moving Base reuires a higher rate, so we allow up to 8 packets.
578- // Drain uORB messages into RTCM parser and inject full messages after draining the queue.
579586 const size_t max_num_injections = gps_inject_data_s::ORB_QUEUE_LENGTH;
580587 size_t num_injections = 0 ;
581588
@@ -585,13 +592,13 @@ void GPS::handleInjectDataTopic()
585592
586593 // Prevent injection of data from self
587594 if (msg.device_id != get_device_id ()) {
588- // Add data to the RTCM parser buffer for frame reassembly
589- size_t added = _rtcm_parser.addData (msg.data , msg.len );
590-
591- if (added < msg.len ) {
592- PX4_WARN (" RTCM buffer full, dropped %zu bytes" , msg.len - added);
593- }
595+ /* Write the message to the gps device. Note that the message could be fragmented.
596+ * But as we don't write anywhere else to the device during operation, we don't
597+ * need to assemble the message first.
598+ */
599+ injectData (msg.data , msg.len );
594600
601+ ++_rtcm_injection_rate_message_count;
595602 _last_rtcm_injection_time = hrt_absolute_time ();
596603 }
597604 }
@@ -609,30 +616,9 @@ void GPS::handleInjectDataTopic()
609616 }
610617
611618 } while (updated && num_injections < max_num_injections);
612-
613- // Now inject all complete RTCM frames from the parser buffer
614- size_t frame_len = {};
615- const uint8_t *frame_ptr = {};
616-
617- while ((frame_ptr = _rtcm_parser.getNextMessage (&frame_len)) != nullptr ) {
618- // Check TX buffer space before writing
619- if (_interface == GPSHelper::Interface::UART) {
620- ssize_t tx_available = _uart.txSpaceAvailable ();
621-
622- if ((ssize_t )frame_len > tx_available) {
623- // TX buffer full, stop and let it drain - frames stay in parser buffer
624- PX4_WARN (" TX buffer full!" );
625- break ;
626- }
627- }
628-
629- injectData (frame_ptr, frame_len);
630- _rtcm_parser.consumeMessage (frame_len);
631- _rtcm_injection_rate_message_count++;
632- }
633619}
634620
635- bool GPS::injectData (const uint8_t *data, size_t len)
621+ bool GPS::injectData (uint8_t *data, size_t len)
636622{
637623 dumpGpsData (data, len, gps_dump_comm_mode_t ::Full, true );
638624
@@ -701,15 +687,15 @@ void GPS::initializeCommunicationDump()
701687 _dump_communication_mode = (gps_dump_comm_mode_t )param_dump_comm;
702688}
703689
704- void GPS::dumpGpsData (const uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device)
690+ void GPS::dumpGpsData (uint8_t *data, size_t len, gps_dump_comm_mode_t mode, bool msg_to_gps_device)
705691{
706692 gps_dump_s *dump_data = msg_to_gps_device ? _dump_to_device : _dump_from_device;
707693
708694 if (_dump_communication_mode != mode || !dump_data) {
709695 return ;
710696 }
711697
712- dump_data->device_id = get_device_id () ;
698+ dump_data->instance = ( uint8_t )_instance ;
713699
714700 while (len > 0 ) {
715701 size_t write_len = len;
@@ -811,13 +797,6 @@ GPS::run()
811797 param_get (handle, &f9p_uart2_baudrate);
812798 }
813799
814- handle = param_find (" GPS_UBX_PPK" );
815- int32_t ppk_output = 0 ;
816-
817- if (handle != PARAM_INVALID) {
818- param_get (handle, &ppk_output);
819- }
820-
821800 int32_t gnssSystemsParam = static_cast <int32_t >(GPSHelper::GNSSSystemsMask::RECEIVER_DEFAULTS);
822801
823802 if (_instance == Instance::Main) {
@@ -899,21 +878,11 @@ GPS::run()
899878 _mode = gps_driver_mode_t ::UBX;
900879
901880 /* FALLTHROUGH */
902- case gps_driver_mode_t ::UBX: {
903- GPSDriverUBX::Settings settings = {
904- .dynamic_model = (uint8_t )gps_ubx_dynmodel,
905- .heading_offset = heading_offset,
906- .uart2_baudrate = f9p_uart2_baudrate,
907- .ppk_output = ppk_output > 0 ,
908- .mode = ubx_mode,
909- };
910-
911- _helper = new GPSDriverUBX (_interface, &GPS::callback, this , &_sensor_gps, _p_report_sat_info, settings);
912-
913- set_device_type (DRV_GPS_DEVTYPE_UBX);
914- break ;
915- }
916-
881+ case gps_driver_mode_t ::UBX:
882+ _helper = new GPSDriverUBX (_interface, &GPS::callback, this , &_sensor_gps, _p_report_sat_info,
883+ gps_ubx_dynmodel, heading_offset, f9p_uart2_baudrate, ubx_mode);
884+ set_device_type (DRV_GPS_DEVTYPE_UBX);
885+ break ;
917886#ifndef CONSTRAINED_FLASH
918887
919888 case gps_driver_mode_t ::MTK:
@@ -1051,8 +1020,6 @@ GPS::run()
10511020 healthy_timeout += TIMEOUT_DUMP_ADD;
10521021 }
10531022
1054- PX4_INFO (" GPS device configured @ %u baud" , _baudrate);
1055-
10561023 while ((helper_ret = _helper->receive (receive_timeout)) > 0 && !should_exit ()) {
10571024
10581025 if (helper_ret & 1 ) {
0 commit comments