add aworkslp

This commit is contained in:
lixianjing 2021-12-23 09:48:27 +08:00
parent 96bca37bcc
commit cef0c50276
11 changed files with 1864 additions and 1 deletions

View File

@ -1,5 +1,8 @@
# 最新动态
2021/12/23
* 增加aworkslp平台支持(感谢林福提供补丁)
2021/12/22
* 复原被覆盖的tools/idl\_gen/README.md(感谢雨欣提供补丁)
* 增加tkc/sha256.h

View 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
/**
* VGCANVASOpenGL硬件加速
*
*/
// #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*/

View 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

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

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

View 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

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

View 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__ */

View 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*/

View 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();
}

View File

@ -1360,4 +1360,3 @@ TEST(FExr, global) {
TK_OBJECT_UNREF(obj);
}