Paparazzi UAS v7.1_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
sdlog_chibios.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013-2015 Gautier Hattenberger, Alexandre Bustico
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22/*
23 * @file modules/loggers/sdlog_chibios.c
24 * @brief sdlog process with battery monitoring
25 *
26 */
27
28#include <ch.h>
29#include <hal.h>
35#include "mcu_periph/adc.h"
36#include "mcu.h"
37#include "led.h"
38
39#if HAL_USE_RTC
40#include <hal_rtc.h>
41#include <time.h>
42#include "modules/gps/gps.h"
43#endif
44
45#define GPS_LEAP_SECONDS 18
46
47// Delay before starting SD log
48#ifndef SDLOG_START_DELAY
49#define SDLOG_START_DELAY 30
50#endif
51
52// Auto-flush period (in seconds)
53#ifndef SDLOG_AUTO_FLUSH_PERIOD
54#define SDLOG_AUTO_FLUSH_PERIOD 10
55#endif
56
57// Contiguous storage memory (in Mo)
58#ifndef SDLOG_CONTIGUOUS_STORAGE_MEM
59#define SDLOG_CONTIGUOUS_STORAGE_MEM 50
60#endif
61
62// Flush file on power loss
63#ifndef SDLOG_ENABLE_LOWBAT_FLUSH
64#define SDLOG_ENABLE_LOWBAT_FLUSH TRUE
65#endif
66
67
68#if (!defined USE_ADC_WATCHDOG) || (USE_ADC_WATCHDOG == 0)
69#error sdlog_chibios need USE_ADC_WATCHDOG in order to properly close files when power is unplugged
70#endif
71
72static const char PPRZ_LOG_NAME[] = "pprzlog_";
73static const char PPRZ_LOG_DIR[] = "PPRZ";
74
75/*
76 * Start log thread
77 */
79static __attribute__((noreturn)) void thd_startlog(void *arg);
80
81bool sdOk = false;
82
84
86
87#if FLIGHTRECORDER_SDLOG
88static const char FLIGHTRECORDER_LOG_NAME[] = "fr_";
89static const char FR_LOG_DIR[] = "FLIGHT_RECORDER";
91#endif
92
95static enum {
100
104static char NO_FILE_NAME[] = "none";
105
106#if PREFLIGHT_CHECKS
107/* Preflight checks */
109static struct preflight_check_t sdlog_pfc;
110
111static void sdlog_preflight(struct preflight_result_t *result) {
113#ifdef SDLOG_PREFLIGHT_ERROR
114 preflight_error(result, "SDLogger is not running [%d:%d]", chibios_sdlog_status, sdLogGetStorageStatus());
115#else
116 preflight_warning(result, "SDLogger is not running [%d:%d]", chibios_sdlog_status, sdLogGetStorageStatus());
117#endif
118 } else {
119 preflight_success(result, "SDLogger running");
120 }
121}
122#endif // PREFLIGHT_CHECKS
123
124#if PERIODIC_TELEMETRY
126static void send_sdlog_status(struct transport_tx *trans, struct link_device *dev)
127{
133 if (size == 0) {
134 // when no file opened
136 size = strlen(filenames);
137 }
138 pprz_msg_send_LOGGER_STATUS(trans, dev, AC_ID, &status, &errno, &used, size, filenames);
139}
140#endif
141
142
143// Functions for the generic device API
144static int sdlog_check_free_space(struct chibios_sdlog *p __attribute__((unused)), long *fd, uint16_t len)
145{
148 if (status != SDLOG_OK) {
149 return 0;
150 } else {
151 *fd = (long) sdb;
152 return 1;
153 }
154}
155
156static void sdlog_transmit(struct chibios_sdlog *p __attribute__((unused)), long fd, uint8_t byte)
157{
160 *data = byte;
162}
163
164static void sdlog_transmit_buffer(struct chibios_sdlog *p __attribute__((unused)), long fd, uint8_t *data, uint16_t len)
165{
167 memcpy(sdLogGetBufferFromSDB(sdb), data, len);
169}
170
171static void sdlog_send(struct chibios_sdlog *p, long fd)
172{
174 sdLogWriteSDB(*(p->file), sdb);
175}
176
177static int null_function(struct chibios_sdlog *p __attribute__((unused))) { return 0; }
178static uint8_t null_byte_function(struct chibios_sdlog *p __attribute__((unused))) { return 0; }
179
181{
182 // Store file descriptor
183 sdlog->file = file;
184 // Configure generic device
185 sdlog->device.periph = (void *)(sdlog);
186 sdlog->device.check_free_space = (check_free_space_t) sdlog_check_free_space;
187 sdlog->device.put_byte = (put_byte_t) sdlog_transmit;
188 sdlog->device.put_buffer = (put_buffer_t) sdlog_transmit_buffer;
189 sdlog->device.send_message = (send_message_t) sdlog_send;
190 sdlog->device.char_available = (char_available_t) null_function; // write only
191 sdlog->device.get_byte = (get_byte_t) null_byte_function; // write only
192
193}
194
196{
198#if PERIODIC_TELEMETRY
200#endif
201
202#if PREFLIGHT_CHECKS
204#endif
205
206 // Start polling on USB
208
209 // Start log thread
212}
213
214
216{
217 if (pprzLogFile != -1) {
218 // if a FF_FS_REENTRANT is true, we can umount fs without closing
219 // file, fatfs lock will assure that umount is done after a write,
220 // and umount will close all open files cleanly. Thats the fatest
221 // way to umount cleanly filesystem.
222 //
223 // if FF_FS_REENTRANT is false,
224 // we have to flush and close files before unmounting filesystem
225#if FF_FS_REENTRANT == 0
227#else
228 (void) flush;
229#endif
230
231 sdLogFinish();
232 pprzLogFile = -1;
233#if FLIGHTRECORDER_SDLOG
235#endif
236 }
238}
239
240#if defined(SDLOG_BAT_ADC) && defined(SDLOG_BAT_CHAN)
241/*
242 * Bat survey thread
243 */
244#if SDLOG_ENABLE_LOWBAT_FLUSH
246static __attribute__((noreturn)) void thd_bat_survey(void *arg);
247static void powerOutageIsr(void);
250
251#define DefaultAdcOfVoltage(voltage) ((uint32_t) (voltage/(DefaultVoltageOfAdc(1))))
252static const uint16_t V_ALERT = DefaultAdcOfVoltage(5.5f);
253
254
255/*
256 powerOutageIsr is called within a lock zone from an isr, so no lock/unlock is needed
257*/
258static void powerOutageIsr(void)
259{
261}
262
263static void thd_bat_survey(void *arg)
264{
265 (void)arg;
266 chRegSetThreadName("battery survey");
269
271
273 // Only try to energy save is it is really a problem and not powered through USB
275 // disable all required periph to save energy and maximize chance to flush files
276 // to mass storage and avoid infamous dirty bit on filesystem
278 }
279
280 // in case of powerloss, we should go fast and avoid to flush ram buffer
282
283 // Only put to deep sleep in case there is no power on the USB
286 }
287 chThdExit(0);
288 while (true); // never goes here, only to avoid compiler warning: 'noreturn' function does return
289}
290#endif // SDLOG_ENABLE_LOWBAT_FLUSH
291#endif
292
293static void thd_startlog(void *arg)
294{
295 (void) arg;
296 chRegSetThreadName("start log");
297 char tmpFilename[32];
298
299 // Wait before starting the log if needed
301 // Check if we are already in USB Storage mode
302 if (usbStorageIsItRunning()) {
303 chThdSleepSeconds(20000); // stuck here for hours FIXME stop the thread ?
304 }
305
306 // Init sdlog struct
308
309 // Check for init errors
310 sdOk = true;
311
312 if (sdLogInit(NULL) != SDLOG_OK) {
313 sdOk = false;
314 } else {
319 sdOk = false;
320 }
322#if FLIGHTRECORDER_SDLOG
327 sdOk = false;
328 }
330#endif
331 }
332
333 if (sdOk) {
334#if defined(SDLOG_BAT_ADC) && defined(SDLOG_BAT_CHAN) && SDLOG_ENABLE_LOWBAT_FLUSH
335 // Create Battery Survey Thread with event
339#endif
340
342 } else {
344 }
345
346 while (true) {
347#ifdef SDLOG_LED
349#endif
350 // Blink faster if init has errors
351 chThdSleepMilliseconds(sdOk == true ? 1000 : 200);
354 sdOk = false;
355 } else {
357 sdOk = true;
358 }
359
360#if HAL_USE_RTC && USE_GPS
361 static uint32_t timestamp = 0;
362 // FIXME this could be done somewhere else, like in sys_time
363 // we sync gps time to rtc every 5 seconds
364 if (chVTGetSystemTime() - timestamp > TIME_S2I(5)) {
365 timestamp = chVTGetSystemTime();
366 if (gps.tow != 0 && (sys_time.nb_sec - gps.last_msg_time) < 5) {
367 // Unix timestamp of the GPS epoch 1980-01-06 00:00:00 UTC
368 const uint32_t unixToGpsEpoch = 315964800;
369 struct tm time_tm;
370 time_t univTime = ((gps.week * 7 * 24 * 3600) + (gps.tow / 1000)) + unixToGpsEpoch - GPS_LEAP_SECONDS;
372 // Chibios date struct
376 }
377 }
378#endif
379
380 }
381}
382
383
386 if(ac_id != AC_ID && ac_id != 0xFF) {
387 return;
388 }
395 }
396}
397
arch independent ADC (Analog to Digital Converter) API
#define SDLOG_BAT_ADC
Definition board.h:533
#define SDLOG_USB_VBUS_PIN
Definition board.h:538
#define SDLOG_USB_VBUS_PORT
Definition board.h:537
#define SDLOG_BAT_CHAN
Definition board.h:534
static uint8_t status
#define LED_TOGGLE(i)
Definition led_hw.h:53
static THD_WORKING_AREA(wa_thd_spi1, SPI_THREAD_STACK_SIZE)
static struct uart_periph * dev
struct GpsState gps
global GPS state
Definition gps.c:74
Device independent GPS code (interface)
uint32_t tow
GPS time of week in ms.
Definition gps.h:112
uint32_t last_msg_time
cpu time in sec at last received GPS message
Definition gps.h:120
uint16_t week
GPS week.
Definition gps.h:111
void chsnprintf(char *buffer, size_t size, const char *fmt,...)
Definition printf.c:377
void mcu_reboot(enum reboot_state_t reboot_state)
Reboot the MCU.
Definition mcu_arch.c:206
void mcu_energy_save(void)
Save energy for performing operations on shutdown Used for example to shutdown SD-card logging.
Definition mcu_arch.c:230
@ MCU_REBOOT_POWEROFF
Poweroff the device.
Definition mcu.h:44
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
static float p[2][2]
arch independent LED (Light Emitting Diodes) API
uint16_t foo
Definition main_demo5.c:58
Arch independent mcu ( Micro Controller Unit ) utilities.
#define byte
void preflight_error(struct preflight_result_t *result, const char *fmt,...)
Register a preflight error used inside the preflight checking functions.
void preflight_success(struct preflight_result_t *result, const char *fmt,...)
Register a preflight success used inside the preflight checking functions.
void preflight_warning(struct preflight_result_t *result, const char *fmt,...)
Register a preflight warning used inside the preflight checking functions.
void preflight_check_register(struct preflight_check_t *check, preflight_check_f func)
Register a preflight check and add it to the linked list.
Mini printf-like functionality.
#define IN_DMA_SECTION(var)
Definition ram_arch.h:87
SdioError sdLogFinish(void)
unmount filesystem
Definition sdLog.c:285
SdioError removeEmptyLogs(const char *directoryName, const char *prefix, const size_t sizeConsideredEmpty)
remove spurious log file left on sd
Definition sdLog.c:815
SdioError sdLogInit(uint32_t *freeSpaceInKo)
initialise sdLog
Definition sdLog.c:225
struct _SdLogBuffer SdLogBuffer
Definition sdLog.h:127
int8_t FileDes
Definition sdLog.h:128
#define LOG_APPEND_TAG_AT_CLOSE_DISABLED
Definition sdLog.h:105
SdioError
Definition sdLog.h:111
@ SDLOG_OK
Definition sdLog.h:112
#define LOG_PREALLOCATION_DISABLED
Definition sdLog.h:103
static void sdlog_send(struct chibios_sdlog *p, long fd)
static int null_function(struct chibios_sdlog *p)
static void send_sdlog_status(struct transport_tx *trans, struct link_device *dev)
#define GPS_LEAP_SECONDS
static int sdlog_check_free_space(struct chibios_sdlog *p, long *fd, uint16_t len)
void logger_log_msg_up(uint8_t *buf)
static void thd_startlog(void *arg)
#define SDLOG_AUTO_FLUSH_PERIOD
static const char PPRZ_LOG_DIR[]
void sdlog_chibios_finish(const bool flush)
static void sdlog_transmit(struct chibios_sdlog *p, long fd, uint8_t byte)
FileDes pprzLogFile
#define SDLOG_START_DELAY
static enum @299 chibios_sdlog_status
sdlog status
static char NO_FILE_NAME[]
@ SDLOG_STOPPED
@ SDLOG_ERROR
@ SDLOG_RUNNING
static const char PPRZ_LOG_NAME[]
#define SDLOG_CONTIGUOUS_STORAGE_MEM
void chibios_sdlog_init(struct chibios_sdlog *sdlog, FileDes *file)
init chibios_sdlog structure
bool sdOk
static char chibios_sdlog_filenames[68]
sdlog filenames
static uint8_t null_byte_function(struct chibios_sdlog *p)
static void sdlog_transmit_buffer(struct chibios_sdlog *p, long fd, uint8_t *data, uint16_t len)
void sdlog_chibios_init(void)
#define DEST_INFO_MSG_PPRZLOG
#define DEST_INFO_MSG_ALL
chibios_sdlog structure
int fd
Definition serial.c:26
volatile uint32_t nb_sec
full seconds since startup
Definition sys_time.h:72
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
Dynamic memory allocation based on TLSF library.
void usbStorageStartPolling(void)
Definition usbStorage.c:76
bool usbStorageIsItRunning(void)
Definition usbStorage.c:163
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.