@ -17,6 +17,7 @@
# if HAL_OS_POSIX_IO
# if HAL_OS_POSIX_IO
# include "DataFlash_File.h"
# include "DataFlash_File.h"
# include <AP_Common/AP_Common.h>
# include <sys/stat.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/types.h>
# include <unistd.h>
# include <unistd.h>
@ -34,7 +35,7 @@
# ifdef __APPLE__
# ifdef __APPLE__
# include <sys/param.h>
# include <sys/param.h>
# include <sys/mount.h>
# include <sys/mount.h>
# else
# elif !DATAFLASH_FILE_MINIMAL
# include <sys/statfs.h>
# include <sys/statfs.h>
# endif
# endif
@ -98,7 +99,7 @@ void DataFlash_File::Init()
semaphore = hal . util - > new_semaphore ( ) ;
semaphore = hal . util - > new_semaphore ( ) ;
if ( semaphore = = nullptr ) {
if ( semaphore = = nullptr ) {
hal . console - > printf ( " Failed to create DataFlash_File semaphore \n " ) ;
AP_HAL : : panic ( " Failed to create DataFlash_File semaphore " ) ;
return ;
return ;
}
}
@ -122,6 +123,7 @@ void DataFlash_File::Init()
_log_directory = custom_dir ;
_log_directory = custom_dir ;
}
}
# if !DATAFLASH_FILE_MINIMAL
ret = stat ( _log_directory , & st ) ;
ret = stat ( _log_directory , & st ) ;
if ( ret = = - 1 ) {
if ( ret = = - 1 ) {
ret = mkdir ( _log_directory , 0777 ) ;
ret = mkdir ( _log_directory , 0777 ) ;
@ -130,6 +132,8 @@ void DataFlash_File::Init()
hal . console - > printf ( " Failed to create log directory %s \n " , _log_directory ) ;
hal . console - > printf ( " Failed to create log directory %s \n " , _log_directory ) ;
return ;
return ;
}
}
# endif
if ( _writebuf ! = NULL ) {
if ( _writebuf ! = NULL ) {
free ( _writebuf ) ;
free ( _writebuf ) ;
_writebuf = NULL ;
_writebuf = NULL ;
@ -166,12 +170,20 @@ void DataFlash_File::Init()
bool DataFlash_File : : file_exists ( const char * filename ) const
bool DataFlash_File : : file_exists ( const char * filename ) const
{
{
# if DATAFLASH_FILE_MINIMAL
int fd = open ( filename , O_RDONLY ) ;
if ( fd = = - 1 ) {
return false ;
}
close ( fd ) ;
# else
struct stat st ;
struct stat st ;
if ( stat ( filename , & st ) = = - 1 ) {
if ( stat ( filename , & st ) = = - 1 ) {
// hopefully errno==ENOENT. If some error occurs it is
// hopefully errno==ENOENT. If some error occurs it is
// probably better to assume this file exists.
// probably better to assume this file exists.
return false ;
return false ;
}
}
# endif
return true ;
return true ;
}
}
@ -208,11 +220,16 @@ bool DataFlash_File::CardInserted(void)
// returns -1 on error
// returns -1 on error
int64_t DataFlash_File : : disk_space_avail ( )
int64_t DataFlash_File : : disk_space_avail ( )
{
{
# if !DATAFLASH_FILE_MINIMAL
struct statfs stats ;
struct statfs stats ;
if ( statfs ( _log_directory , & stats ) < 0 ) {
if ( statfs ( _log_directory , & stats ) < 0 ) {
return - 1 ;
return - 1 ;
}
}
return ( ( ( int64_t ) stats . f_bavail ) * stats . f_bsize ) ;
return ( ( ( int64_t ) stats . f_bavail ) * stats . f_bsize ) ;
# else
// return a fake disk space size
return 100 * 1000 * 1000UL ;
# endif
}
}
// returns the total amount of disk space (in use + available) in
// returns the total amount of disk space (in use + available) in
@ -220,11 +237,16 @@ int64_t DataFlash_File::disk_space_avail()
// returns -1 on error
// returns -1 on error
int64_t DataFlash_File : : disk_space ( )
int64_t DataFlash_File : : disk_space ( )
{
{
# if !DATAFLASH_FILE_MINIMAL
struct statfs stats ;
struct statfs stats ;
if ( statfs ( _log_directory , & stats ) < 0 ) {
if ( statfs ( _log_directory , & stats ) < 0 ) {
return - 1 ;
return - 1 ;
}
}
return ( ( ( int64_t ) stats . f_blocks ) * stats . f_bsize ) ;
return ( ( ( int64_t ) stats . f_blocks ) * stats . f_bsize ) ;
# else
// return fake disk space size
return 200 * 1000 * 1000UL ;
# endif
}
}
// returns the available space in _log_directory as a percentage
// returns the available space in _log_directory as a percentage
@ -247,6 +269,9 @@ float DataFlash_File::avail_space_percent()
// returns 0 if no log was found
// returns 0 if no log was found
uint16_t DataFlash_File : : find_oldest_log ( )
uint16_t DataFlash_File : : find_oldest_log ( )
{
{
# if DATAFLASH_FILE_MINIMAL
return 0 ;
# else
if ( _cached_oldest_log ! = 0 ) {
if ( _cached_oldest_log ! = 0 ) {
return _cached_oldest_log ;
return _cached_oldest_log ;
}
}
@ -306,8 +331,10 @@ uint16_t DataFlash_File::find_oldest_log()
_cached_oldest_log = current_oldest_log ;
_cached_oldest_log = current_oldest_log ;
return current_oldest_log ;
return current_oldest_log ;
# endif
}
}
# if !DATAFLASH_FILE_MINIMAL
void DataFlash_File : : Prep_MinSpace ( )
void DataFlash_File : : Prep_MinSpace ( )
{
{
const uint16_t first_log_to_remove = find_oldest_log ( ) ;
const uint16_t first_log_to_remove = find_oldest_log ( ) ;
@ -364,13 +391,16 @@ void DataFlash_File::Prep_MinSpace()
}
}
} while ( log_to_remove ! = first_log_to_remove ) ;
} while ( log_to_remove ! = first_log_to_remove ) ;
}
}
# endif
void DataFlash_File : : Prep ( ) {
void DataFlash_File : : Prep ( ) {
if ( hal . util - > get_soft_armed ( ) ) {
if ( hal . util - > get_soft_armed ( ) ) {
// do not want to do any filesystem operations while we are e.g. flying
// do not want to do any filesystem operations while we are e.g. flying
return ;
return ;
}
}
# if !DATAFLASH_FILE_MINIMAL
Prep_MinSpace ( ) ;
Prep_MinSpace ( ) ;
# endif
}
}
bool DataFlash_File : : NeedPrep ( )
bool DataFlash_File : : NeedPrep ( )
@ -419,6 +449,7 @@ void DataFlash_File::EraseAll()
{
{
uint16_t log_num ;
uint16_t log_num ;
stop_logging ( ) ;
stop_logging ( ) ;
# if !DATAFLASH_FILE_MINIMAL
for ( log_num = 1 ; log_num < = MAX_LOG_FILES ; log_num + + ) {
for ( log_num = 1 ; log_num < = MAX_LOG_FILES ; log_num + + ) {
char * fname = _log_file_name ( log_num ) ;
char * fname = _log_file_name ( log_num ) ;
if ( fname = = NULL ) {
if ( fname = = NULL ) {
@ -432,7 +463,7 @@ void DataFlash_File::EraseAll()
unlink ( fname ) ;
unlink ( fname ) ;
free ( fname ) ;
free ( fname ) ;
}
}
# endif
_cached_oldest_log = 0 ;
_cached_oldest_log = 0 ;
}
}
@ -536,22 +567,24 @@ uint16_t DataFlash_File::find_last_log()
if ( fname = = NULL ) {
if ( fname = = NULL ) {
return ret ;
return ret ;
}
}
FILE * f = : : f open( fname , " r " ) ;
int fd = open ( fname , O_RDONLY ) ;
free ( fname ) ;
free ( fname ) ;
if ( f ! = NULL ) {
if ( fd ! = - 1 ) {
char buf [ 10 ] ;
char buf [ 10 ] ;
memset ( buf , 0 , sizeof ( buf ) ) ;
memset ( buf , 0 , sizeof ( buf ) ) ;
// PX4 doesn't have fscanf()
if ( read ( fd , buf , sizeof ( buf ) - 1 ) > 0 ) {
if ( fread ( buf , 1 , sizeof ( buf ) - 1 , f ) > 0 ) {
sscanf ( buf , " %u " , & ret ) ;
sscanf ( buf , " %u " , & ret ) ;
}
}
f close( f ) ;
close ( fd ) ;
}
}
return ret ;
return ret ;
}
}
uint32_t DataFlash_File : : _get_log_size ( const uint16_t log_num ) const
uint32_t DataFlash_File : : _get_log_size ( const uint16_t log_num ) const
{
{
# if DATAFLASH_FILE_MINIMAL
return 1 ;
# else
char * fname = _log_file_name ( log_num ) ;
char * fname = _log_file_name ( log_num ) ;
if ( fname = = NULL ) {
if ( fname = = NULL ) {
return 0 ;
return 0 ;
@ -563,10 +596,14 @@ uint32_t DataFlash_File::_get_log_size(const uint16_t log_num) const
}
}
free ( fname ) ;
free ( fname ) ;
return st . st_size ;
return st . st_size ;
# endif
}
}
uint32_t DataFlash_File : : _get_log_time ( const uint16_t log_num ) const
uint32_t DataFlash_File : : _get_log_time ( const uint16_t log_num ) const
{
{
# if DATAFLASH_FILE_MINIMAL
return 0 ;
# else
char * fname = _log_file_name ( log_num ) ;
char * fname = _log_file_name ( log_num ) ;
if ( fname = = NULL ) {
if ( fname = = NULL ) {
return 0 ;
return 0 ;
@ -578,6 +615,7 @@ uint32_t DataFlash_File::_get_log_time(const uint16_t log_num) const
}
}
free ( fname ) ;
free ( fname ) ;
return st . st_mtime ;
return st . st_mtime ;
# endif
}
}
/*
/*
@ -813,14 +851,19 @@ uint16_t DataFlash_File::start_new_log(void)
// now update lastlog.txt with the new log number
// now update lastlog.txt with the new log number
fname = _lastlog_file_name ( ) ;
fname = _lastlog_file_name ( ) ;
FILE * f = : : fopen ( fname , " w " ) ;
if ( f = = NULL ) {
// we avoid fopen()/fprintf() here as it is not available on as many
free ( fname ) ;
// systems as open/write (specifically the QURT RTOS)
int fd = open ( fname , O_WRONLY | O_CREAT , 0644 ) ;
free ( fname ) ;
if ( fd = = - 1 ) {
return 0xFFFF ;
return 0xFFFF ;
}
}
fprintf ( f , " %u \r \n " , ( unsigned ) log_num ) ;
fclose ( f ) ;
char buf [ 30 ] ;
free ( fname ) ;
snprintf ( buf , sizeof ( buf ) , " %u \r \n " , ( unsigned ) log_num ) ;
write ( fd , buf , strlen ( buf ) ) ;
close ( fd ) ;
return log_num ;
return log_num ;
}
}
@ -948,6 +991,7 @@ void DataFlash_File::ListAvailableLogs(AP_HAL::BetterStream *port)
}
}
port - > printf ( " \n %u logs \n " , ( unsigned ) num_logs ) ;
port - > printf ( " \n %u logs \n " , ( unsigned ) num_logs ) ;
# if !DATAFLASH_FILE_MINIMAL
for ( uint16_t i = 1 ; i < = num_logs ; i + + ) {
for ( uint16_t i = 1 ; i < = num_logs ; i + + ) {
uint16_t log_num = _log_num_from_list_entry ( i ) ;
uint16_t log_num = _log_num_from_list_entry ( i ) ;
char * filename = _log_file_name ( log_num ) ;
char * filename = _log_file_name ( log_num ) ;
@ -968,6 +1012,7 @@ void DataFlash_File::ListAvailableLogs(AP_HAL::BetterStream *port)
free ( filename ) ;
free ( filename ) ;
}
}
}
}
# endif
port - > println ( ) ;
port - > println ( ) ;
}
}
@ -1047,7 +1092,7 @@ void DataFlash_File::_io_timer(void)
write .
write .
*/
*/
BUF_ADVANCEHEAD ( _writebuf , nwritten ) ;
BUF_ADVANCEHEAD ( _writebuf , nwritten ) ;
# if CONFIG_HAL_BOARD != HAL_BOARD_SITL && CONFIG_HAL_BOARD_SUBTYPE != HAL_BOARD_SUBTYPE_LINUX_NONE
# if CONFIG_HAL_BOARD != HAL_BOARD_SITL && CONFIG_HAL_BOARD_SUBTYPE != HAL_BOARD_SUBTYPE_LINUX_NONE && CONFIG_HAL_BOARD != HAL_BOARD_QURT
: : fsync ( _write_fd ) ;
: : fsync ( _write_fd ) ;
# endif
# endif
}
}