From 5fc669295655ec0eea7722aa4a48921dc6b700ec Mon Sep 17 00:00:00 2001 From: Minep Date: Sun, 24 Jul 2022 13:51:16 +0100 Subject: [PATCH] feat: twifs - pseudo file system for lunaix kernel state exposure feat: vfs_path_walk now capable to mkdir enroute, and handle malformed path. feat: mkdir, open and close file. feat: datetime to unix time conversion. fix: some design consideration. --- lunaix-os/.gitignore | 3 +- lunaix-os/includes/lunaix/clock.h | 21 ++- lunaix-os/includes/lunaix/ds/hstr.h | 6 +- lunaix-os/includes/lunaix/fs.h | 134 ++++++++++++++--- lunaix-os/includes/lunaix/fs/twifs.h | 24 +++ lunaix-os/includes/lunaix/spike.h | 3 + lunaix-os/kernel/fs/twifs.c | 153 +++++++++++++++++++ lunaix-os/kernel/fs/vfs.c | 212 ++++++++++++++++++++------- lunaix-os/kernel/time/clock.c | 47 +++--- 9 files changed, 504 insertions(+), 99 deletions(-) create mode 100644 lunaix-os/includes/lunaix/fs/twifs.h create mode 100644 lunaix-os/kernel/fs/twifs.c diff --git a/lunaix-os/.gitignore b/lunaix-os/.gitignore index 31aeefd..a54615d 100644 --- a/lunaix-os/.gitignore +++ b/lunaix-os/.gitignore @@ -5,4 +5,5 @@ playground/ .VSCodeCounter/ .idea bx_enh_dbg.ini -machine/ \ No newline at end of file +machine/ +draft/ \ No newline at end of file diff --git a/lunaix-os/includes/lunaix/clock.h b/lunaix-os/includes/lunaix/clock.h index dbfdfe5..44dfa04 100644 --- a/lunaix-os/includes/lunaix/clock.h +++ b/lunaix-os/includes/lunaix/clock.h @@ -7,7 +7,7 @@ typedef uint32_t time_t; typedef struct { - uint32_t year; // use int32 as we need to store the 4-digit year + uint32_t year; // use int32 as we need to store the 4-digit year uint8_t month; uint8_t day; uint8_t weekday; @@ -19,7 +19,7 @@ typedef struct void clock_init(); -void +void clock_walltime(datetime_t* datetime); int @@ -27,10 +27,21 @@ clock_datatime_eq(datetime_t* a, datetime_t* b); /** * @brief 返回当前系统时间,即自从开机到当前时刻的毫秒时。 - * - * @return time_t + * + * @return time_t */ -time_t +time_t clock_systime(); +time_t +clock_unixtime(); + +static inline time_t +clock_tounixtime(datetime_t* dt) +{ + return (dt->year - 1970) * 31556926u + (dt->month - 1) * 2629743u + + (dt->day - 1) * 86400u + (dt->hour - 1) * 3600u + + (dt->minute - 1) * 60u + dt->second; +} + #endif /* __LUNAIX_CLOCK_H */ diff --git a/lunaix-os/includes/lunaix/ds/hstr.h b/lunaix-os/includes/lunaix/ds/hstr.h index 4864052..5fb84d9 100644 --- a/lunaix-os/includes/lunaix/ds/hstr.h +++ b/lunaix-os/includes/lunaix/ds/hstr.h @@ -3,6 +3,8 @@ #include +#define HSTR_FULL_HASH 32 + struct hstr { unsigned int hash; @@ -13,9 +15,11 @@ struct hstr #define HSTR(str, length) \ (struct hstr) \ { \ - .len = length, .value = str \ + .len = (length), .value = (str) \ } +#define HSTR_EQ(str1, str2) ((str1)->hash == (str2)->hash) + inline void hstr_rehash(struct hstr* hash_str, unsigned int truncate_to) { diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index 8e34d81..0f8d0d5 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -8,6 +8,32 @@ #include #define VFS_NAME_MAXLEN 128 +#define VFS_MAX_FD 32 + +#define VFS_INODE_TYPE_DIR 0x1 +#define VFS_INODE_TYPE_FILE 0x2 +#define VFS_INODE_TYPE_DEVICE 0x4 + +#define VFS_ETOOLONG -1 +#define VFS_ENOFS -2 +#define VFS_EBADMNT -3 +#define VFS_ENODIR -4 +#define VFS_EENDOFDIR -5 +#define VFS_ENOTFOUND -6 +#define VFS_ENOOPS -7 +#define VFS_EINVLD -8 +#define VFS_EEOF -9 + +#define VFS_WALK_MKPARENT 0x1 +#define VFS_WALK_FSRELATIVE 0x2 +#define VFS_WALK_MKDIR 0x4 + +#define VFS_IOBUF_FDIRTY 0x1 + +#define VFS_VALID_CHAR(chr) \ + ('A' <= (chr) && (chr) <= 'Z' || 'a' <= (chr) && (chr) <= 'z' || \ + '0' <= (chr) && (chr) <= '9' || (chr) == '.' || (chr) == '_' || \ + (chr) == '-') struct v_dnode; @@ -26,6 +52,7 @@ struct v_superblock bdev_t dev; struct v_dnode* root; struct filesystem* fs; + uint32_t iobuf_size; struct { uint32_t (*read_capacity)(struct v_superblock* vsb); @@ -33,27 +60,39 @@ struct v_superblock } ops; }; +struct dir_context +{ + int index; + void* cb_data; + void (*read_complete_callback)(struct dir_context* dctx, + const char* name, + const int dtype); +}; + +struct v_file_ops +{ + int (*write)(struct v_file* file, void* buffer, size_t len); + int (*read)(struct v_file* file, void* buffer, size_t len); + int (*readdir)(struct v_file* file, struct dir_context* dctx); + int (*seek)(struct v_file* file, size_t offset); + int (*rename)(struct v_file* file, char* new_name); + int (*close)(struct v_file* file); + int (*sync)(struct v_file* file); +}; + struct v_file { struct v_inode* inode; - struct - { - void* data; - uint32_t size; - uint64_t lb_addr; - uint32_t offset; - int dirty; - } buffer; - struct - { - int (*write)(struct v_file* file, void* data_in, uint32_t size); - int (*read)(struct v_file* file, void* data_out, uint32_t size); - int (*readdir)(struct v_file* file, int dir_index); - int (*seek)(struct v_file* file, size_t offset); - int (*rename)(struct v_file* file, char* new_name); - int (*close)(struct v_file* file); - int (*sync)(struct v_file* file); - } ops; + struct llist_header* f_list; + uint32_t f_pos; + void* data; // 允许底层FS绑定他的一些专有数据 + struct v_file_ops ops; +}; + +struct v_fd +{ + struct v_file* file; + int pos; }; struct v_inode @@ -64,6 +103,7 @@ struct v_inode uint64_t lb_addr; uint32_t ref_count; uint32_t lb_usage; + void* data; // 允许底层FS绑定他的一些专有数据 struct { int (*open)(struct v_inode* inode, struct v_file* file); @@ -82,6 +122,15 @@ struct v_dnode struct llist_header children; struct llist_header siblings; struct v_superblock* super_block; + struct + { + void (*destruct)(struct v_dnode* dnode); + } ops; +}; + +struct v_fdtable +{ + struct v_fd* fds[VFS_MAX_FD]; }; /* --- file system manager --- */ @@ -94,4 +143,53 @@ fsm_register(struct filesystem* fs); struct filesystem* fsm_get(const char* fs_name); +struct v_dnode* +vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str); + +void +vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode); + +int +vfs_walk(struct v_dnode* start, + const char* path, + struct v_dnode** dentry, + int walk_options); + +int +vfs_mount(const char* fs_name, bdev_t device, struct v_dnode* mnt_point); + +int +vfs_unmount(struct v_dnode* mnt_point); + +int +vfs_mkdir(const char* parent_path, + const char* component, + struct v_dnode** dentry); + +int +vfs_open(struct v_dnode* dnode, struct v_file** file); + +int +vfs_close(struct v_file* file); + +int +vfs_fsync(struct v_file* file); + +struct v_superblock* +vfs_sb_alloc(); + +void +vfs_sb_free(struct v_superblock* sb); + +struct v_dnode* +vfs_d_alloc(); + +void +vfs_d_free(struct v_dnode* dnode); + +struct v_inode* +vfs_i_alloc(); + +void +vfs_i_free(struct v_inode* inode); #endif /* __LUNAIX_VFS_H */ diff --git a/lunaix-os/includes/lunaix/fs/twifs.h b/lunaix-os/includes/lunaix/fs/twifs.h new file mode 100644 index 0000000..48b35b9 --- /dev/null +++ b/lunaix-os/includes/lunaix/fs/twifs.h @@ -0,0 +1,24 @@ +#ifndef __LUNAIX_TWIFS_H +#define __LUNAIX_TWIFS_H + +#include + +struct twifs_node +{ + struct hstr name; + uint32_t itype; + struct llist_header children; + struct llist_header siblings; + struct v_file_ops fops; +}; + +void +twifs_init(); + +struct twifs_node* +twifs_child_node(struct twifs_node* parent, const char* name, int name_len); + +struct twifs_node* +twifs_toplevel_node(const char* name, int name_len); + +#endif /* __LUNAIX_TWIFS_H */ diff --git a/lunaix-os/includes/lunaix/spike.h b/lunaix-os/includes/lunaix/spike.h index 777a457..8297f0e 100644 --- a/lunaix-os/includes/lunaix/spike.h +++ b/lunaix-os/includes/lunaix/spike.h @@ -17,6 +17,9 @@ // 获取v最近的最小k倍数 #define ROUNDDOWN(v, k) ((v) & ~((k)-1)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define __USER__ __attribute__((section(".usrtext"))) inline static void diff --git a/lunaix-os/kernel/fs/twifs.c b/lunaix-os/kernel/fs/twifs.c new file mode 100644 index 0000000..d24b6a0 --- /dev/null +++ b/lunaix-os/kernel/fs/twifs.c @@ -0,0 +1,153 @@ +/** + * @file twifs.c + * @author Lunaixsky (zelong56@gmail.com) + * @brief TwiFS - A pseudo file system for kernel state exposure. + * @version 0.1 + * @date 2022-07-21 + * + * @copyright Copyright (c) 2022 + * + */ +#include +#include +#include +#include +#include +#include + +static struct twifs_node fs_root; + +static struct cake_pile* twi_pile; + +int +__twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode); + +int +__twifs_openfile(struct v_inode* inode, struct v_file* file); + +struct twifs_node* +__twifs_get_node(struct twifs_node* parent, struct hstr* name); + +void +twifs_init() +{ + twi_pile = cake_new_pile("twifs_node", sizeof(struct twifs_node), 1, 0); + + struct filesystem* twifs = vzalloc(sizeof(struct filesystem)); + twifs->fs_name = HSTR("twifs", 5); + twifs->mount = __twifs_mount; + + fsm_register(twifs); + + memset(&fs_root, 0, sizeof(fs_root)); + llist_init_head(&fs_root.children); + + // 预备一些常用的类别 + twifs_toplevel_node("kernel", 6); + twifs_toplevel_node("dev", 3); + twifs_toplevel_node("bus", 3); +} + +struct twifs_node* +twifs_child_node(struct twifs_node* parent, const char* name, int name_len) +{ + struct hstr hname = HSTR(name, name_len); + hstr_rehash(&hname, HSTR_FULL_HASH); + + struct twifs_node* node = __twifs_get_node(parent, &hname); + if (node) { + return node; + } + + node = cake_grab(twi_pile); + memset(node, 0, sizeof(*node)); + + node->name = hname; + llist_init_head(&node->children); + llist_append(&parent->children, &node->siblings); + + return node; +} + +struct twifs_node* +twifs_toplevel_node(const char* name, int name_len) +{ + return twifs_child_node(&fs_root, name, name_len); +} + +void +__twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point) +{ + mount_point->inode = __twifs_create_inode(&fs_root); +} + +struct v_inode* +__twifs_create_inode(struct twifs_node* twi_node) +{ + struct v_inode* inode = vfs_i_alloc(); + *inode = (struct v_inode){ .ctime = 0, + .itype = twi_node->itype, + .lb_addr = 0, + .lb_usage = 0, + .data = twi_node, + .mtime = 0, + .ref_count = 0 }; + inode->ops.dir_lookup = __twifs_dirlookup; + inode->ops.open = __twifs_openfile; +} + +struct twifs_node* +__twifs_get_node(struct twifs_node* parent, struct hstr* name) +{ + struct twifs_node *pos, *n; + llist_for_each(pos, n, &parent->children, siblings) + { + if (HSTR_EQ(&pos->name, name)) { + return pos; + } + } + return NULL; +} + +int +__twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode) +{ + struct twifs_node* twi_node = (struct twifs_node*)inode->data; + + struct twifs_node* child_node = __twifs_get_node(twi_node, &dnode->name); + if (child_node) { + dnode->inode = __twifs_create_inode(child_node); + return 0; + } + return VFS_ENODIR; +} + +int +__twifs_iterate_dir(struct v_file* file, struct dir_context* dctx) +{ + struct twifs_node* twi_node = (struct twifs_node*)(file->inode->data); + int counter = 0; + struct twifs_node *pos, *n; + + llist_for_each(pos, n, &twi_node->children, siblings) + { + if (counter++ >= dctx->index) { + dctx->index = counter; + dctx->read_complete_callback(dctx, pos->name.value, pos->itype); + return 0; + } + } + + return VFS_EENDOFDIR; +} + +int +__twifs_openfile(struct v_inode* inode, struct v_file* file) +{ + struct twifs_node* twi_node = (struct twifs_node*)inode->data; + if (twi_node) { + file->ops = twi_node->fops; + return 1; + } + return 0; +} diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 09539c9..4640dbd 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #define PATH_DELIM '/' #define DNODE_HASHTABLE_BITS 10 @@ -9,13 +11,10 @@ #define DNODE_HASH_MASK (DNODE_HASHTABLE_SIZE - 1) #define DNODE_HASHBITS (32 - DNODE_HASHTABLE_BITS) -#define VFS_ETOOLONG -1 -#define VFS_ENOFS -2 - static struct cake_pile* dnode_pile; static struct cake_pile* inode_pile; +static struct cake_pile* file_pile; static struct cake_pile* superblock_pile; -static struct cake_pile* name_pile; static struct v_superblock* root_sb; static struct hbucket* dnode_cache; @@ -23,32 +22,32 @@ static struct hbucket* dnode_cache; static int fs_id = 0; struct v_dnode* -__new_dnode(); +vfs_d_alloc(); void -__free_dnode(struct v_dnode* dnode); +vfs_d_free(struct v_dnode* dnode); struct v_superblock* -__new_superblock(); +vfs_sb_alloc(); void -__free_superblock(struct v_superblock* sb); +vfs_sb_free(struct v_superblock* sb); void vfs_init() { - // 为他们专门创建一个蛋糕堆,而不使用valloc,这样我们可以最小化内部碎片的产生 - dnode_pile = cake_new_pile("dnode", sizeof(struct v_dnode), 1, 0); - inode_pile = cake_new_pile("inode", sizeof(struct v_inode), 1, 0); - name_pile = cake_new_pile("dname", VFS_NAME_MAXLEN, 1, 0); + // 为他们专门创建一个蛋糕堆,而不使用valloc,这样我们可以最小化内碎片的产生 + dnode_pile = cake_new_pile("dnode_cache", sizeof(struct v_dnode), 1, 0); + inode_pile = cake_new_pile("inode_cache", sizeof(struct v_inode), 1, 0); + inode_pile = cake_new_pile("file_cache", sizeof(struct v_file), 1, 0); superblock_pile = - cake_new_pile("superblock", sizeof(struct v_superblock), 1, 0); + cake_new_pile("sb_cache", sizeof(struct v_superblock), 1, 0); dnode_cache = valloc(DNODE_HASHTABLE_SIZE * sizeof(struct hbucket)); // 挂载Lunaix的根文件系统,TwiFS! struct filesystem* rootfs = fsm_get("twifs"); - root_sb = __new_superblock(); + root_sb = vfs_sb_alloc(); rootfs->mount(root_sb, NULL); } @@ -85,13 +84,20 @@ vfs_dcache_add(struct v_dnode* parent, struct v_dnode* dnode) } int -vfs_walk(struct v_dnode* start, const char* path, struct v_dnode** dentry) +vfs_walk(struct v_dnode* start, + const char* path, + struct v_dnode** dentry, + int walk_options) { int errno = 0; int i = 0, j = 0; if (path[0] == PATH_DELIM) { - start = start->super_block->root; + if ((walk_options & VFS_WALK_FSRELATIVE)) { + start = start->super_block->root; + } else { + start = root_sb->root; + } i++; } @@ -101,34 +107,59 @@ vfs_walk(struct v_dnode* start, const char* path, struct v_dnode** dentry) char name_content[VFS_NAME_MAXLEN]; struct hstr name = HSTR(name_content, 0); - char current, lookahead; - do { - current = path[i++]; + char current = path[i++], lookahead; + while (current) { lookahead = path[i++]; if (current != PATH_DELIM) { if (j >= VFS_NAME_MAXLEN - 1) { - errno = VFS_ETOOLONG; - goto error; + return VFS_ETOOLONG; + } + if (!VFS_VALID_CHAR(current)) { + return VFS_EINVLD; } name_content[j++] = current; if (lookahead) { - continue; + goto cont; } } + // handling cases like /^.*(\/+).*$/ + if (lookahead == PATH_DELIM) { + goto cont; + } + name_content[j] = 0; - hstr_rehash(&name, 32); + hstr_rehash(&name, HSTR_FULL_HASH); dnode = vfs_dcache_lookup(current_level, &name); if (!dnode) { - dnode = __new_dnode(); - strcpy(dnode->name.value, name_content); + dnode = vfs_d_alloc(); + dnode->name = HSTR(valloc(VFS_NAME_MAXLEN), j); dnode->name.hash = name.hash; - dnode->name.len = j; - if ((errno = - dnode->inode->ops.dir_lookup(current_level->inode, dnode))) { + strcpy(dnode->name.value, name_content); + + errno = + current_level->inode->ops.dir_lookup(current_level->inode, dnode); + + if (errno == VFS_ENOTFOUND && + ((walk_options & VFS_WALK_MKPARENT) || + ((walk_options & VFS_WALK_MKDIR) && !lookahead))) { + /* + 两种创建文件夹的情况: + 1) VFS_WALK_MKPARENT:沿路创建所有不存在的文件夹 + 2) VFS_WALK_MKDIR:仅创建路径最后一级的不存在文件夹 + */ + if (!current_level->inode->ops.mkdir) { + errno = VFS_ENOOPS; + } else { + errno = current_level->inode->ops.mkdir( + current_level->inode, dnode); + } + } + + if (errno) { goto error; } @@ -140,13 +171,16 @@ vfs_walk(struct v_dnode* start, const char* path, struct v_dnode** dentry) j = 0; current_level = dnode; - } while (lookahead); + cont: + current = lookahead; + }; - *dentry = dnode; + *dentry = current_level; return 0; error: - __free_dnode(dnode); + vfree(dnode->name.value); + vfs_d_free(dnode); return errno; } @@ -156,13 +190,15 @@ vfs_mount(const char* fs_name, bdev_t device, struct v_dnode* mnt_point) struct filesystem* fs = fsm_get(fs_name); if (!fs) return VFS_ENOFS; - struct v_superblock* sb = __new_superblock(); + struct v_superblock* sb = vfs_sb_alloc(); sb->dev = device; sb->fs_id = fs_id++; int errno = 0; if (!(errno = fs->mount(sb, mnt_point))) { sb->fs = fs; + sb->root = mnt_point; + mnt_point->super_block = sb; llist_append(&root_sb->sb_list, &sb->sb_list); } @@ -170,52 +206,118 @@ vfs_mount(const char* fs_name, bdev_t device, struct v_dnode* mnt_point) } int -vfs_unmount(const int fs_id) +vfs_mkdir(const char* parent_path, + const char* component, + struct v_dnode** dentry) +{ + return vfs_walk(root_sb->root, parent_path, dentry, VFS_WALK_MKDIR); +} + +int +vfs_unmount(struct v_dnode* mnt_point) { int errno = 0; - struct v_superblock *pos, *n; - llist_for_each(pos, n, &root_sb->sb_list, sb_list) - { - if (pos->fs_id != fs_id) { - continue; - } - if (!(errno = pos->fs->unmount(pos))) { - llist_delete(&pos->sb_list); - __free_superblock(pos); - } - break; + struct v_superblock* sb = mnt_point->super_block; + if (!sb) { + return VFS_EBADMNT; + } + if (!(errno = sb->fs->unmount(sb))) { + struct v_dnode* fs_root = sb->root; + llist_delete(&fs_root->siblings); + llist_delete(&sb->sb_list); + vfs_sb_free(sb); + } + return errno; +} + +int +vfs_open(struct v_dnode* dnode, struct v_file** file) +{ + if (!dnode->inode || !dnode->inode->ops.open) { + return VFS_ENOOPS; + } + + struct v_file* vfile = cake_grab(file_pile); + memset(vfile, 0, sizeof(*vfile)); + + int errno = dnode->inode->ops.open(dnode->inode, vfile); + if (errno) { + cake_release(file_pile, vfile); + } else { + *file = vfile; + } + return errno; +} + +int +vfs_close(struct v_file* file) +{ + if (!file->ops.close) { + return VFS_ENOOPS; + } + + int errno = file->ops.close(file); + if (!errno) { + cake_release(file_pile, file); + } + return errno; +} + +int +vfs_fsync(struct v_file* file) +{ + int errno = VFS_ENOOPS; + if (file->ops.sync) { + errno = file->ops.sync(file); + } + if (!errno && file->inode->ops.sync) { + return file->inode->ops.sync(file->inode); } return errno; } struct v_superblock* -__new_superblock() +vfs_sb_alloc() { struct v_superblock* sb = cake_grab(superblock_pile); memset(sb, 0, sizeof(*sb)); llist_init_head(&sb->sb_list); - sb->root = __new_dnode(); + return sb; } void -__free_superblock(struct v_superblock* sb) +vfs_sb_free(struct v_superblock* sb) { - __free_dnode(sb->root); cake_release(superblock_pile, sb); } struct v_dnode* -__new_dnode() +vfs_d_alloc() { struct v_dnode* dnode = cake_grab(dnode_pile); - dnode->inode = cake_grab(inode_pile); - dnode->name.value = cake_grab(name_pile); + llist_init_head(&dnode->children); } void -__free_dnode(struct v_dnode* dnode) +vfs_d_free(struct v_dnode* dnode) { - cake_release(inode_pile, dnode->inode); - cake_release(name_pile, dnode->name.value); + if (dnode->ops.destruct) { + dnode->ops.destruct(dnode); + } cake_release(dnode_pile, dnode); -} \ No newline at end of file +} + +struct v_inode* +vfs_i_alloc() +{ + struct v_inode* inode = cake_grab(inode_pile); + memset(inode, 0, sizeof(*inode)); + + return inode; +} + +void +vfs_i_free(struct v_inode* inode) +{ + cake_release(inode_pile, inode); +} diff --git a/lunaix-os/kernel/time/clock.c b/lunaix-os/kernel/time/clock.c index e862f79..15a6a32 100644 --- a/lunaix-os/kernel/time/clock.c +++ b/lunaix-os/kernel/time/clock.c @@ -1,33 +1,35 @@ -#include -#include #include +#include #include +#include static volatile time_t sys_time; -void clock_systime_counter(void* arg); +void +clock_systime_counter(void* arg); void -clock_init() { +clock_init() +{ if (!timer_context()) { panick("Systimer not initialized"); } - + // 系统计时器每毫秒累加。 timer_run_ms(1, clock_systime_counter, NULL, TIMER_MODE_PERIODIC); } -void clock_systime_counter(void* arg) { +void +clock_systime_counter(void* arg) +{ sys_time++; } int -clock_datatime_eq(datetime_t* a, datetime_t* b) { - return a->year == b->year && - a->month == b->month && - a->day == b->day && - a->weekday == b->weekday && - a->minute == b->minute && +clock_datatime_eq(datetime_t* a, datetime_t* b) +{ + return a->year == b->year && a->month == b->month && a->day == b->day && + a->weekday == b->weekday && a->minute == b->minute && a->second == b->second; } @@ -35,10 +37,10 @@ void clock_walltime(datetime_t* datetime) { datetime_t current; - - do - { - while (rtc_read_reg(RTC_REG_A) & 0x80); + + do { + while (rtc_read_reg(RTC_REG_A) & 0x80) + ; memcpy(¤t, datetime, sizeof(datetime_t)); datetime->year = rtc_read_reg(RTC_REG_YRS); @@ -62,7 +64,6 @@ clock_walltime(datetime_t* datetime) datetime->second = bcd2dec(datetime->second); } - // To 24 hour format if (!RTC_24HRS_ENCODED(regbv) && (datetime->hour >> 7)) { datetime->hour = (12 + datetime->hour & 0x80); @@ -71,8 +72,16 @@ clock_walltime(datetime_t* datetime) datetime->year += RTC_CURRENT_CENTRY * 100; } +time_t +clock_unixtime() +{ + datetime_t dt; + clock_walltime(&dt); + return clock_tounixtime(&dt); +} -time_t -clock_systime() { +time_t +clock_systime() +{ return sys_time; } \ No newline at end of file -- 2.27.0