Добавлена ОС и ошибки

This commit is contained in:
cfif 2026-08-31 18:15:11 +03:00
parent 0a36a55574
commit fb1a1f04a3
22 changed files with 8461 additions and 52 deletions

View File

@ -49,6 +49,8 @@ SET(VECT_TAB_OFFSET "0x00000")
#-- Defines --------------------------------------------------------------------
ADD_DEFINITIONS(-DLFS_NO_MALLOC=1)
ADD_DEFINITIONS(-DINTERNAL_HW_YEAR=${INTERNAL_HW_YEAR})
ADD_DEFINITIONS(-DINTERNAL_HW_MONTH=${INTERNAL_HW_MONTH})
ADD_DEFINITIONS(-DINTERNAL_HW_DAY=${INTERNAL_HW_DAY})

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,10 @@
{
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c"
]
}
}

View File

@ -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);
if (countQueue_ccu_candb_rx) {
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);
if (countQueue_ccu_candb_rx) {
status = osMessageQueuePut(env->ccu_candb_time_missing_rx, &ccu_candb_time_missing_rx, 0, 0U);
return;
}

View File

@ -2787,6 +2787,7 @@ void ReceivedTP_func(void *arg, tCanTP_data *data) {
}
}
osMutexRelease(env->access);
} else {
LoggerErrorStatic(LOGGER, LOG_SIGN, "Access error ReceivedTP_func");

View File

@ -32,6 +32,7 @@
#include "CanUds.h"
#include "DiagnosticTask.h"
#include "LinSensorTasks.h"
#include "LittleFsInterface.h"
typedef struct {
@ -51,6 +52,7 @@ typedef struct {
tDeviceStorage storage;
tPowerManagement power;
tCommandLine cli;

View File

@ -46,6 +46,7 @@ const DMA_InitType dmaInitCfg =
#define CHECK_JTAG_DEBUG_ACTIVE ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0)
#define CHECK_PARALLEL_ENABLE (((*(volatile uint32_t*)0x044000E8) & 0x0000000F) != 0x00000005)
tLittleFileFs fs;
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,
&env->slog.logger);
LittleFileFsInit(&fs, env->storage.dumpObserver.accessDumper);
memcpy(dataTmp, env->storage.dataParam->device.identification.Tester_Fingerprint.tester_serial, 9);

View File

@ -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_count;
__attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
__attribute__((section(".save_data"))) volatile uint32_t none_data;
void vTaskGetCurrentTaskStackInfo(void **ppvStackStart, void **ppvStackEnd);

View File

@ -9,8 +9,8 @@
#define SIZE_BUF_HARD_FAULT 32
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_addresses[32];
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_count;
extern __attribute__((section(".ncache_bss"))) volatile uint32_t hardFault_magic;
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_addresses[32];
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_count;
extern __attribute__((section(".save_data"))) volatile uint32_t hardFault_magic;
#endif //HVAC_M7_HARDFAULT_H

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,10 @@
{
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c"
]
}
}

View File

@ -9,6 +9,9 @@
#include "SystemDelayInterface.h"
#include "fc7xxx_driver_smc.h"
#include "MainStack.h"
#include "lfs.h"
#include "LittleFsInterface.h"
#include "StatusError.h"
#define LOG_SIGN "ModelTask"
#define LOGGER env->logger
@ -91,7 +94,8 @@ void ModelTask_Init(
// InitThreadAtrStatic(&env->thread.attr, "ModelTask", env->thread.controlBlock, env->thread.stack, osPriorityNormal);
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;
}
@ -608,8 +612,36 @@ void InitWakeupModel(tModelTask *env) {
#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) {
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 (;;) {
if (GPIO_ReadPins((uint8_t) PORT_E, PORT_PIN_16)) {
@ -632,7 +664,8 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
//начало--------------------------------------------------ВХОД МОДЕЛИ ADC----------------------------------------------
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------------------------------------------------
@ -664,9 +697,12 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
//начало-------------------------------------------------ВХОД МОДЕЛИ SlEEP----------------------------------------------
memcpy((void *) &rtDW.CCU_STAT1_WAKEUP_MODEL, (void *) &CCU_STAT1_MODEL_SAVE, sizeof(CmdCAN_CCU_STAT1_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_STAT1_WAKEUP_MODEL, (void *) &CCU_STAT1_MODEL_SAVE,
sizeof(CmdCAN_CCU_STAT1_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));
//конец--------------------------------------------------ВХОД МОДЕЛИ SLEEP----------------------------------------------
@ -832,8 +868,10 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
//начало--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ PWM------------------------------------------
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->pwmRearIo.setActivePercent(env->pwms->pwmRearIo.env, model_Status_Pwm_For_Model_output.Pwm_Rear / 10);
env->pwms->pwmFrontIo.setActivePercent(env->pwms->pwmFrontIo.env,
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,
rtY.PWM_Get_f.pwmPercentFrontReserved);
env->pwms->pwmRearReservedIo.setActivePercent(env->pwms->pwmRearReservedIo.env,
@ -864,7 +902,11 @@ static _Noreturn void ModelTask_Thread(tModelTask *env) {
//начало--------------------------------------------------ВЫХОД МОДЕЛИ ДЛЯ DTC------------------------------------------
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-------------------------------------------
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) {
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_Rear = model_Status_Pwm_For_Model_output.Pwm_Rear / 10;
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_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_Rear = env->ccu_candb_dbg_tx.dbg_Logic_Blower.Logic_Blower_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_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_Incar, &rtY.dbgCAN_dbg_Sen_Incar_model, sizeof(env->ccu_candb_dbg_tx.dbg_Sen_Incar));
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_Logic_Ac, &rtY.dbg_Logic_Ac_model, sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Ac));
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_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_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_Incar, &rtY.dbgCAN_dbg_Sen_Incar_model,
sizeof(env->ccu_candb_dbg_tx.dbg_Sen_Incar));
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_Logic_Ac, &rtY.dbg_Logic_Ac_model,
sizeof(env->ccu_candb_dbg_tx.dbg_Logic_Ac));
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_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_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.I_FUL = 502 + 2048;

View File

@ -7,10 +7,143 @@
#include "StatusError.h"
#include "HVAC_model.h"
#include "SystemDelayInterface.h"
#include "lfs.h"
#include "lfs_file_utils.h"
#include "LittleFsInterface.h"
#define LOG_SIGN "DIAGNOSTIC"
#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) {
env->logger = logger;
@ -168,9 +301,10 @@ static bool isVINError(char *VIN) {
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) {
if (osMutexAcquire(env->access, 5000) == osOK) {
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);
@ -178,14 +312,131 @@ void set_Dtc_state(tDiagnostic *env, CCU_Errors_t *CCU_Errors, uint8_t *dtc_stat
// - VIN собран, но невалидный
// - ИЛИ таймаут (сообщение VIN вообще не приходит)
if (vin_error || vin_timeout) {
dtc_state_error_model[DTC_VIN_INVALID_CONFIG] = 1;
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] = 0;
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) {
for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) {
if (dtc_state_error_model[i]) {
dtc_state_error_model[i] = DTC_TEST_FAILED_CONFIRMED;
} else {
dtc_state_error_model[i] = dtc_state_error[i] & (~(DTC_TEST_FAILED));
}
}
setErrorDTC_CAN_VIN(dtc_state_error_model, CAN_ERROR_MISSLE, VIN, CCU_Errors);
setErrorDTC_CAN(dtc_state_error_model, CAN_ERROR_MISSLE);
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");
}
osMutexRelease(env->access);
} else {
LoggerErrorStatic(LOGGER, LOG_SIGN, "Access error set_Dtc_state_error");

View File

@ -8,7 +8,11 @@
#include <cmsis_os.h>
#include "LoggerInterface.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 {
uint8_t mask;
@ -25,8 +29,8 @@ typedef struct {
void Diagnostic_Init(tDiagnostic *env, tLoggerInterface *logger);
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_UDS_ReadDTCInformation_19_count(tDiagnostic *env, tDiagnosticDTC *diagnosticDTC);
uint32_t diagnostic_UDS_ReadDTCInformation_19_dtc(tDiagnostic *env, tDiagnosticDTC *diagnosticDTC);

View File

@ -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_FIX_error[COUNT_DTC_CODE_ERROR];
enum eDTC_Error_Code {
DTC_CCU_POWER_SUPPLY_VOLTAGE_OUT_OF_RANGE = 0, // 0xA0101C
DTC_IGNITION_VOLTAGE_OUT_OF_RANGE = 1, // 0xA0111C

View File

@ -28,8 +28,10 @@
},
{
"type": "local",
"dir": "./MODULES/FileSystemLittleFs"
},
{
"type": "local",
@ -492,6 +494,22 @@
"dir": "./MODULES/Adc"
},
{
"type": "local",
"dir": "./MODULES/FileSystemLittleFs"
},
{
"type": "local",
"dir": "./MODULES/HVAC_M7_LittleFs"
},
{
"type": "local",
"dir": "APP"