Добавлена ОС и ошибки
This commit is contained in:
parent
0a36a55574
commit
fb1a1f04a3
|
|
@ -49,6 +49,8 @@ SET(VECT_TAB_OFFSET "0x00000")
|
||||||
#-- Defines --------------------------------------------------------------------
|
#-- Defines --------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DLFS_NO_MALLOC=1)
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DINTERNAL_HW_YEAR=${INTERNAL_HW_YEAR})
|
ADD_DEFINITIONS(-DINTERNAL_HW_YEAR=${INTERNAL_HW_YEAR})
|
||||||
ADD_DEFINITIONS(-DINTERNAL_HW_MONTH=${INTERNAL_HW_MONTH})
|
ADD_DEFINITIONS(-DINTERNAL_HW_MONTH=${INTERNAL_HW_MONTH})
|
||||||
ADD_DEFINITIONS(-DINTERNAL_HW_DAY=${INTERNAL_HW_DAY})
|
ADD_DEFINITIONS(-DINTERNAL_HW_DAY=${INTERNAL_HW_DAY})
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,797 @@
|
||||||
|
/*
|
||||||
|
* The little filesystem
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#ifndef LFS_H
|
||||||
|
#define LFS_H
|
||||||
|
|
||||||
|
#include "lfs_util.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/// Version info ///
|
||||||
|
|
||||||
|
// Software library version
|
||||||
|
// Major (top-nibble), incremented on backwards incompatible changes
|
||||||
|
// Minor (bottom-nibble), incremented on feature additions
|
||||||
|
#define LFS_VERSION 0x00020009
|
||||||
|
#define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
|
||||||
|
#define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0))
|
||||||
|
|
||||||
|
// Version of On-disk data structures
|
||||||
|
// Major (top-nibble), incremented on backwards incompatible changes
|
||||||
|
// Minor (bottom-nibble), incremented on feature additions
|
||||||
|
#define LFS_DISK_VERSION 0x00020001
|
||||||
|
#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
|
||||||
|
#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
|
||||||
|
|
||||||
|
|
||||||
|
/// Definitions ///
|
||||||
|
|
||||||
|
// Type definitions
|
||||||
|
typedef uint32_t lfs_size_t;
|
||||||
|
typedef uint32_t lfs_off_t;
|
||||||
|
|
||||||
|
typedef int32_t lfs_ssize_t;
|
||||||
|
typedef int32_t lfs_soff_t;
|
||||||
|
|
||||||
|
typedef uint32_t lfs_block_t;
|
||||||
|
|
||||||
|
// Maximum name size in bytes, may be redefined to reduce the size of the
|
||||||
|
// info struct. Limited to <= 1022. Stored in superblock and must be
|
||||||
|
// respected by other littlefs drivers.
|
||||||
|
#ifndef LFS_NAME_MAX
|
||||||
|
#define LFS_NAME_MAX 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Maximum size of a file in bytes, may be redefined to limit to support other
|
||||||
|
// drivers. Limited on disk to <= 2147483647. Stored in superblock and must be
|
||||||
|
// respected by other littlefs drivers.
|
||||||
|
#ifndef LFS_FILE_MAX
|
||||||
|
#define LFS_FILE_MAX 2147483647
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Maximum size of custom attributes in bytes, may be redefined, but there is
|
||||||
|
// no real benefit to using a smaller LFS_ATTR_MAX. Limited to <= 1022. Stored
|
||||||
|
// in superblock and must be respected by other littlefs drivers.
|
||||||
|
#ifndef LFS_ATTR_MAX
|
||||||
|
#define LFS_ATTR_MAX 1022
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Possible error codes, these are negative to allow
|
||||||
|
// valid positive return values
|
||||||
|
enum lfs_error {
|
||||||
|
LFS_ERR_OK = 0, // No error
|
||||||
|
LFS_ERR_IO = -5, // Error during device operation
|
||||||
|
LFS_ERR_CORRUPT = -84, // Corrupted
|
||||||
|
LFS_ERR_NOENT = -2, // No directory entry
|
||||||
|
LFS_ERR_EXIST = -17, // Entry already exists
|
||||||
|
LFS_ERR_NOTDIR = -20, // Entry is not a dir
|
||||||
|
LFS_ERR_ISDIR = -21, // Entry is a dir
|
||||||
|
LFS_ERR_NOTEMPTY = -39, // Dir is not empty
|
||||||
|
LFS_ERR_BADF = -9, // Bad file number
|
||||||
|
LFS_ERR_FBIG = -27, // File too large
|
||||||
|
LFS_ERR_INVAL = -22, // Invalid parameter
|
||||||
|
LFS_ERR_NOSPC = -28, // No space left on device
|
||||||
|
LFS_ERR_NOMEM = -12, // No more memory available
|
||||||
|
LFS_ERR_NOATTR = -61, // No data/attr available
|
||||||
|
LFS_ERR_NAMETOOLONG = -36, // File name too long
|
||||||
|
};
|
||||||
|
|
||||||
|
// File types
|
||||||
|
enum lfs_type {
|
||||||
|
// file types
|
||||||
|
LFS_TYPE_REG = 0x001,
|
||||||
|
LFS_TYPE_DIR = 0x002,
|
||||||
|
|
||||||
|
// internally used types
|
||||||
|
LFS_TYPE_SPLICE = 0x400,
|
||||||
|
LFS_TYPE_NAME = 0x000,
|
||||||
|
LFS_TYPE_STRUCT = 0x200,
|
||||||
|
LFS_TYPE_USERATTR = 0x300,
|
||||||
|
LFS_TYPE_FROM = 0x100,
|
||||||
|
LFS_TYPE_TAIL = 0x600,
|
||||||
|
LFS_TYPE_GLOBALS = 0x700,
|
||||||
|
LFS_TYPE_CRC = 0x500,
|
||||||
|
|
||||||
|
// internally used type specializations
|
||||||
|
LFS_TYPE_CREATE = 0x401,
|
||||||
|
LFS_TYPE_DELETE = 0x4ff,
|
||||||
|
LFS_TYPE_SUPERBLOCK = 0x0ff,
|
||||||
|
LFS_TYPE_DIRSTRUCT = 0x200,
|
||||||
|
LFS_TYPE_CTZSTRUCT = 0x202,
|
||||||
|
LFS_TYPE_INLINESTRUCT = 0x201,
|
||||||
|
LFS_TYPE_SOFTTAIL = 0x600,
|
||||||
|
LFS_TYPE_HARDTAIL = 0x601,
|
||||||
|
LFS_TYPE_MOVESTATE = 0x7ff,
|
||||||
|
LFS_TYPE_CCRC = 0x500,
|
||||||
|
LFS_TYPE_FCRC = 0x5ff,
|
||||||
|
|
||||||
|
// internal chip sources
|
||||||
|
LFS_FROM_NOOP = 0x000,
|
||||||
|
LFS_FROM_MOVE = 0x101,
|
||||||
|
LFS_FROM_USERATTRS = 0x102,
|
||||||
|
};
|
||||||
|
|
||||||
|
// File open flags
|
||||||
|
enum lfs_open_flags {
|
||||||
|
// open flags
|
||||||
|
LFS_O_RDONLY = 1, // Open a file as read only
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
LFS_O_WRONLY = 2, // Open a file as write only
|
||||||
|
LFS_O_RDWR = 3, // Open a file as read and write
|
||||||
|
LFS_O_CREAT = 0x0100, // Create a file if it does not exist
|
||||||
|
LFS_O_EXCL = 0x0200, // Fail if a file already exists
|
||||||
|
LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
|
||||||
|
LFS_O_APPEND = 0x0800, // Move to end of file on every write
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// internally used flags
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
LFS_F_DIRTY = 0x010000, // File does not match storage
|
||||||
|
LFS_F_WRITING = 0x020000, // File has been written since last flush
|
||||||
|
#endif
|
||||||
|
LFS_F_READING = 0x040000, // File has been read since last flush
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
LFS_F_ERRED = 0x080000, // An error occurred during write
|
||||||
|
#endif
|
||||||
|
LFS_F_INLINE = 0x100000, // Currently inlined in directory entry
|
||||||
|
};
|
||||||
|
|
||||||
|
// File seek flags
|
||||||
|
enum lfs_whence_flags {
|
||||||
|
LFS_SEEK_SET = 0, // Seek relative to an absolute position
|
||||||
|
LFS_SEEK_CUR = 1, // Seek relative to the current file position
|
||||||
|
LFS_SEEK_END = 2, // Seek relative to the end of the file
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Configuration provided during initialization of the littlefs
|
||||||
|
struct lfs_config {
|
||||||
|
// Opaque user provided context that can be used to pass
|
||||||
|
// information to the block device operations
|
||||||
|
void *context;
|
||||||
|
|
||||||
|
// Read a region in a block. Negative error codes are propagated
|
||||||
|
// to the user.
|
||||||
|
int (*read)(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Program a region in a block. The block must have previously
|
||||||
|
// been erased. Negative error codes are propagated to the user.
|
||||||
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
int (*prog)(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, const void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Erase a block. A block must be erased before being programmed.
|
||||||
|
// The state of an erased block is undefined. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
int (*erase)(const struct lfs_config *c, lfs_block_t block);
|
||||||
|
|
||||||
|
// Sync the state of the underlying block device. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
int (*sync)(const struct lfs_config *c);
|
||||||
|
|
||||||
|
#ifdef LFS_THREADSAFE
|
||||||
|
// Lock the underlying block device. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
int (*lock)(const struct lfs_config *c);
|
||||||
|
|
||||||
|
// Unlock the underlying block device. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
int (*unlock)(const struct lfs_config *c);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Minimum size of a block read in bytes. All read operations will be a
|
||||||
|
// multiple of this value.
|
||||||
|
lfs_size_t read_size;
|
||||||
|
|
||||||
|
// Minimum size of a block program in bytes. All program operations will be
|
||||||
|
// a multiple of this value.
|
||||||
|
lfs_size_t prog_size;
|
||||||
|
|
||||||
|
// Size of an erasable block in bytes. This does not impact ram consumption
|
||||||
|
// and may be larger than the physical erase size. However, non-inlined
|
||||||
|
// files take up at minimum one block. Must be a multiple of the read and
|
||||||
|
// program sizes.
|
||||||
|
lfs_size_t block_size;
|
||||||
|
|
||||||
|
// Number of erasable blocks on the device. Defaults to block_count stored
|
||||||
|
// on disk when zero.
|
||||||
|
lfs_size_t block_count;
|
||||||
|
|
||||||
|
// Number of erase cycles before littlefs evicts metadata logs and moves
|
||||||
|
// the metadata to another block. Suggested values are in the
|
||||||
|
// range 100-1000, with large values having better performance at the cost
|
||||||
|
// of less consistent wear distribution.
|
||||||
|
//
|
||||||
|
// Set to -1 to disable block-level wear-leveling.
|
||||||
|
int32_t block_cycles;
|
||||||
|
|
||||||
|
// Size of block caches in bytes. Each cache buffers a portion of a block in
|
||||||
|
// RAM. The littlefs needs a read cache, a program cache, and one additional
|
||||||
|
// cache per file. Larger caches can improve performance by storing more
|
||||||
|
// data and reducing the number of disk accesses. Must be a multiple of the
|
||||||
|
// read and program sizes, and a factor of the block size.
|
||||||
|
lfs_size_t cache_size;
|
||||||
|
|
||||||
|
// Size of the lookahead buffer in bytes. A larger lookahead buffer
|
||||||
|
// increases the number of blocks found during an allocation pass. The
|
||||||
|
// lookahead buffer is stored as a compact bitmap, so each byte of RAM
|
||||||
|
// can track 8 blocks.
|
||||||
|
lfs_size_t lookahead_size;
|
||||||
|
|
||||||
|
// Threshold for metadata compaction during lfs_fs_gc in bytes. Metadata
|
||||||
|
// pairs that exceed this threshold will be compacted during lfs_fs_gc.
|
||||||
|
// Defaults to ~88% block_size when zero, though the default may change
|
||||||
|
// in the future.
|
||||||
|
//
|
||||||
|
// Note this only affects lfs_fs_gc. Normal compactions still only occur
|
||||||
|
// when full.
|
||||||
|
//
|
||||||
|
// Set to -1 to disable metadata compaction during lfs_fs_gc.
|
||||||
|
lfs_size_t compact_thresh;
|
||||||
|
|
||||||
|
// Optional statically allocated read buffer. Must be cache_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *read_buffer;
|
||||||
|
|
||||||
|
// Optional statically allocated program buffer. Must be cache_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *prog_buffer;
|
||||||
|
|
||||||
|
// Optional statically allocated lookahead buffer. Must be lookahead_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *lookahead_buffer;
|
||||||
|
|
||||||
|
// Optional upper limit on length of file names in bytes. No downside for
|
||||||
|
// larger names except the size of the info struct which is controlled by
|
||||||
|
// the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX or name_max stored on
|
||||||
|
// disk when zero.
|
||||||
|
lfs_size_t name_max;
|
||||||
|
|
||||||
|
// Optional upper limit on files in bytes. No downside for larger files
|
||||||
|
// but must be <= LFS_FILE_MAX. Defaults to LFS_FILE_MAX or file_max stored
|
||||||
|
// on disk when zero.
|
||||||
|
lfs_size_t file_max;
|
||||||
|
|
||||||
|
// Optional upper limit on custom attributes in bytes. No downside for
|
||||||
|
// larger attributes size but must be <= LFS_ATTR_MAX. Defaults to
|
||||||
|
// LFS_ATTR_MAX or attr_max stored on disk when zero.
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
|
||||||
|
// Optional upper limit on total space given to metadata pairs in bytes. On
|
||||||
|
// devices with large blocks (e.g. 128kB) setting this to a low size (2-8kB)
|
||||||
|
// can help bound the metadata compaction time. Must be <= block_size.
|
||||||
|
// Defaults to block_size when zero.
|
||||||
|
lfs_size_t metadata_max;
|
||||||
|
|
||||||
|
// Optional upper limit on inlined files in bytes. Inlined files live in
|
||||||
|
// metadata and decrease storage requirements, but may be limited to
|
||||||
|
// improve metadata-related performance. Must be <= cache_size, <=
|
||||||
|
// attr_max, and <= block_size/8. Defaults to the largest possible
|
||||||
|
// inline_max when zero.
|
||||||
|
//
|
||||||
|
// Set to -1 to disable inlined files.
|
||||||
|
lfs_size_t inline_max;
|
||||||
|
|
||||||
|
#ifdef LFS_MULTIVERSION
|
||||||
|
// On-disk version to use when writing in the form of 16-bit major version
|
||||||
|
// + 16-bit minor version. This limiting metadata to what is supported by
|
||||||
|
// older minor versions. Note that some features will be lost. Defaults to
|
||||||
|
// to the most recent minor version when zero.
|
||||||
|
uint32_t disk_version;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// File info structure
|
||||||
|
struct lfs_info {
|
||||||
|
// Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
// Size of the file, only valid for REG files. Limited to 32-bits.
|
||||||
|
lfs_size_t size;
|
||||||
|
|
||||||
|
// Name of the file stored as a null-terminated string. Limited to
|
||||||
|
// LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to
|
||||||
|
// reduce RAM. LFS_NAME_MAX is stored in superblock and must be
|
||||||
|
// respected by other littlefs drivers.
|
||||||
|
char name[LFS_NAME_MAX+1];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filesystem info structure
|
||||||
|
struct lfs_fsinfo {
|
||||||
|
// On-disk version.
|
||||||
|
uint32_t disk_version;
|
||||||
|
|
||||||
|
// Size of a logical block in bytes.
|
||||||
|
lfs_size_t block_size;
|
||||||
|
|
||||||
|
// Number of logical blocks in filesystem.
|
||||||
|
lfs_size_t block_count;
|
||||||
|
|
||||||
|
// Upper limit on the length of file names in bytes.
|
||||||
|
lfs_size_t name_max;
|
||||||
|
|
||||||
|
// Upper limit on the size of files in bytes.
|
||||||
|
lfs_size_t file_max;
|
||||||
|
|
||||||
|
// Upper limit on the size of custom attributes in bytes.
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Custom attribute structure, used to describe custom attributes
|
||||||
|
// committed atomically during file writes.
|
||||||
|
struct lfs_attr {
|
||||||
|
// 8-bit type of attribute, provided by user and used to
|
||||||
|
// identify the attribute
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
// Pointer to buffer containing the attribute
|
||||||
|
void *buffer;
|
||||||
|
|
||||||
|
// Size of attribute in bytes, limited to LFS_ATTR_MAX
|
||||||
|
lfs_size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Optional configuration provided during lfs_file_opencfg
|
||||||
|
struct lfs_file_config {
|
||||||
|
// Optional statically allocated file buffer. Must be cache_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *buffer;
|
||||||
|
|
||||||
|
// Optional list of custom attributes related to the file. If the file
|
||||||
|
// is opened with read access, these attributes will be read from disk
|
||||||
|
// during the open call. If the file is opened with write access, the
|
||||||
|
// attributes will be written to disk every file sync or close. This
|
||||||
|
// write occurs atomically with update to the file's contents.
|
||||||
|
//
|
||||||
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
|
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller
|
||||||
|
// than the buffer, it will be padded with zeros. If the stored attribute
|
||||||
|
// is larger, then it will be silently truncated. If the attribute is not
|
||||||
|
// found, it will be created implicitly.
|
||||||
|
struct lfs_attr *attrs;
|
||||||
|
|
||||||
|
// Number of custom attributes in the list
|
||||||
|
lfs_size_t attr_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// internal littlefs data structures ///
|
||||||
|
typedef struct lfs_cache {
|
||||||
|
lfs_block_t block;
|
||||||
|
lfs_off_t off;
|
||||||
|
lfs_size_t size;
|
||||||
|
uint8_t *buffer;
|
||||||
|
} lfs_cache_t;
|
||||||
|
|
||||||
|
typedef struct lfs_mdir {
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
uint32_t rev;
|
||||||
|
lfs_off_t off;
|
||||||
|
uint32_t etag;
|
||||||
|
uint16_t count;
|
||||||
|
bool erased;
|
||||||
|
bool split;
|
||||||
|
lfs_block_t tail[2];
|
||||||
|
} lfs_mdir_t;
|
||||||
|
|
||||||
|
// littlefs directory type
|
||||||
|
typedef struct lfs_dir {
|
||||||
|
struct lfs_dir *next;
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t type;
|
||||||
|
lfs_mdir_t m;
|
||||||
|
|
||||||
|
lfs_off_t pos;
|
||||||
|
lfs_block_t head[2];
|
||||||
|
} lfs_dir_t;
|
||||||
|
|
||||||
|
// littlefs file type
|
||||||
|
typedef struct lfs_file {
|
||||||
|
struct lfs_file *next;
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t type;
|
||||||
|
lfs_mdir_t m;
|
||||||
|
|
||||||
|
struct lfs_ctz {
|
||||||
|
lfs_block_t head;
|
||||||
|
lfs_size_t size;
|
||||||
|
} ctz;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
lfs_off_t pos;
|
||||||
|
lfs_block_t block;
|
||||||
|
lfs_off_t off;
|
||||||
|
lfs_cache_t cache;
|
||||||
|
|
||||||
|
const struct lfs_file_config *cfg;
|
||||||
|
} lfs_file_t;
|
||||||
|
|
||||||
|
typedef struct lfs_superblock {
|
||||||
|
uint32_t version;
|
||||||
|
lfs_size_t block_size;
|
||||||
|
lfs_size_t block_count;
|
||||||
|
lfs_size_t name_max;
|
||||||
|
lfs_size_t file_max;
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
} lfs_superblock_t;
|
||||||
|
|
||||||
|
typedef struct lfs_gstate {
|
||||||
|
uint32_t tag;
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
} lfs_gstate_t;
|
||||||
|
|
||||||
|
// The littlefs filesystem type
|
||||||
|
typedef struct lfs {
|
||||||
|
lfs_cache_t rcache;
|
||||||
|
lfs_cache_t pcache;
|
||||||
|
|
||||||
|
lfs_block_t root[2];
|
||||||
|
struct lfs_mlist {
|
||||||
|
struct lfs_mlist *next;
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t type;
|
||||||
|
lfs_mdir_t m;
|
||||||
|
} *mlist;
|
||||||
|
uint32_t seed;
|
||||||
|
|
||||||
|
lfs_gstate_t gstate;
|
||||||
|
lfs_gstate_t gdisk;
|
||||||
|
lfs_gstate_t gdelta;
|
||||||
|
|
||||||
|
struct lfs_lookahead {
|
||||||
|
lfs_block_t start;
|
||||||
|
lfs_block_t size;
|
||||||
|
lfs_block_t next;
|
||||||
|
lfs_block_t ckpoint;
|
||||||
|
uint8_t *buffer;
|
||||||
|
} lookahead;
|
||||||
|
|
||||||
|
const struct lfs_config *cfg;
|
||||||
|
lfs_size_t block_count;
|
||||||
|
lfs_size_t name_max;
|
||||||
|
lfs_size_t file_max;
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
lfs_size_t inline_max;
|
||||||
|
|
||||||
|
#ifdef LFS_MIGRATE
|
||||||
|
struct lfs1 *lfs1;
|
||||||
|
#endif
|
||||||
|
} lfs_t;
|
||||||
|
|
||||||
|
|
||||||
|
/// Filesystem functions ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Format a block device with the littlefs
|
||||||
|
//
|
||||||
|
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||||
|
// object, and does not leave the filesystem mounted. The config struct must
|
||||||
|
// be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mounts a littlefs
|
||||||
|
//
|
||||||
|
// Requires a littlefs object and config struct. Multiple filesystems
|
||||||
|
// may be mounted simultaneously with multiple littlefs objects. Both
|
||||||
|
// lfs and config must be allocated while mounted. The config struct must
|
||||||
|
// be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
|
||||||
|
|
||||||
|
// Unmounts a littlefs
|
||||||
|
//
|
||||||
|
// Does nothing besides releasing any allocated resources.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_unmount(lfs_t *lfs);
|
||||||
|
|
||||||
|
/// General operations ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Removes a file or directory
|
||||||
|
//
|
||||||
|
// If removing a directory, the directory must be empty.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_remove(lfs_t *lfs, const char *path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Rename or move a file or directory
|
||||||
|
//
|
||||||
|
// If the destination exists, it must match the source in type.
|
||||||
|
// If the destination is a directory, the directory must be empty.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Find info about a file or directory
|
||||||
|
//
|
||||||
|
// Fills out the info structure, based on the specified file or directory.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
|
||||||
|
|
||||||
|
// Get a custom attribute
|
||||||
|
//
|
||||||
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
|
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller than
|
||||||
|
// the buffer, it will be padded with zeros. If the stored attribute is larger,
|
||||||
|
// then it will be silently truncated. If no attribute is found, the error
|
||||||
|
// LFS_ERR_NOATTR is returned and the buffer is filled with zeros.
|
||||||
|
//
|
||||||
|
// Returns the size of the attribute, or a negative error code on failure.
|
||||||
|
// Note, the returned size is the size of the attribute on disk, irrespective
|
||||||
|
// of the size of the buffer. This can be used to dynamically allocate a buffer
|
||||||
|
// or check for existence.
|
||||||
|
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
||||||
|
uint8_t type, void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Set custom attributes
|
||||||
|
//
|
||||||
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
|
// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be
|
||||||
|
// implicitly created.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_setattr(lfs_t *lfs, const char *path,
|
||||||
|
uint8_t type, const void *buffer, lfs_size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Removes a custom attribute
|
||||||
|
//
|
||||||
|
// If an attribute is not found, nothing happens.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/// File operations ///
|
||||||
|
|
||||||
|
#ifndef LFS_NO_MALLOC
|
||||||
|
// Open a file
|
||||||
|
//
|
||||||
|
// The mode that the file is opened in is determined by the flags, which
|
||||||
|
// are values from the enum lfs_open_flags that are bitwise-ored together.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
const char *path, int flags);
|
||||||
|
|
||||||
|
// if LFS_NO_MALLOC is defined, lfs_file_open() will fail with LFS_ERR_NOMEM
|
||||||
|
// thus use lfs_file_opencfg() with config.buffer set.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Open a file with extra configuration
|
||||||
|
//
|
||||||
|
// The mode that the file is opened in is determined by the flags, which
|
||||||
|
// are values from the enum lfs_open_flags that are bitwise-ored together.
|
||||||
|
//
|
||||||
|
// The config struct provides additional config options per file as described
|
||||||
|
// above. The config struct must remain allocated while the file is open, and
|
||||||
|
// the config struct must be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
const char *path, int flags,
|
||||||
|
const struct lfs_file_config *config);
|
||||||
|
|
||||||
|
// Close a file
|
||||||
|
//
|
||||||
|
// Any pending writes are written out to storage as though
|
||||||
|
// sync had been called and releases any allocated resources.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Synchronize a file on storage
|
||||||
|
//
|
||||||
|
// Any pending writes are written out to storage.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Read data from file
|
||||||
|
//
|
||||||
|
// Takes a buffer and size indicating where to store the read data.
|
||||||
|
// Returns the number of bytes read, or a negative error code on failure.
|
||||||
|
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Write data to file
|
||||||
|
//
|
||||||
|
// Takes a buffer and size indicating the data to write. The file will not
|
||||||
|
// actually be updated on the storage until either sync or close is called.
|
||||||
|
//
|
||||||
|
// Returns the number of bytes written, or a negative error code on failure.
|
||||||
|
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
const void *buffer, lfs_size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Change the position of the file
|
||||||
|
//
|
||||||
|
// The change in position is determined by the offset and whence flag.
|
||||||
|
// Returns the new position of the file, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
lfs_soff_t off, int whence);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Truncates the size of the file to the specified size
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Return the position of the file
|
||||||
|
//
|
||||||
|
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
|
||||||
|
// Returns the position of the file, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Change the position of the file to the beginning of the file
|
||||||
|
//
|
||||||
|
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_SET)
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Return the size of the file
|
||||||
|
//
|
||||||
|
// Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END)
|
||||||
|
// Returns the size of the file, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
|
||||||
|
/// Directory operations ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Create a directory
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_mkdir(lfs_t *lfs, const char *path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Open a directory
|
||||||
|
//
|
||||||
|
// Once open a directory can be used with read to iterate over files.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
|
||||||
|
|
||||||
|
// Close a directory
|
||||||
|
//
|
||||||
|
// Releases any allocated resources.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
|
||||||
|
|
||||||
|
// Read an entry in the directory
|
||||||
|
//
|
||||||
|
// Fills out the info structure, based on the specified file or directory.
|
||||||
|
// Returns a positive value on success, 0 at the end of directory,
|
||||||
|
// or a negative error code on failure.
|
||||||
|
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
|
||||||
|
|
||||||
|
// Change the position of the directory
|
||||||
|
//
|
||||||
|
// The new off must be a value previous returned from tell and specifies
|
||||||
|
// an absolute offset in the directory seek.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
|
||||||
|
|
||||||
|
// Return the position of the directory
|
||||||
|
//
|
||||||
|
// The returned offset is only meant to be consumed by seek and may not make
|
||||||
|
// sense, but does indicate the current position in the directory iteration.
|
||||||
|
//
|
||||||
|
// Returns the position of the directory, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
|
||||||
|
|
||||||
|
// Change the position of the directory to the beginning of the directory
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
|
||||||
|
|
||||||
|
|
||||||
|
/// Filesystem-level filesystem operations
|
||||||
|
|
||||||
|
// Find on-disk info about the filesystem
|
||||||
|
//
|
||||||
|
// Fills out the fsinfo structure based on the filesystem found on-disk.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo);
|
||||||
|
|
||||||
|
// Finds the current size of the filesystem
|
||||||
|
//
|
||||||
|
// Note: Result is best effort. If files share COW structures, the returned
|
||||||
|
// size may be larger than the filesystem actually is.
|
||||||
|
//
|
||||||
|
// Returns the number of allocated blocks, or a negative error code on failure.
|
||||||
|
lfs_ssize_t lfs_fs_size(lfs_t *lfs);
|
||||||
|
|
||||||
|
// Traverse through all blocks in use by the filesystem
|
||||||
|
//
|
||||||
|
// The provided callback will be called with each block address that is
|
||||||
|
// currently in use by the filesystem. This can be used to determine which
|
||||||
|
// blocks are in use or how much of the storage is available.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Attempt to make the filesystem consistent and ready for writing
|
||||||
|
//
|
||||||
|
// Calling this function is not required, consistency will be implicitly
|
||||||
|
// enforced on the first operation that writes to the filesystem, but this
|
||||||
|
// function allows the work to be performed earlier and without other
|
||||||
|
// filesystem changes.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_fs_mkconsistent(lfs_t *lfs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Attempt any janitorial work
|
||||||
|
//
|
||||||
|
// This currently:
|
||||||
|
// 1. Calls mkconsistent if not already consistent
|
||||||
|
// 2. Compacts metadata > compact_thresh
|
||||||
|
// 3. Populates the block allocator
|
||||||
|
//
|
||||||
|
// Though additional janitorial work may be added in the future.
|
||||||
|
//
|
||||||
|
// Calling this function is not required, but may allow the offloading of
|
||||||
|
// expensive janitorial work to a less time-critical code path.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure. Accomplishing nothing is not
|
||||||
|
// an error.
|
||||||
|
int lfs_fs_gc(lfs_t *lfs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
// Grows the filesystem to a new size, updating the superblock with the new
|
||||||
|
// block count.
|
||||||
|
//
|
||||||
|
// Note: This is irreversible.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
|
#ifdef LFS_MIGRATE
|
||||||
|
// Attempts to migrate a previous version of littlefs
|
||||||
|
//
|
||||||
|
// Behaves similarly to the lfs_format function. Attempts to mount
|
||||||
|
// the previous version of littlefs and update the filesystem so it can be
|
||||||
|
// mounted with the current version of littlefs.
|
||||||
|
//
|
||||||
|
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||||
|
// object, and does not leave the filesystem mounted. The config struct must
|
||||||
|
// be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
//
|
||||||
|
// Created by cfif on 13.06.2024.
|
||||||
|
//
|
||||||
|
#include "lfs_file_utils.h"
|
||||||
|
|
||||||
|
#define CHECK_LFS_ERR if (lfs_err != LFS_ERR_OK) return lfs_err;
|
||||||
|
|
||||||
|
int dumpEbuFile(lfs_t *env, char *filename, void *buf, uint16_t size) {
|
||||||
|
lfs_file_t file;
|
||||||
|
|
||||||
|
int lfs_err = lfs_file_open(env, &file, filename, LFS_O_WRONLY | LFS_O_CREAT);
|
||||||
|
CHECK_LFS_ERR
|
||||||
|
|
||||||
|
lfs_err = lfs_file_rewind(env, &file);
|
||||||
|
CHECK_LFS_ERR
|
||||||
|
|
||||||
|
int writes = lfs_file_write(env, &file, buf, size);
|
||||||
|
if (writes != size)
|
||||||
|
return -100;
|
||||||
|
|
||||||
|
lfs_err = lfs_file_close(env, &file);
|
||||||
|
CHECK_LFS_ERR
|
||||||
|
|
||||||
|
return lfs_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadEbuFile(lfs_t *env, char *filename, void *buf, uint16_t size) {
|
||||||
|
lfs_file_t file;
|
||||||
|
|
||||||
|
int lfs_err = lfs_file_open(env, &file, filename, LFS_O_RDONLY);
|
||||||
|
CHECK_LFS_ERR
|
||||||
|
|
||||||
|
int reading = lfs_file_read(env, &file, buf, size);
|
||||||
|
if (reading != size)
|
||||||
|
return -100;
|
||||||
|
|
||||||
|
lfs_err = lfs_file_close(env, &file);
|
||||||
|
CHECK_LFS_ERR
|
||||||
|
|
||||||
|
return lfs_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getFreeSize(lfs_t *env) {
|
||||||
|
lfs_ssize_t size = lfs_fs_size(env);
|
||||||
|
lfs_ssize_t countFree = (lfs_ssize_t)env->block_count - size;
|
||||||
|
return countFree;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getBufCrc(uint8_t *buf, uint32_t size) {
|
||||||
|
|
||||||
|
uint32_t crc = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size; ++i) {
|
||||||
|
crc += buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getFileCrc(lfs_t *env, char *filename, uint32_t size) {
|
||||||
|
uint8_t buf[256];
|
||||||
|
uint32_t crc = 0;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t countPartFull = size / sizeof(buf);
|
||||||
|
uint32_t countPartTail = size % sizeof(buf);
|
||||||
|
|
||||||
|
int lfs_err;
|
||||||
|
lfs_file_t file;
|
||||||
|
|
||||||
|
lfs_err = lfs_file_open(env, &file, filename, LFS_O_RDONLY);
|
||||||
|
lfs_err = lfs_file_rewind(env, &file);
|
||||||
|
|
||||||
|
uint32_t pCountPart = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < countPartFull; ++i) {
|
||||||
|
int reading = lfs_file_read(env, &file, &buf[pCountPart], countPartFull);
|
||||||
|
crc += getBufCrc(buf, countPartFull);
|
||||||
|
pCountPart += countPartFull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countPartTail) {
|
||||||
|
int reading = lfs_file_read(env, &file, &buf[pCountPart], countPartTail);
|
||||||
|
crc += getBufCrc(buf, countPartFull);
|
||||||
|
}
|
||||||
|
lfs_err = lfs_file_close(env, &file);
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// Created by cfif on 13.06.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SMART_COMPONENTS_LFS_DILE_UTILS_H
|
||||||
|
#define SMART_COMPONENTS_LFS_DILE_UTILS_H
|
||||||
|
#include "lfs.h"
|
||||||
|
|
||||||
|
int dumpEbuFile(lfs_t *env, char *filename, void *buf, uint16_t size);
|
||||||
|
int loadEbuFile(lfs_t *env, char *filename, void *buf, uint16_t size);
|
||||||
|
int32_t getFreeSize(lfs_t *env);
|
||||||
|
|
||||||
|
uint32_t getFileCrc(lfs_t *env, char *filename, uint32_t size);
|
||||||
|
|
||||||
|
#endif //SMART_COMPONENTS_LFS_DILE_UTILS_H
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* lfs util functions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include "lfs_util.h"
|
||||||
|
|
||||||
|
// Only compile if user does not provide custom config
|
||||||
|
#ifndef LFS_CONFIG
|
||||||
|
|
||||||
|
|
||||||
|
// If user provides their own CRC impl we don't need this
|
||||||
|
#ifndef LFS_CRC
|
||||||
|
// Software CRC implementation with small lookup table
|
||||||
|
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
|
||||||
|
static const uint32_t rtable[16] = {
|
||||||
|
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||||
|
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||||
|
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||||
|
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t *data = buffer;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf];
|
||||||
|
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,275 @@
|
||||||
|
/*
|
||||||
|
* lfs utility functions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#ifndef LFS_UTIL_H
|
||||||
|
#define LFS_UTIL_H
|
||||||
|
|
||||||
|
|
||||||
|
// Users can override lfs_util.h with their own configuration by defining
|
||||||
|
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
|
||||||
|
//
|
||||||
|
// If LFS_CONFIG is used, none of the default utils will be emitted and must be
|
||||||
|
// provided by the config file. To start, I would suggest copying lfs_util.h
|
||||||
|
// and modifying as needed.
|
||||||
|
#ifdef LFS_CONFIG
|
||||||
|
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
|
||||||
|
#define LFS_STRINGIZE2(x) #x
|
||||||
|
#include LFS_STRINGIZE(LFS_CONFIG)
|
||||||
|
#else
|
||||||
|
|
||||||
|
// System includes
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#ifndef LFS_NO_MALLOC
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifndef LFS_NO_ASSERT
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if !defined(LFS_NO_DEBUG) || \
|
||||||
|
!defined(LFS_NO_WARN) || \
|
||||||
|
!defined(LFS_NO_ERROR) || \
|
||||||
|
defined(LFS_YES_TRACE)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void * pvPortMalloc( size_t xSize );
|
||||||
|
extern void vPortFree( void * pv );
|
||||||
|
|
||||||
|
|
||||||
|
// Macros, may be replaced by system specific wrappers. Arguments to these
|
||||||
|
// macros must not have side-effects as the macros can be removed for a smaller
|
||||||
|
// code footprint
|
||||||
|
|
||||||
|
// Logging functions
|
||||||
|
#ifndef LFS_TRACE
|
||||||
|
#ifdef LFS_YES_TRACE
|
||||||
|
#define LFS_TRACE_(fmt, ...) \
|
||||||
|
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_TRACE(...)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_DEBUG
|
||||||
|
#ifndef LFS_NO_DEBUG
|
||||||
|
#define LFS_DEBUG_(fmt, ...) \
|
||||||
|
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_DEBUG(...)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_WARN
|
||||||
|
#ifndef LFS_NO_WARN
|
||||||
|
#define LFS_WARN_(fmt, ...) \
|
||||||
|
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_WARN(...)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_ERROR
|
||||||
|
#ifndef LFS_NO_ERROR
|
||||||
|
#define LFS_ERROR_(fmt, ...) \
|
||||||
|
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_ERROR(...)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Runtime assertions
|
||||||
|
#ifndef LFS_ASSERT
|
||||||
|
#ifndef LFS_NO_ASSERT
|
||||||
|
#define LFS_ASSERT(test) assert(test)
|
||||||
|
#else
|
||||||
|
#define LFS_ASSERT(test)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Builtin functions, these may be replaced by more efficient
|
||||||
|
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
|
||||||
|
// expensive basic C implementation for debugging purposes
|
||||||
|
|
||||||
|
// Min/max functions for unsigned 32-bit numbers
|
||||||
|
static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
|
||||||
|
return (a < b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align to nearest multiple of a size
|
||||||
|
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
|
||||||
|
return a - (a % alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) {
|
||||||
|
return lfs_aligndown(a + alignment - 1, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the smallest power of 2 greater than or equal to a
|
||||||
|
static inline uint32_t lfs_npw2(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||||
|
return 32 - __builtin_clz(a - 1);
|
||||||
|
#else
|
||||||
|
uint32_t r = 0;
|
||||||
|
uint32_t s;
|
||||||
|
a -= 1;
|
||||||
|
s = (a > 0xffff) << 4; a >>= s; r |= s;
|
||||||
|
s = (a > 0xff ) << 3; a >>= s; r |= s;
|
||||||
|
s = (a > 0xf ) << 2; a >>= s; r |= s;
|
||||||
|
s = (a > 0x3 ) << 1; a >>= s; r |= s;
|
||||||
|
return (r | (a >> 1)) + 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of trailing binary zeros in a
|
||||||
|
// lfs_ctz(0) may be undefined
|
||||||
|
static inline uint32_t lfs_ctz(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__)
|
||||||
|
return __builtin_ctz(a);
|
||||||
|
#else
|
||||||
|
return lfs_npw2((a & -a) + 1) - 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of binary ones in a
|
||||||
|
static inline uint32_t lfs_popc(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||||
|
return __builtin_popcount(a);
|
||||||
|
#else
|
||||||
|
a = a - ((a >> 1) & 0x55555555);
|
||||||
|
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
|
||||||
|
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the sequence comparison of a and b, this is the distance
|
||||||
|
// between a and b ignoring overflow
|
||||||
|
static inline int lfs_scmp(uint32_t a, uint32_t b) {
|
||||||
|
return (int) (unsigned) (a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert between 32-bit little-endian and native order
|
||||||
|
static inline uint32_t lfs_fromle32(uint32_t a) {
|
||||||
|
#if (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
|
return a;
|
||||||
|
#elif !defined(LFS_NO_INTRINSICS) && (\
|
||||||
|
(defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||||
|
return __builtin_bswap32(a);
|
||||||
|
#else
|
||||||
|
return (((uint8_t*)&a)[0] << 0) |
|
||||||
|
(((uint8_t*)&a)[1] << 8) |
|
||||||
|
(((uint8_t*)&a)[2] << 16) |
|
||||||
|
(((uint8_t*)&a)[3] << 24);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_tole32(uint32_t a) {
|
||||||
|
return lfs_fromle32(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert between 32-bit big-endian and native order
|
||||||
|
static inline uint32_t lfs_frombe32(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && (\
|
||||||
|
(defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||||
|
return __builtin_bswap32(a);
|
||||||
|
#elif (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||||
|
return a;
|
||||||
|
#else
|
||||||
|
return (((uint8_t*)&a)[0] << 24) |
|
||||||
|
(((uint8_t*)&a)[1] << 16) |
|
||||||
|
(((uint8_t*)&a)[2] << 8) |
|
||||||
|
(((uint8_t*)&a)[3] << 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_tobe32(uint32_t a) {
|
||||||
|
return lfs_frombe32(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate CRC-32 with polynomial = 0x04c11db7
|
||||||
|
#ifdef LFS_CRC
|
||||||
|
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
|
||||||
|
return LFS_CRC(crc, buffer, size)
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Allocate memory, only used if buffers are not provided to littlefs
|
||||||
|
//
|
||||||
|
// littlefs current has no alignment requirements, as it only allocates
|
||||||
|
// byte-level buffers.
|
||||||
|
static inline void *lfs_malloc(size_t size) {
|
||||||
|
#if defined(LFS_MALLOC)
|
||||||
|
return LFS_MALLOC(size);
|
||||||
|
#elif !defined(LFS_NO_MALLOC)
|
||||||
|
void *p = malloc(size);
|
||||||
|
return p;
|
||||||
|
|
||||||
|
// void *p = pvPortMalloc(size);
|
||||||
|
// return p;
|
||||||
|
|
||||||
|
#else
|
||||||
|
(void)size;
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deallocate memory, only used if buffers are not provided to littlefs
|
||||||
|
static inline void lfs_free(void *p) {
|
||||||
|
#if defined(LFS_FREE)
|
||||||
|
LFS_FREE(p);
|
||||||
|
#elif !defined(LFS_NO_MALLOC)
|
||||||
|
|
||||||
|
// vPortFree(p);
|
||||||
|
free(p);
|
||||||
|
//free(p);
|
||||||
|
#else
|
||||||
|
(void)p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"./**.c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -142,13 +142,11 @@ static void set_CanSpamReceiver(tCanSpamReceiver *env, uint32_t recid) {
|
||||||
uint32_t countQueue_ccu_candb_rx = osMessageQueueGetSpace(env->ccu_candb_error_missing_rx);
|
uint32_t countQueue_ccu_candb_rx = osMessageQueueGetSpace(env->ccu_candb_error_missing_rx);
|
||||||
if (countQueue_ccu_candb_rx) {
|
if (countQueue_ccu_candb_rx) {
|
||||||
status = osMessageQueuePut(env->ccu_candb_error_missing_rx, &ccu_candb_error_missing_rx, 0, 0U);
|
status = osMessageQueuePut(env->ccu_candb_error_missing_rx, &ccu_candb_error_missing_rx, 0, 0U);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
countQueue_ccu_candb_rx = osMessageQueueGetSpace(env->ccu_candb_time_missing_rx);
|
countQueue_ccu_candb_rx = osMessageQueueGetSpace(env->ccu_candb_time_missing_rx);
|
||||||
if (countQueue_ccu_candb_rx) {
|
if (countQueue_ccu_candb_rx) {
|
||||||
status = osMessageQueuePut(env->ccu_candb_time_missing_rx, &ccu_candb_time_missing_rx, 0, 0U);
|
status = osMessageQueuePut(env->ccu_candb_time_missing_rx, &ccu_candb_time_missing_rx, 0, 0U);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2787,6 +2787,7 @@ void ReceivedTP_func(void *arg, tCanTP_data *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
osMutexRelease(env->access);
|
osMutexRelease(env->access);
|
||||||
} else {
|
} else {
|
||||||
LoggerErrorStatic(LOGGER, LOG_SIGN, "Access error ReceivedTP_func");
|
LoggerErrorStatic(LOGGER, LOG_SIGN, "Access error ReceivedTP_func");
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "CanUds.h"
|
#include "CanUds.h"
|
||||||
#include "DiagnosticTask.h"
|
#include "DiagnosticTask.h"
|
||||||
#include "LinSensorTasks.h"
|
#include "LinSensorTasks.h"
|
||||||
|
#include "LittleFsInterface.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -51,6 +52,7 @@ typedef struct {
|
||||||
|
|
||||||
tDeviceStorage storage;
|
tDeviceStorage storage;
|
||||||
|
|
||||||
|
|
||||||
tPowerManagement power;
|
tPowerManagement power;
|
||||||
|
|
||||||
tCommandLine cli;
|
tCommandLine cli;
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ const DMA_InitType dmaInitCfg =
|
||||||
#define CHECK_JTAG_DEBUG_ACTIVE ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
|
#define CHECK_JTAG_DEBUG_ACTIVE ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
|
||||||
#define CHECK_PARALLEL_ENABLE (((*(volatile uint32_t*)0x044000E8) & 0x0000000F) != 0x00000005)
|
#define CHECK_PARALLEL_ENABLE (((*(volatile uint32_t*)0x044000E8) & 0x0000000F) != 0x00000005)
|
||||||
|
|
||||||
|
tLittleFileFs fs;
|
||||||
|
|
||||||
static void Mma_InitSubSystems(tMma *env) {
|
static void Mma_InitSubSystems(tMma *env) {
|
||||||
|
|
||||||
|
|
@ -148,6 +149,8 @@ static void Mma_InitSubSystems(tMma *env) {
|
||||||
bool result = DeviceStorage_Init(&env->storage, true, &env->flash->interface_calib, &env->flash->interface_param,
|
bool result = DeviceStorage_Init(&env->storage, true, &env->flash->interface_calib, &env->flash->interface_param,
|
||||||
&env->slog.logger);
|
&env->slog.logger);
|
||||||
|
|
||||||
|
LittleFileFsInit(&fs, env->storage.dumpObserver.accessDumper);
|
||||||
|
|
||||||
|
|
||||||
memcpy(dataTmp, env->storage.dataParam->device.identification.Tester_Fingerprint.tester_serial, 9);
|
memcpy(dataTmp, env->storage.dataParam->device.identification.Tester_Fingerprint.tester_serial, 9);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ extern uint32_t __StackTop;
|
||||||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_addresses[SIZE_BUF_HARD_FAULT]; // массив для адресов возврата (достаточно 32)
|
__attribute__((section(".save_data"))) volatile uint32_t hardFault_addresses[SIZE_BUF_HARD_FAULT]; // массив для адресов возврата (достаточно 32)
|
||||||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
|
__attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
|
||||||
__attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
|
__attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
|
||||||
|
__attribute__((section(".save_data"))) volatile uint32_t none_data;
|
||||||
|
|
||||||
void vTaskGetCurrentTaskStackInfo(void **ppvStackStart, void **ppvStackEnd);
|
void vTaskGetCurrentTaskStackInfo(void **ppvStackStart, void **ppvStackEnd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
#define SIZE_BUF_HARD_FAULT 32
|
#define SIZE_BUF_HARD_FAULT 32
|
||||||
|
|
||||||
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_addresses[32];
|
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_addresses[32];
|
||||||
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_count;
|
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
|
||||||
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_magic;
|
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
|
||||||
|
|
||||||
#endif //HVAC_M7_HARDFAULT_H
|
#endif //HVAC_M7_HARDFAULT_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
//
|
||||||
|
// Created by cfif on 29.05.2024.
|
||||||
|
//
|
||||||
|
#include "LittleFsInterface.h"
|
||||||
|
#include "InternalFlashPage.h"
|
||||||
|
|
||||||
|
#define FLASH_BASE ((uint32_t)0x04000000)
|
||||||
|
#define FLASH_START_SECTOR ((uint32_t)0x10000 / FLASH_PAGE_D_SIZE)
|
||||||
|
#define FLASH_STOP_SECTOR ((uint32_t)0x1F000 / FLASH_PAGE_D_SIZE)
|
||||||
|
|
||||||
|
// Read a region in a block. Negative error codes are propagated
|
||||||
|
// to the user.
|
||||||
|
int readFlash(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, void *buffer, lfs_size_t size) {
|
||||||
|
|
||||||
|
uint32_t sectorAdr = (FLASH_START_SECTOR + block) * FLASH_PAGE_D_SIZE + off + FLASH_BASE;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size; ++i) {
|
||||||
|
((uint8_t *) buffer)[i] = *(uint8_t *) sectorAdr;
|
||||||
|
++sectorAdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Program a region in a block. The block must have previously
|
||||||
|
// been erased. Negative error codes are propagated to the user.
|
||||||
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
int progFlash(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, const void *buffer, lfs_size_t size) {
|
||||||
|
|
||||||
|
uint32_t sectorAdr = (FLASH_START_SECTOR + block) * FLASH_PAGE_D_SIZE + off + FLASH_BASE;
|
||||||
|
|
||||||
|
if (D_bInternalFlashPage_WriteFromRam(sectorAdr, (void *)buffer, size) == false) {
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
flash_unlock();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size; ++i) {
|
||||||
|
if (FLASH_OPERATE_DONE != flash_byte_program(sectorAdr + i, ((uint8_t *) buffer)[i])) {
|
||||||
|
flash_lock();
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
*/
|
||||||
|
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Erase a block. A block must be erased before being programmed.
|
||||||
|
// The state of an erased block is undefined. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
int eraseFlash(const struct lfs_config *c, lfs_block_t block) {
|
||||||
|
|
||||||
|
uint32_t sectorAdr = (FLASH_START_SECTOR + block) * FLASH_PAGE_D_SIZE + FLASH_BASE;
|
||||||
|
|
||||||
|
if (D_bInternalFlashPage_Clear(sectorAdr, NULL, NULL) == false) {
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
flash_unlock();
|
||||||
|
|
||||||
|
if (FLASH_OPERATE_DONE != flash_sector_erase(sectorAdr)) {
|
||||||
|
flash_lock();
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_lock();
|
||||||
|
*/
|
||||||
|
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync the state of the underlying block device. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
int syncFlash(const struct lfs_config *c) {
|
||||||
|
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
osMutexId_t accessDumperLittleFS;
|
||||||
|
|
||||||
|
// Lock the underlying block device. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
int lockFlash(const struct lfs_config *c) {
|
||||||
|
|
||||||
|
if (osMutexAcquire(accessDumperLittleFS, 5000) == osOK)
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock the underlying block device. Negative error codes
|
||||||
|
// are propagated to the user.
|
||||||
|
int unlockFlash(const struct lfs_config *c) {
|
||||||
|
|
||||||
|
if (osMutexRelease(accessDumperLittleFS) == osOK)
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LFS_CACHE_SIZE (2048)
|
||||||
|
#define LFS_LOOK_HEAD_SIZE (256)
|
||||||
|
|
||||||
|
#ifdef LFS_NO_MALLOC
|
||||||
|
uint8_t readBuffer[LFS_CACHE_SIZE];
|
||||||
|
uint8_t writeBuffer[LFS_CACHE_SIZE];
|
||||||
|
uint8_t lookBuffer[LFS_LOOK_HEAD_SIZE];
|
||||||
|
uint8_t g_file_buffer[LFS_CACHE_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int lfs_init_Over(lfs_t *lfs, const struct lfs_config *cfg);
|
||||||
|
|
||||||
|
|
||||||
|
int LittleFileFsInit(tLittleFileFs *env, osMutexId_t accessDumper) {
|
||||||
|
|
||||||
|
accessDumperLittleFS = accessDumper;
|
||||||
|
|
||||||
|
env->cfg.read = readFlash;
|
||||||
|
env->cfg.prog = progFlash;
|
||||||
|
env->cfg.erase = eraseFlash;
|
||||||
|
env->cfg.sync = syncFlash;
|
||||||
|
env->cfg.lock = lockFlash;
|
||||||
|
env->cfg.unlock = unlockFlash;
|
||||||
|
|
||||||
|
// block device configuration
|
||||||
|
env->cfg.read_size = LFS_CACHE_SIZE;
|
||||||
|
env->cfg.prog_size = LFS_CACHE_SIZE;
|
||||||
|
env->cfg.block_size = FLASH_PAGE_D_SIZE;
|
||||||
|
env->cfg.block_count = FLASH_STOP_SECTOR - FLASH_START_SECTOR;
|
||||||
|
env->cfg.cache_size = LFS_CACHE_SIZE;
|
||||||
|
env->cfg.lookahead_size = LFS_LOOK_HEAD_SIZE;
|
||||||
|
env->cfg.block_cycles = 100;
|
||||||
|
|
||||||
|
#ifdef LFS_NO_MALLOC
|
||||||
|
env->cfg.read_buffer = readBuffer;
|
||||||
|
env->cfg.prog_buffer = writeBuffer;
|
||||||
|
env->cfg.lookahead_buffer = lookBuffer;
|
||||||
|
|
||||||
|
env->g_file_cfg.buffer = g_file_buffer;
|
||||||
|
#endif
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = lfs_init_Over(&env->lfs, &env->cfg);
|
||||||
|
|
||||||
|
// err = lfs_format(&env->lfs, &env->cfg);
|
||||||
|
|
||||||
|
// mount the filesystem
|
||||||
|
err = lfs_mount(&env->lfs, &env->cfg);
|
||||||
|
|
||||||
|
// reformat if we can't mount the filesystem
|
||||||
|
// this should only happen on the first boot
|
||||||
|
if (err != 0) {
|
||||||
|
err = lfs_format(&env->lfs, &env->cfg);
|
||||||
|
err = lfs_mount(&env->lfs, &env->cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// Created by cfif on 29.05.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HVAC_LITTLEFSINTERFACE_H
|
||||||
|
#define HVAC_LITTLEFSINTERFACE_H
|
||||||
|
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "lfs.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
lfs_t lfs;
|
||||||
|
struct lfs_config cfg;
|
||||||
|
#ifdef LFS_NO_MALLOC
|
||||||
|
struct lfs_file_config g_file_cfg;
|
||||||
|
#endif
|
||||||
|
} tLittleFileFs;
|
||||||
|
|
||||||
|
extern tLittleFileFs fs;
|
||||||
|
|
||||||
|
int LittleFileFsInit(tLittleFileFs *env, osMutexId_t accessDumper);
|
||||||
|
|
||||||
|
#endif //HVAC_LITTLEFSINTERFACE_H
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"./**.c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
#include "SystemDelayInterface.h"
|
#include "SystemDelayInterface.h"
|
||||||
#include "fc7xxx_driver_smc.h"
|
#include "fc7xxx_driver_smc.h"
|
||||||
#include "MainStack.h"
|
#include "MainStack.h"
|
||||||
|
#include "lfs.h"
|
||||||
|
#include "LittleFsInterface.h"
|
||||||
|
#include "StatusError.h"
|
||||||
|
|
||||||
#define LOG_SIGN "ModelTask"
|
#define LOG_SIGN "ModelTask"
|
||||||
#define LOGGER env->logger
|
#define LOGGER env->logger
|
||||||
|
|
@ -91,7 +94,8 @@ void ModelTask_Init(
|
||||||
// InitThreadAtrStatic(&env->thread.attr, "ModelTask", env->thread.controlBlock, env->thread.stack, osPriorityNormal);
|
// InitThreadAtrStatic(&env->thread.attr, "ModelTask", env->thread.controlBlock, env->thread.stack, osPriorityNormal);
|
||||||
|
|
||||||
env->thread.stack = tModelTask_stack;
|
env->thread.stack = tModelTask_stack;
|
||||||
InitThreadAtr(&env->thread.attr,"ModelTask",&env->thread.controlBlock,sizeof(env->thread.controlBlock),env->thread.stack,tModelTask_stack_size,osPriorityNormal);
|
InitThreadAtr(&env->thread.attr, "ModelTask", &env->thread.controlBlock, sizeof(env->thread.controlBlock),
|
||||||
|
env->thread.stack, tModelTask_stack_size, osPriorityNormal);
|
||||||
env->thread.id = 0;
|
env->thread.id = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +341,7 @@ static bool setActuatorBusy(tModelTask *env) {
|
||||||
if (isCaptured) {
|
if (isCaptured) {
|
||||||
|
|
||||||
#if (LOG_LIN_ACTUATOR == 1)
|
#if (LOG_LIN_ACTUATOR == 1)
|
||||||
#if (LOG_LIN1_ACTUATOR == 1)
|
#if (LOG_LIN1_ACTUATOR == 1)
|
||||||
|
|
||||||
LoggerFormatTrace(LOGGER, LOG_SIGN,
|
LoggerFormatTrace(LOGGER, LOG_SIGN,
|
||||||
"LIN1 (ADR[%d] = %d): UDS CAPTURED", i,
|
"LIN1 (ADR[%d] = %d): UDS CAPTURED", i,
|
||||||
|
|
@ -361,7 +365,7 @@ static bool setActuatorBusy(tModelTask *env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (LOG_LIN_ACTUATOR == 1)
|
#if (LOG_LIN_ACTUATOR == 1)
|
||||||
#if (LOG_LIN1_ACTUATOR == 1)
|
#if (LOG_LIN1_ACTUATOR == 1)
|
||||||
|
|
||||||
switch (env->triggerActuatorCmdBus_1.COM[i]) {
|
switch (env->triggerActuatorCmdBus_1.COM[i]) {
|
||||||
case LIN_ACT_CFR_MOD: {
|
case LIN_ACT_CFR_MOD: {
|
||||||
|
|
@ -420,7 +424,7 @@ static bool setActuatorBusy(tModelTask *env) {
|
||||||
if (isCaptured) {
|
if (isCaptured) {
|
||||||
|
|
||||||
#if (LOG_LIN_ACTUATOR == 1)
|
#if (LOG_LIN_ACTUATOR == 1)
|
||||||
#if (LOG_LIN2_ACTUATOR == 1)
|
#if (LOG_LIN2_ACTUATOR == 1)
|
||||||
|
|
||||||
LoggerFormatTrace(LOGGER, LOG_SIGN,
|
LoggerFormatTrace(LOGGER, LOG_SIGN,
|
||||||
"LIN2 (ADR[%d] = %d): UDS CAPTURED", i,
|
"LIN2 (ADR[%d] = %d): UDS CAPTURED", i,
|
||||||
|
|
@ -443,7 +447,7 @@ static bool setActuatorBusy(tModelTask *env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (LOG_LIN_ACTUATOR == 1)
|
#if (LOG_LIN_ACTUATOR == 1)
|
||||||
#if (LOG_LIN2_ACTUATOR == 1)
|
#if (LOG_LIN2_ACTUATOR == 1)
|
||||||
|
|
||||||
|
|
||||||
switch (env->triggerActuatorCmdBus_2.COM[i]) {
|
switch (env->triggerActuatorCmdBus_2.COM[i]) {
|
||||||
|
|
@ -503,7 +507,7 @@ static bool setActuatorBusy(tModelTask *env) {
|
||||||
if (isCaptured) {
|
if (isCaptured) {
|
||||||
|
|
||||||
#if (LOG_LIN_ACTUATOR == 1)
|
#if (LOG_LIN_ACTUATOR == 1)
|
||||||
#if (LOG_LIN3_ACTUATOR == 1)
|
#if (LOG_LIN3_ACTUATOR == 1)
|
||||||
|
|
||||||
LoggerFormatTrace(LOGGER, LOG_SIGN,
|
LoggerFormatTrace(LOGGER, LOG_SIGN,
|
||||||
"LIN3 (ADR[%d] = %d): UDS CAPTURED", i,
|
"LIN3 (ADR[%d] = %d): UDS CAPTURED", i,
|
||||||
|
|
@ -526,7 +530,7 @@ static bool setActuatorBusy(tModelTask *env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (LOG_LIN_ACTUATOR == 1)
|
#if (LOG_LIN_ACTUATOR == 1)
|
||||||
#if (LOG_LIN3_ACTUATOR == 1)
|
#if (LOG_LIN3_ACTUATOR == 1)
|
||||||
|
|
||||||
|
|
||||||
switch (env->triggerActuatorCmdBus_3.COM[i]) {
|
switch (env->triggerActuatorCmdBus_3.COM[i]) {
|
||||||
|
|
@ -608,8 +612,36 @@ void InitWakeupModel(tModelTask *env) {
|
||||||
|
|
||||||
#define SLEEP_TIME 3000
|
#define SLEEP_TIME 3000
|
||||||
|
|
||||||
|
static uint8_t fileBuffer[2048];
|
||||||
|
|
||||||
|
struct lfs_file_config file_cfg = {
|
||||||
|
.buffer = fileBuffer, // Указываем статический буфер
|
||||||
|
.attrs = NULL,
|
||||||
|
.attr_count = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_file_t file;
|
||||||
|
|
||||||
|
|
||||||
static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
||||||
|
|
||||||
|
lfs_soff_t lfs_err = lfs_file_opencfg(&fs.lfs, &file, "/dtc.bin", LFS_O_RDONLY, &file_cfg);
|
||||||
|
uint32_t timeDTC = SystemGetMs() + 5000;
|
||||||
|
|
||||||
|
if (lfs_err == LFS_ERR_OK) {
|
||||||
|
|
||||||
|
int reading = lfs_file_read(&fs.lfs, &file, dtc_state_error, sizeof(dtc_state_error));
|
||||||
|
|
||||||
|
if (reading != sizeof(dtc_state_error)) {
|
||||||
|
LoggerInfoStatic(LOGGER, LOG_SIGN, "Error read dtc.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_file_close(&fs.lfs, &file);
|
||||||
|
} else {
|
||||||
|
LoggerInfoStatic(LOGGER, LOG_SIGN, "Error open (read) dtc.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (GPIO_ReadPins((uint8_t) PORT_E, PORT_PIN_16)) {
|
if (GPIO_ReadPins((uint8_t) PORT_E, PORT_PIN_16)) {
|
||||||
|
|
@ -632,7 +664,8 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
||||||
|
|
||||||
//начало--------------------------------------------------ВХОД МОДЕЛИ ADC----------------------------------------------
|
//начало--------------------------------------------------ВХОД МОДЕЛИ ADC----------------------------------------------
|
||||||
getCmdBusADCData(env->adc0Task, &rtDW.ADC_Data_Model);
|
getCmdBusADCData(env->adc0Task, &rtDW.ADC_Data_Model);
|
||||||
getCmdBusADC2Data(env->adc1Task,(CmdBusADC2Data *) &rtDW.ADC_Data_Model.VN7008AJ_DIAG_FrontLINActuatorPowerDriverAB);
|
getCmdBusADC2Data(env->adc1Task,
|
||||||
|
(CmdBusADC2Data *) &rtDW.ADC_Data_Model.VN7008AJ_DIAG_FrontLINActuatorPowerDriverAB);
|
||||||
//конец--------------------------------------------------ВХОД МОДЕЛИ ADC------------------------------------------------
|
//конец--------------------------------------------------ВХОД МОДЕЛИ ADC------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -664,9 +697,12 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
||||||
|
|
||||||
//начало-------------------------------------------------ВХОД МОДЕЛИ SlEEP----------------------------------------------
|
//начало-------------------------------------------------ВХОД МОДЕЛИ SlEEP----------------------------------------------
|
||||||
|
|
||||||
memcpy((void *) &rtDW.CCU_STAT1_WAKEUP_MODEL, (void *) &CCU_STAT1_MODEL_SAVE, sizeof(CmdCAN_CCU_STAT1_WakeUp_Bus));
|
memcpy((void *) &rtDW.CCU_STAT1_WAKEUP_MODEL, (void *) &CCU_STAT1_MODEL_SAVE,
|
||||||
memcpy((void *) &rtDW.CCU_STAT2_WAKEUP_MODEL, (void *) &CCU_STAT2_MODEL_SAVE, sizeof(CmdCAN_CCU_STAT2_WakeUp_Bus));
|
sizeof(CmdCAN_CCU_STAT1_WakeUp_Bus));
|
||||||
memcpy((void *) &rtDW.CCU_STAT3_WAKEUP_MODEL, (void *) &CCU_STAT3_MODEL_SAVE, sizeof(CmdCAN_CCU_STAT3_WakeUp_Bus));
|
memcpy((void *) &rtDW.CCU_STAT2_WAKEUP_MODEL, (void *) &CCU_STAT2_MODEL_SAVE,
|
||||||
|
sizeof(CmdCAN_CCU_STAT2_WakeUp_Bus));
|
||||||
|
memcpy((void *) &rtDW.CCU_STAT3_WAKEUP_MODEL, (void *) &CCU_STAT3_MODEL_SAVE,
|
||||||
|
sizeof(CmdCAN_CCU_STAT3_WakeUp_Bus));
|
||||||
memcpy((void *) &rtDW.CCU_Msg1_WakeUp_model, (void *) &CCU_MSG1_MODEL_SAVE, sizeof(CCU_Msg1_WakeUp_Bus));
|
memcpy((void *) &rtDW.CCU_Msg1_WakeUp_model, (void *) &CCU_MSG1_MODEL_SAVE, sizeof(CCU_Msg1_WakeUp_Bus));
|
||||||
|
|
||||||
//конец--------------------------------------------------ВХОД МОДЕЛИ SLEEP----------------------------------------------
|
//конец--------------------------------------------------ВХОД МОДЕЛИ SLEEP----------------------------------------------
|
||||||
|
|
@ -832,8 +868,10 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
||||||
//начало--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ PWM------------------------------------------
|
//начало--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ PWM------------------------------------------
|
||||||
if (model_Status_Set_For_Model_output.Pwm == 1) {
|
if (model_Status_Set_For_Model_output.Pwm == 1) {
|
||||||
|
|
||||||
env->pwms->pwmFrontIo.setActivePercent(env->pwms->pwmFrontIo.env, model_Status_Pwm_For_Model_output.Pwm_Front / 10);
|
env->pwms->pwmFrontIo.setActivePercent(env->pwms->pwmFrontIo.env,
|
||||||
env->pwms->pwmRearIo.setActivePercent(env->pwms->pwmRearIo.env, model_Status_Pwm_For_Model_output.Pwm_Rear / 10);
|
model_Status_Pwm_For_Model_output.Pwm_Front / 10);
|
||||||
|
env->pwms->pwmRearIo.setActivePercent(env->pwms->pwmRearIo.env,
|
||||||
|
model_Status_Pwm_For_Model_output.Pwm_Rear / 10);
|
||||||
env->pwms->pwmFrontReservedIo.setActivePercent(env->pwms->pwmFrontReservedIo.env,
|
env->pwms->pwmFrontReservedIo.setActivePercent(env->pwms->pwmFrontReservedIo.env,
|
||||||
rtY.PWM_Get_f.pwmPercentFrontReserved);
|
rtY.PWM_Get_f.pwmPercentFrontReserved);
|
||||||
env->pwms->pwmRearReservedIo.setActivePercent(env->pwms->pwmRearReservedIo.env,
|
env->pwms->pwmRearReservedIo.setActivePercent(env->pwms->pwmRearReservedIo.env,
|
||||||
|
|
@ -864,7 +902,11 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
||||||
|
|
||||||
//начало--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ DTC------------------------------------------
|
//начало--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ DTC------------------------------------------
|
||||||
memcpy(env->dtc_state_error, rtY.dtc_state_error_model, sizeof(env->dtc_state_error));
|
memcpy(env->dtc_state_error, rtY.dtc_state_error_model, sizeof(env->dtc_state_error));
|
||||||
set_Dtc_state(env->diagnostic, &env->ccu_candb_tx.CCU_Errors, env->dtc_state_error, env->GET_HVAC_VIN, &env->CAN_ERROR_MISSLE, &env->CAN_TIME_MISSLE);
|
|
||||||
|
if (SystemGetMs() > timeDTC) {
|
||||||
|
set_Dtc_state(env->diagnostic, &file, &file_cfg, &env->ccu_candb_tx.CCU_Errors, env->dtc_state_error,
|
||||||
|
env->GET_HVAC_VIN, &env->CAN_ERROR_MISSLE, &env->CAN_TIME_MISSLE);
|
||||||
|
}
|
||||||
//конец--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ DTC-------------------------------------------
|
//конец--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ DTC-------------------------------------------
|
||||||
|
|
||||||
memcpy(&env->ccu_candb_tx.CCU_Stat1, &rtY.CCU_Stat1_model, sizeof(env->ccu_candb_tx.CCU_Stat1));
|
memcpy(&env->ccu_candb_tx.CCU_Stat1, &rtY.CCU_Stat1_model, sizeof(env->ccu_candb_tx.CCU_Stat1));
|
||||||
|
|
@ -937,27 +979,42 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
|
||||||
if (model_Status_Set_For_Model_output.Pwm == 1) {
|
if (model_Status_Set_For_Model_output.Pwm == 1) {
|
||||||
|
|
||||||
|
|
||||||
env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Front = model_Status_Pwm_For_Model_output.Pwm_Front / 10;
|
env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Front =
|
||||||
env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Rear = model_Status_Pwm_For_Model_output.Pwm_Rear / 10;
|
model_Status_Pwm_For_Model_output.Pwm_Front / 10;
|
||||||
|
env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Rear =
|
||||||
|
model_Status_Pwm_For_Model_output.Pwm_Rear / 10;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model_Status_Pwm_For_Model_input.Pwm_Front = env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Front * 10;
|
model_Status_Pwm_For_Model_input.Pwm_Front =
|
||||||
model_Status_Pwm_For_Model_input.Pwm_Rear = env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Rear * 10;
|
env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Front * 10;
|
||||||
|
model_Status_Pwm_For_Model_input.Pwm_Rear =
|
||||||
|
env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_Pwm_Rear * 10;
|
||||||
|
|
||||||
|
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Sen_Amb, &rtY.dbgCAN_dbg_Sen_Amb_model, sizeof(env->ccu_candb_dbg_tx.dbg_Sen_Amb));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Sen_Amb, &rtY.dbgCAN_dbg_Sen_Amb_model,
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Sen_Incar, &rtY.dbgCAN_dbg_Sen_Incar_model, sizeof(env->ccu_candb_dbg_tx.dbg_Sen_Incar));
|
sizeof(env->ccu_candb_dbg_tx.dbg_Sen_Amb));
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Sen_0, &rtY.dbgCAN_dbg_Sen_0_model, sizeof(env->ccu_candb_dbg_tx.dbg_Sen_0));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Sen_Incar, &rtY.dbgCAN_dbg_Sen_Incar_model,
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_Ac, &rtY.dbg_Logic_Ac_model, sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Ac));
|
sizeof(env->ccu_candb_dbg_tx.dbg_Sen_Incar));
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_CCU_IO, &rtY.dbgCAN_CCU_IO_model, sizeof(env->ccu_candb_dbg_tx.dbg_CCU_IO));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Sen_0, &rtY.dbgCAN_dbg_Sen_0_model,
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_Rec, &rtY.dbgCAN_Logic_Rec_model, sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Rec));
|
sizeof(env->ccu_candb_dbg_tx.dbg_Sen_0));
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_State, &rtY.dbgCAN_Logic_State_model, sizeof(env->ccu_candb_dbg_tx.dbg_Logic_State));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_Ac, &rtY.dbg_Logic_Ac_model,
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Auto_AF, &rtY.dbgCAN_Auto_AF_model, sizeof(env->ccu_candb_dbg_tx.dbg_Auto_AF));
|
sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Ac));
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Auto_Duct, &rtY.dbgCAN_Auto_Duct_model, sizeof(env->ccu_candb_dbg_tx.dbg_Auto_Duct));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_CCU_IO, &rtY.dbgCAN_CCU_IO_model,
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_Valve, &rtY.dbg_Logic_Valve_model, sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Valve));
|
sizeof(env->ccu_candb_dbg_tx.dbg_CCU_IO));
|
||||||
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_Rec, &rtY.dbgCAN_Logic_Rec_model,
|
||||||
|
sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Rec));
|
||||||
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_State, &rtY.dbgCAN_Logic_State_model,
|
||||||
|
sizeof(env->ccu_candb_dbg_tx.dbg_Logic_State));
|
||||||
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Auto_AF, &rtY.dbgCAN_Auto_AF_model,
|
||||||
|
sizeof(env->ccu_candb_dbg_tx.dbg_Auto_AF));
|
||||||
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Auto_Duct, &rtY.dbgCAN_Auto_Duct_model,
|
||||||
|
sizeof(env->ccu_candb_dbg_tx.dbg_Auto_Duct));
|
||||||
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Logic_Valve, &rtY.dbg_Logic_Valve_model,
|
||||||
|
sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Valve));
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_Drs, &rtY.dbg_Drs_t_model, sizeof(env->ccu_candb_dbg_tx.dbg_Drs));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_Drs, &rtY.dbg_Drs_t_model, sizeof(env->ccu_candb_dbg_tx.dbg_Drs));
|
||||||
memcpy(&env->ccu_candb_dbg_tx.dbg_LIN_AirQS_Stat, &rtY.dbg_LIN_AirQS_Stat_t_model, sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Valve));
|
memcpy(&env->ccu_candb_dbg_tx.dbg_LIN_AirQS_Stat, &rtY.dbg_LIN_AirQS_Stat_t_model,
|
||||||
|
sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Valve));
|
||||||
/*
|
/*
|
||||||
env->ccu_candb_dbg_tx.dbg_stat_PID.P_FUL = 501 + 2048;
|
env->ccu_candb_dbg_tx.dbg_stat_PID.P_FUL = 501 + 2048;
|
||||||
env->ccu_candb_dbg_tx.dbg_stat_PID.I_FUL = 502 + 2048;
|
env->ccu_candb_dbg_tx.dbg_stat_PID.I_FUL = 502 + 2048;
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,143 @@
|
||||||
#include "StatusError.h"
|
#include "StatusError.h"
|
||||||
#include "HVAC_model.h"
|
#include "HVAC_model.h"
|
||||||
#include "SystemDelayInterface.h"
|
#include "SystemDelayInterface.h"
|
||||||
|
#include "lfs.h"
|
||||||
|
#include "lfs_file_utils.h"
|
||||||
|
#include "LittleFsInterface.h"
|
||||||
|
|
||||||
#define LOG_SIGN "DIAGNOSTIC"
|
#define LOG_SIGN "DIAGNOSTIC"
|
||||||
#define LOGGER env->logger
|
#define LOGGER env->logger
|
||||||
|
|
||||||
|
const char* DTC_Error_Code_Strings[COUNT_DTC_CODE_ERROR] = {
|
||||||
|
"DTC_CCU_POWER_SUPPLY_VOLTAGE_OUT_OF_RANGE", // 0xA0101C
|
||||||
|
"DTC_IGNITION_VOLTAGE_OUT_OF_RANGE", // 0xA0111C
|
||||||
|
"DTC_REAR_HVAC_AROMA_CONFIG_INVALID", // 0xA02056
|
||||||
|
"DTC_INCAR_TEMP_FRONT_LEFT_SHORT_BAT_OPEN", // 0xA03015
|
||||||
|
"DTC_INCAR_TEMP_FRONT_LEFT_SHORT_GND", // 0xA03011
|
||||||
|
"DTC_INCAR_TEMP_FRONT_RIGHT_SHORT_BAT_OPEN", // 0xA03115
|
||||||
|
"DTC_INCAR_TEMP_FRONT_RIGHT_SHORT_GND", // 0xA03111
|
||||||
|
"DTC_INCAR_TEMP_REAR_LEFT_SHORT_BAT_OPEN", // 0xA05415
|
||||||
|
"DTC_INCAR_TEMP_REAR_LEFT_SHORT_GND", // 0xA05411
|
||||||
|
"DTC_INCAR_TEMP_REAR_RIGHT_SHORT_BAT_OPEN", // 0xA05515
|
||||||
|
"DTC_INCAR_TEMP_REAR_RIGHT_SHORT_GND", // 0xA05511
|
||||||
|
"DTC_AMBIENT_TEMP_SHORT_BAT_OPEN", // 0xA03215
|
||||||
|
"DTC_AMBIENT_TEMP_SHORT_GND", // 0xA03211
|
||||||
|
"DTC_FRONT_EVAP_TEMP_SHORT_BAT_OPEN", // 0xA03315
|
||||||
|
"DTC_FRONT_EVAP_TEMP_SHORT_GND", // 0xA03311
|
||||||
|
"DTC_REAR_EVAP_TEMP_SHORT_BAT_OPEN", // 0xA03415
|
||||||
|
"DTC_REAR_EVAP_TEMP_SHORT_GND", // 0xA03411
|
||||||
|
"DTC_DUCT_VENT_FL_SHORT_BAT_OPEN", // 0xA03515
|
||||||
|
"DTC_DUCT_VENT_FL_SHORT_GND", // 0xA03511
|
||||||
|
"DTC_DUCT_VENT_FR_SHORT_BAT_OPEN", // 0xA03615
|
||||||
|
"DTC_DUCT_VENT_FR_SHORT_GND", // 0xA03611
|
||||||
|
"DTC_DUCT_FOOT_FL_SHORT_BAT_OPEN", // 0xA03715
|
||||||
|
"DTC_DUCT_FOOT_FL_SHORT_GND", // 0xA03711
|
||||||
|
"DTC_DUCT_FOOT_FR_SHORT_BAT_OPEN", // 0xA03815
|
||||||
|
"DTC_DUCT_FOOT_FR_SHORT_GND", // 0xA03811
|
||||||
|
"DTC_DUCT_VENT_SIDE_FL_SHORT_BAT_OPEN", // 0xA04115
|
||||||
|
"DTC_DUCT_VENT_SIDE_FL_SHORT_GND", // 0xA04111
|
||||||
|
"DTC_DUCT_VENT_SIDE_FR_SHORT_BAT_OPEN", // 0xA04215
|
||||||
|
"DTC_DUCT_VENT_SIDE_FR_SHORT_GND", // 0xA04211
|
||||||
|
"DTC_DUCT_VENT_RL_SHORT_BAT_OPEN", // 0xA03915
|
||||||
|
"DTC_DUCT_VENT_RL_SHORT_GND", // 0xA03911
|
||||||
|
"DTC_DUCT_VENT_RR_SHORT_BAT_OPEN", // 0xA04015
|
||||||
|
"DTC_DUCT_VENT_RR_SHORT_GND", // 0xA04011
|
||||||
|
"DTC_DUCT_FOOT_RL_SHORT_BAT_OPEN", // 0xA04515
|
||||||
|
"DTC_DUCT_FOOT_RL_SHORT_GND", // 0xA04511
|
||||||
|
"DTC_DUCT_FOOT_RR_SHORT_BAT_OPEN", // 0xA04615
|
||||||
|
"DTC_DUCT_FOOT_RR_SHORT_GND", // 0xA04611
|
||||||
|
"DTC_UV_LAMP_OPEN_SHORT_BAT", // 0xA04713
|
||||||
|
"DTC_UV_LAMP_SHORT_GND", // 0xA04711
|
||||||
|
"DTC_AROMATIZATION_OPEN", // 0xA04813
|
||||||
|
"DTC_AROMATIZATION_SHORT_GND", // 0xA04811
|
||||||
|
"DTC_AROMATIZATION_MALFUNCTION", // 0xA04896
|
||||||
|
"DTC_IONIZER_OPEN", // 0xA04913
|
||||||
|
"DTC_IONIZER_SHORT_GND", // 0xA04911
|
||||||
|
"DTC_IONIZER_MALFUNCTION", // 0xA04996
|
||||||
|
"DTC_DRS_FRONT_ZONE_MALFUNCTION", // 0xA05096
|
||||||
|
"DTC_DRS_REAR_ZONE_MALFUNCTION", // 0xA05196
|
||||||
|
"DTC_AIR_QUALITY_SENSOR_OPEN", // 0xA04315
|
||||||
|
"DTC_AIR_QUALITY_SENSOR_SHORT_GND", // 0xA04311
|
||||||
|
"DTC_AIR_QUALITY_SENSOR_MALFUNCTION", // 0xA04396
|
||||||
|
"DTC_AC_PRESSURE_SHORT_BAT", // 0xA04412
|
||||||
|
"DTC_AC_PRESSURE_SHORT_GND_OPEN", // 0xA04414
|
||||||
|
"DTC_AC_PRESSURE_SIGNAL_BELOW_RANGE", // 0xA04484
|
||||||
|
"DTC_FRONT_BLOWER_TXV_PERFORMANCE", // 0xA05692
|
||||||
|
"DTC_REAR_BLOWER_TXV_PERFORMANCE", // 0xA05892
|
||||||
|
"DTC_DEFROSTER_GATE_POSITION_NOT_REACHED", // 0xA07004
|
||||||
|
"DTC_RECIRC_GATE_POSITION_NOT_REACHED", // 0xA07104
|
||||||
|
"DTC_RECIRC_OSA_GATE_POSITION_NOT_REACHED", // 0xA09304
|
||||||
|
"DTC_TEMP_UP_FL_GATE_POSITION_NOT_REACHED", // 0xA07204
|
||||||
|
"DTC_VENT_CFL_GATE_POSITION_NOT_REACHED", // 0xA07304
|
||||||
|
"DTC_VENT_SFL_GATE_POSITION_NOT_REACHED", // 0xA07404
|
||||||
|
"DTC_TEMP_DN_FL_GATE_POSITION_NOT_REACHED", // 0xA07504
|
||||||
|
"DTC_FOOT_FL_GATE_POSITION_NOT_REACHED", // 0xA07604
|
||||||
|
"DTC_REAR_FOOT_FL_GATE_POSITION_NOT_REACHED", // 0xA07704
|
||||||
|
"DTC_TEMP_UP_FR_GATE_POSITION_NOT_REACHED", // 0xA07804
|
||||||
|
"DTC_VENT_CFR_GATE_POSITION_NOT_REACHED", // 0xA07904
|
||||||
|
"DTC_VENT_SFR_GATE_POSITION_NOT_REACHED", // 0xA08004
|
||||||
|
"DTC_TEMP_DN_FR_GATE_POSITION_NOT_REACHED", // 0xA08104
|
||||||
|
"DTC_FOOT_FR_GATE_POSITION_NOT_REACHED", // 0xA08204
|
||||||
|
"DTC_REAR_FOOT_FR_GATE_POSITION_NOT_REACHED", // 0xA08304
|
||||||
|
"DTC_TEMP_RR_GATE_POSITION_NOT_REACHED", // 0xA08404
|
||||||
|
"DTC_TEMP_RL_GATE_POSITION_NOT_REACHED", // 0xA08504
|
||||||
|
"DTC_VENT_SRL_GATE_POSITION_NOT_REACHED", // 0xA08604
|
||||||
|
"DTC_FOOT_RL_GATE_POSITION_NOT_REACHED", // 0xA08704
|
||||||
|
"DTC_VENT_CRL_GATE_POSITION_NOT_REACHED", // 0xA08804
|
||||||
|
"DTC_VENT_CRR_GATE_POSITION_NOT_REACHED", // 0xA08904
|
||||||
|
"DTC_FOOT_RR_GATE_POSITION_NOT_REACHED", // 0xA09004
|
||||||
|
"DTC_VENT_SRR_GATE_POSITION_NOT_REACHED", // 0xA09104
|
||||||
|
"DTC_SEALING_VALVE_GATE_POSITION_NOT_REACHED", // 0xA09204
|
||||||
|
"DTC_BODY_CAN_BUS_OFF", // 0xC02888
|
||||||
|
"DTC_HVAC_CAN_BUS_OFF", // 0xC03788
|
||||||
|
"DTC_LOST_COMM_ECM_PCM", // 0xC10087
|
||||||
|
"DTC_LOST_COMM_ESP", // 0xC12287
|
||||||
|
"DTC_LOST_COMM_BCM", // 0xC14187
|
||||||
|
"DTC_LOST_COMM_AC_COMPRESSOR", // 0xC16B87
|
||||||
|
"DTC_LOST_COMM_DOOR_MODULE_A_DMFL", // 0xC19987
|
||||||
|
"DTC_LOST_COMM_DOOR_MODULE_B_DMFR", // 0xC20087
|
||||||
|
"DTC_LOST_COMM_SEAT_MODULE_A_SMFL", // 0xC20887
|
||||||
|
"DTC_LOST_COMM_SEAT_MODULE_B_SMFR", // 0xC20987
|
||||||
|
"DTC_LOST_COMM_SEAT_MODULE_C_SMRL", // 0xC21087
|
||||||
|
"DTC_LOST_COMM_SEAT_MODULE_D_SMRR", // 0xC21187
|
||||||
|
"DTC_LOST_COMM_TRUNK_CCPF_CCPR", // 0xE2A187
|
||||||
|
"DTC_LOST_COMM_CGW", // 0xE2A287
|
||||||
|
"DTC_LOST_COMM_DEFROSTER_GATE", // 0xE23087
|
||||||
|
"DTC_LOST_COMM_RECIRC_GATE", // 0xE23187
|
||||||
|
"DTC_LOST_COMM_RECIRC_OSA_GATE", // 0xE26287
|
||||||
|
"DTC_LOST_COMM_TEMP_UP_FL_GATE", // 0xE23287
|
||||||
|
"DTC_LOST_COMM_VENT_CFL_GATE", // 0xE23387
|
||||||
|
"DTC_LOST_COMM_FOOT_FR_GATE_LIN1", // 0xE23487
|
||||||
|
"DTC_LOST_COMM_TEMP_DN_FL_GATE", // 0xE23587
|
||||||
|
"DTC_LOST_COMM_FOOT_FL_GATE", // 0xE23687
|
||||||
|
"DTC_LOST_COMM_REAR_FOOT_FL_GATE", // 0xE23787
|
||||||
|
"DTC_LOST_COMM_TEMP_UP_FR_GATE", // 0xE23887
|
||||||
|
"DTC_LOST_COMM_VENT_CFR_GATE", // 0xE23987
|
||||||
|
"DTC_LOST_COMM_VENT_SFR_GATE", // 0xE24087
|
||||||
|
"DTC_LOST_COMM_TEMP_DN_FR_GATE", // 0xE24187
|
||||||
|
"DTC_LOST_COMM_FOOT_FR_GATE", // 0xE24287
|
||||||
|
"DTC_LOST_COMM_REAR_FOOT_FR_GATE", // 0xE24387
|
||||||
|
"DTC_LOST_COMM_TEMP_RR_GATE", // 0xE24487
|
||||||
|
"DTC_LOST_COMM_TEMP_RL_GATE", // 0xE24587
|
||||||
|
"DTC_LOST_COMM_VENT_SRL_GATE", // 0xE24687
|
||||||
|
"DTC_LOST_COMM_TEMP_RL_GATE2", // 0xE24787
|
||||||
|
"DTC_LOST_COMM_VENT_CRL_GATE", // 0xE24887
|
||||||
|
"DTC_LOST_COMM_VENT_CRR_GATE", // 0xE24987
|
||||||
|
"DTC_LOST_COMM_FOOT_RR_GATE", // 0xE25087
|
||||||
|
"DTC_LOST_COMM_VENT_SRR_GATE", // 0xE25187
|
||||||
|
"DTC_LOST_COMM_SEALING_VALVE_GATE", // 0xE25287
|
||||||
|
"DTC_LOST_COMM_AIR_QUALITY_SENSOR", // 0xE25387
|
||||||
|
"DTC_LOST_COMM_IONIZER", // 0xE25487
|
||||||
|
"DTC_LOST_COMM_AROMATIZATION", // 0xE25587
|
||||||
|
"DTC_LOST_COMM_FRONT_TXV", // 0xE25687
|
||||||
|
"DTC_LOST_COMM_REAR_TXV", // 0xE25787
|
||||||
|
"DTC_LOST_COMM_HV_BATTERY_CHILLER_TXV", // 0xE25887
|
||||||
|
"DTC_LOST_COMM_HEAT_PUMP_CHILLER_TXV", // 0xE25987
|
||||||
|
"DTC_LOST_COMM_DRS_FRONT", // 0xE26087
|
||||||
|
"DTC_LOST_COMM_DRS_REAR", // 0xE26187
|
||||||
|
"DTC_VIN_INVALID_CONFIG" // 0xF00256
|
||||||
|
};
|
||||||
|
|
||||||
void Diagnostic_Init(tDiagnostic *env, tLoggerInterface *logger) {
|
void Diagnostic_Init(tDiagnostic *env, tLoggerInterface *logger) {
|
||||||
|
|
||||||
env->logger = logger;
|
env->logger = logger;
|
||||||
|
|
@ -168,24 +301,142 @@ static bool isVINError(char *VIN) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_Dtc_state(tDiagnostic *env, CCU_Errors_t *CCU_Errors, uint8_t *dtc_state_error_model, char *VIN, ccu_candb_error_missing_rx_t *CAN_ERROR_MISSLE, ccu_candb_time_missing_rx_t *CAN_TIME_MISSLE) {
|
|
||||||
|
static void
|
||||||
|
setErrorDTC_CAN_VIN(uint8_t *dtc_state_error_model, ccu_candb_error_missing_rx_t *CAN_ERROR_MISSLE, char *VIN,
|
||||||
|
CCU_Errors_t *CCU_Errors) {
|
||||||
|
bool vin_timeout = CAN_ERROR_MISSLE->VEH_VIN;
|
||||||
|
bool vin_error = isVINError(VIN);
|
||||||
|
|
||||||
|
// DTC = 1 только если:
|
||||||
|
// - VIN собран, но невалидный
|
||||||
|
// - ИЛИ таймаут (сообщение VIN вообще не приходит)
|
||||||
|
if (vin_error || vin_timeout) {
|
||||||
|
dtc_state_error_model[DTC_VIN_INVALID_CONFIG] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
CCU_Errors->CCU_VinRecordErr_Stat = 1;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_VIN_INVALID_CONFIG] = dtc_state_error[DTC_VIN_INVALID_CONFIG] & (~(DTC_TEST_FAILED));
|
||||||
|
CCU_Errors->CCU_VinRecordErr_Stat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setErrorDTC_CAN(uint8_t *dtc_state_error_model, ccu_candb_error_missing_rx_t *CAN_ERROR_MISSLE) {
|
||||||
|
if (CAN_ERROR_MISSLE->EMS_Veh) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_ECM_PCM] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_ECM_PCM] = dtc_state_error[DTC_LOST_COMM_ECM_PCM] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->ESC_04) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_ESP] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_ESP] = dtc_state_error[DTC_LOST_COMM_ESP] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->BCM_Powertrain) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_BCM] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_BCM] = dtc_state_error[DTC_LOST_COMM_BCM] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->EMS_HVC_Req_Msg) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_AC_COMPRESSOR] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_AC_COMPRESSOR] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_AC_COMPRESSOR] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->DMFR_Msg1) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_DOOR_MODULE_A_DMFL] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_DOOR_MODULE_A_DMFL] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_DOOR_MODULE_A_DMFL] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->DMFL_Msg1) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_DOOR_MODULE_B_DMFR] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_DOOR_MODULE_B_DMFR] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_DOOR_MODULE_B_DMFR] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->SMFL_status) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_A_SMFL] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_A_SMFL] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_SEAT_MODULE_A_SMFL] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->SMFR_status) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_B_SMFR] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_B_SMFR] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_SEAT_MODULE_B_SMFR] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->SMRL_status) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_C_SMRL] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_C_SMRL] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_SEAT_MODULE_C_SMRL] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN_ERROR_MISSLE->SMRR_status) {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_D_SMRR] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
|
} else {
|
||||||
|
dtc_state_error_model[DTC_LOST_COMM_SEAT_MODULE_D_SMRR] =
|
||||||
|
dtc_state_error[DTC_LOST_COMM_SEAT_MODULE_D_SMRR] & (~(DTC_TEST_FAILED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_Dtc_state(tDiagnostic *env, lfs_file_t *file, struct lfs_file_config *file_cfg, CCU_Errors_t *CCU_Errors,
|
||||||
|
uint8_t *dtc_state_error_model, char *VIN,
|
||||||
|
ccu_candb_error_missing_rx_t *CAN_ERROR_MISSLE, ccu_candb_time_missing_rx_t *CAN_TIME_MISSLE) {
|
||||||
|
|
||||||
if (osMutexAcquire(env->access, 5000) == osOK) {
|
if (osMutexAcquire(env->access, 5000) == osOK) {
|
||||||
|
|
||||||
bool vin_timeout = CAN_ERROR_MISSLE->VEH_VIN;
|
for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) {
|
||||||
bool vin_error = isVINError(VIN);
|
if (dtc_state_error_model[i]) {
|
||||||
|
dtc_state_error_model[i] = DTC_TEST_FAILED_CONFIRMED;
|
||||||
// DTC = 1 только если:
|
} else {
|
||||||
// - VIN собран, но невалидный
|
dtc_state_error_model[i] = dtc_state_error[i] & (~(DTC_TEST_FAILED));
|
||||||
// - ИЛИ таймаут (сообщение VIN вообще не приходит)
|
}
|
||||||
if (vin_error || vin_timeout) {
|
}
|
||||||
dtc_state_error_model[DTC_VIN_INVALID_CONFIG] = 1;
|
|
||||||
CCU_Errors->CCU_VinRecordErr_Stat = 1;
|
setErrorDTC_CAN_VIN(dtc_state_error_model, CAN_ERROR_MISSLE, VIN, CCU_Errors);
|
||||||
} else {
|
setErrorDTC_CAN(dtc_state_error_model, CAN_ERROR_MISSLE);
|
||||||
dtc_state_error_model[DTC_VIN_INVALID_CONFIG] = 0;
|
|
||||||
CCU_Errors->CCU_VinRecordErr_Stat = 0;
|
if (memcmp(dtc_state_error, dtc_state_error_model, sizeof(dtc_state_error)) != 0) {
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) {
|
||||||
|
if (dtc_state_error_model[i]) {
|
||||||
|
LoggerFormatInfo(LOGGER, LOG_SIGN, "DTC: %s", DTC_Error_Code_Strings[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(dtc_state_error, dtc_state_error_model, sizeof(dtc_state_error));
|
||||||
|
|
||||||
|
lfs_soff_t lfs_err = lfs_file_opencfg(&fs.lfs, file, "/dtc.bin", LFS_O_RDWR | LFS_O_CREAT, file_cfg);
|
||||||
|
|
||||||
|
if (lfs_err == LFS_ERR_OK) {
|
||||||
|
|
||||||
|
int writes = lfs_file_write(&fs.lfs, file, dtc_state_error, sizeof(dtc_state_error));
|
||||||
|
|
||||||
|
if (writes != sizeof(dtc_state_error)) {
|
||||||
|
LoggerInfoStatic(LOGGER, LOG_SIGN, "Error write dtc.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_err = lfs_file_close(&fs.lfs, file);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LoggerInfoStatic(LOGGER, LOG_SIGN, "Error open (write) dtc.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
asm("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dtc_state_error, dtc_state_error_model, sizeof(dtc_state_error));
|
|
||||||
osMutexRelease(env->access);
|
osMutexRelease(env->access);
|
||||||
} else {
|
} else {
|
||||||
LoggerErrorStatic(LOGGER, LOG_SIGN, "Access error set_Dtc_state_error");
|
LoggerErrorStatic(LOGGER, LOG_SIGN, "Access error set_Dtc_state_error");
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,11 @@
|
||||||
#include <cmsis_os.h>
|
#include <cmsis_os.h>
|
||||||
#include "LoggerInterface.h"
|
#include "LoggerInterface.h"
|
||||||
#include "ccu_candb-binutil.h"
|
#include "ccu_candb-binutil.h"
|
||||||
|
#include "lfs.h"
|
||||||
|
|
||||||
|
#define DTC_TEST_FAILED 1
|
||||||
|
#define DTC_TEST_CONFIRMED 8
|
||||||
|
#define DTC_TEST_FAILED_CONFIRMED (DTC_TEST_FAILED | DTC_TEST_CONFIRMED)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t mask;
|
uint8_t mask;
|
||||||
|
|
@ -25,8 +29,8 @@ typedef struct {
|
||||||
|
|
||||||
void Diagnostic_Init(tDiagnostic *env, tLoggerInterface *logger);
|
void Diagnostic_Init(tDiagnostic *env, tLoggerInterface *logger);
|
||||||
void set_NoBitsDTC(tDiagnostic *env, bool noBitsDTC);
|
void set_NoBitsDTC(tDiagnostic *env, bool noBitsDTC);
|
||||||
void set_Dtc_state(tDiagnostic *env, CCU_Errors_t *CCU_Errors, uint8_t *dtc_state_error_model, char *VIN, ccu_candb_error_missing_rx_t *CAN_ERROR_MISSLE, ccu_candb_time_missing_rx_t *CAN_TIME_MISSLE);
|
void set_Dtc_state(tDiagnostic *env, lfs_file_t *file, struct lfs_file_config *file_cfg, CCU_Errors_t *CCU_Errors, uint8_t *dtc_state_error_model, char *VIN,
|
||||||
|
ccu_candb_error_missing_rx_t *CAN_ERROR_MISSLE, ccu_candb_time_missing_rx_t *CAN_TIME_MISSLE);
|
||||||
uint32_t diagnostic_ClearDiagnosticInformation_14(tDiagnostic *env);
|
uint32_t diagnostic_ClearDiagnosticInformation_14(tDiagnostic *env);
|
||||||
uint32_t diagnostic_UDS_ReadDTCInformation_19_count(tDiagnostic *env, tDiagnosticDTC *diagnosticDTC);
|
uint32_t diagnostic_UDS_ReadDTCInformation_19_count(tDiagnostic *env, tDiagnosticDTC *diagnosticDTC);
|
||||||
uint32_t diagnostic_UDS_ReadDTCInformation_19_dtc(tDiagnostic *env, tDiagnosticDTC *diagnosticDTC);
|
uint32_t diagnostic_UDS_ReadDTCInformation_19_dtc(tDiagnostic *env, tDiagnosticDTC *diagnosticDTC);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ extern const tDTC_Entry dtc_codes[COUNT_DTC_CODE_ERROR];
|
||||||
extern uint8_t dtc_state_error[COUNT_DTC_CODE_ERROR];
|
extern uint8_t dtc_state_error[COUNT_DTC_CODE_ERROR];
|
||||||
extern uint8_t dtc_state_FIX_error[COUNT_DTC_CODE_ERROR];
|
extern uint8_t dtc_state_FIX_error[COUNT_DTC_CODE_ERROR];
|
||||||
|
|
||||||
|
|
||||||
enum eDTC_Error_Code {
|
enum eDTC_Error_Code {
|
||||||
DTC_CCU_POWER_SUPPLY_VOLTAGE_OUT_OF_RANGE = 0, // 0xA0101C
|
DTC_CCU_POWER_SUPPLY_VOLTAGE_OUT_OF_RANGE = 0, // 0xA0101C
|
||||||
DTC_IGNITION_VOLTAGE_OUT_OF_RANGE = 1, // 0xA0111C
|
DTC_IGNITION_VOLTAGE_OUT_OF_RANGE = 1, // 0xA0111C
|
||||||
|
|
|
||||||
22
modular.json
22
modular.json
|
|
@ -28,8 +28,10 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dir": "./MODULES/FileSystemLittleFs"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"type": "local",
|
"type": "local",
|
||||||
|
|
@ -492,6 +494,22 @@
|
||||||
"dir": "./MODULES/Adc"
|
"dir": "./MODULES/Adc"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dir": "./MODULES/FileSystemLittleFs"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dir": "./MODULES/HVAC_M7_LittleFs"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"dir": "APP"
|
"dir": "APP"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue