mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 02:58:26 +08:00
add aworkslp
This commit is contained in:
parent
96bca37bcc
commit
cef0c50276
@ -1,5 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2021/12/23
|
||||
* 增加aworkslp平台支持(感谢林福提供补丁)
|
||||
|
||||
2021/12/22
|
||||
* 复原被覆盖的tools/idl\_gen/README.md(感谢雨欣提供补丁)
|
||||
* 增加tkc/sha256.h
|
||||
|
142
src/platforms/aworkslp/awtk_config.h
Normal file
142
src/platforms/aworkslp/awtk_config.h
Normal file
@ -0,0 +1,142 @@
|
||||
|
||||
/**
|
||||
* File: awtk_config.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: config
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-09-12 Li XianJing <xianjimli@hotmail.com> created
|
||||
*/
|
||||
|
||||
#ifndef AWTK_CONFIG_H
|
||||
#define AWTK_CONFIG_H
|
||||
|
||||
#define WITH_SOCKET 1
|
||||
|
||||
#ifndef __AWORKS_LP__
|
||||
#define __AWORKS_LP__
|
||||
#endif
|
||||
|
||||
#ifndef AWORKS
|
||||
#define AWORKS
|
||||
#endif
|
||||
|
||||
#ifndef AXIO_AWORKS
|
||||
#define AXIO_AWORKS
|
||||
#endif
|
||||
|
||||
extern int aw_kprintf(const char* fmt, ...);
|
||||
#define log_impl(format, args...) aw_kprintf(format, ##args)
|
||||
|
||||
/**
|
||||
* 如果出现wcsxxx之类的函数没有定义时,请定义该宏
|
||||
*
|
||||
* #define WITH_WCSXXX 1
|
||||
*/
|
||||
// #define WITH_WCSXXX 1
|
||||
|
||||
/**
|
||||
* 如果需要配置文件或者使用data_reader/data_writer,请定义本宏。
|
||||
*
|
||||
* #define WITH_DATA_READER_WRITER 1
|
||||
*/
|
||||
#define WITH_DATA_READER_WRITER 1
|
||||
|
||||
/**
|
||||
* 如果不需输入法,请定义本宏
|
||||
*
|
||||
* #define WITH_NULL_IM 1
|
||||
*/
|
||||
#define WITH_NULL_IM 1
|
||||
|
||||
/**
|
||||
* 嵌入式系统有自己的main函数时,请定义本宏。
|
||||
*
|
||||
*/
|
||||
#define USE_GUI_MAIN 1
|
||||
|
||||
/**
|
||||
* 如果支持png/jpeg图片,请定义本宏
|
||||
*
|
||||
*/
|
||||
// #define WITH_STB_IMAGE 1
|
||||
|
||||
/**
|
||||
* 如果支持Truetype字体,请定义本宏
|
||||
*
|
||||
*/
|
||||
// #define WITH_STB_FONT 1
|
||||
|
||||
/**
|
||||
* 如果定义本宏,使用标准的UNICODE换行算法,除非资源极为有限,请定义本宏。
|
||||
*
|
||||
*/
|
||||
// #define WITH_UNICODE_BREAK 1
|
||||
|
||||
/**
|
||||
* 如果定义本宏,将图片解码成BGRA8888格式,否则解码成RGBA8888的格式。
|
||||
*
|
||||
*/
|
||||
// #define WITH_BITMAP_BGRA 1
|
||||
|
||||
/**
|
||||
* 如果定义本宏,将不透明的PNG图片解码成BGR565格式,建议定义。
|
||||
*
|
||||
*/
|
||||
// #define WITH_BITMAP_BGR565 1
|
||||
|
||||
/**
|
||||
* 如果有优化版本的memcpy函数,请定义本宏
|
||||
*
|
||||
*/
|
||||
#define HAS_FAST_MEMCPY 1
|
||||
|
||||
/**
|
||||
* 如果系统有标准的malloc函数,请定义本宏
|
||||
*
|
||||
*/
|
||||
#define HAS_STD_MALLOC 1
|
||||
|
||||
/**
|
||||
* 如果启用NXP PXP硬件加速,请定义本宏
|
||||
*
|
||||
*/
|
||||
// #define WITH_PXP_G2D 1
|
||||
|
||||
/**
|
||||
* 如果启用三缓冲模式,请定义本宏,否则默认使用双缓冲模式
|
||||
*
|
||||
* 注意:如果使用 tk_set_lcd_orientation 旋转屏幕,则应该注释该行,
|
||||
* 使用默认的双缓冲机制,否则窗口动画可能有花屏现象
|
||||
*/
|
||||
// #define WITH_THREE_FB 1
|
||||
|
||||
/**
|
||||
* 如果启用VGCANVAS,而且没有OpenGL硬件加速,请定义本宏
|
||||
*
|
||||
*/
|
||||
// #define WITH_NANOVG_AGGE 1
|
||||
|
||||
/**
|
||||
* 按新awtk加入pinyin输入法开关
|
||||
* 并关闭联想输入法,避免编译超出RT1052-AWorks上的代码段4088K
|
||||
*
|
||||
*/
|
||||
// #define WITH_IME_PINYIN 1
|
||||
// #define WITHOUT_SUGGEST_WORDS 1
|
||||
|
||||
#ifndef __BUILDING_AWTK_LIB__
|
||||
#endif // __BUILDING_AWTK_LIB__
|
||||
|
||||
#endif /*AWTK_CONFIG_H*/
|
550
src/platforms/aworkslp/fs_aworks.c
Normal file
550
src/platforms/aworkslp/fs_aworks.c
Normal file
@ -0,0 +1,550 @@
|
||||
/**
|
||||
* File: mutex.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mutex
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "aworks.h"
|
||||
#include "aw_mount.h"
|
||||
#include "aw_unistd.h"
|
||||
#include "aw_fcntl.h"
|
||||
#include "aw_fs_type.h"
|
||||
#include "aw_dirent.h"
|
||||
#include "aw_stat.h"
|
||||
#include "aw_ioctl.h"
|
||||
#include "aw_stropts.h"
|
||||
#include "aw_fs_type.h"
|
||||
|
||||
#include "tkc/fs.h"
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/path.h"
|
||||
#include "tkc/utils.h"
|
||||
|
||||
#ifndef tk_log_info_lf
|
||||
#define tk_log_info_lf(fmt, args...)
|
||||
#define tk_log_info_htlf(header, fmt, args...)
|
||||
#endif
|
||||
|
||||
#ifndef TKC_FS_EXE_PATH
|
||||
#define TKC_FS_EXE_PATH "/lfs/bin/app/"
|
||||
#endif
|
||||
|
||||
#ifndef TKC_FS_TEMP_PATH
|
||||
#define TKC_FS_TEMP_PATH "/lfs/tmp/"
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 文件操作 */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static int32_t fs_os_file_read(fs_file_t* file, void* buffer, uint32_t size) {
|
||||
return_value_if_fail(file, -1);
|
||||
int fd = (int)(file->data);
|
||||
|
||||
return (int32_t)aw_read(fd, buffer, size);
|
||||
}
|
||||
|
||||
static int32_t fs_os_file_write(fs_file_t* file, const void* buffer, uint32_t size) {
|
||||
return_value_if_fail(file, -1);
|
||||
int fd = (int)(file->data);
|
||||
|
||||
return aw_write(fd, buffer, size);
|
||||
}
|
||||
|
||||
static ret_t fs_os_file_seek(fs_file_t* file, int32_t offset) {
|
||||
return_value_if_fail(file, RET_BAD_PARAMS);
|
||||
int fd = (int)(file->data);
|
||||
|
||||
return aw_lseek(fd, offset, AW_SEEK_SET) >= 0 ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t fs_os_file_truncate(fs_file_t* file, int32_t size) {
|
||||
return_value_if_fail(file, RET_BAD_PARAMS);
|
||||
int fd = (int)(file->data);
|
||||
|
||||
return aw_ftruncate(fd, size) == AW_OK ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t fs_os_file_sync(fs_file_t* file) {
|
||||
return_value_if_fail(file, RET_BAD_PARAMS);
|
||||
int fd = (int)(file->data);
|
||||
return aw_fsync(fd) == AW_OK ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t fs_os_file_close(fs_file_t* file) {
|
||||
return_value_if_fail(file, RET_BAD_PARAMS);
|
||||
int fd = (int)(file->data);
|
||||
|
||||
aw_close(fd);
|
||||
TKMEM_FREE(file);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
static ret_t fs_os_file_stat(fs_file_t* file, fs_stat_info_t* fst) {
|
||||
return_value_if_fail(file && fst, RET_FAIL);
|
||||
struct aw_stat st;
|
||||
int fd = (int)(file->data);
|
||||
return_value_if_fail(aw_fstat(fd, &st) == AW_OK, -1);
|
||||
|
||||
memset(fst, 0, sizeof(*fst));
|
||||
fst->mode = st.st_mode;
|
||||
fst->size = st.st_size;
|
||||
fst->dev = st.st_dev;
|
||||
fst->rdev = st.st_rdev;
|
||||
|
||||
fst->dev = st.st_dev;
|
||||
fst->ino = st.st_ino;
|
||||
fst->mode = st.st_mode;
|
||||
fst->nlink = st.st_nlink;
|
||||
fst->uid = st.st_uid;
|
||||
fst->gid = st.st_gid;
|
||||
fst->rdev = st.st_rdev;
|
||||
fst->size = st.st_size;
|
||||
|
||||
fst->is_dir = AW_S_ISDIR(st.st_mode);
|
||||
fst->is_reg_file = AW_S_ISREG(st.st_mode);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const fs_file_vtable_t s_fs_file_vtable_t = {.read = fs_os_file_read,
|
||||
.write = fs_os_file_write,
|
||||
.seek = fs_os_file_seek,
|
||||
.truncate = fs_os_file_truncate,
|
||||
.stat = fs_os_file_stat,
|
||||
.sync = fs_os_file_sync,
|
||||
.close = fs_os_file_close};
|
||||
|
||||
static fs_file_t* fs_file_create(int fd) {
|
||||
fs_file_t* f = NULL;
|
||||
return_value_if_fail(fd >= 0, NULL);
|
||||
|
||||
f = TKMEM_ZALLOC(fs_file_t);
|
||||
if (f != NULL) {
|
||||
f->vt = &s_fs_file_vtable_t;
|
||||
f->data = (void*)fd;
|
||||
} else {
|
||||
aw_close(fd);
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
#if TKC_SAVE_FIRMWARE_BY_BL
|
||||
|
||||
static int32_t fs_bl_firmware_read(fs_file_t* file, void* buffer, uint32_t size) {
|
||||
return_value_if_fail(!"not support!", -1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t fs_bl_firmware_write(fs_file_t* file, const void* buffer, uint32_t size) {
|
||||
return BL_AppUpdateProcess(buffer, size);
|
||||
}
|
||||
|
||||
static ret_t fs_bl_firmware_seek(fs_file_t* file, int32_t offset) {
|
||||
return_value_if_fail(!"not support!", RET_NOT_IMPL);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fs_bl_firmware_truncate(fs_file_t* file, int32_t size) {
|
||||
return_value_if_fail(!"not support!", -1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ret_t fs_bl_firmware_sync(fs_file_t* file) {
|
||||
return_value_if_fail(!"not support!", -1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ret_t fs_bl_firmware_close(fs_file_t* file) {
|
||||
return_value_if_fail(BL_AppUpdateEnd() == 0, RET_FAIL);
|
||||
TKMEM_FREE(file);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fs_bl_firmware_stat(fs_file_t* file, fs_stat_info_t* fst) {
|
||||
return_value_if_fail(!"not support!", -1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const fs_file_vtable_t s_fs_bl_firmware_vtable_t = {
|
||||
.read = fs_bl_firmware_read,
|
||||
.write = fs_bl_firmware_write,
|
||||
.seek = fs_bl_firmware_seek,
|
||||
.truncate = fs_bl_firmware_truncate,
|
||||
.stat = fs_bl_firmware_stat,
|
||||
.sync = fs_bl_firmware_sync,
|
||||
.close = fs_bl_firmware_close,
|
||||
};
|
||||
|
||||
static fs_file_t* fs_bl_firmware_create(void) {
|
||||
fs_file_t* f = NULL;
|
||||
int ret;
|
||||
|
||||
f = TKMEM_ZALLOC(fs_file_t);
|
||||
if (f != NULL) {
|
||||
f->vt = &s_fs_bl_firmware_vtable_t;
|
||||
f->data = NULL;
|
||||
ret = BL_AppUpdateStart(TKC_FIRMWARE_PATH);
|
||||
if (ret != 0) {
|
||||
TKMEM_FREE(f);
|
||||
return_value_if_fail(!"BL_AppUpdateStart() failed", NULL);
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
#endif /* TKC_SAVE_FIRMWARE_BY_BL */
|
||||
|
||||
static fs_file_t* fs_os_open_file(fs_t* fs, const char* name, const char* mode) {
|
||||
(void)fs;
|
||||
return_value_if_fail(name && mode, NULL);
|
||||
int oflag = 0;
|
||||
fs_file_t* file;
|
||||
|
||||
if (strchr(mode, '+')) {
|
||||
if (strchr(mode, 'r')) {
|
||||
oflag |= AW_O_RDWR;
|
||||
} else if (strchr(mode, 'w')) {
|
||||
oflag |= AW_O_RDWR | AW_O_CREAT | AW_O_TRUNC;
|
||||
} else if (strchr(mode, 'a')) {
|
||||
#if 0
|
||||
oflag |= AW_O_RDWR | AW_O_CREAT | AW_O_APPEND;
|
||||
#else
|
||||
/* lfs bug:带有 APPEND 标志,则每次写都从文件尾开始写,seek 就无效了,因此这里不带 append 标志,创建完后再 seek 一次 */
|
||||
oflag |= AW_O_RDWR | AW_O_CREAT;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (strchr(mode, 'r')) {
|
||||
oflag |= AW_O_RDONLY;
|
||||
} else if (strchr(mode, 'w')) {
|
||||
oflag |= AW_O_WRONLY | AW_O_CREAT | AW_O_TRUNC;
|
||||
} else if (strchr(mode, 'a')) {
|
||||
#if 0
|
||||
oflag |= AW_O_RDWR | AW_O_CREAT | AW_O_APPEND;
|
||||
#else
|
||||
/* lfs bug:带有 APPEND 标志,则每次写都从文件尾开始写,seek 就无效了,因此这里不带 append 标志,创建完后再 seek 一次 */
|
||||
oflag |= AW_O_RDWR | AW_O_CREAT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if TKC_SAVE_FIRMWARE_BY_BL
|
||||
if (tk_str_eq(TKC_FIRMWARE_PATH, name)) {
|
||||
file = fs_bl_firmware_create();
|
||||
}
|
||||
return file;
|
||||
#endif /* TKC_SAVE_FIRMWARE_BY_BL */
|
||||
|
||||
file = fs_file_create(aw_open(name, oflag, 0777));
|
||||
if (file) {
|
||||
if (strchr(mode, 'a')) {
|
||||
int fd = (int)(file->data);
|
||||
aw_lseek(fd, 0, AW_SEEK_END);
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
static ret_t fs_os_remove_file(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
return_value_if_fail(name, RET_BAD_PARAMS);
|
||||
|
||||
return aw_unlink(name) == AW_OK ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
static bool_t fs_os_file_exist(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
return_value_if_fail(name, FALSE);
|
||||
|
||||
struct aw_stat st;
|
||||
return (aw_stat(name, &st) == 0 && AW_S_ISREG(st.st_mode));
|
||||
}
|
||||
|
||||
static bool_t fs_os_file_rename(fs_t* fs, const char* name, const char* new_name) {
|
||||
(void)fs;
|
||||
return_value_if_fail(name && new_name, FALSE);
|
||||
|
||||
return (aw_rename(name, new_name) == AW_OK);
|
||||
}
|
||||
|
||||
static ret_t fs_os_stat(fs_t* fs, const char* name, fs_stat_info_t* fst) {
|
||||
struct aw_stat st;
|
||||
return_value_if_fail(fs && fst && name, RET_FAIL);
|
||||
return_value_if_fail(aw_stat(name, &st) == AW_OK, -1);
|
||||
|
||||
memset(fst, 0, sizeof(*fst));
|
||||
fst->mode = st.st_mode;
|
||||
fst->size = st.st_size;
|
||||
fst->dev = st.st_dev;
|
||||
fst->rdev = st.st_rdev;
|
||||
|
||||
fst->dev = st.st_dev;
|
||||
fst->ino = st.st_ino;
|
||||
fst->mode = st.st_mode;
|
||||
fst->nlink = st.st_nlink;
|
||||
fst->uid = st.st_uid;
|
||||
fst->gid = st.st_gid;
|
||||
fst->rdev = st.st_rdev;
|
||||
fst->size = st.st_size;
|
||||
|
||||
fst->is_dir = AW_S_ISDIR(st.st_mode);
|
||||
fst->is_reg_file = AW_S_ISREG(st.st_mode);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 文件夹操作 */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
struct fs_dir_ex {
|
||||
fs_dir_t dir;
|
||||
char dir_name[MAX_PATH + 1];
|
||||
};
|
||||
|
||||
static ret_t fs_os_dir_read(fs_dir_t* dir, fs_item_t* item) {
|
||||
return_value_if_fail(dir && dir->data && item, RET_BAD_PARAMS);
|
||||
char item_path[MAX_PATH];
|
||||
struct aw_dirent* entry;
|
||||
struct aw_dir* d = (struct aw_dir*)(dir->data);
|
||||
return_value_if_fail(aw_readdir(d, &entry) == AW_OK, RET_FAIL);
|
||||
|
||||
memset(item, 0x00, sizeof(fs_item_t));
|
||||
if (entry != NULL) {
|
||||
item_path[0] = '\0';
|
||||
strncat(item_path, ((struct fs_dir_ex*)dir)->dir_name, MAX_PATH);
|
||||
strncat(item_path, "/", MAX_PATH);
|
||||
strncat(item_path, entry->d_name, MAX_PATH);
|
||||
|
||||
struct aw_stat st;
|
||||
return_value_if_fail(aw_stat(item_path, &st) == AW_OK, RET_FAIL);
|
||||
|
||||
item->is_dir = AW_S_ISDIR(st.st_mode);
|
||||
item->is_reg_file = AW_S_ISREG(st.st_mode);
|
||||
tk_strncpy(item->name, entry->d_name, MAX_PATH);
|
||||
return RET_OK;
|
||||
} else {
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t fs_os_dir_rewind(fs_dir_t* dir) {
|
||||
return_value_if_fail(!"fs_os_dir_rewind not supported yet", RET_BAD_PARAMS);
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
static ret_t fs_os_dir_close(fs_dir_t* dir) {
|
||||
return_value_if_fail(dir && dir->data, RET_BAD_PARAMS);
|
||||
struct aw_dir* d = (struct aw_dir*)dir->data;
|
||||
|
||||
aw_closedir(d);
|
||||
TKMEM_FREE(d);
|
||||
TKMEM_FREE(dir);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const fs_dir_vtable_t s_fs_dir_vtable_t = {
|
||||
.read = fs_os_dir_read, .rewind = fs_os_dir_rewind, .close = fs_os_dir_close};
|
||||
|
||||
static fs_dir_t* fs_dir_create(struct aw_dir* dir, const char* dir_name) {
|
||||
fs_dir_t* d = NULL;
|
||||
return_value_if_fail(dir != NULL, NULL);
|
||||
|
||||
struct fs_dir_ex* d_ex = TKMEM_ZALLOC(struct fs_dir_ex);
|
||||
if (d_ex != NULL) {
|
||||
d = &d_ex->dir;
|
||||
d->vt = &s_fs_dir_vtable_t;
|
||||
d->data = dir;
|
||||
tk_strncpy(d_ex->dir_name, dir_name, MAX_PATH);
|
||||
} else {
|
||||
aw_closedir(dir);
|
||||
TKMEM_FREE(dir);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static ret_t fs_os_create_dir(fs_t* fs, const char* name) {
|
||||
return aw_mkdir(name, AW_S_IRWXU | AW_S_IRWXG | AW_S_IRWXO) == 0 ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
static fs_dir_t* fs_os_open_dir(fs_t* fs, const char* name) {
|
||||
struct aw_dir* dir = TKMEM_ZALLOC(struct aw_dir);
|
||||
return_value_if_fail(aw_opendir(dir, name) == AW_OK, NULL);
|
||||
return fs_dir_create(dir, name);
|
||||
}
|
||||
|
||||
static ret_t fs_os_remove_dir(fs_t* fs, const char* name) {
|
||||
return aw_rmdir(name) == AW_OK ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
static bool_t fs_os_dir_exist(fs_t* fs, const char* name) {
|
||||
struct aw_stat st;
|
||||
return (aw_stat(name, &st) == AW_OK && AW_S_ISDIR(st.st_mode));
|
||||
}
|
||||
|
||||
static ret_t fs_os_dir_rename(fs_t* fs, const char* name, const char* new_name) {
|
||||
return (aw_rename(name, new_name) == AW_OK) ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* 文件系统操作 */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static int32_t fs_os_get_file_size(fs_t* fs, const char* name) {
|
||||
struct aw_stat st;
|
||||
|
||||
return_value_if_fail(aw_stat(name, &st) == AW_OK, -1);
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_disk_info(fs_t* fs, const char* volume, int32_t* free_kb,
|
||||
int32_t* total_kb) {
|
||||
(void)fs;
|
||||
return_value_if_fail(free_kb && total_kb, RET_BAD_PARAMS);
|
||||
return_value_if_fail(!"fs_os_get_disk_info not supported yet", RET_BAD_PARAMS);
|
||||
|
||||
*free_kb = 0;
|
||||
*total_kb = 0;
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_exe(fs_t* fs, char path[MAX_PATH + 1]) {
|
||||
(void)fs;
|
||||
|
||||
tk_strcpy(path, TKC_FS_EXE_PATH);
|
||||
if (!path_exist(path)) {
|
||||
fs_create_dir_r(os_fs(), path);
|
||||
tk_log_info_lf("create dir '%s'", path);
|
||||
}
|
||||
return_value_if_fail(path_exist(path), RET_FAIL);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_cwd(fs_t* fs, char path[MAX_PATH + 1]) {
|
||||
(void)fs;
|
||||
return_value_if_fail(path, RET_BAD_PARAMS);
|
||||
|
||||
*path = '\0';
|
||||
// return aw_getcwd(path, MAX_PATH) != NULL ? RET_OK : RET_FAIL;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_temp_path(fs_t* fs, char path[MAX_PATH + 1]) {
|
||||
tk_strcpy(path, TKC_FS_TEMP_PATH);
|
||||
if (!path_exist(path)) {
|
||||
fs_create_dir_r(os_fs(), path);
|
||||
tk_log_info_lf("create dir '%s'", path);
|
||||
}
|
||||
return_value_if_fail(path_exist(path), RET_FAIL);
|
||||
return RET_OK;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static const fs_t s_os_fs = {
|
||||
.open_file = fs_os_open_file,
|
||||
.remove_file = fs_os_remove_file,
|
||||
.file_exist = fs_os_file_exist,
|
||||
.file_rename = fs_os_file_rename,
|
||||
.stat = fs_os_stat,
|
||||
|
||||
.create_dir = fs_os_create_dir,
|
||||
.open_dir = fs_os_open_dir,
|
||||
.remove_dir = fs_os_remove_dir,
|
||||
.dir_exist = fs_os_dir_exist,
|
||||
.dir_rename = fs_os_dir_rename,
|
||||
|
||||
.get_file_size = fs_os_get_file_size,
|
||||
.get_disk_info = fs_os_get_disk_info,
|
||||
.get_cwd = fs_os_get_cwd,
|
||||
.get_exe = fs_os_get_exe,
|
||||
.get_temp_path = fs_os_get_temp_path,
|
||||
};
|
||||
|
||||
#define __MAKE_SYSFILE_NAME "~systemmkiffd.reserved"
|
||||
#define __LFFS_DEVNAME "/dev/is25lpx_partition_1"
|
||||
|
||||
#define __LFS_DEVNAME "/dev/is25lpx_partition_0"
|
||||
|
||||
fs_t* fs_aworks_create(const char* mnt) {
|
||||
int ret;
|
||||
struct aw_fs_format_arg fmt = {"awdisk", 0, 1};
|
||||
struct aw_stat file_stat;
|
||||
char stmp[64];
|
||||
memset(stmp, 0, sizeof(stmp));
|
||||
|
||||
if (tk_str_eq("/lffs", mnt)) {
|
||||
aw_umount("/lffs", 0);
|
||||
ret = aw_mount("/lffs", __LFFS_DEVNAME, AW_LFFS_TYPE_NAME, 0, NULL);
|
||||
if (ret == 0) {
|
||||
tk_str_append(stmp, sizeof(stmp), mnt);
|
||||
tk_str_append(stmp, sizeof(stmp), "/" __MAKE_SYSFILE_NAME);
|
||||
ret = aw_stat(stmp, &file_stat);
|
||||
}
|
||||
if (ret != 0) {
|
||||
aw_umount("/lffs", 0);
|
||||
aw_make_fs(__LFFS_DEVNAME, AW_LFFS_TYPE_NAME, &fmt);
|
||||
ret = aw_mount("/lffs", __LFFS_DEVNAME, AW_LFFS_TYPE_NAME, 0, NULL);
|
||||
goto_error_if_fail(ret == 0);
|
||||
ret = aw_create("/lffs/" __MAKE_SYSFILE_NAME, AW_S_IRWXU | AW_S_IRWXG | AW_S_IRWXO);
|
||||
goto_error_if_fail(ret == 0);
|
||||
}
|
||||
} else if (tk_str_eq("/lfs", mnt)) {
|
||||
ret = aw_mount(mnt, __LFS_DEVNAME, AW_LITTLEFS_TYPE_NAME, 0, NULL);
|
||||
if (ret != 0) {
|
||||
aw_umount(mnt, 0);
|
||||
ret = aw_make_fs(__LFS_DEVNAME, AW_LITTLEFS_TYPE_NAME, &fmt);
|
||||
if (ret != AW_OK) {
|
||||
ret = aw_make_fs(__LFS_DEVNAME, AW_LITTLEFS_TYPE_NAME, NULL);
|
||||
goto_error_if_fail(ret == 0);
|
||||
}
|
||||
ret = aw_mount(mnt, __LFS_DEVNAME, AW_LITTLEFS_TYPE_NAME, 0, NULL);
|
||||
goto_error_if_fail(ret == 0);
|
||||
}
|
||||
} else if (tk_str_eq("/dev", mnt)) {
|
||||
return &s_os_fs;
|
||||
} else {
|
||||
return_value_if_fail(!"Not support the mnt!", NULL);
|
||||
}
|
||||
return &s_os_fs;
|
||||
|
||||
error:
|
||||
aw_umount(mnt, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#if defined(UTEST_ENABLE)
|
||||
void fs_aworks_utest(void) {
|
||||
char* p;
|
||||
uint32_t sz;
|
||||
if (!dir_exist("/lfs/test_dir")) {
|
||||
fs_create_dir(os_fs(), "/lfs/test_dir");
|
||||
}
|
||||
ENSURE(file_write("/lfs/test_dir/tkc_test", "abc123456", tk_strlen("abc123456") + 1) == RET_OK);
|
||||
p = file_read("/lfs/test_dir/tkc_test", &sz);
|
||||
ENSURE(p && sz >= tk_strlen("abc123456") + 1 &&
|
||||
tk_str_eq_with_len(p, "abc123456", tk_strlen("abc123456") + 1));
|
||||
TKMEM_FREE(p);
|
||||
|
||||
tk_log_info_htlf("[UTEST]", "test R/W \"/lfs\" pass.");
|
||||
}
|
||||
#else
|
||||
void fs_aworks_utest(void) {
|
||||
}
|
||||
#endif
|
225
src/platforms/aworkslp/fs_os.c
Normal file
225
src/platforms/aworkslp/fs_os.c
Normal file
@ -0,0 +1,225 @@
|
||||
/**
|
||||
* File: mutex.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mutex
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/fs.h"
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/str_str.h"
|
||||
|
||||
#define FS_REG_MAX 6
|
||||
|
||||
static str_str_t s_items[FS_REG_MAX + 1];
|
||||
|
||||
static const char* str_str_value_with_len(const str_str_t* items, const char* name) {
|
||||
const str_str_t* iter = items;
|
||||
uint32_t len;
|
||||
return_value_if_fail(items != NULL && name != NULL, NULL);
|
||||
|
||||
while (iter->name != NULL) {
|
||||
len = tk_strlen(iter->name);
|
||||
if (tk_str_eq_with_len(iter->name, name, len)) {
|
||||
if (name[len] == '/' || name[len] == '\0') {
|
||||
return iter->value;
|
||||
}
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static fs_file_t* fs_os_open_file(fs_t* fs, const char* name, const char* mode) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, NULL);
|
||||
return rfs->open_file(rfs, name, mode);
|
||||
}
|
||||
|
||||
static ret_t fs_os_remove_file(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->remove_file(rfs, name);
|
||||
}
|
||||
|
||||
static bool_t fs_os_file_exist(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, FALSE);
|
||||
return rfs->file_exist(rfs, name);
|
||||
}
|
||||
|
||||
static ret_t fs_os_file_rename(fs_t* fs, const char* name, const char* new_name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
if ((fs_t*)str_str_value_with_len(s_items, new_name) != rfs) {
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
}
|
||||
return rfs->file_rename(rfs, name, new_name);
|
||||
}
|
||||
|
||||
static ret_t fs_os_stat(fs_t* fs, const char* name, fs_stat_info_t* fst) {
|
||||
fs_t* rfs = NULL;
|
||||
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->stat(rfs, name, fst);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static ret_t fs_os_create_dir(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->create_dir(rfs, name);
|
||||
}
|
||||
|
||||
static fs_dir_t* fs_os_open_dir(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, NULL);
|
||||
return rfs->open_dir(rfs, name);
|
||||
}
|
||||
|
||||
static ret_t fs_os_remove_dir(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->remove_dir(rfs, name);
|
||||
}
|
||||
|
||||
static bool_t fs_os_dir_exist(fs_t* fs, const char* name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, FALSE);
|
||||
if (strrchr(name, '/') == name) {
|
||||
return TRUE;
|
||||
}
|
||||
return rfs->dir_exist(rfs, name);
|
||||
}
|
||||
|
||||
static ret_t fs_os_dir_rename(fs_t* fs, const char* name, const char* new_name) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, FALSE);
|
||||
if ((fs_t*)str_str_value_with_len(s_items, new_name) != rfs) {
|
||||
return_value_if_fail(rfs, FALSE);
|
||||
}
|
||||
return rfs->dir_rename(rfs, name, new_name);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static int32_t fs_os_get_file_size(fs_t* fs, const char* name) {
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, name);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->get_file_size(rfs, name);
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_disk_info(fs_t* fs, const char* volume, int32_t* free_kb,
|
||||
int32_t* total_kb) {
|
||||
(void)fs;
|
||||
fs_t* rfs = NULL;
|
||||
rfs = (fs_t*)str_str_value_with_len(s_items, volume);
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->get_disk_info(rfs, volume, free_kb, total_kb);
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_exe(fs_t* fs, char path[MAX_PATH + 1]) {
|
||||
fs_t* rfs = s_items[0].value;
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->get_exe(rfs, path);
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_cwd(fs_t* fs, char path[MAX_PATH + 1]) {
|
||||
(void)fs;
|
||||
return_value_if_fail(path, RET_BAD_PARAMS);
|
||||
|
||||
*path = '\0';
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
|
||||
static ret_t fs_os_get_temp_path(fs_t* fs, char path[MAX_PATH + 1]) {
|
||||
fs_t* rfs = s_items[0].value;
|
||||
return_value_if_fail(rfs, RET_BAD_PARAMS);
|
||||
return rfs->get_temp_path(rfs, path);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef fs_t* (*fs_create_t)(const char* mnt);
|
||||
|
||||
ret_t fs_os_register(const char* mnt_name, fs_t* (*create)(const char*)) {
|
||||
return_value_if_fail(mnt_name && create, RET_BAD_PARAMS);
|
||||
return_value_if_fail(mnt_name[0] == '/', RET_BAD_PARAMS);
|
||||
int i;
|
||||
fs_t* fs = create(mnt_name);
|
||||
return_value_if_fail(fs, RET_BAD_PARAMS);
|
||||
|
||||
for (i = 0; i < FS_REG_MAX; i++) {
|
||||
if (s_items[i].name == NULL) {
|
||||
s_items[i].name = tk_strdup(mnt_name);
|
||||
s_items[i].value = (char*)fs;
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
return_value_if_fail(!"fs register num over FS_REG_MAX!", RET_OOM);
|
||||
return RET_OOM;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static const fs_t s_os_fs = {
|
||||
.open_file = fs_os_open_file,
|
||||
.remove_file = fs_os_remove_file,
|
||||
.file_exist = fs_os_file_exist,
|
||||
.file_rename = fs_os_file_rename,
|
||||
.stat = fs_os_stat,
|
||||
|
||||
.create_dir = fs_os_create_dir,
|
||||
.open_dir = fs_os_open_dir,
|
||||
.remove_dir = fs_os_remove_dir,
|
||||
.dir_exist = fs_os_dir_exist,
|
||||
.dir_rename = fs_os_dir_rename,
|
||||
|
||||
.get_file_size = fs_os_get_file_size,
|
||||
.get_disk_info = fs_os_get_disk_info,
|
||||
.get_cwd = fs_os_get_cwd,
|
||||
.get_exe = fs_os_get_exe,
|
||||
.get_temp_path = fs_os_get_temp_path,
|
||||
};
|
||||
|
||||
fs_t* os_fs(void) {
|
||||
return (fs_t*)&s_os_fs;
|
||||
}
|
88
src/platforms/aworkslp/mutex.c
Normal file
88
src/platforms/aworkslp/mutex.c
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* File: mutex.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mutex
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "aw_sem.h"
|
||||
#include "aw_mem.h"
|
||||
#include "tkc/mutex.h"
|
||||
|
||||
struct _tk_mutex_t {
|
||||
AW_MUTEX_DECL(__lock);
|
||||
};
|
||||
|
||||
//static tk_mutex_t s_tk_mutex_null;
|
||||
|
||||
tk_mutex_t* tk_mutex_create(void) {
|
||||
tk_mutex_t* mutex = (tk_mutex_t*)aw_mem_alloc(sizeof(tk_mutex_t));
|
||||
|
||||
if (mutex) {
|
||||
memset(mutex, 0, sizeof(tk_mutex_t));
|
||||
if (NULL == AW_MUTEX_INIT(mutex->__lock, AW_SEM_INVERSION_SAFE)) {
|
||||
aw_mem_free(mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
ret_t tk_mutex_lock(tk_mutex_t* mutex) {
|
||||
assert(mutex);
|
||||
aw_err_t err = AW_MUTEX_LOCK(mutex->__lock, AW_SEM_WAIT_FOREVER);
|
||||
|
||||
switch (err) {
|
||||
case AW_OK:
|
||||
return RET_OK;
|
||||
default:
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t tk_mutex_try_lock(tk_mutex_t* mutex) {
|
||||
assert(mutex);
|
||||
aw_err_t err = AW_MUTEX_LOCK(mutex->__lock, 0);
|
||||
|
||||
switch (err) {
|
||||
case AW_OK:
|
||||
return RET_OK;
|
||||
default:
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t tk_mutex_unlock(tk_mutex_t* mutex) {
|
||||
assert(mutex);
|
||||
aw_err_t err = AW_MUTEX_UNLOCK(mutex->__lock);
|
||||
|
||||
switch (err) {
|
||||
case AW_OK:
|
||||
return RET_OK;
|
||||
default:
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t tk_mutex_destroy(tk_mutex_t* mutex) {
|
||||
assert(mutex);
|
||||
AW_MUTEX_TERMINATE(mutex->__lock);
|
||||
|
||||
aw_mem_free(mutex);
|
||||
return RET_OK;
|
||||
}
|
276
src/platforms/aworkslp/platform.c
Normal file
276
src/platforms/aworkslp/platform.c
Normal file
@ -0,0 +1,276 @@
|
||||
/**
|
||||
* File: platform.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: platform dependent function of aworks
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* this program is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. see the
|
||||
* license file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* history:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "aworks.h"
|
||||
#include "aw_system.h"
|
||||
#include "aw_delay.h"
|
||||
#include "aw_mem.h"
|
||||
#include "aw_time.h"
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/date_time.h"
|
||||
#include "tkc/fscript.h"
|
||||
#include "tkc/fs.h"
|
||||
#include "tkc/data_reader_factory.h"
|
||||
#include "tkc/data_reader_file.h"
|
||||
#include "tkc/data_reader_mem.h"
|
||||
#include "tkc/data_writer_factory.h"
|
||||
#include "tkc/data_writer_file.h"
|
||||
#include "tkc/path.h"
|
||||
|
||||
#ifndef tk_log_info_lf
|
||||
#define tk_log_info_lf(fmt, args...)
|
||||
#define tk_log_info_htlf(header, fmt, args...)
|
||||
#define tk_log_warn_htlf(header, fmt, args...)
|
||||
#endif
|
||||
|
||||
extern ret_t fs_os_register(const char* mnt_name, fs_t* (*create)(const char*));
|
||||
extern fs_t* fs_aworks_create(const char* mnt);
|
||||
static void platform_test(void);
|
||||
|
||||
static ret_t date_time_get_now_impl(date_time_t* dt) {
|
||||
aw_err_t ret;
|
||||
aw_tm_t t;
|
||||
ret = aw_local_tm_get(&t);
|
||||
|
||||
if (ret == AW_OK) {
|
||||
dt->second = t.tm_sec;
|
||||
dt->minute = t.tm_min;
|
||||
dt->hour = t.tm_hour;
|
||||
dt->day = t.tm_mday;
|
||||
dt->month = t.tm_mon + 1;
|
||||
dt->year = t.tm_year + 1900;
|
||||
dt->wday = t.tm_wday;
|
||||
} else {
|
||||
dt->second = 0;
|
||||
dt->minute = 0;
|
||||
dt->hour = 0;
|
||||
dt->day = 11;
|
||||
dt->month = 11;
|
||||
dt->year = 2018;
|
||||
dt->wday = 0;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
#ifndef HAS_STD_MALLOC
|
||||
#define TK_MEM_SIZE 1 * 1024 * 1024
|
||||
|
||||
static ret_t mem_init(void) {
|
||||
uint32_t* mem = (uint32_t*)aw_mem_alloc(TK_MEM_SIZE);
|
||||
assert(mem != NULL);
|
||||
|
||||
tk_mem_init(mem, TK_MEM_SIZE);
|
||||
}
|
||||
#else
|
||||
#define mem_init()
|
||||
#endif
|
||||
|
||||
uint64_t get_time_ms64() {
|
||||
return aw_sys_tick_get();
|
||||
}
|
||||
|
||||
void sleep_ms(uint32_t ms) {
|
||||
aw_mdelay(ms);
|
||||
}
|
||||
|
||||
void perror(const char* a) {
|
||||
}
|
||||
|
||||
static ret_t fs_func_memdump(tk_object_t* obj, fscript_args_t* args, value_t* result) {
|
||||
tk_mem_dump();
|
||||
value_set_bool(result, 1);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t writer_reader_init(void) {
|
||||
data_reader_factory_t* reader_factory = data_reader_factory_create();
|
||||
data_writer_factory_t* writer_factory = data_writer_factory_create();
|
||||
|
||||
data_reader_factory_set(reader_factory);
|
||||
// data_reader_factory_register(reader_factory, "asset", data_reader_asset_create);
|
||||
data_reader_factory_register(reader_factory, "mem", data_reader_mem_create);
|
||||
data_reader_factory_register(reader_factory, "file", data_reader_file_create);
|
||||
data_writer_factory_set(writer_factory);
|
||||
data_writer_factory_register(writer_factory, "file", data_writer_file_create);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t platform_prepare(void) {
|
||||
static bool_t inited = FALSE;
|
||||
char path[MAX_PATH + 1];
|
||||
|
||||
if (inited) {
|
||||
return RET_OK;
|
||||
}
|
||||
inited = TRUE;
|
||||
|
||||
mem_init();
|
||||
date_time_set_impl(date_time_get_now_impl);
|
||||
writer_reader_init();
|
||||
fs_os_register("/lfs", fs_aworks_create); /* littlefs */
|
||||
fscript_register_func("memdump", fs_func_memdump);
|
||||
|
||||
fs_get_exe(os_fs(), path);
|
||||
tk_log_info_lf("fs_get_exe('%s').", path);
|
||||
|
||||
fs_get_temp_path(os_fs(), path);
|
||||
tk_log_info_lf("fs_get_temp_path('%s').", path);
|
||||
|
||||
path_app_root(path);
|
||||
tk_log_info_lf("path_app_root('%s').", path);
|
||||
|
||||
tk_log_info_lf("done.");
|
||||
|
||||
platform_test();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
#if defined(UTEST_ENABLE) && 1
|
||||
|
||||
#include "tkc/thread.h"
|
||||
#include "tkc/semaphore.h"
|
||||
#include "tkc/mutex.h"
|
||||
#include "tkc/fs.h"
|
||||
#include "tkc/str.h"
|
||||
|
||||
typedef struct {
|
||||
void* args;
|
||||
int run;
|
||||
} thread_ctx_t;
|
||||
|
||||
static void* task_entry(void* args) {
|
||||
int i = 5;
|
||||
static int chk_pri = 1;
|
||||
if (chk_pri == 1) {
|
||||
ENSURE(tk_str_eq_with_len("high", (const char*)args, 4));
|
||||
chk_pri++;
|
||||
}
|
||||
while (i-- > 0) {
|
||||
sleep_ms(1000);
|
||||
tk_log_info_htlf("[UTEST]", "task %s execute.", (char*)args);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void platform_test(void) {
|
||||
#ifdef HAS_STD_MALLOC
|
||||
if (1) {
|
||||
void* p = malloc(8);
|
||||
tk_log_info_htlf("[UTEST]", "test_str: step1 %p", p);
|
||||
ENSURE(p);
|
||||
tk_snprintf(p, 8, "abc123");
|
||||
p = realloc(p, 16);
|
||||
tk_log_info_htlf("[UTEST]", "test_str: step1");
|
||||
ENSURE(p);
|
||||
ENSURE(tk_str_cmp(p, "abc123") == 0);
|
||||
free(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (1) {
|
||||
uint64_t s = time_now_ms();
|
||||
tk_log_info_htlf("[TEST]", "sleep_ms: start %u ms", (unsigned int)s);
|
||||
sleep_ms(1050);
|
||||
tk_log_info_htlf("[TEST]", "sleep_ms: stop %u ms (%u)", (unsigned int)time_now_ms(),
|
||||
(unsigned int)(time_now_ms() - s));
|
||||
ENSURE((time_now_ms() - s) >= 1020 && (time_now_ms() - s) <= 1080);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
tk_mutex_t* p = tk_mutex_create();
|
||||
ENSURE(tk_mutex_lock(p) == RET_OK);
|
||||
ENSURE(tk_mutex_try_lock(p) == RET_OK);
|
||||
ENSURE(tk_mutex_lock(p) == RET_OK);
|
||||
|
||||
ENSURE(tk_mutex_unlock(p) == RET_OK);
|
||||
ENSURE(tk_mutex_unlock(p) == RET_OK);
|
||||
ENSURE(tk_mutex_unlock(p) == RET_OK);
|
||||
|
||||
tk_mutex_destroy(p);
|
||||
}
|
||||
if (1) {
|
||||
tk_semaphore_t* p = tk_semaphore_create(3, NULL);
|
||||
|
||||
tk_log_info_htlf("[TEST]", "tk_semaphore_t: start time %u ms", (unsigned int)time_now_ms());
|
||||
ENSURE(tk_semaphore_wait(p, 1000) == RET_OK);
|
||||
ENSURE(tk_semaphore_wait(p, 1000) == RET_OK);
|
||||
ENSURE(tk_semaphore_wait(p, 1000) == RET_OK);
|
||||
ENSURE(tk_semaphore_wait(p, 1000) != RET_OK);
|
||||
|
||||
tk_log_info_htlf("[TEST]", "tk_semaphore_t: locked time %u ms", (unsigned int)time_now_ms());
|
||||
ENSURE(tk_semaphore_post(p) == RET_OK);
|
||||
ENSURE(tk_semaphore_post(p) == RET_OK);
|
||||
ENSURE(tk_semaphore_post(p) == RET_OK);
|
||||
tk_log_info_htlf("[TEST]", "tk_semaphore_t: stop time %u ms", (unsigned int)time_now_ms());
|
||||
|
||||
tk_semaphore_destroy(p);
|
||||
}
|
||||
if (1) {
|
||||
tk_thread_t* p = tk_thread_create(task_entry, "low_t1");
|
||||
tk_thread_t* p1 = tk_thread_create(task_entry, "high_t2");
|
||||
ENSURE(p && p1);
|
||||
|
||||
tk_log_info_htlf("[TEST]", "tk_thread: start %u ms ", (unsigned int)time_now_ms());
|
||||
ENSURE(tk_thread_set_priority(p1, tk_thread_get_priority_from_platform(
|
||||
TK_THREAD_PRIORITY_BELOW_NORAML)) == RET_OK);
|
||||
ENSURE(tk_thread_start(p) == RET_OK);
|
||||
|
||||
tk_log_info_htlf("[TEST]", "tk_thread: start %u ms ", (unsigned int)time_now_ms());
|
||||
ENSURE(tk_thread_set_priority(p1, tk_thread_get_priority_from_platform(
|
||||
TK_THREAD_PRIORITY_ABOVE_NORAML)) == RET_OK);
|
||||
ENSURE(tk_thread_start(p1) == RET_OK);
|
||||
|
||||
tk_log_info_htlf("[TEST]", "task startup:");
|
||||
sleep_ms(3050);
|
||||
|
||||
tk_thread_join(p);
|
||||
tk_thread_destroy(p);
|
||||
tk_log_info_htlf("[TEST]", "tk_thread: stop %u ms ", (unsigned int)time_now_ms());
|
||||
|
||||
tk_thread_join(p1);
|
||||
tk_thread_destroy(p1);
|
||||
tk_log_info_htlf("[TEST]", "tk_thread: stop %u ms ", (unsigned int)time_now_ms());
|
||||
}
|
||||
|
||||
if (1) {
|
||||
char* p;
|
||||
uint32_t sz;
|
||||
if (!dir_exist("/lfs/test_dir")) {
|
||||
fs_create_dir(os_fs(), "/lfs/test_dir");
|
||||
}
|
||||
ENSURE(file_write("/lfs/test_dir/tkc_test", "abc123456", tk_strlen("abc123456") + 1) == RET_OK);
|
||||
p = file_read("/lfs/test_dir/tkc_test", &sz);
|
||||
ENSURE(p && sz >= tk_strlen("abc123456") + 1 &&
|
||||
tk_str_eq_with_len(p, "abc123456", tk_strlen("abc123456") + 1));
|
||||
TKMEM_FREE(p);
|
||||
}
|
||||
|
||||
tk_log_info_htlf("[UTEST]", "pass.");
|
||||
}
|
||||
#else
|
||||
static void platform_test(void) {
|
||||
tk_log_info_htlf("[UTEST]", "nothing.");
|
||||
}
|
||||
#endif
|
74
src/platforms/aworkslp/semaphore.c
Normal file
74
src/platforms/aworkslp/semaphore.c
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* File: semaphore.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: semaphore
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "aw_sem.h"
|
||||
#include "aw_mem.h"
|
||||
#include "tkc/semaphore.h"
|
||||
|
||||
struct _tk_semaphore_t {
|
||||
AW_SEMC_DECL(__sem);
|
||||
};
|
||||
|
||||
tk_semaphore_t* tk_semaphore_create(uint32_t value, const char* name) {
|
||||
tk_semaphore_t* semaphore = (tk_semaphore_t*)aw_mem_alloc(sizeof(tk_semaphore_t));
|
||||
|
||||
if (semaphore) {
|
||||
memset(semaphore, 0, sizeof(tk_semaphore_t));
|
||||
if (NULL == AW_SEMC_INIT(semaphore->__sem, value, AW_SEM_Q_FIFO)) {
|
||||
aw_mem_free(semaphore);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return semaphore;
|
||||
}
|
||||
|
||||
ret_t tk_semaphore_wait(tk_semaphore_t* semaphore, uint32_t timeout_ms) {
|
||||
assert(semaphore);
|
||||
aw_err_t err = AW_SEMC_TAKE(semaphore->__sem, timeout_ms);
|
||||
|
||||
switch (err) {
|
||||
case AW_OK:
|
||||
return RET_OK;
|
||||
default:
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t tk_semaphore_post(tk_semaphore_t* semaphore) {
|
||||
assert(semaphore);
|
||||
aw_err_t err = AW_SEMC_GIVE(semaphore->__sem);
|
||||
|
||||
switch (err) {
|
||||
case AW_OK:
|
||||
return RET_OK;
|
||||
default:
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t tk_semaphore_destroy(tk_semaphore_t* semaphore) {
|
||||
assert(semaphore);
|
||||
AW_SEMC_TERMINATE(semaphore->__sem);
|
||||
|
||||
aw_mem_free(semaphore);
|
||||
return RET_OK;
|
||||
}
|
326
src/platforms/aworkslp/serial_helper.c
Normal file
326
src/platforms/aworkslp/serial_helper.c
Normal file
@ -0,0 +1,326 @@
|
||||
/**
|
||||
* File: serial_helper.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: serial helper functions
|
||||
*
|
||||
* Copyright (c) 2019 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-09-11 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*the following code adapted from: https://github.com/wjwwood/serial/tree/master/src/impl
|
||||
*
|
||||
* Copyright 2012 William Woodall and John Harrison
|
||||
*
|
||||
* Additional Contributors: Christopher Baker @bakercp
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/wstr.h"
|
||||
#include "tkc/thread.h"
|
||||
#include "tkc/socket_pair.h"
|
||||
#include "tkc/socket_helper.h"
|
||||
#include "streams/serial/serial_helper.h"
|
||||
|
||||
#ifdef __AWORKS_LP__
|
||||
|
||||
#include "aworks.h"
|
||||
#include "aw_stropts.h"
|
||||
#include "aw_fcntl.h"
|
||||
#include "aw_unistd.h"
|
||||
|
||||
#include "aw_serial.h"
|
||||
#include "tkc/ring_buffer.h"
|
||||
#include "tkc/darray.h"
|
||||
|
||||
static darray_t* s_darray = NULL;
|
||||
|
||||
typedef struct {
|
||||
tk_thread_t* thread;
|
||||
serial_handle_t handle;
|
||||
bool_t broken;
|
||||
ring_buffer_t* rb;
|
||||
bool_t is_usb2uart;
|
||||
} serial_dev_prv_t;
|
||||
|
||||
static int da_serial_cmp(const void* a, const void* b) {
|
||||
serial_dev_prv_t* pa = a;
|
||||
if (pa->handle == b) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ret_t da_serial_destroy(void* data) {
|
||||
serial_dev_prv_t* p_this = data;
|
||||
|
||||
if (p_this->thread) {
|
||||
p_this->broken = TRUE;
|
||||
ENSURE(tk_thread_join(p_this->thread) == RET_OK);
|
||||
tk_thread_destroy(p_this->thread);
|
||||
}
|
||||
|
||||
ring_buffer_destroy(p_this->rb);
|
||||
TKMEM_FREE(p_this);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static void* thread_serial_recv(void* args) {
|
||||
serial_dev_prv_t* p_this = args;
|
||||
int32_t cnt = 0;
|
||||
int fd = serial_handle_get_fd(p_this->handle);
|
||||
uint8_t buff[64];
|
||||
ENSURE(p_this && fd >= 0);
|
||||
|
||||
while (!p_this->broken) {
|
||||
cnt = aw_read(fd, buff, sizeof(buff));
|
||||
if (cnt > 0) {
|
||||
ring_buffer_write_len(p_this->rb, buff, cnt);
|
||||
} else {
|
||||
sleep_ms(10);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int serial_handle_get_fd(serial_handle_t handle) {
|
||||
return handle->dev;
|
||||
}
|
||||
|
||||
serial_dev_t serial_handle_get_dev(serial_handle_t handle) {
|
||||
return handle->dev;
|
||||
}
|
||||
|
||||
serial_handle_t serial_open(const char* port) {
|
||||
serial_dev_prv_t* p_this = TKMEM_ZALLOC(serial_dev_prv_t);
|
||||
serial_handle_t handle = TKMEM_ZALLOC(serial_info_t);
|
||||
return_value_if_fail(p_this && handle != NULL && port != NULL && *port != '\0', NULL);
|
||||
handle->dev = aw_open(port, AW_O_RDWR, 0);
|
||||
return_value_if_fail(handle, NULL);
|
||||
|
||||
if (handle->dev < 0) {
|
||||
TKMEM_FREE(p_this);
|
||||
TKMEM_FREE(handle);
|
||||
return_value_if_fail(FALSE, NULL);
|
||||
}
|
||||
|
||||
memset(p_this, 0, sizeof(serial_dev_prv_t));
|
||||
p_this->handle = handle;
|
||||
p_this->rb = ring_buffer_create(256, 4096);
|
||||
ENSURE(p_this->rb);
|
||||
|
||||
if (strstr(port, "USB")) {
|
||||
p_this->is_usb2uart = TRUE;
|
||||
}
|
||||
|
||||
if (!s_darray) {
|
||||
s_darray = darray_create(5, da_serial_destroy, da_serial_cmp);
|
||||
ENSURE(s_darray);
|
||||
}
|
||||
ENSURE(darray_push(s_darray, p_this) == RET_OK);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
ret_t serial_iflush(serial_handle_t handle) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return aw_ioctl(fd, AW_FIORFLUSH, NULL) == 0 ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t serial_oflush(serial_handle_t handle) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
serial_dev_prv_t* p_this = darray_find(s_darray, handle);
|
||||
return_value_if_fail(p_this, RET_FAIL);
|
||||
ring_buffer_reset(p_this->rb);
|
||||
return aw_ioctl(fd, AW_FIOWFLUSH, NULL) == 0 ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t serial_wait_for_data(serial_handle_t handle, uint32_t timeout_ms) {
|
||||
serial_dev_prv_t* p_this = darray_find(s_darray, handle);
|
||||
return_value_if_fail(p_this, RET_FAIL);
|
||||
if (ring_buffer_size(p_this->rb)) {
|
||||
return RET_OK;
|
||||
}
|
||||
sleep_ms(timeout_ms);
|
||||
return RET_TIMEOUT;
|
||||
}
|
||||
|
||||
int32_t serial_read(serial_handle_t handle, uint8_t* buff, uint32_t max_size) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
serial_dev_prv_t* p_this = darray_find(s_darray, handle);
|
||||
return_value_if_fail(fd >= 0, RET_FAIL);
|
||||
return ring_buffer_read(p_this->rb, buff, max_size);
|
||||
}
|
||||
|
||||
int32_t serial_write(serial_handle_t handle, const uint8_t* buff, uint32_t max_size) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return_value_if_fail(fd >= 0, RET_FAIL);
|
||||
int32_t cnt = aw_write(fd, buff, max_size);
|
||||
return_value_if_fail(cnt >= 0, cnt);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int serial_close(serial_handle_t handle) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
serial_dev_prv_t* p_this = darray_find(s_darray, handle);
|
||||
return_value_if_fail(aw_close(fd) == 0, RET_FAIL);
|
||||
darray_remove(s_darray, handle);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t serial_config(serial_handle_t handle, uint32_t baudrate, bytesize_t bytesize,
|
||||
stopbits_t stopbits, flowcontrol_t flowcontrol, parity_t parity) {
|
||||
struct aw_serial_dcb dcb;
|
||||
struct aw_serial_timeout timeout;
|
||||
ret_t ret;
|
||||
serial_dev_prv_t* p_this = darray_find(s_darray, handle);
|
||||
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return_value_if_fail(flowcontrol != flowcontrol_software, RET_FAIL);
|
||||
return_value_if_fail(fd >= 0 && p_this, RET_FAIL);
|
||||
|
||||
if (!p_this->is_usb2uart) {
|
||||
ret = aw_serial_dcb_get(fd, &dcb);
|
||||
return_value_if_fail(ret == RET_OK, RET_FAIL);
|
||||
|
||||
dcb.baud_rate = baudrate;
|
||||
dcb.byte_size = bytesize;
|
||||
dcb.stop_bits = stopbits;
|
||||
|
||||
if (flowcontrol == flowcontrol_hardware) {
|
||||
dcb.f_rtsctrl = 1;
|
||||
dcb.f_ctsflow = 1;
|
||||
}
|
||||
if (parity == 1) {
|
||||
dcb.parity = 1;
|
||||
}
|
||||
|
||||
ret = aw_serial_dcb_set(fd, &dcb);
|
||||
return_value_if_fail(ret == RET_OK, RET_FAIL);
|
||||
|
||||
/* 串口超时配置获取 */
|
||||
ret = aw_serial_timeout_get(fd, &timeout);
|
||||
return_value_if_fail(ret == RET_OK, RET_FAIL);
|
||||
|
||||
timeout.rd_timeout = 1000; /* 读总超时 1s */
|
||||
timeout.rd_interval_timeout = 50; /* 码间超时为 50ms */
|
||||
|
||||
/* 配置串口超时 */
|
||||
ret = aw_serial_timeout_set(fd, &timeout);
|
||||
return_value_if_fail(ret == RET_OK, RET_FAIL);
|
||||
}
|
||||
|
||||
if (!p_this->thread) {
|
||||
p_this->thread = tk_thread_create(thread_serial_recv, p_this);
|
||||
// tk_thread_set_priority(p_this->thread, 6);
|
||||
tk_thread_set_stack_size(p_this->thread, 2048);
|
||||
ENSURE(tk_thread_start(p_this->thread) == RET_OK);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
#endif /* __AWORKS_LP__ */
|
||||
|
||||
#ifdef __AWORKS__
|
||||
|
||||
#include "aworks.h"
|
||||
#include "io/aw_stropts.h"
|
||||
#include "io/aw_fcntl.h"
|
||||
#include "io/aw_unistd.h"
|
||||
|
||||
#include "aw_serial.h"
|
||||
|
||||
int serial_handle_get_fd(serial_handle_t handle) {
|
||||
return handle->dev;
|
||||
}
|
||||
|
||||
serial_dev_t serial_handle_get_dev(serial_handle_t handle) {
|
||||
return handle->dev;
|
||||
}
|
||||
|
||||
serial_handle_t serial_open(const char* port) {
|
||||
serial_handle_t handle = TKMEM_ZALLOC(serial_info_t);
|
||||
return_value_if_fail(handle != NULL && port != NULL && *port != '\0', NULL);
|
||||
handle->dev = aw_open(port, 0, O_RDWR);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
ret_t serial_iflush(serial_handle_t handle) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return aw_ioctl(fd, AW_FIORFLUSH, NULL) == 0 ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t serial_oflush(serial_handle_t handle) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return aw_ioctl(fd, AW_FIOWFLUSH, NULL) == 0 ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t serial_wait_for_data(serial_handle_t handle, uint32_t timeout_ms) {
|
||||
int len = 0;
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
while (timeout_ms) {
|
||||
aw_ioctl(fd, AW_FIONREAD, &len);
|
||||
if (len > 0) {
|
||||
return RET_OK;
|
||||
}
|
||||
sleep_ms(10);
|
||||
timeout_ms -= tk_min(timeout_ms, 10);
|
||||
}
|
||||
return RET_TIMEOUT;
|
||||
}
|
||||
|
||||
int32_t serial_read(serial_handle_t handle, uint8_t* buff, uint32_t max_size) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return aw_read(fd, buff, max_size);
|
||||
}
|
||||
|
||||
int32_t serial_write(serial_handle_t handle, const uint8_t* buff, uint32_t max_size) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return aw_write(fd, buff, max_size);
|
||||
}
|
||||
|
||||
int serial_close(serial_handle_t handle) {
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return aw_close(fd);
|
||||
}
|
||||
|
||||
ret_t serial_config(serial_handle_t handle, uint32_t baudrate, bytesize_t bytesize,
|
||||
stopbits_t stopbits, flowcontrol_t flowcontrol, parity_t parity) {
|
||||
struct aw_serial_dcb dcb;
|
||||
int fd = serial_handle_get_fd(handle);
|
||||
return_value_if_fail(flowcontrol != flowcontrol_software, RET_FAIL);
|
||||
|
||||
memset(&dcb, 0, sizeof(dcb));
|
||||
dcb.baud_rate = baudrate;
|
||||
dcb.byte_size = bytesize;
|
||||
dcb.stop_bits = stopbits;
|
||||
|
||||
if (flowcontrol == flowcontrol_hardware) {
|
||||
dcb.f_rtsctrl = 1;
|
||||
dcb.f_ctsflow = 1;
|
||||
}
|
||||
if (parity == 1) {
|
||||
dcb.parity = 1;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
struct aw_serial_timeout tm = {.rd_interval_timeout = 10, .rd_timeout = 100};
|
||||
aw_ioctl(fd, AW_TIOCRDTIMEOUT, &tm);
|
||||
}
|
||||
return aw_ioctl(fd, AW_TIOSETOPTIONS, &dcb);
|
||||
}
|
||||
|
||||
#endif /* __AWORKS__ */
|
31
src/platforms/aworkslp/socket.c
Normal file
31
src/platforms/aworkslp/socket.c
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* File: socket_helper.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: socket helper functions
|
||||
*
|
||||
* Copyright (c) 2019 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/socket_helper.h"
|
||||
|
||||
#ifdef WITH_SOCKET
|
||||
|
||||
int socketpair(int family, int type, int flags, int fd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /*WITH_SOCKET*/
|
149
src/platforms/aworkslp/thread.c
Normal file
149
src/platforms/aworkslp/thread.c
Normal file
@ -0,0 +1,149 @@
|
||||
/**
|
||||
* File: mutex.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mutex
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-12-16 Wang LinFu <wanglinfu@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "aworks.h"
|
||||
#include "aw_task.h"
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/thread.h"
|
||||
|
||||
struct _tk_thread_t {
|
||||
void* args;
|
||||
tk_thread_entry_t entry;
|
||||
|
||||
aw_task_id_t id;
|
||||
bool_t running;
|
||||
|
||||
const char* name;
|
||||
uint32_t stack_size;
|
||||
uint32_t priority;
|
||||
void* status;
|
||||
};
|
||||
|
||||
tk_thread_t* tk_thread_create(tk_thread_entry_t entry, void* args) {
|
||||
return_value_if_fail(entry != NULL, NULL);
|
||||
|
||||
tk_thread_t* thread = (tk_thread_t*)TKMEM_ZALLOC(tk_thread_t);
|
||||
return_value_if_fail(thread != NULL, NULL);
|
||||
|
||||
thread->id = AW_TASK_ID_INVALID;
|
||||
thread->args = args;
|
||||
thread->entry = entry;
|
||||
thread->name = "tk_thread";
|
||||
thread->stack_size = 1024;
|
||||
thread->priority = aw_task_lowest_priority();
|
||||
|
||||
return thread;
|
||||
}
|
||||
ret_t tk_thread_set_name(tk_thread_t* thread, const char* name) {
|
||||
return_value_if_fail(thread != NULL && name != NULL, RET_BAD_PARAMS);
|
||||
|
||||
thread->name = name;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
ret_t tk_thread_set_stack_size(tk_thread_t* thread, uint32_t stack_size) {
|
||||
return_value_if_fail(thread != NULL, RET_BAD_PARAMS);
|
||||
|
||||
thread->stack_size = stack_size;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32_t tk_thread_get_priority_from_platform(tk_thread_priority_t priority) {
|
||||
int32_t lowest_priority = aw_task_lowest_priority();
|
||||
int32_t priority_count = aw_task_priority_count();
|
||||
ENSURE(priority_count >= TK_THREAD_PRIORITY_TIME_CRITICAL);
|
||||
switch (priority) {
|
||||
case TK_THREAD_PRIORITY_TIME_CRITICAL:
|
||||
return lowest_priority - 6;
|
||||
case TK_THREAD_PRIORITY_HIGHEST:
|
||||
return lowest_priority - 5;
|
||||
case TK_THREAD_PRIORITY_ABOVE_NORAML:
|
||||
return lowest_priority - 4;
|
||||
case TK_THREAD_PRIORITY_NORMAL:
|
||||
return lowest_priority - 3;
|
||||
case TK_THREAD_PRIORITY_BELOW_NORAML:
|
||||
return lowest_priority - 2;
|
||||
case TK_THREAD_PRIORITY_LOWEST:
|
||||
return lowest_priority - 1;
|
||||
default:
|
||||
return lowest_priority;
|
||||
}
|
||||
}
|
||||
|
||||
ret_t tk_thread_set_priority(tk_thread_t* thread, tk_thread_priority_t priority) {
|
||||
return_value_if_fail(thread != NULL, RET_BAD_PARAMS);
|
||||
|
||||
thread->priority = tk_thread_get_priority_from_platform(priority);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
ret_t tk_thread_start(tk_thread_t* thread) {
|
||||
return_value_if_fail(thread != NULL && !thread->running, RET_BAD_PARAMS);
|
||||
|
||||
thread->id = aw_task_create(thread->name, thread->priority, thread->stack_size, thread->entry,
|
||||
thread->args);
|
||||
|
||||
if (thread->id == AW_TASK_ID_INVALID) {
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
if (aw_task_startup(thread->id) == AW_OK) {
|
||||
thread->running = TRUE;
|
||||
} else {
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
ret_t tk_thread_join(tk_thread_t* thread) {
|
||||
return_value_if_fail(thread != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (!aw_task_valid(thread->id) || aw_task_join(thread->id, &thread->status) == AW_OK) {
|
||||
thread->id = AW_TASK_ID_INVALID;
|
||||
thread->running = FALSE;
|
||||
return RET_OK;
|
||||
} else {
|
||||
return RET_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
void* tk_thread_get_args(tk_thread_t* thread) {
|
||||
return_value_if_fail(thread != NULL, NULL);
|
||||
|
||||
return thread->args;
|
||||
}
|
||||
|
||||
ret_t tk_thread_destroy(tk_thread_t* thread) {
|
||||
return_value_if_fail(thread != NULL && thread->id != AW_TASK_ID_INVALID, RET_BAD_PARAMS);
|
||||
|
||||
return_value_if_fail(aw_task_terminate(thread->id) == AW_OK, RET_FAIL);
|
||||
|
||||
memset(thread, 0x00, sizeof(tk_thread_t));
|
||||
TKMEM_FREE(thread);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
uint64_t tk_thread_self(void) {
|
||||
return (uint64_t)aw_task_id_self();
|
||||
}
|
@ -1360,4 +1360,3 @@ TEST(FExr, global) {
|
||||
|
||||
TK_OBJECT_UNREF(obj);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user