Skip to content

Commit 2221cd7

Browse files
performance GPS driver
1 parent 3376242 commit 2221cd7

File tree

7 files changed

+182
-133
lines changed

7 files changed

+182
-133
lines changed

boards/XCORE/board_ex.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,6 @@
5959
// 255.255.255.0
6060
#define FALLBACK_NETMASK 0xFFFFFF00
6161

62-
// Flash information for the bootloader
63-
#define BOOT_ADDRESS 0x8020000
64-
// Available flash pages for user program
65-
#define FLASH_PAGE_COUNT 7
66-
// Size of each flash page in bytes
67-
#define FLASH_PAGE_SIZE_BYTES 0x20000
68-
// Size of flash memory for the user program
69-
#define PROGRAM_FLASH_SIZE_BYTES (FLASH_PAGE_COUNT * FLASH_PAGE_SIZE_BYTES)
7062

7163
#define SPID_IMU SPID3
7264
#ifndef __ASSEMBLER__

main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ int main(void) {
126126

127127
// chThdCreateStatic(testWa, sizeof(testWa), NORMALPRIO, testThreadFunc, NULL);
128128
gps.set_state_callback(etl::delegate<void(const xbot::driver::gps::GpsInterface::GpsState &new_state)>::create<gpsUpdated>());
129+
gps.set_datum(49.0, 10.0, 150);
129130
gps.start_driver(&UARTD6, 921600);
130131

131132
// Subscribe to global events and dispatch to our services

src/boot_service_discovery.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ static void multicast_sender_thread(void *p) {
6868
recvfrom(sockfd, boardAdvertisementRequestBuffer,
6969
sizeof(boardAdvertisementRequestBuffer) - 1, 0, NULL, NULL);
7070
if (received > 0) {
71+
// check, if the command was "RESET", if so, we reset
72+
if(strncmp(boardAdvertisementBuffer, "RESET", sizeof(boardAdvertisementBuffer)) == 0) {
73+
// Set the boot address to bootloader and reset the system
74+
MODIFY_REG(SYSCFG->UR2, SYSCFG_UR2_BOOT_ADD0,
75+
(0x8000000 >> 16) << SYSCFG_UR2_BOOT_ADD0_Pos);
76+
NVIC_SystemReset();
77+
while(1);
78+
}
7179
// Send the multicast message
7280
sendto(sockfd, boardAdvertisementBuffer, strlen(boardAdvertisementBuffer),
7381
0, (struct sockaddr *)&multicast_addr, sizeof(multicast_addr));

src/drivers/gps/gps_interface.cpp

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "gps_interface.h"
66

77
#include <etl/algorithm.h>
8+
#include <ulog.h>
89

910
#include <cmath>
1011

@@ -14,18 +15,26 @@ namespace gps {
1415

1516
GpsInterface::GpsInterface() {
1617
datum_lat_ = datum_long_ = NAN;
18+
chMtxObjectInit(&processing_mutex);
1719
}
1820
bool GpsInterface::start_driver(UARTDriver *uart, uint32_t baudrate) {
1921
chDbgAssert(stopped_, "don't start the driver twice");
2022
chDbgAssert(uart != nullptr, "need to provide a driver");
2123
if(!stopped_) {
2224
return false;
2325
}
24-
stopped_ = false;
2526
this->uart = uart;
2627
uart_config.speed = baudrate;
27-
chThdCreateStatic(&wa, sizeof(wa), NORMALPRIO, GpsInterface::threadHelper, this);
28-
return uartStart(uart, &uart_config) == MSG_OK;
28+
bool uartStarted = uartStart(uart, &uart_config) == MSG_OK;
29+
if(!uartStarted) {
30+
return false;
31+
}
32+
33+
stopped_ = false;
34+
processing_thread_ = chThdCreateStatic(&wa, sizeof(wa), NORMALPRIO, threadHelper, this);
35+
// Allow higher prio in order to not lose buffers. Active time in this thread is very minimal (it's just swapping buffers)
36+
chThdCreateStatic(&recvThdWa, sizeof(recvThdWa), NORMALPRIO+1, receivingThreadHelper, this);
37+
return true;
2938
}
3039

3140
void GpsInterface::set_state_callback(const GpsInterface::StateCallback &function) {
@@ -45,23 +54,59 @@ bool GpsInterface::send_raw(const void *data, size_t size) {
4554
}
4655

4756
void GpsInterface::threadFunc() {
48-
size_t bytes_to_process = 1;
57+
// size_t bytes_to_process = 1;
4958
while(!stopped_) {
59+
// Wait for data to arrive
60+
chEvtWaitAny(ALL_EVENTS);
61+
// Lock the processing buffer and process the data
62+
chMtxLock(&processing_mutex);
5063
// try to read as much as possible in order to not interrupt on single bytes
51-
size_t read = sizeof(gps_buffer);
52-
uartReceiveTimeout(uart, &read, gps_buffer, TIME_MS2I(100));
53-
size_t processed = 0;
54-
while(processed < read) {
55-
size_t in = etl::min(bytes_to_process, read-processed);
56-
bytes_to_process = process_bytes(gps_buffer+processed, in);
57-
processed+=in;
64+
// size_t processed = 0;
65+
// while(processed < processing_buffer_len) {
66+
// const size_t in = etl::min(bytes_to_process, processing_buffer_len-processed);
67+
// bytes_to_process = process_bytes(processing_buffer+processed, in);
68+
// processed+=in;
69+
// }
70+
process_bytes(processing_buffer, processing_buffer_len);
71+
chMtxUnlock(&processing_mutex);
72+
}
73+
}
74+
75+
76+
void GpsInterface::receivingThreadFunc() {
77+
while(!stopped_) {
78+
// try to read as much as possible in order to not interrupt on single bytes
79+
size_t read = RECV_BUFFER_SIZE;
80+
// Get the pointer to the receiving buffer (it's not the processing buffer)
81+
uint8_t* buffer = (processing_buffer == recv_buffer1) ? recv_buffer2 : recv_buffer1;
82+
memset(buffer, 0, RECV_BUFFER_SIZE);
83+
uartReceiveTimeout(uart, &read, buffer, TIME_S2I(1));
84+
// swap buffers and instantly restart DMA
85+
bool locked = chMtxTryLock(&processing_mutex);
86+
if(!locked) {
87+
ULOG_WARNING("GPS processing too slow to keep up with incoming data");
88+
chMtxLock(&processing_mutex);
89+
}
90+
// Swap the buffers
91+
processing_buffer = buffer;
92+
processing_buffer_len = read;
93+
chMtxUnlock(&processing_mutex);
94+
// Signal the processing thread
95+
if(processing_thread_) {
96+
chEvtSignal(processing_thread_, 1);
5897
}
5998
}
6099
}
100+
101+
61102
void GpsInterface::threadHelper(void *instance) {
62103
auto *gps_interface = static_cast<GpsInterface *>(instance);
63104
gps_interface->threadFunc();
64105
}
106+
void GpsInterface::receivingThreadHelper(void *instance) {
107+
auto *gps_interface = static_cast<GpsInterface *>(instance);
108+
gps_interface->receivingThreadFunc();
109+
}
65110

66111
void GpsInterface::send_rtcm(const uint8_t *data, size_t size) {
67112
send_raw(data, size);

src/drivers/gps/gps_interface.h

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define OPEN_MOWER_ROS_GPS_INTERFACE_H
77

88
#include <etl/delegate.h>
9+
910
#include "ch.h"
1011
#include "hal.h"
1112

@@ -22,13 +23,7 @@ class GpsInterface {
2223
* The final GPS state we're interested in.
2324
*/
2425
struct GpsState {
25-
enum FixType {
26-
NO_FIX = 0,
27-
DR_ONLY = 1,
28-
FIX_2D = 2,
29-
FIX_3D = 3,
30-
GNSS_DR_COMBINED = 4
31-
};
26+
enum FixType { NO_FIX = 0, DR_ONLY = 1, FIX_2D = 2, FIX_3D = 3, GNSS_DR_COMBINED = 4 };
3227

3328
enum RTKType { RTK_NONE = 0, RTK_FLOAT = 1, RTK_FIX = 2 };
3429

@@ -65,7 +60,7 @@ class GpsInterface {
6560
typedef etl::delegate<void(const GpsState &new_state)> StateCallback;
6661

6762
public:
68-
bool start_driver(UARTDriver* uart, uint32_t baudrate);
63+
bool start_driver(UARTDriver *uart, uint32_t baudrate);
6964
void set_state_callback(const GpsInterface::StateCallback &function);
7065

7166
void set_datum(double datum_lat, double datum_long, double datum_height);
@@ -94,21 +89,29 @@ class GpsInterface {
9489
virtual size_t process_bytes(const uint8_t *buffer, size_t len) = 0;
9590

9691
private:
97-
uint8_t gps_buffer[512]{};
98-
uint8_t gps_buffer2[512]{};
99-
uint8_t current_buffer = 0;
100-
size_t gps_buffer_count = 0;
101-
size_t requested_bytes = 0;
92+
static constexpr size_t RECV_BUFFER_SIZE=512;
93+
// Keep two buffers for streaming data while doing processing
94+
uint8_t recv_buffer1[RECV_BUFFER_SIZE]{};
95+
uint8_t recv_buffer2[RECV_BUFFER_SIZE]{};
96+
uint8_t* processing_buffer = recv_buffer1;
97+
size_t processing_buffer_len = 0;
10298
UARTDriver *uart{};
103-
UARTConfig uart_config{};
99+
UARTConfig uart_config{};
104100

105-
THD_WORKING_AREA(wa, 1024);
101+
THD_WORKING_AREA(wa, 1024){};
102+
THD_WORKING_AREA(recvThdWa, 100){};
103+
thread_t* processing_thread_ = nullptr;
104+
// mutex held while processing data
105+
// i.e. receiving thread cannot swap buffers when this is held
106+
ch_mutex processing_mutex{};
106107

107108
bool stopped_ = true;
108109

109-
void threadFunc();
110+
void threadFunc();
111+
void receivingThreadFunc();
110112

111-
static void threadHelper(void* instance);
113+
static void threadHelper(void *instance);
114+
static void receivingThreadHelper(void *instance);
112115
};
113116
} // namespace gps
114117
} // namespace driver

0 commit comments

Comments
 (0)