[sdlog] update sdlog for chibios (#2029)

* [sdlog] update sdlog for chibios

- fix several small bugs
- update to fatfs 0.12b
- add status report

* calculate mass storage thread size accordingly to ffconf choice for _USE_LFN and _FS_EXFAT

* [sdlog] improved documentation
This commit is contained in:
Gautier Hattenberger
2017-03-01 13:05:48 +01:00
committed by GitHub
parent 356062f2f5
commit aea1d5f8e9
21 changed files with 1609 additions and 1075 deletions
+6
View File
@@ -9,6 +9,10 @@
Files are written on a FAT file system using the FatFS library and can be accessed Files are written on a FAT file system using the FatFS library and can be accessed
by using the autopilot as a mass storage (plug USB while the board is running). by using the autopilot as a mass storage (plug USB while the board is running).
</description> </description>
<configure name="SDLOG_LED" value="none|num" description="LED number or 'none' to disable. Default: none"/>
<define name="SDLOG_START_DELAY" value="30" unit="s" description="Set the delay in seconds before starting the logger. This delay can be used to get plug USB cable and get data without starting a new log. Default: 30s"/>
<define name="SDLOG_AUTO_FLUSH_PERIOD" value="10" unit="s" description="Data flush period. Shorter period may decrease performances. Default: 10s"/>
<define name="SDLOG_CONTIGUOUS_STORAGE_MEM" value="50" unit="Mo" description="Try to reserve a given contiguous mass storage memory. Default: 50Mo"/>
</doc> </doc>
<depends>tlsf</depends> <depends>tlsf</depends>
<header> <header>
@@ -16,6 +20,8 @@
</header> </header>
<init fun="sdlog_chibios_init()"/> <init fun="sdlog_chibios_init()"/>
<makefile target="ap"> <makefile target="ap">
<configure name="SDLOG_LED" default="none"/>
<define name="SDLOG_LED" value="$(SDLOG_LED)" cond="ifneq ($(SDLOG_LED),none)"/>
<file name="sdlog_chibios.c"/> <file name="sdlog_chibios.c"/>
<file name="sdlog_chibios/sdLog.c"/> <file name="sdlog_chibios/sdLog.c"/>
<file name="sdlog_chibios/msg_queue.c"/> <file name="sdlog_chibios/msg_queue.c"/>
@@ -35,6 +35,7 @@
<message name="FBW_STATUS" period="2"/> <message name="FBW_STATUS" period="2"/>
<message name="AIR_DATA" period="1.3"/> <message name="AIR_DATA" period="1.3"/>
<message name="ESC" period="0.9"/> <message name="ESC" period="0.9"/>
<message name="LOGGER_STATUS" period="5.1"/>
</mode> </mode>
<mode name="minimal"> <mode name="minimal">
<message name="ALIVE" period="5"/> <message name="ALIVE" period="5"/>
+11 -3
View File
@@ -54,9 +54,17 @@
#error "section defined only for STM32F1, STM32F4 and STM32F7" #error "section defined only for STM32F1, STM32F4 and STM32F7"
#endif #endif
#define IN_STD_SECTION(var) var __attribute__ ((section(STD_SECTION), aligned(8))) #define IN_STD_SECTION_NOINIT(var) var __attribute__ ((section(STD_SECTION), aligned(8)))
#define IN_FAST_SECTION(var) var __attribute__ ((section(FAST_SECTION), aligned(8))) #define IN_STD_SECTION_CLEAR(var) var __attribute__ ((section(STD_SECTION "_clear"), aligned(8)))
#define IN_DMA_SECTION(var) var __attribute__ ((section(DMA_SECTION), aligned(8))) #define IN_STD_SECTION(var) var __attribute__ ((section(STD_SECTION "_init"), aligned(8)))
#define IN_FAST_SECTION_NOINIT(var) var __attribute__ ((section(FAST_SECTION), aligned(8)))
#define IN_FAST_SECTION_CLEAR(var) var __attribute__ ((section(FAST_SECTION "_clear"), aligned(8)))
#define IN_FAST_SECTION(var) var __attribute__ ((section(FAST_SECTION "_init"), aligned(8)))
#define IN_DMA_SECTION_NOINIT(var) var __attribute__ ((section(DMA_SECTION), aligned(8)))
#define IN_DMA_SECTION_CLEAR(var) var __attribute__ ((section(DMA_SECTION "_clear"), aligned(8)))
#define IN_DMA_SECTION(var) var __attribute__ ((section(DMA_SECTION "_init"), aligned(8)))
#endif #endif
+186 -155
View File
@@ -2,176 +2,196 @@
#include "ch.h" #include "ch.h"
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.10b (C)ChaN, 2014 / FatFs - FAT file system module configuration file
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#ifndef _FFCONF #define _FFCONF 68020 /* Revision ID */
#define _FFCONF 8051 /* Revision ID */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations / Function Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ #define _FS_READONLY 0
/* When _FS_TINY is set to 1, it reduces memory consumption _MAX_SS bytes each /* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ file object. For file data transfer, FatFs uses the common sector buffer in / Read-only configuration removes writing API functions, f_write(), f_sync(),
/ the file system object (FATFS) instead of private sector buffer eliminated / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ from the file object (FIL). */ / and optional writing functions as well. */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ #define _FS_MINIMIZE 0
/* Setting _FS_READONLY to 1 defines read only configuration. This removes /* This option defines minimization level to remove some basic API functions.
/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(),
/ f_rename(), f_truncate() and useless f_getfree(). */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* The _FS_MINIMIZE option defines minimization level to remove API functions.
/ /
/ 0: All basic functions are enabled. / 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ f_truncate() and f_rename() function are removed. / are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */ / 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */ #define _USE_STRFUNC 0
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ /* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */ #define _USE_FIND 1
/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ /* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ #define _USE_MKFS 1
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_LABEL 0 /* 0:Disable or 1:Enable */ #define _USE_FASTSEEK 1
/* To enable volume label functions, set _USE_LAVEL to 1 */ /* This option switches fast seek function. (0:Disable or 1:Enable) */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ #define _USE_EXPAND 1
/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ /* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 1
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 1
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations / Locale and Namespace Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _CODE_PAGE 1252 #define _CODE_PAGE 850
/* The _CODE_PAGE specifies the OEM code page to be used on the target system. /* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure. / Incorrect setting of the code page can cause a file open failure.
/ /
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows) / 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) / 437 - U.S.
/ 949 - Korean (DBCS, OEM, Windows) / 720 - Arabic
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) / 737 - Greek
/ 1250 - Central Europe (Windows) / 771 - KBL
/ 1251 - Cyrillic (Windows) / 775 - Baltic
/ 1252 - Latin 1 (Windows) / 850 - Latin 1
/ 1253 - Greek (Windows) / 852 - Latin 2
/ 1254 - Turkish (Windows) / 855 - Cyrillic
/ 1255 - Hebrew (Windows) / 857 - Turkish
/ 1256 - Arabic (Windows) / 860 - Portuguese
/ 1257 - Baltic (Windows) / 861 - Icelandic
/ 1258 - Vietnam (OEM, Windows) / 862 - Hebrew
/ 437 - U.S. (OEM) / 863 - Canadian French
/ 720 - Arabic (OEM) / 864 - Arabic
/ 737 - Greek (OEM) / 865 - Nordic
/ 775 - Baltic (OEM) / 866 - Russian
/ 850 - Multilingual Latin 1 (OEM) / 869 - Greek 2
/ 858 - Multilingual Latin 1 + Euro (OEM) / 932 - Japanese (DBCS)
/ 852 - Latin 2 (OEM) / 936 - Simplified Chinese (DBCS)
/ 855 - Cyrillic (OEM) / 949 - Korean (DBCS)
/ 866 - Russian (OEM) / 950 - Traditional Chinese (DBCS)
/ 857 - Turkish (OEM) */
/ 862 - Hebrew (OEM)
/ 874 - Thai (OEM, Windows)
/ 1 - ASCII (Valid for only non-LFN configuration) */
#define _USE_LFN 2 /* 0 to 3 */ #define _USE_LFN 3
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ #define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature. /* The _USE_LFN switches the support of long file name (LFN).
/ /
/ 0: Disable LFN feature. _MAX_LFN has no effect. / 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK. / 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP. / 3: Enable LFN with dynamic working buffer on the HEAP.
/ /
/ When enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper() / To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ function must be added to the project. / to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the / additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/ working buffer, take care on stack overflow. When use heap memory for the working / It should be set 255 to support full featured LFN operations.
/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added / When use stack for the working buffer, take care on stack overflow. When use heap
/ to the project. */ / memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ #define _LFN_UNICODE 0
/* To switch the character encoding on the FatFs API (TCHAR) to Unicode, enable LFN /* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
/ feature and set _LFN_UNICODE to 1. This option affects behavior of string I/O / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ functions. This option must be 0 when LFN feature is not enabled. */ / This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ #define _STRF_ENCODE 3
/* When Unicode API is enabled by _LFN_UNICODE option, this option selects the character /* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
/ encoding on the file to be read/written via string I/O functions, f_gets(), f_putc(), / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/ f_puts and f_printf(). This option has no effect when Unicode API is not enabled. */
#define _FS_RPATH 2 /* 0 to 2 */
/* The _FS_RPATH option configures relative path feature.
/ /
/ 0: Disable relative path feature and remove related functions. / 0: ANSI/OEM
/ 1: Enable relative path. f_chdrive() and f_chdir() function are available. / 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 1
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1. / 2: f_getcwd() function is available in addition to 1.
/ */
/ Note that output of the f_readdir() fnction is affected by this option. */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Drive/Volume Configurations / Drive/Volume Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _VOLUMES 1 #define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */ /* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */ #define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" #define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive /* _STR_VOLUME_ID switches string support of volume ID.
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each logical / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ drives. Number of items must be equal to _VOLUMES. Valid characters for the drive ID / number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ strings are: 0-9 and A-Z. */ / logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */ #define _MULTI_PARTITION 0
/* By default(0), each logical drive number is bound to the same physical drive number /* This option switches support of multi-partition on a physical drive.
/ and only a FAT volume found on the physical drive is mounted. When it is set to 1, / By default (0), each logical drive number is bound to the same physical drive
/ each logical drive number is bound to arbitrary drive/partition listed in VolToPart[]. / number and only an FAT volume found on the physical drive will be mounted.
*/ / When multi-partition is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define _MIN_SS 512 #define _MIN_SS 512
#define _MAX_SS 512 #define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024, 2048 or /* These options configure the range of sector size to be supported. (512, 1024,
/ 4096) Always set both 512 for most systems, all memory card and harddisk. But a larger / 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ value may be required for on-board flash memory and some type of optical media. / harddisk. But a larger value may be required for on-board flash memory and some
/ When _MAX_SS is larger than _MIN_SS, FatFs is configured to variable sector size and / type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */ / to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_ERASE 1 /* 0:Disable or 1:Enable */ #define _USE_TRIM 0
/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command /* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ should be added to the disk_ioctl() function. */ / To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0 /* 0 to 3 */ #define _FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this option /* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ and f_getfree() function at first time after volume mount will force a full FAT scan. / option, and f_getfree() function at first time after volume mount will force
/ Bit 1 controls the last allocated cluster number as bit 0. / a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/ /
/ bit0=0: Use free cluster count in the FSINFO if available. / bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO. / bit0=1: Do not trust free cluster count in the FSINFO.
@@ -185,55 +205,66 @@
/ System Configurations / System Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */ #define _FS_TINY 0
#define _FS_TIMEOUT MS2ST(1000) /* Timeout period in unit of time tick */ /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
#define _SYNC_t semaphore_t* /* O/S dependent sync object type. e.g. HANDLE, OS_EVENT*, ID, SemaphoreHandle_t and etc.. */ / At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module. / Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
#define _FS_EXFAT 1
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2016
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to get current time form real-time clock. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 0
/* The option _FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define _FS_REENTRANT 1
#define _FS_TIMEOUT MS2ST(1000)
#define _SYNC_t semaphore_t*
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/ /
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. / 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers, / 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function must be added to the project. / function, must be added to the project. Samples are available in
*/ / option/syscall.c.
#define _WORD_ACCESS 1 /* 0 or 1 */
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/ /
/ 0: Byte-by-byte access. Always compatible with all platforms. / The _FS_TIMEOUT defines timeout period in unit of time tick.
/ 1: Word access. Do not choose this unless under both the following conditions. / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ / SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ * Address misaligned memory access is always allowed for ALL instructions. / included somewhere in the scope of ff.h. */
/ * Byte order on the memory is little-endian.
/ /* #include <windows.h> // O/S definitions */
/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance and
/ reduce code size. Following table shows an example of some processor types.
/
/ ARM7TDMI 0 ColdFire 0 V850E2 0
/ Cortex-M3 0 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 RX600(LE) 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(BE) 0 TLCS-900 0/1
/ AVR32 0 RL78 0 R32C 0
/ PIC18 0/1 SH-2 0 M16C 0/1
/ PIC24 0 H8S 0 MSP430 0
/ PIC32 0 H8/300H 0 x86 0/1
*/
/*--- End of configuration options ---*/
#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */
/* To enable file lock control feature, set _FS_LOCK to non-zero value.
/ The value defines how many files/sub-directories can be opened simultaneously
/ with file lock control. This feature uses bss _FS_LOCK * 12 bytes.
/
/ IMPORTANT NOTE:
/ For Paparazzi, we don't need file locking since all file are written sequentially
/ from one thread (thdSdLog)
/
*/
#endif /* _FFCONF */
@@ -379,14 +379,17 @@
#define STM32_SDC_SDIO_UNALIGNED_SUPPORT FALSE #define STM32_SDC_SDIO_UNALIGNED_SUPPORT FALSE
#define STM32_SDC_WRITE_TIMEOUT_MS 250 #define STM32_SDC_WRITE_TIMEOUT_MS 250
#define STM32_SDC_READ_TIMEOUT_MS 15 #define STM32_SDC_READ_TIMEOUT_MS 15
#define SDLOG_ALL_BUFFERS_SIZE 8192
#define SDLOG_MAX_MESSAGE_LEN 252
#define SDLOG_QUEUE_BUCKETS 1024
/* /*
* workaround hardware bug in REV.A revision of old STM32F4 (sold in 2012, early 2013) sdlog message buffer and queue configuration
*/ */
#define SDLOG_QUEUE_BUCKETS 1024
#define SDLOG_MAX_MESSAGE_LEN 252
#define SDLOG_NUM_FILES 2
#define SDLOG_ALL_BUFFERS_SIZE (SDLOG_NUM_FILES*4096)
#define STM32_USE_REVISION_A_FIX 1
#endif /* _MCUCONF_H_ */ #endif /* _MCUCONF_H_ */
+186 -155
View File
@@ -2,176 +2,196 @@
#include "ch.h" #include "ch.h"
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.10b (C)ChaN, 2014 / FatFs - FAT file system module configuration file
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#ifndef _FFCONF #define _FFCONF 68020 /* Revision ID */
#define _FFCONF 8051 /* Revision ID */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations / Function Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ #define _FS_READONLY 0
/* When _FS_TINY is set to 1, it reduces memory consumption _MAX_SS bytes each /* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ file object. For file data transfer, FatFs uses the common sector buffer in / Read-only configuration removes writing API functions, f_write(), f_sync(),
/ the file system object (FATFS) instead of private sector buffer eliminated / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ from the file object (FIL). */ / and optional writing functions as well. */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ #define _FS_MINIMIZE 0
/* Setting _FS_READONLY to 1 defines read only configuration. This removes /* This option defines minimization level to remove some basic API functions.
/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(),
/ f_rename(), f_truncate() and useless f_getfree(). */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* The _FS_MINIMIZE option defines minimization level to remove API functions.
/ /
/ 0: All basic functions are enabled. / 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ f_truncate() and f_rename() function are removed. / are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */ / 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */ #define _USE_STRFUNC 0
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ /* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */ #define _USE_FIND 1
/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ /* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ #define _USE_MKFS 1
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_LABEL 0 /* 0:Disable or 1:Enable */ #define _USE_FASTSEEK 1
/* To enable volume label functions, set _USE_LAVEL to 1 */ /* This option switches fast seek function. (0:Disable or 1:Enable) */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ #define _USE_EXPAND 1
/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ /* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 1
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 1
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations / Locale and Namespace Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _CODE_PAGE 1252 #define _CODE_PAGE 850
/* The _CODE_PAGE specifies the OEM code page to be used on the target system. /* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure. / Incorrect setting of the code page can cause a file open failure.
/ /
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows) / 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) / 437 - U.S.
/ 949 - Korean (DBCS, OEM, Windows) / 720 - Arabic
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) / 737 - Greek
/ 1250 - Central Europe (Windows) / 771 - KBL
/ 1251 - Cyrillic (Windows) / 775 - Baltic
/ 1252 - Latin 1 (Windows) / 850 - Latin 1
/ 1253 - Greek (Windows) / 852 - Latin 2
/ 1254 - Turkish (Windows) / 855 - Cyrillic
/ 1255 - Hebrew (Windows) / 857 - Turkish
/ 1256 - Arabic (Windows) / 860 - Portuguese
/ 1257 - Baltic (Windows) / 861 - Icelandic
/ 1258 - Vietnam (OEM, Windows) / 862 - Hebrew
/ 437 - U.S. (OEM) / 863 - Canadian French
/ 720 - Arabic (OEM) / 864 - Arabic
/ 737 - Greek (OEM) / 865 - Nordic
/ 775 - Baltic (OEM) / 866 - Russian
/ 850 - Multilingual Latin 1 (OEM) / 869 - Greek 2
/ 858 - Multilingual Latin 1 + Euro (OEM) / 932 - Japanese (DBCS)
/ 852 - Latin 2 (OEM) / 936 - Simplified Chinese (DBCS)
/ 855 - Cyrillic (OEM) / 949 - Korean (DBCS)
/ 866 - Russian (OEM) / 950 - Traditional Chinese (DBCS)
/ 857 - Turkish (OEM) */
/ 862 - Hebrew (OEM)
/ 874 - Thai (OEM, Windows)
/ 1 - ASCII (Valid for only non-LFN configuration) */
#define _USE_LFN 2 /* 0 to 3 */ #define _USE_LFN 3
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ #define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature. /* The _USE_LFN switches the support of long file name (LFN).
/ /
/ 0: Disable LFN feature. _MAX_LFN has no effect. / 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK. / 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP. / 3: Enable LFN with dynamic working buffer on the HEAP.
/ /
/ When enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper() / To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ function must be added to the project. / to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the / additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/ working buffer, take care on stack overflow. When use heap memory for the working / It should be set 255 to support full featured LFN operations.
/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added / When use stack for the working buffer, take care on stack overflow. When use heap
/ to the project. */ / memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ #define _LFN_UNICODE 0
/* To switch the character encoding on the FatFs API (TCHAR) to Unicode, enable LFN /* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
/ feature and set _LFN_UNICODE to 1. This option affects behavior of string I/O / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ functions. This option must be 0 when LFN feature is not enabled. */ / This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ #define _STRF_ENCODE 3
/* When Unicode API is enabled by _LFN_UNICODE option, this option selects the character /* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
/ encoding on the file to be read/written via string I/O functions, f_gets(), f_putc(), / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/ f_puts and f_printf(). This option has no effect when Unicode API is not enabled. */
#define _FS_RPATH 2 /* 0 to 2 */
/* The _FS_RPATH option configures relative path feature.
/ /
/ 0: Disable relative path feature and remove related functions. / 0: ANSI/OEM
/ 1: Enable relative path. f_chdrive() and f_chdir() function are available. / 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 1
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1. / 2: f_getcwd() function is available in addition to 1.
/ */
/ Note that output of the f_readdir() fnction is affected by this option. */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Drive/Volume Configurations / Drive/Volume Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _VOLUMES 1 #define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */ /* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */ #define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" #define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive /* _STR_VOLUME_ID switches string support of volume ID.
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each logical / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ drives. Number of items must be equal to _VOLUMES. Valid characters for the drive ID / number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ strings are: 0-9 and A-Z. */ / logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */ #define _MULTI_PARTITION 0
/* By default(0), each logical drive number is bound to the same physical drive number /* This option switches support of multi-partition on a physical drive.
/ and only a FAT volume found on the physical drive is mounted. When it is set to 1, / By default (0), each logical drive number is bound to the same physical drive
/ each logical drive number is bound to arbitrary drive/partition listed in VolToPart[]. / number and only an FAT volume found on the physical drive will be mounted.
*/ / When multi-partition is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define _MIN_SS 512 #define _MIN_SS 512
#define _MAX_SS 512 #define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024, 2048 or /* These options configure the range of sector size to be supported. (512, 1024,
/ 4096) Always set both 512 for most systems, all memory card and harddisk. But a larger / 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ value may be required for on-board flash memory and some type of optical media. / harddisk. But a larger value may be required for on-board flash memory and some
/ When _MAX_SS is larger than _MIN_SS, FatFs is configured to variable sector size and / type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */ / to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_ERASE 1 /* 0:Disable or 1:Enable */ #define _USE_TRIM 0
/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command /* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ should be added to the disk_ioctl() function. */ / To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0 /* 0 to 3 */ #define _FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this option /* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ and f_getfree() function at first time after volume mount will force a full FAT scan. / option, and f_getfree() function at first time after volume mount will force
/ Bit 1 controls the last allocated cluster number as bit 0. / a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/ /
/ bit0=0: Use free cluster count in the FSINFO if available. / bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO. / bit0=1: Do not trust free cluster count in the FSINFO.
@@ -185,55 +205,66 @@
/ System Configurations / System Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */ #define _FS_TINY 0
#define _FS_TIMEOUT MS2ST(1000) /* Timeout period in unit of time tick */ /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
#define _SYNC_t semaphore_t* /* O/S dependent sync object type. e.g. HANDLE, OS_EVENT*, ID, SemaphoreHandle_t and etc.. */ / At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module. / Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
#define _FS_EXFAT 1
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2016
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to get current time form real-time clock. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 0
/* The option _FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define _FS_REENTRANT 1
#define _FS_TIMEOUT MS2ST(1000)
#define _SYNC_t semaphore_t*
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/ /
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. / 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers, / 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function must be added to the project. / function, must be added to the project. Samples are available in
*/ / option/syscall.c.
#define _WORD_ACCESS 1 /* 0 or 1 */
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/ /
/ 0: Byte-by-byte access. Always compatible with all platforms. / The _FS_TIMEOUT defines timeout period in unit of time tick.
/ 1: Word access. Do not choose this unless under both the following conditions. / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ / SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ * Address misaligned memory access is always allowed for ALL instructions. / included somewhere in the scope of ff.h. */
/ * Byte order on the memory is little-endian.
/ /* #include <windows.h> // O/S definitions */
/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance and
/ reduce code size. Following table shows an example of some processor types.
/
/ ARM7TDMI 0 ColdFire 0 V850E2 0
/ Cortex-M3 0 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 RX600(LE) 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(BE) 0 TLCS-900 0/1
/ AVR32 0 RL78 0 R32C 0
/ PIC18 0/1 SH-2 0 M16C 0/1
/ PIC24 0 H8S 0 MSP430 0
/ PIC32 0 H8/300H 0 x86 0/1
*/
/*--- End of configuration options ---*/
#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */
/* To enable file lock control feature, set _FS_LOCK to non-zero value.
/ The value defines how many files/sub-directories can be opened simultaneously
/ with file lock control. This feature uses bss _FS_LOCK * 12 bytes.
/
/ IMPORTANT NOTE:
/ For Paparazzi, we don't need file locking since all file are written sequentially
/ from one thread (thdSdLog)
/
*/
#endif /* _FFCONF */
@@ -452,11 +452,13 @@
#define STM32_SDC_SDMMC1_DMA_PRIORITY 3 #define STM32_SDC_SDMMC1_DMA_PRIORITY 3
#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9 #define STM32_SDC_SDMMC1_IRQ_PRIORITY 9
/* sdlog message buffer and queue configuration /*
sdlog message buffer and queue configuration
*/ */
#define SDLOG_QUEUE_BUCKETS 512 #define SDLOG_QUEUE_BUCKETS 1024
#define SDLOG_ALL_BUFFERS_SIZE 8192
#define SDLOG_MAX_MESSAGE_LEN 252 #define SDLOG_MAX_MESSAGE_LEN 252
#define SDLOG_NUM_FILES 1
#define SDLOG_ALL_BUFFERS_SIZE (SDLOG_NUM_FILES*4096*2)
/* /*
* WDG driver system settings. * WDG driver system settings.
+186 -155
View File
@@ -2,176 +2,196 @@
#include "ch.h" #include "ch.h"
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.10b (C)ChaN, 2014 / FatFs - FAT file system module configuration file
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#ifndef _FFCONF #define _FFCONF 68020 /* Revision ID */
#define _FFCONF 8051 /* Revision ID */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations / Function Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ #define _FS_READONLY 0
/* When _FS_TINY is set to 1, it reduces memory consumption _MAX_SS bytes each /* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ file object. For file data transfer, FatFs uses the common sector buffer in / Read-only configuration removes writing API functions, f_write(), f_sync(),
/ the file system object (FATFS) instead of private sector buffer eliminated / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ from the file object (FIL). */ / and optional writing functions as well. */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ #define _FS_MINIMIZE 0
/* Setting _FS_READONLY to 1 defines read only configuration. This removes /* This option defines minimization level to remove some basic API functions.
/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(),
/ f_rename(), f_truncate() and useless f_getfree(). */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* The _FS_MINIMIZE option defines minimization level to remove API functions.
/ /
/ 0: All basic functions are enabled. / 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ f_truncate() and f_rename() function are removed. / are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */ / 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */ #define _USE_STRFUNC 0
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ /* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */ #define _USE_FIND 1
/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ /* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ #define _USE_MKFS 1
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_LABEL 0 /* 0:Disable or 1:Enable */ #define _USE_FASTSEEK 1
/* To enable volume label functions, set _USE_LAVEL to 1 */ /* This option switches fast seek function. (0:Disable or 1:Enable) */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ #define _USE_EXPAND 1
/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ /* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 1
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 1
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations / Locale and Namespace Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _CODE_PAGE 1252 #define _CODE_PAGE 850
/* The _CODE_PAGE specifies the OEM code page to be used on the target system. /* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure. / Incorrect setting of the code page can cause a file open failure.
/ /
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows) / 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) / 437 - U.S.
/ 949 - Korean (DBCS, OEM, Windows) / 720 - Arabic
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) / 737 - Greek
/ 1250 - Central Europe (Windows) / 771 - KBL
/ 1251 - Cyrillic (Windows) / 775 - Baltic
/ 1252 - Latin 1 (Windows) / 850 - Latin 1
/ 1253 - Greek (Windows) / 852 - Latin 2
/ 1254 - Turkish (Windows) / 855 - Cyrillic
/ 1255 - Hebrew (Windows) / 857 - Turkish
/ 1256 - Arabic (Windows) / 860 - Portuguese
/ 1257 - Baltic (Windows) / 861 - Icelandic
/ 1258 - Vietnam (OEM, Windows) / 862 - Hebrew
/ 437 - U.S. (OEM) / 863 - Canadian French
/ 720 - Arabic (OEM) / 864 - Arabic
/ 737 - Greek (OEM) / 865 - Nordic
/ 775 - Baltic (OEM) / 866 - Russian
/ 850 - Multilingual Latin 1 (OEM) / 869 - Greek 2
/ 858 - Multilingual Latin 1 + Euro (OEM) / 932 - Japanese (DBCS)
/ 852 - Latin 2 (OEM) / 936 - Simplified Chinese (DBCS)
/ 855 - Cyrillic (OEM) / 949 - Korean (DBCS)
/ 866 - Russian (OEM) / 950 - Traditional Chinese (DBCS)
/ 857 - Turkish (OEM) */
/ 862 - Hebrew (OEM)
/ 874 - Thai (OEM, Windows)
/ 1 - ASCII (Valid for only non-LFN configuration) */
#define _USE_LFN 2 /* 0 to 3 */ #define _USE_LFN 3
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ #define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature. /* The _USE_LFN switches the support of long file name (LFN).
/ /
/ 0: Disable LFN feature. _MAX_LFN has no effect. / 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK. / 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP. / 3: Enable LFN with dynamic working buffer on the HEAP.
/ /
/ When enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper() / To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ function must be added to the project. / to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the / additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/ working buffer, take care on stack overflow. When use heap memory for the working / It should be set 255 to support full featured LFN operations.
/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added / When use stack for the working buffer, take care on stack overflow. When use heap
/ to the project. */ / memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ #define _LFN_UNICODE 0
/* To switch the character encoding on the FatFs API (TCHAR) to Unicode, enable LFN /* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
/ feature and set _LFN_UNICODE to 1. This option affects behavior of string I/O / To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ functions. This option must be 0 when LFN feature is not enabled. */ / This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ #define _STRF_ENCODE 3
/* When Unicode API is enabled by _LFN_UNICODE option, this option selects the character /* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
/ encoding on the file to be read/written via string I/O functions, f_gets(), f_putc(), / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/ f_puts and f_printf(). This option has no effect when Unicode API is not enabled. */
#define _FS_RPATH 2 /* 0 to 2 */
/* The _FS_RPATH option configures relative path feature.
/ /
/ 0: Disable relative path feature and remove related functions. / 0: ANSI/OEM
/ 1: Enable relative path. f_chdrive() and f_chdir() function are available. / 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 1
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1. / 2: f_getcwd() function is available in addition to 1.
/ */
/ Note that output of the f_readdir() fnction is affected by this option. */
/*---------------------------------------------------------------------------/ /*---------------------------------------------------------------------------/
/ Drive/Volume Configurations / Drive/Volume Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _VOLUMES 1 #define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */ /* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */ #define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" #define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive /* _STR_VOLUME_ID switches string support of volume ID.
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each logical / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ drives. Number of items must be equal to _VOLUMES. Valid characters for the drive ID / number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ strings are: 0-9 and A-Z. */ / logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */ #define _MULTI_PARTITION 0
/* By default(0), each logical drive number is bound to the same physical drive number /* This option switches support of multi-partition on a physical drive.
/ and only a FAT volume found on the physical drive is mounted. When it is set to 1, / By default (0), each logical drive number is bound to the same physical drive
/ each logical drive number is bound to arbitrary drive/partition listed in VolToPart[]. / number and only an FAT volume found on the physical drive will be mounted.
*/ / When multi-partition is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define _MIN_SS 512 #define _MIN_SS 512
#define _MAX_SS 512 #define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024, 2048 or /* These options configure the range of sector size to be supported. (512, 1024,
/ 4096) Always set both 512 for most systems, all memory card and harddisk. But a larger / 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ value may be required for on-board flash memory and some type of optical media. / harddisk. But a larger value may be required for on-board flash memory and some
/ When _MAX_SS is larger than _MIN_SS, FatFs is configured to variable sector size and / type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */ / to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_ERASE 1 /* 0:Disable or 1:Enable */ #define _USE_TRIM 0
/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command /* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ should be added to the disk_ioctl() function. */ / To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0 /* 0 to 3 */ #define _FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this option /* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ and f_getfree() function at first time after volume mount will force a full FAT scan. / option, and f_getfree() function at first time after volume mount will force
/ Bit 1 controls the last allocated cluster number as bit 0. / a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/ /
/ bit0=0: Use free cluster count in the FSINFO if available. / bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO. / bit0=1: Do not trust free cluster count in the FSINFO.
@@ -185,55 +205,66 @@
/ System Configurations / System Configurations
/---------------------------------------------------------------------------*/ /---------------------------------------------------------------------------*/
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */ #define _FS_TINY 0
#define _FS_TIMEOUT MS2ST(1000) /* Timeout period in unit of time tick */ /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
#define _SYNC_t semaphore_t* /* O/S dependent sync object type. e.g. HANDLE, OS_EVENT*, ID, SemaphoreHandle_t and etc.. */ / At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module. / Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
#define _FS_EXFAT 1
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2016
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to get current time form real-time clock. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 0
/* The option _FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define _FS_REENTRANT 1
#define _FS_TIMEOUT MS2ST(1000)
#define _SYNC_t semaphore_t*
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/ /
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. / 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers, / 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function must be added to the project. / function, must be added to the project. Samples are available in
*/ / option/syscall.c.
#define _WORD_ACCESS 1 /* 0 or 1 */
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/ /
/ 0: Byte-by-byte access. Always compatible with all platforms. / The _FS_TIMEOUT defines timeout period in unit of time tick.
/ 1: Word access. Do not choose this unless under both the following conditions. / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ / SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ * Address misaligned memory access is always allowed for ALL instructions. / included somewhere in the scope of ff.h. */
/ * Byte order on the memory is little-endian.
/ /* #include <windows.h> // O/S definitions */
/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance and
/ reduce code size. Following table shows an example of some processor types.
/
/ ARM7TDMI 0 ColdFire 0 V850E2 0
/ Cortex-M3 0 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 RX600(LE) 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(BE) 0 TLCS-900 0/1
/ AVR32 0 RL78 0 R32C 0
/ PIC18 0/1 SH-2 0 M16C 0/1
/ PIC24 0 H8S 0 MSP430 0
/ PIC32 0 H8/300H 0 x86 0/1
*/
/*--- End of configuration options ---*/
#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */
/* To enable file lock control feature, set _FS_LOCK to non-zero value.
/ The value defines how many files/sub-directories can be opened simultaneously
/ with file lock control. This feature uses bss _FS_LOCK * 12 bytes.
/
/ IMPORTANT NOTE:
/ For Paparazzi, we don't need file locking since all file are written sequentially
/ from one thread (thdSdLog)
/
*/
#endif /* _FFCONF */
@@ -383,9 +383,15 @@
#define STM32_SDC_SDIO_UNALIGNED_SUPPORT FALSE #define STM32_SDC_SDIO_UNALIGNED_SUPPORT FALSE
#define STM32_SDC_WRITE_TIMEOUT_MS 250 #define STM32_SDC_WRITE_TIMEOUT_MS 250
#define STM32_SDC_READ_TIMEOUT_MS 15 #define STM32_SDC_READ_TIMEOUT_MS 15
#define SDLOG_ALL_BUFFERS_SIZE 8192
#define SDLOG_MAX_MESSAGE_LEN 252 /*
#define SDLOG_QUEUE_BUCKETS 1024 sdlog message buffer and queue configuration
*/
#define SDLOG_QUEUE_BUCKETS 1024
#define SDLOG_MAX_MESSAGE_LEN 252
#define SDLOG_NUM_FILES 2
#define SDLOG_ALL_BUFFERS_SIZE (SDLOG_NUM_FILES*4096*2)
/* /*
* workaround hardware bug in REV.A revision of old STM32F4 (sold in 2012, early 2013) * workaround hardware bug in REV.A revision of old STM32F4 (sold in 2012, early 2013)
+87 -33
View File
@@ -46,6 +46,15 @@
#define SDLOG_START_DELAY 30 #define SDLOG_START_DELAY 30
#endif #endif
// Auto-flush period (in seconds)
#ifndef SDLOG_AUTO_FLUSH_PERIOD
#define SDLOG_AUTO_FLUSH_PERIOD 10
#endif
// Contiguous storage memory (in Mo)
#ifndef SDLOG_CONTIGUOUS_STORAGE_MEM
#define SDLOG_CONTIGUOUS_STORAGE_MEM 50
#endif
#if (!defined USE_ADC_WATCHDOG) || (USE_ADC_WATCHDOG == 0) #if (!defined USE_ADC_WATCHDOG) || (USE_ADC_WATCHDOG == 0)
#error sdlog_chibios need USE_ADC_WATCHDOG in order to properly close files when power is unplugged #error sdlog_chibios need USE_ADC_WATCHDOG in order to properly close files when power is unplugged
@@ -67,7 +76,7 @@ static __attribute__((noreturn)) void thd_startlog(void *arg);
*/ */
static THD_WORKING_AREA(wa_thd_bat_survey, 1024); static THD_WORKING_AREA(wa_thd_bat_survey, 1024);
static __attribute__((noreturn)) void thd_bat_survey(void *arg); static __attribute__((noreturn)) void thd_bat_survey(void *arg);
static void powerOutageIsr (void); static void powerOutageIsr(void);
event_source_t powerOutageSource; event_source_t powerOutageSource;
event_listener_t powerOutageListener; event_listener_t powerOutageListener;
@@ -83,9 +92,28 @@ static const char FR_LOG_DIR[] = "FLIGHT_RECORDER";
FileDes flightRecorderLogFile = -1; FileDes flightRecorderLogFile = -1;
#endif #endif
/** sdlog status
*/
static enum {
SDLOG_STOPPED = 0,
SDLOG_RUNNING,
SDLOG_ERROR
} chibios_sdlog_status;
#if PERIODIC_TELEMETRY
#include "subsystems/datalink/telemetry.h"
static void send_sdlog_status(struct transport_tx *trans, struct link_device *dev)
{
uint8_t status = (uint8_t) chibios_sdlog_status;
uint8_t errno = (uint8_t) sdLogGetStorageStatus();
uint32_t used = (uint32_t) sdLogGetNbBytesWrittenToStorage();
pprz_msg_send_LOGGER_STATUS(trans, dev, AC_ID, &status, &errno, &used);
}
#endif
// Functions for the generic device API // Functions for the generic device API
static int sdlog_check_free_space(struct chibios_sdlog* p __attribute__((unused)), long *fd, uint16_t len) static int sdlog_check_free_space(struct chibios_sdlog *p __attribute__((unused)), long *fd, uint16_t len)
{ {
SdLogBuffer *sdb; SdLogBuffer *sdb;
SdioError status = sdLogAllocSDB(&sdb, len); SdioError status = sdLogAllocSDB(&sdb, len);
@@ -97,7 +125,7 @@ static int sdlog_check_free_space(struct chibios_sdlog* p __attribute__((unused)
} }
} }
static void sdlog_transmit(struct chibios_sdlog* p __attribute__((unused)), long fd, uint8_t byte) static void sdlog_transmit(struct chibios_sdlog *p __attribute__((unused)), long fd, uint8_t byte)
{ {
SdLogBuffer *sdb = (SdLogBuffer *) fd; SdLogBuffer *sdb = (SdLogBuffer *) fd;
uint8_t *data = (uint8_t *) sdLogGetBufferFromSDB(sdb); uint8_t *data = (uint8_t *) sdLogGetBufferFromSDB(sdb);
@@ -105,14 +133,14 @@ static void sdlog_transmit(struct chibios_sdlog* p __attribute__((unused)), long
sdLogSeekBufferFromSDB(sdb, 1); sdLogSeekBufferFromSDB(sdb, 1);
} }
static void sdlog_transmit_buffer(struct chibios_sdlog* p __attribute__((unused)), long fd, uint8_t *data, uint16_t len) static void sdlog_transmit_buffer(struct chibios_sdlog *p __attribute__((unused)), long fd, uint8_t *data, uint16_t len)
{ {
SdLogBuffer *sdb = (SdLogBuffer *) fd; SdLogBuffer *sdb = (SdLogBuffer *) fd;
memcpy(sdLogGetBufferFromSDB(sdb), data, len); memcpy(sdLogGetBufferFromSDB(sdb), data, len);
sdLogSeekBufferFromSDB(sdb, len); sdLogSeekBufferFromSDB(sdb, len);
} }
static void sdlog_send(struct chibios_sdlog* p, long fd) static void sdlog_send(struct chibios_sdlog *p, long fd)
{ {
SdLogBuffer *sdb = (SdLogBuffer *) fd; SdLogBuffer *sdb = (SdLogBuffer *) fd;
sdLogWriteSDB(*(p->file), sdb); sdLogWriteSDB(*(p->file), sdb);
@@ -137,25 +165,34 @@ void chibios_sdlog_init(struct chibios_sdlog *sdlog, FileDes *file)
void sdlog_chibios_init(void) void sdlog_chibios_init(void)
{ {
chibios_sdlog_status = SDLOG_STOPPED;
#if PERIODIC_TELEMETRY
register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_LOGGER_STATUS, send_sdlog_status);
#endif
// Start polling on USB // Start polling on USB
usbStorageStartPolling(); usbStorageStartPolling();
// Start log thread // Start log thread
chThdCreateStatic(wa_thd_startlog, sizeof(wa_thd_startlog), chThdCreateStatic(wa_thd_startlog, sizeof(wa_thd_startlog),
NORMALPRIO+2, thd_startlog, NULL); NORMALPRIO + 2, thd_startlog, NULL);
} }
void sdlog_chibios_finish(bool flush) void sdlog_chibios_finish(const bool flush)
{ {
if (pprzLogFile != -1) { if (pprzLogFile != -1) {
// disable all the LEDs to save energy and maximize chance to flush files
// to mass storage and avoid infamous dirty bit on filesystem
led_disable();
sdLogCloseAllLogs(flush); sdLogCloseAllLogs(flush);
sdLogFinish (); sdLogFinish();
pprzLogFile = 0; pprzLogFile = 0;
#if FLIGHTRECORDER_SDLOG #if FLIGHTRECORDER_SDLOG
flightRecorderLogFile = 0; flightRecorderLogFile = 0;
#endif #endif
} }
chibios_sdlog_status = SDLOG_STOPPED;
} }
static void thd_startlog(void *arg) static void thd_startlog(void *arg)
@@ -164,10 +201,11 @@ static void thd_startlog(void *arg)
chRegSetThreadName("start log"); chRegSetThreadName("start log");
// Wait before starting the log if needed // Wait before starting the log if needed
chThdSleepSeconds (SDLOG_START_DELAY); chThdSleepSeconds(SDLOG_START_DELAY);
// Check if we are already in USB Storage mode // Check if we are already in USB Storage mode
if (usbStorageIsItRunning ()) if (usbStorageIsItRunning()) {
chThdSleepSeconds (20000); // stuck here for hours FIXME stop the thread ? chThdSleepSeconds(20000); // stuck here for hours FIXME stop the thread ?
}
// Init sdlog struct // Init sdlog struct
chibios_sdlog_init(&chibios_sdlog, &pprzLogFile); chibios_sdlog_init(&chibios_sdlog, &pprzLogFile);
@@ -175,37 +213,52 @@ static void thd_startlog(void *arg)
// Check for init errors // Check for init errors
sdOk = true; sdOk = true;
if (sdLogInit (NULL) != SDLOG_OK) { if (sdLogInit(NULL) != SDLOG_OK) {
sdOk = false; sdOk = false;
} } else {
else { removeEmptyLogs(PPRZ_LOG_DIR, PPRZ_LOG_NAME, 50);
removeEmptyLogs (PPRZ_LOG_DIR, PPRZ_LOG_NAME, 50); if (sdLogOpenLog(&pprzLogFile, PPRZ_LOG_DIR, PPRZ_LOG_NAME, SDLOG_AUTO_FLUSH_PERIOD, true) != SDLOG_OK) {
if (sdLogOpenLog (&pprzLogFile, PPRZ_LOG_DIR, PPRZ_LOG_NAME, true) != SDLOG_OK)
sdOk = false; sdOk = false;
}
// try to reserve contiguous mass storage memory
sdLogExpandLogFile(pprzLogFile, SDLOG_CONTIGUOUS_STORAGE_MEM, false);
#if FLIGHTRECORDER_SDLOG #if FLIGHTRECORDER_SDLOG
removeEmptyLogs (FR_LOG_DIR, FLIGHTRECORDER_LOG_NAME, 50); removeEmptyLogs(FR_LOG_DIR, FLIGHTRECORDER_LOG_NAME, 50);
if (sdLogOpenLog (&flightRecorderLogFile, FR_LOG_DIR, FLIGHTRECORDER_LOG_NAME, false) != SDLOG_OK) if (sdLogOpenLog(&flightRecorderLogFile, FR_LOG_DIR, FLIGHTRECORDER_LOG_NAME, SDLOG_AUTO_FLUSH_PERIOD, false) != SDLOG_OK) {
sdOk = false; sdOk = false;
}
// try to reserve contiguous mass storage memory
sdLogExpandLogFile(flightRecorderLogFile, SDLOG_CONTIGUOUS_STORAGE_MEM, false);
#endif #endif
} }
if (sdOk) { if (sdOk) {
// Create Battery Survey Thread with event // Create Battery Survey Thread with event
chEvtObjectInit (&powerOutageSource); chEvtObjectInit(&powerOutageSource);
chThdCreateStatic (wa_thd_bat_survey, sizeof(wa_thd_bat_survey), chThdCreateStatic(wa_thd_bat_survey, sizeof(wa_thd_bat_survey),
NORMALPRIO+2, thd_bat_survey, NULL); NORMALPRIO + 2, thd_bat_survey, NULL);
chibios_sdlog_status = SDLOG_RUNNING;
} else {
chibios_sdlog_status = SDLOG_ERROR;
} }
while (true) { while (true) {
#ifdef LED_SDLOG #ifdef SDLOG_LED
LED_TOGGLE(LED_SDLOG); LED_TOGGLE(SDLOG_LED);
#endif #endif
// Blink faster if init has errors // Blink faster if init has errors
chThdSleepMilliseconds (sdOk == true ? 1000 : 200); chThdSleepMilliseconds(sdOk == true ? 1000 : 200);
static uint32_t timestamp = 0; if (sdLogGetStorageStatus() != SDLOG_OK) {
chibios_sdlog_status = SDLOG_ERROR;
sdOk = false;
} else {
chibios_sdlog_status = SDLOG_RUNNING;
sdOk = true;
}
#if HAL_USE_RTC && USE_GPS #if HAL_USE_RTC && USE_GPS
static uint32_t timestamp = 0;
// FIXME this could be done somewhere else, like in sys_time // FIXME this could be done somewhere else, like in sys_time
// we sync gps time to rtc every 5 seconds // we sync gps time to rtc every 5 seconds
if (chVTGetSystemTime() - timestamp > 5000) { if (chVTGetSystemTime() - timestamp > 5000) {
@@ -214,7 +267,7 @@ static void thd_startlog(void *arg)
// Unix timestamp of the GPS epoch 1980-01-06 00:00:00 UTC // Unix timestamp of the GPS epoch 1980-01-06 00:00:00 UTC
const uint32_t unixToGpsEpoch = 315964800; const uint32_t unixToGpsEpoch = 315964800;
struct tm time_tm; struct tm time_tm;
time_t univTime = ((gps.week * 7 * 24 * 3600) + (gps.tow/1000)) + unixToGpsEpoch; time_t univTime = ((gps.week * 7 * 24 * 3600) + (gps.tow / 1000)) + unixToGpsEpoch;
gmtime_r(&univTime, &time_tm); gmtime_r(&univTime, &time_tm);
// Chibios date struct // Chibios date struct
RTCDateTime date; RTCDateTime date;
@@ -231,25 +284,26 @@ static void thd_startlog(void *arg)
static void thd_bat_survey(void *arg) static void thd_bat_survey(void *arg)
{ {
(void)arg; (void)arg;
chRegSetThreadName ("battery survey"); chRegSetThreadName("battery survey");
chEvtRegister(&powerOutageSource, &powerOutageListener, 1); chEvtRegister(&powerOutageSource, &powerOutageListener, 1);
chThdSleepMilliseconds (2000); chThdSleepMilliseconds(2000);
register_adc_watchdog(&SDLOG_BAT_ADC, SDLOG_BAT_CHAN, V_ALERT, &powerOutageIsr); register_adc_watchdog(&SDLOG_BAT_ADC, SDLOG_BAT_CHAN, V_ALERT, &powerOutageIsr);
chEvtWaitOne(EVENT_MASK(1)); chEvtWaitOne(EVENT_MASK(1));
sdlog_chibios_finish (true); // in case of powerloss, we should go fast and avoid to flush ram buffer
sdlog_chibios_finish(false);
chThdExit(0); chThdExit(0);
mcu_deep_sleep(); mcu_deep_sleep();
chThdSleepMilliseconds (TIME_INFINITE); chThdSleep(TIME_INFINITE);
while (1); // never goes here, only to avoid compiler warning: 'noreturn' function does return while (true); // never goes here, only to avoid compiler warning: 'noreturn' function does return
} }
/* /*
powerOutageIsr is called within a lock zone from an isr, so no lock/unlock is needed powerOutageIsr is called within a lock zone from an isr, so no lock/unlock is needed
*/ */
static void powerOutageIsr (void) static void powerOutageIsr(void)
{ {
chEvtBroadcastI(&powerOutageSource); chEvtBroadcastI(&powerOutageSource);
} }
@@ -49,7 +49,6 @@ extern FileDes flightRecorderLogFile;
extern void sdlog_chibios_init(void); extern void sdlog_chibios_init(void);
extern void sdlog_chibios_finish(bool flush); extern void sdlog_chibios_finish(bool flush);
/** chibios_sdlog structure /** chibios_sdlog structure
*/ */
struct chibios_sdlog { struct chibios_sdlog {
@@ -140,7 +140,11 @@ int32_t msgqueue_pop_timeout(MsgQueue *que, void **msgPtr, const systime_t timou
{ {
MsgPtrLen mpl = {.ptrOfst = 0, .len = 0}; MsgPtrLen mpl = {.ptrOfst = 0, .len = 0};
const msg_t status = chMBFetch(&que->mb, (msg_t *) &mpl.msg_ptr_len, timout); msg_t status;
do {
status = chMBFetch(&que->mb, (msg_t *) &mpl.msg_ptr_len, timout);
} while (status == MSG_RESET);
if (status != MSG_OK) { if (status != MSG_OK) {
return MsgQueue_MAILBOX_TIMEOUT; return MsgQueue_MAILBOX_TIMEOUT;
} }
File diff suppressed because it is too large Load Diff
+130 -61
View File
@@ -29,7 +29,6 @@
#include "std.h" #include "std.h"
#include "mcuconf.h" #include "mcuconf.h"
//#include "ff.h"
#include <stdarg.h> #include <stdarg.h>
#define NUMBERLEN 4 #define NUMBERLEN 4
@@ -44,29 +43,53 @@ extern "C" {
This module is highly coupled with fatfs, and mcuconf.h This module is highly coupled with fatfs, and mcuconf.h
several MACRO should be defined before use several MACRO should be defined before use
FATFS (ffconf.h) : FATFS (ffconf.h)
° _FS_LOCK : number of simultaneously open file
° _FS_REENTRANT : If you need to open / close file during log, this should be set to 1 at
the expense of more used cam and cpu.
If you open all files prior to log data on them, it should be left to 0
MCUCONF.H (or any other header included before sdLog.h
mcuconf.h (or any other header included before sdLog.h
° SDLOG_ALL_BUFFERS_SIZE : (in bytes) cache buffer size shared between all opened log file ° SDLOG_ALL_BUFFERS_SIZE : (in bytes) cache buffer size shared between all opened log file
minumum size by opened log file should be at least 512 and
should be a POWER OF TWO
° SDLOG_MAX_MESSAGE_LEN : (in bytes) maximum length of a message ° SDLOG_MAX_MESSAGE_LEN : (in bytes) maximum length of a message
° SDLOG_QUEUE_BUCKETS : number of entries in queue ° SDLOG_QUEUE_BUCKETS : number of entries in bufering queue
° SDLOG_NUM_FILES : number of simultaneous opened log files
EXAMPLE:
#define SDLOG_QUEUE_BUCKETS 1024
#define SDLOG_MAX_MESSAGE_LEN 252
#define SDLOG_NUM_FILES 1
#define SDLOG_ALL_BUFFERS_SIZE (SDLOG_NUM_FILES*4096)
use of the api : use of the api :
sdLogInit (initialize peripheral, verify sdCard availibility) sdLogInit (initialize peripheral, verify sdCard availibility)
sdLogOpenLog : open file sdLogOpenLog : open file
sdLogWriteXXX sdLogExpandLogFile : reserve contiguous space on storage
sdLogFlushLog : flush buffer (optional) sdLogWriteXXX : write log using one off the many function of the API
sdLogCloseLog sdLogCloseLog : close log
sdLogFinish sdLogFinish : terminate logging thread
and asynchronous emergency close (power outage detection by example) : and asynchronous emergency close (power outage detection by example) :
sdLogCloseAllLogs sdLogCloseAllLogs
sdLogFinish sdLogFinish
+ ADVICE for maximizing throughtput by order of inportance
° define STM32_SDC_SDIO_UNALIGNED_SUPPORT to FALSE in mcuconf.h
° do not use sdLogFlushXXX API but instead give a flush period of 10 in sdLogOpenLog
° SDLOG_ALL_BUFFERS_SIZE/SDLOG_NUM_FILES should be around 8192 and a power of two
° reserve contiguous room for your entire log file using sdLogExpandLogFile
just after opening log
° use class 10 SD card
+ ADVICE for maximizing reliability
° survey power loss, and call sdLogCloseAllLogs (false) when power loss is detected
after having powered off all you can (LEDs or anything draining power from MCU pins)
° always check return status of function (sdLogOpenLog will fail if filesystem is dirty)
° always check filesystem health with fsck (linux) or CHKDSK (windows) when
mounting sd card on a computer
*/ */
@@ -90,10 +113,12 @@ typedef enum {
SDLOG_FSFULL, SDLOG_FSFULL,
SDLOG_FDFULL, SDLOG_FDFULL,
SDLOG_QUEUEFULL, SDLOG_QUEUEFULL,
SDLOG_MEMFULL,
SDLOG_NOTHREAD, SDLOG_NOTHREAD,
SDLOG_INTERNAL_ERROR, SDLOG_INTERNAL_ERROR,
SDLOG_CANNOT_EXPAND,
SDLOG_LOGNUM_ERROR, SDLOG_LOGNUM_ERROR,
SDLOG_WAS_LAUNCHED SDLOG_WAS_LAUNCHED,
} SdioError; } SdioError;
typedef struct _SdLogBuffer SdLogBuffer; typedef struct _SdLogBuffer SdLogBuffer;
@@ -108,7 +133,7 @@ typedef int8_t FileDes;
* This function is available even without thread login facility : even * This function is available even without thread login facility : even
* if SDLOG_XXX macro are zeroed * if SDLOG_XXX macro are zeroed
* @param[out] freeSpaceInKo : if pointer in nonnull, return free space on filesystem * @param[out] freeSpaceInKo : if pointer in nonnull, return free space on filesystem
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogInit(uint32_t *freeSpaceInKo); SdioError sdLogInit(uint32_t *freeSpaceInKo);
@@ -121,10 +146,10 @@ SdioError sdLogInit(uint32_t *freeSpaceInKo);
* if SDLOG_XXX macro are zeroed * if SDLOG_XXX macro are zeroed
* @param[in] prefix : the pattern for the file : example LOG_ * @param[in] prefix : the pattern for the file : example LOG_
* @param[in] directoryName : root directory where to find file * @param[in] directoryName : root directory where to find file
* @param[out] nextFileName : file with path ready to be used for f_open system call * @param[out] nextFileName : file with path ready to be used for f_open system call
* @param[in] nameLength : length of previous buffer * @param[in] nameLength : length of previous buffer
* @param[in] indexOffset : use 0 to retrieve last existent filename, 1 for next filename * @param[in] indexOffset : use 0 to retrieve last existent filename, 1 for next filename
* @return status (always check status) * @return status (always check status)
*/ */
SdioError getFileName(const char *prefix, const char *directoryName, SdioError getFileName(const char *prefix, const char *directoryName,
char *nextFileName, const size_t nameLength, const int indexOffset); char *nextFileName, const size_t nameLength, const int indexOffset);
@@ -141,16 +166,16 @@ SdioError getFileName(const char *prefix, const char *directoryName,
* @param[in] prefix : the pattern for the file : example LOG_ * @param[in] prefix : the pattern for the file : example LOG_
* @param[in] directoryName : root directory where to find file * @param[in] directoryName : root directory where to find file
* @param[in] sizeConsideredEmpty : file whose size is less or equal to that value will be removed * @param[in] sizeConsideredEmpty : file whose size is less or equal to that value will be removed
* @return status (always check status) * @return status (always check status)
*/ */
SdioError removeEmptyLogs(const char *directoryName, const char *prefix, SdioError removeEmptyLogs(const char *directoryName, const char *prefix,
const size_t sizeConsideredEmpty); const size_t sizeConsideredEmpty);
/** /**
* @brief unmount filesystem * @brief unmount filesystem
* @details unmount filesystem, free sdio peripheral * @details unmount filesystem, free sdio peripheral
* This function is available even without thread login facility : even * This function is available even without thread login facility : even
* if SDLOG_XXX macro are zeroed * if SDLOG_XXX macro are zeroed
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogFinish(void); SdioError sdLogFinish(void);
@@ -159,40 +184,68 @@ SdioError sdLogFinish(void);
/** /**
* @brief open new log file * @brief open new log file
* @details always open new file with numeric index * @details always open new file with numeric index
* @param[out] fileObject : file descriptor : small integer between 0 and _FS_REENTRANT-1 * @param[out] fileObject : file descriptor : small integer between 0 and _FS_REENTRANT-1
* @param[in] directoryName : name of directory just under ROOT, created if nonexistant * @param[in] directoryName : name of directory just under ROOT, created if nonexistant
* @param[in] fileName : the name will be appended with 3 digits number * @param[in] fileName : the name will be appended with 3 digits number
* @param[in] autoFlushPeriod : if non 0, period in second at which flush to mass storage is done
* if 0, no autoflush is done.
* @param[in] appendTagAtClose : at close, a marker will be added to prove that the file is complete * @param[in] appendTagAtClose : at close, a marker will be added to prove that the file is complete
* and not corrupt. useful for text logging purpose, but probably not wanted fort binary * and not corrupt. useful for text logging purpose, but probably not wanted for binary
* files. * files.
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogOpenLog(FileDes *fileObject, const char *directoryName, const char *fileName, SdioError sdLogOpenLog(FileDes *fileObject, const char *directoryName, const char *fileName,
bool appendTagAtClose); const uint32_t autoFlushPeriod,
const bool appendTagAtClose);
/**
* @brief expand underlying file to maximise throughtput
* @details ask underlying file system to prepare a contiguous data area to the file.
* if expand fail, file system is still avalaible but performance may suffer
* @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @param[in] sizeInMo : size of the contiguous storage
* @param[in] preallocate : if true, the file is preallocated at asked size, more efficient
* but take room on storage ans is not easy to manipulate afterward because of big files
* even if no log id recorded on file
* @return status (always check status)
*/
SdioError sdLogExpandLogFile(const FileDes fileObject, const size_t sizeInMo,
const bool preallocate);
/** /**
* @brief flush ram buffer associated with file to sdCard * @brief flush ram buffer associated with file to sdCard
* @details *WARNING* this lower throughtput by a factor of ten or more,
* @details leading to lost messages if writing rate is high
* @param[in] fileObject : file descriptor returned by sdLogOpenLog * @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogFlushLog(const FileDes fileObject); SdioError sdLogFlushLog(const FileDes fileObject);
/**
* @brief flush all ram buffers to sdCard
* @details *WARNING* this lower throughtput by a factor of ten or more,
* @details leading to lost messages if writing rate is high
* @return status (always check status)
*/
SdioError sdLogFlushAllLogs(void);
/** /**
* @brief flush ram buffer then close file. * @brief flush ram buffer then close file.
* @param[in] fileObject : file descriptor returned by sdLogOpenLog * @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogCloseLog(const FileDes fileObject); SdioError sdLogCloseLog(const FileDes fileObject);
/** /**
* @brief close all opened logs then stop worker thread * @brief close all opened logs then stop worker thread
* @param[in] flush : if true : flush all ram buffers before closing (take more time) * @param[in] flush : if true : flush all ram buffers before closing (take more time)
* if false : close imediatly files without flushing buffers, * if false : close imediatly files without flushing buffers,
* more chance to keep filesystem integrity in case of * more chance to keep filesystem integrity in case of
* emergency close after power outage is detected * emergency close after power outage is detected
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogCloseAllLogs(bool flush); SdioError sdLogCloseAllLogs(bool flush);
@@ -201,7 +254,7 @@ SdioError sdLogCloseAllLogs(bool flush);
* @brief log text * @brief log text
* @param[in] fileObject : file descriptor returned by sdLogOpenLog * @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @param[in] fmt : format and args in printf convention * @param[in] fmt : format and args in printf convention
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogWriteLog(const FileDes fileObject, const char *fmt, ...); SdioError sdLogWriteLog(const FileDes fileObject, const char *fmt, ...);
@@ -211,24 +264,25 @@ SdioError sdLogWriteLog(const FileDes fileObject, const char *fmt, ...);
* @param[in] fileObject : file descriptor returned by sdLogOpenLog * @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @param[in] buffer : memory pointer on buffer * @param[in] buffer : memory pointer on buffer
* @param[in] len : number of bytes to write * @param[in] len : number of bytes to write
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogWriteRaw(const FileDes fileObject, const uint8_t *buffer, const size_t len); SdioError sdLogWriteRaw(const FileDes fileObject, const uint8_t *buffer, const size_t len);
/** /**
* @brief log binary data limiting buffer copy by preallocating space * @brief log binary data limiting buffer copy by preallocating space
* @param[in] len : number of bytes to write * @param[in] len : number of bytes to write
* @param[out] sdb : pointer to opaque object pointer containing buffer * @param[out] sdb : pointer to opaque object pointer containing buffer
* there is two accessor functions (below) to access * there is two accessor functions (below) to access
* buffer ptr and buffer len. * buffer ptr and buffer len.
* @details usage of the set of 4 functions : * @details usage of the set of 4 functions :
* SdLogBuffer *sdb; * SdLogBuffer *sdb;
* sdLogAllocSDB (&sdb, 100); * sdLogAllocSDB (&sdb, 100);
* memcpy (getBufferFromSDB(sdb), SOURCE, offset); * memcpy (getBufferFromSDB(sdb), SOURCE, offset);
* sdLogSeekBufferFromSDB (sdb, offset); * sdLogSeekBufferFromSDB (sdb, offset);
* sdLogWriteSDB (file, sdb); * sdLogWriteSDB (file, sdb);
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogAllocSDB(SdLogBuffer **sdb, const size_t len); SdioError sdLogAllocSDB(SdLogBuffer **sdb, const size_t len);
/** /**
@@ -236,38 +290,38 @@ SdioError sdLogAllocSDB(SdLogBuffer **sdb, const size_t len);
* message + offset managed by sdLogSeekBufferFromSDB * message + offset managed by sdLogSeekBufferFromSDB
* @param[in] sdb : pointer to opaque object containing buffer * @param[in] sdb : pointer to opaque object containing buffer
* and previously filled by sdLogAllocSDB * and previously filled by sdLogAllocSDB
* @return pointer to writable area * @return pointer to writable area
*/ */
char *sdLogGetBufferFromSDB(SdLogBuffer *sdb); char *sdLogGetBufferFromSDB(SdLogBuffer *sdb);
/** /**
* @brief manage internal offset in user buffer * @brief manage internal offset in user buffer
* @param[in] sdb : pointer to opaque object containing buffer * @param[in] sdb : pointer to opaque object containing buffer
* and previously filled by sdLogAllocSDB * and previously filled by sdLogAllocSDB
* offset : increment internal offset with this value * offset : increment internal offset with this value
* @return true if offset is withing internal buffer boundary * @return true if offset is withing internal buffer boundary
* false if offset is NOT withing internal buffer boundary, in this case, false if offset is NOT withing internal buffer boundary, in this case,
* no keek is done no seek is done
*/ */
bool sdLogSeekBufferFromSDB(SdLogBuffer *sdb, uint32_t offset); bool sdLogSeekBufferFromSDB(SdLogBuffer *sdb, uint32_t offset);
/** /**
* @brief return len of the writable area of a preallocated message (this take into account * @brief return len of the writable area of a preallocated message (this take into account
* the offset) * the offset)
* @param[in] sdb : pointer to opaque object containing buffer * @param[in] sdb : pointer to opaque object containing buffer
* and previously filled by sdLogAllocSDB * and previously filled by sdLogAllocSDB
* @return len of writable area * @return len of writable area
*/ */
size_t sdLogGetBufferLenFromSDB(SdLogBuffer *sdb); size_t sdLogGetBufferLenFromSDB(SdLogBuffer *sdb);
/** /**
* @brief send a preallocted message after it has been filled * @brief send a preallocted message after it has been filled
* @param[in] fileObject : file descriptor returned by sdLogOpenLog * @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @param[in] sdb : pointer to opaque object containing buffer * @param[in] sdb : pointer to opaque object containing buffer
* and previously filled by sdLogAllocSDB * and previously filled by sdLogAllocSDB
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogWriteSDB(const FileDes fd, SdLogBuffer *sdb); SdioError sdLogWriteSDB(const FileDes fd, SdLogBuffer *sdb);
@@ -276,9 +330,24 @@ SdioError sdLogWriteSDB(const FileDes fd, SdLogBuffer *sdb);
* @brief log one byte of binary data * @brief log one byte of binary data
* @param[in] fileObject : file descriptor returned by sdLogOpenLog * @param[in] fileObject : file descriptor returned by sdLogOpenLog
* @param[in] value : byte to log * @param[in] value : byte to log
* @return status (always check status) * @return status (always check status)
*/ */
SdioError sdLogWriteByte(const FileDes fileObject, const uint8_t value); SdioError sdLogWriteByte(const FileDes fileObject, const uint8_t value);
/**
* @brief return number of bytes actually written to the mass storage
* @return number of bytes actually written to the mass storage (due to buffering, this can be
different than number of byte sent to the logger)
*/
size_t sdLogGetNbBytesWrittenToStorage(void);
/**
* @brief return storage backend status
* @return storage backend status
*/
SdioError sdLogGetStorageStatus(void);
#endif #endif
@@ -36,198 +36,21 @@
#include "mcu_periph/sdio.h" #include "mcu_periph/sdio.h"
#include "led.h" #include "led.h"
static uint8_t nibbleToHex(uint8_t nibble);
static void populateSerialNumberDescriptorData(void);
static void thdUsbStorage(void *arg); static void thdUsbStorage(void *arg);
static thread_t *usbStorageThreadPtr = NULL; static thread_t *usbStorageThreadPtr = NULL;
/* USB mass storage driver */ /* USB mass storage driver */
static USBMassStorageDriver UMSD1;
static bool isRunning = false; static bool isRunning = false;
/* endpoint index */
#define USB_MS_DATA_EP 1
/* USB device descriptor */
static const uint8_t deviceDescriptorData[] = {
USB_DESC_DEVICE
(
0x0200, /* supported USB version (2.0) */
0x00, /* device class (none, specified in interface) */
0x00, /* device sub-class (none, specified in interface) */
0x00, /* device protocol (none, specified in interface) */
64, /* max packet size of control end-point */
0x0483, /* vendor ID (STMicroelectronics!) */
0x5740, /* product ID (STM32F407) */
0x0100, /* device release number */
1, /* index of manufacturer string descriptor */
2, /* index of product string descriptor */
3, /* index of serial number string descriptor */
1 /* number of possible configurations */
)
};
static const USBDescriptor deviceDescriptor = {
sizeof(deviceDescriptorData),
deviceDescriptorData
};
/* configuration descriptor */
static const uint8_t configurationDescriptorData[] = {
/* configuration descriptor */
USB_DESC_CONFIGURATION
(
32, /* total length */
1, /* number of interfaces */
1, /* value that selects this configuration */
0, /* index of string descriptor describing this configuration */
0xC0, /* attributes (self-powered) */
50 /* max power (100 mA) */
),
/* interface descriptor */
USB_DESC_INTERFACE
(
0, /* interface number */
0, /* value used to select alternative setting */
2, /* number of end-points used by this interface */
0x08, /* interface class (Mass Storage) */
0x06, /* interface sub-class (SCSI Transparent Storage) */
0x50, /* interface protocol (Bulk Only) */
0 /* index of string descriptor describing this interface */
),
/* end-point descriptor */
USB_DESC_ENDPOINT
(
USB_MS_DATA_EP | 0x80, /* address (end point index | OUT direction) */
USB_EP_MODE_TYPE_BULK, /* attributes (bulk) */
64, /* max packet size */
0x05 /* polling interval (ignored for bulk end-points) */
),
/* end-point descriptor */
USB_DESC_ENDPOINT
(
USB_MS_DATA_EP | 0x00, /* address (end point index | IN direction) */
USB_EP_MODE_TYPE_BULK, /* attributes (bulk) */
64, /* max packet size */
0x05 /* polling interval (ignored for bulk end-points) */
)
};
static const USBDescriptor configurationDescriptor = {
sizeof(configurationDescriptorData),
configurationDescriptorData
};
/* Language descriptor */
static const uint8_t languageDescriptorData[] = {
USB_DESC_BYTE(4),
USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
USB_DESC_WORD(0x0409) /* U.S. english */
};
static const USBDescriptor languageDescriptor = {
sizeof(languageDescriptorData),
languageDescriptorData
};
/* Vendor descriptor */
static const uint8_t vendorDescriptorData[] = {
USB_DESC_BYTE(20),
USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
'P', 0, 'a', 0, 'p', 0, 'a', 0, 'r', 0, 'a', 0, 'z', 0, 'z', 0, 'i', 0
};
static const USBDescriptor vendorDescriptor = {
sizeof(vendorDescriptorData),
vendorDescriptorData
};
/* Product descriptor */
static const uint8_t productDescriptorData[] = {
USB_DESC_BYTE(20),
USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
'A', 0, 'u', 0, 't', 0, 'o', 0, 'p', 0, 'i', 0, 'l', 0, 'o', 0, 't', 0
};
static const USBDescriptor productDescriptor = {
sizeof(productDescriptorData),
productDescriptorData
};
/* Serial number descriptor from stm32 uniq id */
/* uniq id is 12 bytes which gives 24 char which require 50 bytes for usb description */
/* this array is the only one in ram (others in flash), and should be populated before */
/* usb initialisation */
uint8_t serialNumberDescriptorData[50] = {
USB_DESC_BYTE(50),
USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
0
};
static const USBDescriptor serialNumberDescriptor = {
sizeof(serialNumberDescriptorData),
serialNumberDescriptorData
};
/* Handles GET_DESCRIPTOR requests from the USB host */
static const USBDescriptor *getDescriptor(USBDriver *usbp, uint8_t type, uint8_t index, uint16_t lang)
{
(void)usbp;
(void)lang;
switch (type) {
case USB_DESCRIPTOR_DEVICE:
return &deviceDescriptor;
case USB_DESCRIPTOR_CONFIGURATION:
return &configurationDescriptor;
case USB_DESCRIPTOR_STRING:
switch (index) {
case 0: return &languageDescriptor;
case 1: return &vendorDescriptor;
case 2: return &productDescriptor;
case 3: return &serialNumberDescriptor;
}
}
return 0;
}
/* Handles global events of the USB driver */
static void usbEvent(USBDriver *usbp, usbevent_t event)
{
(void) usbp;
switch (event) {
case USB_EVENT_CONFIGURED:
chSysLockFromISR();
msdConfigureHookI(&UMSD1);
chSysUnlockFromISR();
break;
case USB_EVENT_RESET:
case USB_EVENT_ADDRESS:
case USB_EVENT_SUSPEND:
case USB_EVENT_WAKEUP:
case USB_EVENT_STALLED:
default:
break;
}
}
/* Configuration of the USB driver */
const USBConfig usbConfig = {
usbEvent,
getDescriptor,
msdRequestsHook,
0
};
/* Turns on a LED when there is I/O activity on the USB port */ /* Turns on a LED when there is I/O activity on the USB port */
static void usbActivity(bool active __attribute__((unused))) static void usbActivity(bool active __attribute__((unused)))
{ {
#ifdef SDLOG_USB_LED #ifdef SDLOG_USB_LED
if (active) if (active) {
LED_ON(SDLOG_USB_LED); LED_ON(SDLOG_USB_LED);
else } else {
LED_OFF(SDLOG_USB_LED); LED_OFF(SDLOG_USB_LED);
}
#endif #endif
} }
@@ -237,16 +60,15 @@ static USBMassStorageConfig msdConfig = {
(BaseBlockDevice *) &SDCD1, (BaseBlockDevice *) &SDCD1,
USB_MS_DATA_EP, USB_MS_DATA_EP,
&usbActivity, &usbActivity,
"DPprz_sd", "Pprz_sd",
"DApogee", "AutoPilot",
"0.1" "0.2"
}; };
static THD_WORKING_AREA(waThdUsbStorage, 1024); static THD_WORKING_AREA(waThdUsbStorage, 1024);
void usbStorageStartPolling(void) void usbStorageStartPolling(void)
{ {
populateSerialNumberDescriptorData();
usbStorageThreadPtr = chThdCreateStatic(waThdUsbStorage, sizeof(waThdUsbStorage), usbStorageThreadPtr = chThdCreateStatic(waThdUsbStorage, sizeof(waThdUsbStorage),
NORMALPRIO + 2, thdUsbStorage, NULL); NORMALPRIO + 2, thdUsbStorage, NULL);
@@ -279,12 +101,6 @@ static void thdUsbStorage(void *arg)
uint antiBounce = 5; uint antiBounce = 5;
event_listener_t connected; event_listener_t connected;
// Should use EXTI interrupt instead of active polling,
// but in the chibios_opencm3 implementation, since EXTI is
// used via libopencm3, ISR are routed on pprz/opencm3 and cannot
// be used concurrently by chibios api
// Should be fixed when using chibios-rt branch
// FIXME: Is the comment still relevant?
while (!chThdShouldTerminateX() && antiBounce) { while (!chThdShouldTerminateX() && antiBounce) {
const bool usbConnected = palReadPad(SDLOG_USB_VBUS_PORT, SDLOG_USB_VBUS_PIN); const bool usbConnected = palReadPad(SDLOG_USB_VBUS_PORT, SDLOG_USB_VBUS_PIN);
if (usbConnected) { if (usbConnected) {
@@ -299,7 +115,8 @@ static void thdUsbStorage(void *arg)
chRegSetThreadName("UsbStorage:connected"); chRegSetThreadName("UsbStorage:connected");
/* Stop the logs*/ /* Stop the logs*/
sdlog_chibios_finish(false); // it's not a powerloss, wa have time to flush the ram buffer
sdlog_chibios_finish(true);
/* connect sdcard sdc interface sdio */ /* connect sdcard sdc interface sdio */
@@ -308,19 +125,10 @@ static void thdUsbStorage(void *arg)
} }
/* initialize the USB mass storage driver */ /* initialize the USB mass storage driver */
msdInit(&UMSD1); init_msd_driver(NULL, &msdConfig);
/* start the USB mass storage service */
msdStart(&UMSD1, &msdConfig);
/* start the USB driver */
usbDisconnectBus(&USBD1);
chThdSleepMilliseconds(1000);
usbStart(&USBD1, &usbConfig);
usbConnectBus(&USBD1);
/* wait for a real usb storage connexion before shutting down autopilot */ /* wait for a real usb storage connexion before shutting down autopilot */
chEvtRegisterMask(&UMSD1.evt_connected, &connected, EVENT_MASK(1)); msd_register_evt_connected(&connected, EVENT_MASK(1));
chEvtWaitOne(EVENT_MASK(1)); chEvtWaitOne(EVENT_MASK(1));
/* stop autopilot */ /* stop autopilot */
@@ -331,15 +139,11 @@ static void thdUsbStorage(void *arg)
chThdSleepMilliseconds(10); chThdSleepMilliseconds(10);
} }
deinit_msd_driver();
/* then close open descriptors and reboot autopilot */
usbDisconnectBus(&USBD1);
chThdSleepMilliseconds(500); chThdSleepMilliseconds(500);
msdStop(&UMSD1);
sdio_disconnect();
mcu_reset(); mcu_reset();
return;
} }
bool usbStorageIsItRunning(void) bool usbStorageIsItRunning(void)
@@ -347,24 +151,3 @@ bool usbStorageIsItRunning(void)
return isRunning; return isRunning;
} }
static uint8_t nibbleToHex(uint8_t nibble)
{
nibble &= 0x0F;
return nibble < 10 ? nibble + '0' : nibble + 'A' - 10;
}
static void populateSerialNumberDescriptorData(void)
{
const uint8_t *UniqProcessorId = (uint8_t *) 0x1FFF7A10;
const uint8_t UniqProcessorIdLen = 12;
uint8_t *baseDdPtr = &serialNumberDescriptorData[2];
for (uint32_t i = 0; i < UniqProcessorIdLen; i++) {
*baseDdPtr++ = nibbleToHex(UniqProcessorId[i] >> 4);
*baseDdPtr++ = 0;
*baseDdPtr++ = nibbleToHex(UniqProcessorId[i]);
*baseDdPtr++ = 0;
}
}
File diff suppressed because it is too large Load Diff
@@ -26,21 +26,39 @@
#pragma once #pragma once
#include <ch.h>
#include <hal.h>
#include "std.h"
#ifndef PACK_STRUCT_BEGIN #include "ch.h"
#define PACK_STRUCT_BEGIN #include "hal.h"
#endif #include "chdebug.h"
#include "modules/loggers/sdlog_chibios/usb_msd.h"
#ifndef PACK_STRUCT_END
#define PACK_STRUCT_END
#endif
#ifndef PACK_STRUCT_STRUCT
#define PACK_STRUCT_STRUCT __attribute__((packed)) #define PACK_STRUCT_STRUCT __attribute__((packed))
#endif #define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
/* endpoint index */
#define USB_MS_DATA_EP 1
#define USBD USBD1
#define SEM_TAKEN
#define SEM_RELEASED
#define EVT_USB_RESET (1 << 0)
#define EVT_BOT_RESET (1 << 1)
#define EVT_SEM_TAKEN (1 << 2)
#define EVT_SEM_RELEASED (1 << 3)
#define EVT_USB_CONFIGURED (1 << 4)
#define EVT_SCSI_REQ_TEST_UNIT_READY (1 << 5)
#define EVT_SCSI_REQ_READ_FMT_CAP (1 << 6)
#define EVT_SCSI_REQ_SENSE6 (1 << 7)
#define EVT_SCSI_REQ_SENSE10 (1 << 8)
#define EVT_WAIT_FOR_COMMAND_BLOCK (1 << 9)
#define EVT_SCSI_REQ_SEND_DIAGNOSTIC (1 << 10)
#define EVT_SCSI_REQ_READ_CAP10 (1 << 11)
#define EVT_SCSI_PROC_INQ (1 << 12)
/** /**
* @brief Command Block Wrapper structure * @brief Command Block Wrapper structure
@@ -95,7 +113,8 @@ PACK_STRUCT_BEGIN typedef struct {
typedef enum { typedef enum {
MSD_IDLE, MSD_IDLE,
MSD_READ_COMMAND_BLOCK, MSD_READ_COMMAND_BLOCK,
MSD_EJECTED MSD_EJECTED,
MSD_BOT_RESET
} msd_state_t; } msd_state_t;
/** /**
@@ -103,44 +122,44 @@ typedef enum {
*/ */
typedef struct { typedef struct {
/** /**
* @brief USB driver to use for communication * @brief USB driver to use for communication
*/ */
USBDriver *usbp; USBDriver *usbp;
/** /**
* @brief Block device to use for storage * @brief Block device to use for storage
*/ */
BaseBlockDevice *bbdp; BaseBlockDevice *bbdp;
/** /**
* @brief Index of the USB endpoint to use for transfers * @brief Index of the USB endpoint to use for transfers
*/ */
usbep_t bulk_ep; usbep_t bulk_ep;
/** /**
* @brief Optional callback that will be called whenever there is * @brief Optional callback that will be called whenever there is
* read/write activity * read/write activity
* @note The callback is called with argument true when activity starts, * @note The callback is called with argument true when activity starts,
* and false when activity stops. * and false when activity stops.
*/ */
void (*rw_activity_callback)(bool); void (*rw_activity_callback)(bool);
/** /**
* @brief Short vendor identification * @brief Short vendor identification
* @note ASCII characters only, maximum 8 characters (pad with zeroes). * @note ASCII characters only, maximum 8 characters (pad with zeroes).
*/ */
uint8_t short_vendor_id[8]; uint8_t short_vendor_id[8];
/** /**
* @brief Short product identification * @brief Short product identification
* @note ASCII characters only, maximum 16 characters (pad with zeroes). * @note ASCII characters only, maximum 16 characters (pad with zeroes).
*/ */
uint8_t short_product_id[16]; uint8_t short_product_id[16];
/** /**
* @brief Short product revision * @brief Short product revision
* @note ASCII characters only, maximum 4 characters (pad with zeroes). * @note ASCII characters only, maximum 4 characters (pad with zeroes).
*/ */
uint8_t short_product_version[4]; uint8_t short_product_version[4];
} USBMassStorageConfig; } USBMassStorageConfig;
@@ -161,7 +180,9 @@ typedef struct {
msd_csw_t csw; msd_csw_t csw;
msd_scsi_sense_response_t sense; msd_scsi_sense_response_t sense;
msd_scsi_inquiry_response_t inquiry; msd_scsi_inquiry_response_t inquiry;
bool reconfigured_or_reset_event;
bool result; bool result;
bool bot_reset;
} USBMassStorageDriver; } USBMassStorageDriver;
#ifdef __cplusplus #ifdef __cplusplus
@@ -214,8 +235,25 @@ void msdConfigureHookI(USBMassStorageDriver *msdp);
*/ */
bool msdRequestsHook(USBDriver *usbp); bool msdRequestsHook(USBDriver *usbp);
void init_msd_driver(void *dbgThreadPtr, USBMassStorageConfig *msdConfig);
void deinit_msd_driver(void);
/**
* @brief register connected event source in local event mask
* @details This function is a stub to chEvtRegisterMask
*/
void msd_register_evt_connected(event_listener_t *elp, eventmask_t mask);
/**
* @brief register ejected event source in local event mask
* @details This function is a stub to chEvtRegisterMask
* ejected event is a logical event : when host unmount the filesystem,
* not a physical event (event is not sent in case of unplugged usb wire)
*/
void msd_register_evt_ejected(event_listener_t *elp, eventmask_t mask);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
+2 -2
View File
@@ -377,11 +377,11 @@ static block_header_t* search_suitable_block(control_t* control, int* fli, int*
** First, search for a block in the list associated with the given ** First, search for a block in the list associated with the given
** fl/sl index. ** fl/sl index.
*/ */
unsigned int sl_map = control->sl_bitmap[fl] & (~0 << sl); unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl);
if (!sl_map) if (!sl_map)
{ {
/* No block exists. Search in the next largest first-level list. */ /* No block exists. Search in the next largest first-level list. */
const unsigned int fl_map = control->fl_bitmap & (~0 << (fl + 1)); const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1));
if (!fl_map) if (!fl_map)
{ {
/* No free blocks available, memory has been exhausted. */ /* No free blocks available, memory has been exhausted. */