Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

182
sdk/lib/posix/mqueue.c Normal file
View File

@@ -0,0 +1,182 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/irq.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "osal/msgqueue.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
struct pthread_mq {
char name[32];
uint32 unlink: 1, rev: 31;
struct pthread_mq *next;
os_msgqueue_t msgq;
};
struct pthread_mq_data {
void *data;
uint32 len;
};
static struct pthread_mq *mq_list = NULL;
static struct pthread_mq *mq_list_find(const char *name, uint8 unlink)
{
struct pthread_mq *prev = NULL;
struct pthread_mq *next = NULL;
uint32 flag = disable_irq();
next = mq_list;
while (next) {
if (os_strcmp(next->name, name) == 0) {
if (unlink) {
if (prev == NULL) {
mq_list = next->next;
} else {
prev->next = next->next;
}
next->unlink = 1;
}
break;
}
prev = next;
next = next->next;
}
enable_irq(flag);
return next;
}
static void mq_list_add(struct pthread_mq *mq)
{
uint32 flag = disable_irq();
mq->next = mq_list;
mq_list = mq;
enable_irq(flag);
}
int mq_close(mqd_t mqdes)
{
return 0;
}
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
{
return 0;
}
mqd_t mq_open(const char *name, int oflag, int mode, struct mq_attr *attr)
{
struct pthread_mq *mq = mq_list_find(name, 0);
if (mq) {
return (mqd_t)mq;
} else {
mq = (struct pthread_mq *)os_zalloc(sizeof(struct pthread_mq));
if (mq == NULL) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
os_strncpy(mq->name, name, 31);
os_msgq_init(&mq->msgq, attr ? attr->mq_msgsize : 32);
mq_list_add(mq);
return (mqd_t)mq;
}
}
static uint32 _mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int tmo)
{
struct pthread_mq_data *val;
struct pthread_mq *mq = (struct pthread_mq *)mqdes;
if (mq->unlink) {
return -ENODEV;
}
val = (struct pthread_mq_data *)os_msgq_get(&mq->msgq, tmo);
if (val) {
if (msg_len >= val->len) {
os_memcpy(msg_ptr, val->data, val->len);
} else {
pthread_err("msg_len(%d) < val_len(%d)\r\n", msg_len, val->len);
}
os_free(val->data);
os_free(val);
return 0;
}
return -1;
}
static int _mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int tmo)
{
int ret;
struct pthread_mq *mq = (struct pthread_mq *)mqdes;
struct pthread_mq_data *val;
if (mq->unlink) {
return -ENODEV;
}
val = os_malloc(sizeof(struct pthread_mq_data));
if (val) {
val->data = os_memdup(msg_ptr, msg_len);
if (val->data) {
ret = os_msgq_put(&mq->msgq, (uint32)val, tmo);
if (ret == 0) {
return RET_OK;
}
os_free(val->data);
} else {
pthread_err("alloc fail\r\n");
}
os_free(val);
} else {
pthread_err("alloc fail\r\n");
}
return -ENOMEM;
}
int mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio)
{
return _mq_receive(mqdes, msg_ptr, msg_len, osWaitForever);
}
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
{
return _mq_send(mqdes, msg_ptr, msg_len, osWaitForever);
}
int mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abstime)
{
return _mq_receive(mqdes, msg_ptr, msg_len, pthread_timespec_delta(abstime));
}
int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abstime)
{
return _mq_send(mqdes, msg_ptr, msg_len, pthread_timespec_delta(abstime));
}
int mq_unlink(const char *name)
{
struct pthread_mq_data *val;
struct pthread_mq *mq = mq_list_find(name, 1);
if (mq) {
while (os_msgq_cnt(&mq->msgq) > 0) {
val = (struct pthread_mq_data *)os_msgq_get(&mq->msgq, 0);
if (val) {
os_free(val->data);
os_free(val);
}
}
os_msgq_del(&mq->msgq);
os_free(mq);
return 0;
}
return -ENODEV;
}
#endif

View File

@@ -0,0 +1,77 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "osal/msgqueue.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#include "osal/sleep.h"
#ifdef TXWSDK_POSIX
pthread_cond_t c;
void posix_mutex_test(void)
{
pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t m2;
pthread_mutex_init(&m2, NULL);
for (int i = 0; i < 100; ++i)
{
os_printf("posix_mutex_test %d\n", i);
pthread_mutex_lock(&m1);
pthread_mutex_unlock(&m1);
pthread_mutex_lock(&m2);
pthread_mutex_unlock(&m2);
}
}
void posix_cond_test(void)
{
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
pthread_cond_init(&c, NULL);
for (int i = 0; i < 100; ++i)
{
os_printf("posix_mutex_test %d\n", i);
pthread_mutex_lock(&m);
pthread_cond_wait(&c, &m);
pthread_mutex_unlock(&m);
}
}
static void *pthread_test_task(void *arg)
{
os_printf(KERN_NOTICE"pthread_test_task running ...\r\n");
if (arg) {
os_sleep(10);
os_printf(KERN_NOTICE"pthread_test_task join!\r\n");
pthread_join((pthread_t)arg, NULL);
} else {
os_sleep(20);
}
os_printf(KERN_NOTICE"pthread_test_task exit!\r\n");
return NULL;
}
void posix_pthread_test(void)
{
pthread_t pthd1, pthd2;
pthread_attr_t attr1, attr2;
pthread_attr_init(&attr1);
pthread_attr_init(&attr2);
pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
pthread_attr_setdetachstate(&attr2, PTHREAD_CREATE_JOINABLE);
os_printf("posix test start!\r\n");
pthread_create(&pthd2, &attr2, pthread_test_task, 0);
pthread_create(&pthd1, &attr1, pthread_test_task, (void *)pthd2);
}
#endif

269
sdk/lib/posix/pthread.c Normal file
View File

@@ -0,0 +1,269 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/irq.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#include "osal/sleep.h"
#ifdef TXWSDK_POSIX
#define PTHREAD_MAX (32)
struct pthread_task {
char name[11];
uint8 inited;
void *task_hdl;
os_semaphore_t join_sema;
pthread_attr_t attr;
void *arg;
void *(*start)(void *);
void *tls;
} ;
static pthread_t pthreads[PTHREAD_MAX];
static int32 pthread_set(pthread_t thread)
{
int32 i = 0;
uint32 flag = disable_irq();
for (i = 0; thread && i < PTHREAD_MAX; i++) {
if (0 == pthreads[i]) {
pthreads[i] = thread;
break;
}
}
enable_irq(flag);
return (thread && i < PTHREAD_MAX);
}
static struct pthread_task *pthread_get(void *thread)
{
int32 i = 0;
struct pthread_task *thd = NULL;
uint32 flag = disable_irq();
for (i = 0; thread && i < PTHREAD_MAX; i++) {
if (thread == pthreads[i]) {
thd = (struct pthread_task *)thread;
break;
}
}
enable_irq(flag);
return thd;
}
static void pthread_del(pthread_t thread)
{
int32 i = 0;
uint32 flag = disable_irq();
for (i = 0; i < PTHREAD_MAX; i++) {
if (thread == pthreads[i]) {
pthreads[i] = 0;
break;
}
}
enable_irq(flag);
}
static void pthread_free(struct pthread_task *thd)
{
pthread_del((pthread_t)thd);
os_sema_del(&thd->join_sema);
pthread_key_destroy(thd->tls);
os_free(thd->tls);
os_free(thd);
}
static void pthread_task_entry(void *args)
{
struct pthread_task *thd = (struct pthread_task *)args;
thd->start(thd->arg);
while(!thd->inited) os_sleep_ms(5);
if (thd->attr.detachstate == PTHREAD_CREATE_JOINABLE) {
pthread_dbg("pthread %s exit: JOINABLE!\r\n", thd->name);
os_sema_up(&thd->join_sema);
} else {
pthread_dbg("pthread %s exit: DETACHED!\r\n", thd->name);
pthread_free(thd);
}
}
static int pthread_priority(pthread_attr_t *attr)
{
if (attr) {
if (attr->schedparam.sched_priority == 0) {
return OS_TASK_PRIORITY_NORMAL;
} else if (attr->schedparam.sched_priority <= 20) {
return OS_TASK_PRIORITY_LOW + attr->schedparam.sched_priority / 2;
} else if (attr->schedparam.sched_priority <= 40) {
return OS_TASK_PRIORITY_BELOW_NORMAL + (attr->schedparam.sched_priority - 20) / 2;
} else if (attr->schedparam.sched_priority <= 60) {
return OS_TASK_PRIORITY_NORMAL + (attr->schedparam.sched_priority - 40) / 2;
} else {
return OS_TASK_PRIORITY_ABOVE_NORMAL + (attr->schedparam.sched_priority - 60) / 4;
}
}
return OS_TASK_PRIORITY_NORMAL;
}
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *), void *arg)
{
struct pthread_task *thd = os_zalloc(sizeof(struct pthread_task));
if (thd == NULL) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
if (!pthread_set((pthread_t)thd)) {
pthread_err("no free pthread, max %d\r\n", PTHREAD_MAX);
os_free(thd);
return -ESRCH;
}
if (attr) {
thd->attr = *attr;
if (attr->schedparam.sched_priority > 99) {
thd->attr.schedparam.sched_priority = 99;
}
} else {
pthread_attr_init(&thd->attr);
}
os_sema_init(&thd->join_sema, 0);
thd->arg = arg;
thd->start = start;
os_sprintf(thd->name, "p_%x", (uint32)start);
thd->task_hdl = os_task_create(thd->name, pthread_task_entry, thd, pthread_priority(&thd->attr), 0, NULL, thd->attr.stacksize);
*thread = (pthread_t)thd;
thd->inited = 1;
return RET_OK;
}
pthread_t pthread_self(void)
{
pthread_t thd = (pthread_t)os_task_data(os_task_current());
return (pthread_t)pthread_get(thd);
}
int pthread_join(pthread_t thread, void **value_ptr)
{
struct pthread_task *thd = pthread_get(thread);
if (thd) {
if (thread == pthread_self()) {
pthread_err("pthread_join self!\r\n");
return -EDEADLK;
}
if (thd->attr.detachstate == PTHREAD_CREATE_DETACHED) {
pthread_err("pthread_join DETACHED thread!\r\n");
return -EINVAL; /* join on a detached pthread */
}
os_sema_down(&thd->join_sema, osWaitForever);
pthread_free(thd);
pthread_dbg("pthread_join DONE!\r\n");
} else {
pthread_dbg("pthread is not exist!\r\n");
}
return 0;
}
void pthread_exit(void *value_ptr)
{
struct pthread_task *thd = pthread_get(pthread_self());
if (thd) {
os_task_destroy(thd->task_hdl);
pthread_free(thd);
} else {
pthread_err("pthread is not exist!\r\n");
}
}
int pthread_detach(pthread_t thread)
{
struct pthread_task *thd = pthread_get(thread);
if (thd) {
thd->attr.detachstate = PTHREAD_CREATE_DETACHED;
} else {
pthread_dbg("pthread is not exist!\r\n");
}
return 0;
}
unsigned int pthread_timespec_delta(const struct timespec *abstime)
{
uint64 ticks;
uint32 tmo = osWaitForever;
struct timespec cur;
if (abstime) {
os_systime(&cur);
if (timespec_detal_ticks(abstime, &cur, &ticks) == RET_OK) {
tmo = os_jiffies_to_msecs(ticks);
}
}
return tmo;
}
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
{
uint8 init = 0;
uint32 flag = disable_irq();
if (once_control == NULL || init_routine == NULL) {
return -EINVAL;
}
#ifdef __NEWLIB__
if (!once_control->is_initialized) {
once_control->is_initialized = 1;
init = 1;
}
#else
if (!(*once_control)) {
*once_control = 1;
init = 1;
}
#endif
enable_irq(flag);
if (init) {
init_routine();
}
return 0;
}
void *pthread_tls(pthread_t thread, int create, int size)
{
void *ptr;
uint32 flag;
struct pthread_task *thd = pthread_get(thread);
if (thd) {
if (!create) {
flag = disable_irq();
ptr = thd->tls;
thd->tls = NULL;
enable_irq(flag);
os_free(ptr);
} else {
flag = disable_irq();
ptr = thd->tls;
if (size && ptr == NULL) {
ptr = os_malloc(size);
if (ptr) {
thd->tls = ptr;
}
}
enable_irq(flag);
return ptr;
}
}
return NULL;
}
#endif

View File

@@ -0,0 +1,131 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int pthread_attr_init(pthread_attr_t *attr)
{
if (attr) {
os_memset(attr, 0, sizeof(pthread_attr_t));
attr->stacksize = 1024;
}
return 0;
}
int pthread_attr_destroy(pthread_attr_t *attr)
{
if (attr) {
os_memset(attr, 0, sizeof(pthread_attr_t));
}
return 0;
}
int pthread_attr_setdetachstate(pthread_attr_t *attr, int state)
{
if (state != PTHREAD_CREATE_JOINABLE && state != PTHREAD_CREATE_DETACHED) {
return -EINVAL;
}
attr->detachstate = state;
return 0;
}
int pthread_attr_getdetachstate(pthread_attr_t const *attr, int *state)
{
*state = (int)attr->detachstate;
return 0;
}
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
//attr->schedpolicy = policy;
return 0;
}
int pthread_attr_getschedpolicy(pthread_attr_t const *attr, int *policy)
{
//*policy = (int)attr->schedpolicy;
return 0;
}
int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param const *param)
{
attr->schedparam.sched_priority = param->sched_priority;
return 0;
}
int pthread_attr_getschedparam(pthread_attr_t const *attr, struct sched_param *param)
{
param->sched_priority = attr->schedparam.sched_priority;
return 0;
}
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size)
{
if (attr) {
attr->stacksize = stack_size;
if (stack_size >= 4096) {
pthread_dbg("set stack size %d, maybe too large!\r\n");
}
}
return 0;
}
int pthread_attr_getstacksize(pthread_attr_t const *attr, size_t *stack_size)
{
*stack_size = attr->stacksize;
return 0;
}
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack_addr)
{
return -EOPNOTSUPP;
}
int pthread_attr_getstackaddr(pthread_attr_t const *attr, void **stack_addr)
{
return -EOPNOTSUPP;
}
int pthread_attr_setstack(pthread_attr_t *attr, void *stack_base, size_t stack_size)
{
//attr->stackaddr = stack_base;
attr->stacksize = ALIGN(stack_size, 4);
return 0;
}
int pthread_attr_getstack(pthread_attr_t const *attr, void **stack_base, size_t *stack_size)
{
*stack_base = 0;//attr->stackaddr;
*stack_size = attr->stacksize;
return 0;
}
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard_size)
{
return EOPNOTSUPP;
}
int pthread_attr_getguardsize(pthread_attr_t const *attr, size_t *guard_size)
{
return EOPNOTSUPP;
}
int pthread_attr_setscope(pthread_attr_t *attr, int scope)
{
return EOPNOTSUPP;
}
int pthread_attr_getscope(pthread_attr_t const *attr, int *scope)
{
return EOPNOTSUPP;
}
#endif

View File

@@ -0,0 +1,106 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
{
if (!attr) {
return -EINVAL;
}
return 0;
}
int pthread_barrierattr_init(pthread_barrierattr_t *attr)
{
if (!attr) {
return -EINVAL;
}
*attr = PTHREAD_PROCESS_PRIVATE;
return 0;
}
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared)
{
if (!attr) {
return -EINVAL;
}
*pshared = (int) * attr;
return 0;
}
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
{
if (!attr) {
return -EINVAL;
}
if (pshared == PTHREAD_PROCESS_PRIVATE) {
attr = PTHREAD_PROCESS_PRIVATE;
}
return -EINVAL;
}
int pthread_barrier_destroy(pthread_barrier_t *barrier)
{
int32 result;
if (!barrier) {
return -EINVAL;
}
result = pthread_cond_destroy(&(barrier->cond));
return result;
}
int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, int count)
{
if (!barrier) {
return -EINVAL;
}
if (attr && (*attr != PTHREAD_PROCESS_PRIVATE)) {
return -EINVAL;
}
barrier->count = count;
pthread_cond_init(&(barrier->cond), NULL);
pthread_mutex_init(&(barrier->mutex), NULL);
return 0;
}
int pthread_barrier_wait(pthread_barrier_t *barrier)
{
int32 result;
if (!barrier) {
return -EINVAL;
}
result = pthread_mutex_lock(&(barrier->mutex));
if (result != 0) {
return -EINVAL;
}
if (barrier->count == 0) {
result = EINVAL;
} else {
barrier->count -= 1;
if (barrier->count == 0) { /* broadcast condition */
pthread_cond_broadcast(&(barrier->cond));
} else {
pthread_cond_wait(&(barrier->cond), &(barrier->mutex));
}
}
pthread_mutex_unlock(&(barrier->mutex));
return result;
}
#endif

View File

@@ -0,0 +1,206 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "osal/condv.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
os_condv_t *condv;
#ifdef __MINILIBC__
if (NULL == cond) {
return -EINVAL;
}
os_memset(cond, 0, sizeof(pthread_cond_t));
condv = os_zalloc(sizeof(os_condv_t));
if (NULL == condv) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
if (os_condv_init(condv)) {
os_free(condv);
pthread_err("os_condv_init fail\r\n");
return RET_ERR;
}
cond->lock = condv;
#else
if (*cond == 0) {
condv = os_zalloc(sizeof(os_condv_t));
if (condv) {
if (os_condv_init(condv)) {
os_free(condv);
pthread_err("os_condv_init fail\r\n");
return RET_ERR;
}
*cond = (pthread_cond_t)condv;
return RET_OK;
} else {
pthread_err("alloc fail\r\n");
}
return -ENOMEM;
}
#endif
return RET_OK;
}
int pthread_cond_broadcast(pthread_cond_t *cond)
{
#ifdef __MINILIBC__
if (NULL == cond) {
return -EINVAL;
}
if (NULL == cond->lock) {
pthread_cond_init(cond, NULL);
}
return os_condv_broadcast((os_condv_t *)(cond->lock));
#else
pthread_cond_init(cond, NULL);
return os_condv_broadcast((os_condv_t *)(*cond));
#endif
}
int pthread_cond_destroy(pthread_cond_t *cond)
{
#ifdef __MINILIBC__
if (NULL == cond) {
return -EINVAL;
}
if (cond->lock) {
os_condv_del((os_condv_t *)(cond->lock));
os_free(cond->lock);
}
#else
os_condv_del((os_condv_t *)(*cond));
#endif
return 0;
}
int pthread_cond_signal(pthread_cond_t *cond)
{
#ifdef __MINILIBC__
if (NULL == cond) {
return -EINVAL;
}
if (NULL == cond->lock) {
pthread_cond_init(cond, NULL);
}
return os_condv_signal((os_condv_t *)(cond->lock));
#else
pthread_cond_init(cond, NULL);
return os_condv_signal((os_condv_t *)(*cond));
#endif
}
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
{
#ifdef __MINILIBC__
if (NULL == cond) {
return -EINVAL;
}
if (NULL == cond->lock) {
pthread_cond_init(cond, NULL);
}
return os_condv_wait((os_condv_t *)(cond->lock), (os_mutex_t *)(mutex->mutex), pthread_timespec_delta(abstime));
#else
pthread_cond_init(cond, NULL);
return os_condv_wait((os_condv_t *)(*cond), (os_mutex_t *)(*mutex), pthread_timespec_delta(abstime));
#endif
}
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
#ifdef __MINILIBC__
if (NULL == cond) {
return -EINVAL;
}
if (NULL == cond->lock) {
pthread_cond_init(cond, NULL);
}
return os_condv_wait((os_condv_t *)(cond->lock), (os_mutex_t *)(mutex->mutex), osWaitForever);
#else
pthread_cond_init(cond, NULL);
return os_condv_wait((os_condv_t *)(*cond), (os_mutex_t *)(*mutex), osWaitForever);
#endif
}
int pthread_condattr_destroy(pthread_condattr_t *attr)
{
if (!attr) {
return -EINVAL;
}
return 0;
}
int pthread_condattr_init(pthread_condattr_t *attr)
{
if (!attr) {
return -EINVAL;
}
#ifdef LIB_PTHREAD_DEF
#if defined(_POSIX_THREAD_PROCESS_SHARED) || defined(__MINILIBC__)
attr->pshared = PTHREAD_PROCESS_PRIVATE;
#endif
#else
*attr = PTHREAD_PROCESS_PRIVATE;
#endif
return 0;
}
int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock_id)
{
return 0;
}
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
{
return 0;
}
int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared)
{
if (!attr || !pshared) {
return -EINVAL;
}
*pshared = PTHREAD_PROCESS_PRIVATE;
return 0;
}
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
{
if ((pshared != PTHREAD_PROCESS_PRIVATE) && (pshared != PTHREAD_PROCESS_SHARED)) {
return -EINVAL;
}
if (pshared != PTHREAD_PROCESS_PRIVATE) {
return -ENOSYS;
}
return 0;
}
#endif

View File

@@ -0,0 +1,198 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
#ifdef __MINILIBC__
os_mutex_t *m = (os_mutex_t *)(mutex->mutex);
if (m) {
os_mutex_del(m);
os_free(m);
}
mutex->initted = 0;
mutex->mutex = NULL;
mutex->attr = NULL;
#else
os_mutex_t *m = (os_mutex_t *)(*mutex);
if (m) {
os_mutex_del(m);
os_free(m);
}
#endif
return 0;
}
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
os_mutex_t *m;
#ifdef __MINILIBC__
if (NULL == mutex) {
return -EINVAL;
}
os_memset(mutex, 0, sizeof(pthread_mutex_t));
m = os_zalloc(sizeof(os_mutex_t));
if (m == NULL) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
os_mutex_init(m);
mutex->initted = 1;
mutex->mutex = m;
mutex->attr = (pthread_mutexattr_t *)attr;
#else
if (mutex == NULL) {
return -EINVAL;
}
m = os_zalloc(sizeof(os_mutex_t));
if (m == NULL) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
os_mutex_init(m);
*mutex = (pthread_mutex_t)m;
#endif
return RET_OK;
}
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
#ifdef __MINILIBC__
if (NULL == mutex) {
return -EINVAL;
}
if (NULL == mutex->mutex) {
pthread_mutex_init(mutex, NULL);
}
return os_mutex_lock((os_mutex_t *)(mutex->mutex), osWaitForever);
#else
os_mutex_t *m;
if (*mutex == 0) {
pthread_mutex_init(mutex, NULL);
}
m = (os_mutex_t *)(*mutex);
if (m) {
return os_mutex_lock(m, osWaitForever);
}
return -EINVAL;
#endif
}
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime)
{
#ifdef __MINILIBC__
if (NULL == mutex) {
return -EINVAL;
}
if (NULL == mutex->mutex) {
pthread_mutex_init(mutex, NULL);
}
return os_mutex_lock((os_mutex_t *)(mutex->mutex), pthread_timespec_delta(abstime));
#else
os_mutex_t *m;
if (*mutex == 0) {
pthread_mutex_init(mutex, NULL);
}
m = (os_mutex_t *)(*mutex);
if (m) {
return os_mutex_lock(m, pthread_timespec_delta(abstime));
}
return -EINVAL;
#endif
}
int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
#ifdef __MINILIBC__
if (NULL == mutex) {
return -EINVAL;
}
if (NULL == mutex->mutex) {
pthread_mutex_init(mutex, NULL);
}
return os_mutex_lock((os_mutex_t *)(mutex->mutex), 0);
#else
os_mutex_t *m;
if (*mutex == 0) {
pthread_mutex_init(mutex, NULL);
}
m = (os_mutex_t *)(*mutex);
if (m) {
return os_mutex_lock(m, 0);
}
return -EINVAL;
#endif
}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
#ifdef __MINILIBC__
if (NULL == mutex) {
return -EINVAL;
}
if (NULL == mutex->mutex) {
pthread_mutex_init(mutex, NULL);
}
return os_mutex_unlock((os_mutex_t *)(mutex->mutex));
#else
os_mutex_t *m;
if (*mutex == 0) {
pthread_mutex_init(mutex, NULL);
}
m = (os_mutex_t *)(*mutex);
if (m) {
return os_mutex_unlock(m);
}
return -EINVAL;
#endif
}
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
return 0;
}
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
{
return 0;
}
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
return 0;
}
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{
return 0;
}
#endif

View File

@@ -0,0 +1,343 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
{
if (!attr) {
return -EINVAL;
}
*attr = PTHREAD_PROCESS_PRIVATE;
return 0;
}
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
{
if (!attr) {
return -EINVAL;
}
return 0;
}
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr,
int *pshared)
{
if (!attr || !pshared) {
return -EINVAL;
}
*pshared = PTHREAD_PROCESS_PRIVATE;
return 0;
}
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
{
if (!attr || pshared != PTHREAD_PROCESS_PRIVATE) {
return -EINVAL;
}
return 0;
}
int pthread_rwlock_init(pthread_rwlock_t *rwlock,
const pthread_rwlockattr_t *attr)
{
if (!rwlock) {
return -EINVAL;
}
rwlock->attr = PTHREAD_PROCESS_PRIVATE;
pthread_mutex_init(&(rwlock->rw_mutex), NULL);
pthread_cond_init(&(rwlock->rw_condreaders), NULL);
pthread_cond_init(&(rwlock->rw_condwriters), NULL);
rwlock->rw_nwaitwriters = 0;
rwlock->rw_nwaitreaders = 0;
rwlock->rw_refcount = 0;
return 0;
}
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
return 0; /* rwlock is not initialized */
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
if (rwlock->rw_refcount != 0 ||
rwlock->rw_nwaitreaders != 0 ||
rwlock->rw_nwaitwriters != 0) {
return -EBUSY;
} else {
pthread_cond_destroy(&rwlock->rw_condreaders);
pthread_cond_destroy(&rwlock->rw_condwriters);
}
pthread_mutex_unlock(&rwlock->rw_mutex);
if (result == 0) {
pthread_mutex_destroy(&rwlock->rw_mutex);
}
return result;
}
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
/* give preference to waiting writers */
while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0) {
rwlock->rw_nwaitreaders++;
/* rw_mutex will be released when waiting for rw_condreaders */
result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex);
/* rw_mutex should have been taken again when returned from waiting */
rwlock->rw_nwaitreaders--;
if (result != 0) { /* wait error */
break;
}
}
/* another reader has a read lock */
if (result == 0) {
rwlock->rw_refcount++;
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
if (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0) {
result = -EBUSY; /* held by a writer or waiting writers */
} else {
rwlock->rw_refcount++; /* increment count of reader locks */
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock,
const struct timespec *abstime)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
/* give preference to waiting writers */
while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0) {
rwlock->rw_nwaitreaders++;
/* rw_mutex will be released when waiting for rw_condreaders */
result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime);
/* rw_mutex should have been taken again when returned from waiting */
rwlock->rw_nwaitreaders--;
if (result != 0) {
break;
}
}
/* another reader has a read lock */
if (result == 0) {
rwlock->rw_refcount++;
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock,
const struct timespec *abstime)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
while (rwlock->rw_refcount != 0) {
rwlock->rw_nwaitwriters++;
/* rw_mutex will be released when waiting for rw_condwriters */
result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime);
/* rw_mutex should have been taken again when returned from waiting */
rwlock->rw_nwaitwriters--;
if (result != 0) {
break;
}
}
if (result == 0) {
rwlock->rw_refcount = -1;
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
if (rwlock->rw_refcount != 0) {
result = -EBUSY; /* held by either writer or reader(s) */
} else {
rwlock->rw_refcount = -1; /* available, indicate a writer has it */
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
if (rwlock->rw_refcount > 0) {
rwlock->rw_refcount--; /* releasing a reader */
} else if (rwlock->rw_refcount == -1) {
rwlock->rw_refcount = 0; /* releasing a writer */
}
/* give preference to waiting writers over waiting readers */
if (rwlock->rw_nwaitwriters > 0) {
if (rwlock->rw_refcount == 0) {
result = pthread_cond_signal(&rwlock->rw_condwriters);
}
} else if (rwlock->rw_nwaitreaders > 0) {
result = pthread_cond_broadcast(&rwlock->rw_condreaders);
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
{
int result;
if (!rwlock) {
return -EINVAL;
}
if (rwlock->attr == -1) {
pthread_rwlock_init(rwlock, NULL);
}
if ((result = pthread_mutex_lock(&rwlock->rw_mutex)) != 0) {
return (result);
}
while (rwlock->rw_refcount != 0) {
rwlock->rw_nwaitwriters++;
/* rw_mutex will be released when waiting for rw_condwriters */
result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex);
/* rw_mutex should have been taken again when returned from waiting */
rwlock->rw_nwaitwriters--;
if (result != 0) {
break;
}
}
if (result == 0) {
rwlock->rw_refcount = -1;
}
pthread_mutex_unlock(&rwlock->rw_mutex);
return (result);
}
#endif

View File

@@ -0,0 +1,87 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "osal/irq.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
struct pthread_key_data {
int is_used;
void (*destructor)(void *args);
};
static struct pthread_key_data thread_keys[PTHREAD_KEY_MAX];
void pthread_key_destroy(void *tls)
{
uint32 index;
void **data = (void **)tls;
if (tls == NULL) {
return;
}
for (index = 0; index < PTHREAD_KEY_MAX; index++) {
if (thread_keys[index].is_used) {
if (data[index]) {
thread_keys[index].destructor(data[index]);
}
}
}
}
void *pthread_getspecific(pthread_key_t key)
{
void **tls = (void **)pthread_tls(pthread_self(), 0, 0);
if (tls && key < PTHREAD_KEY_MAX && thread_keys[key].is_used) {
return tls[key];
}
return NULL;
}
int pthread_setspecific(pthread_key_t key, const void *value)
{
void **tls = (void **)pthread_tls(pthread_self(), 1, PTHREAD_KEY_MAX * sizeof(void *));
if (tls && key < PTHREAD_KEY_MAX && thread_keys[key].is_used) {
tls[key] = (void *)value;
return RET_OK;
}
return -EINVAL;
}
int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
{
uint32 index;
uint32 flag = disable_irq();
for (index = 0; index < PTHREAD_KEY_MAX; index ++) {
if (thread_keys[index].is_used == 0) {
thread_keys[index].is_used = 1;
thread_keys[index].destructor = destructor;
*key = index;
enable_irq(flag);
return 0;
}
}
enable_irq(flag);
return -EAGAIN;
}
int pthread_key_delete(pthread_key_t key)
{
if (key >= PTHREAD_KEY_MAX) {
return -EINVAL;
}
uint32 flag = disable_irq();
thread_keys[key].is_used = 0;
thread_keys[key].destructor = 0;
enable_irq(flag);
return RET_OK;
}
#endif

35
sdk/lib/posix/sched.c Normal file
View File

@@ -0,0 +1,35 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int sched_yield(void)
{
os_task_yield();
return 0;
}
int sched_get_priority_min(int policy)
{
return OS_TASK_PRIORITY_LOW;
}
int sched_get_priority_max(int policy)
{
return OS_TASK_PRIORITY_HIGH;
}
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)
{
return -EOPNOTSUPP;
}
#endif

68
sdk/lib/posix/semaphore.c Normal file
View File

@@ -0,0 +1,68 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#ifdef TXWSDK_POSIX
int sem_destroy(sem_t *sem)
{
os_semaphore_t *s = (os_semaphore_t *)(*sem);
os_sema_del(s);
os_free(s);
return 0;
}
int sem_getvalue(sem_t *sem, int *sval)
{
*sval = os_sema_count((os_semaphore_t *)(*sem));
return 0;
}
int sem_init(sem_t *sem, int pshared, unsigned value)
{
os_semaphore_t *s;
if (sem == NULL) {
return -EINVAL;
}
s = (os_semaphore_t *)os_zalloc(sizeof(os_semaphore_t));
if (s == NULL) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
os_sema_init(s, 0);
*sem = (sem_t)s;
return RET_OK;
}
int sem_post(sem_t *sem)
{
return os_sema_up((os_semaphore_t *)(*sem));
}
int sem_timedwait(sem_t *sem, const struct timespec *abstime)
{
return os_sema_down((os_semaphore_t *)(*sem), pthread_timespec_delta(abstime));
}
int sem_trywait(sem_t *sem)
{
return os_sema_down((os_semaphore_t *)(*sem), 0);
}
int sem_wait(sem_t *sem)
{
return os_sema_down((os_semaphore_t *)(*sem), osWaitForever);
}
#endif

165
sdk/lib/posix/sockets.c Normal file
View File

@@ -0,0 +1,165 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/sleep.h"
#include "lwip/netdb.h"
#include "lwip/if_api.h"
#ifdef TXWSDK_POSIX
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
return lwip_accept(s, addr, addrlen);
}
int bind(int s, const struct sockaddr *name, socklen_t namelen)
{
return lwip_bind(s, name, namelen);
}
int shutdown(int s, int how)
{
return lwip_shutdown(s, how);
}
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
{
return lwip_getpeername(s, name, namelen);
}
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
{
return lwip_getsockname(s, name, namelen);
}
int setsockopt(int s, int level, int optname, const void *opval, socklen_t optlen)
{
return lwip_setsockopt(s, level, optname, opval, optlen);
}
int getsockopt(int s, int level, int optname, void *opval, socklen_t *optlen)
{
return lwip_getsockopt(s, level, optname, opval, optlen);
}
int closesocket(int s)
{
return lwip_close(s);
}
int connect(int s, const struct sockaddr *name, socklen_t namelen)
{
return lwip_connect(s, name, namelen);
}
int listen(int s, int backlog)
{
return lwip_listen(s, backlog);
}
ssize_t recv(int s, void *mem, size_t len, int flags)
{
return lwip_recv(s, mem, len, flags);
}
ssize_t recvmsg(int s, struct msghdr *message, int flags)
{
return lwip_recvmsg(s, message, flags);
}
ssize_t recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
{
return lwip_recvfrom(s, mem, len, flags, from, fromlen);
}
ssize_t send(int s, const void *dataptr, size_t size, int flags)
{
return lwip_send(s, dataptr, size, flags);
}
ssize_t sendmsg(int s, const struct msghdr *msg, int flags)
{
return lwip_sendmsg(s, msg, flags);
}
ssize_t sendto(int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
{
return lwip_sendto(s, data, size, flags, to, tolen);
}
int socket(int domain, int type, int protocol)
{
return lwip_socket(domain, type, protocol);
}
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout)
{
return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
}
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
return lwip_poll(fds, nfds, timeout);
}
int ioctlsocket(int s, long cmd, void *argp)
{
return lwip_ioctl(s, cmd, argp);
}
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{
return lwip_inet_ntop(af, src, dst, size);
}
int inet_pton(int af, const char *src, void *dst)
{
return lwip_inet_pton(af, src, dst);
}
char *if_indextoname(unsigned int ifindex, char *ifname)
{
return lwip_if_indextoname(ifindex, ifname);
}
unsigned int if_nametoindex(const char *ifname)
{
return lwip_if_nametoindex(ifname);
}
struct hostent *gethostbyname(const char *name)
{
return lwip_gethostbyname(name, 1);
}
int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop)
{
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop, 1);
}
struct hostent *gethostbyname_async(const char *name)
{
return lwip_gethostbyname(name, 0);
}
int gethostbyname_r_async(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop)
{
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop, 0);
}
void freeaddrinfo(struct addrinfo *ai)
{
lwip_freeaddrinfo(ai);
}
int getaddrinfo(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
return lwip_getaddrinfo(nodename, servname, hints, res);
}
#endif

556
sdk/lib/posix/stdio.c Normal file
View File

@@ -0,0 +1,556 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/sleep.h"
#include "osal/string.h"
#include "lib/posix/stdio.h"
#include "lwip/sockets.h"
#ifdef TXWSDK_POSIX
#if FS_EN
#include "fatfs/osal_file.h"
#include "fatfs/ff.h"
#endif
#define FILE void
#define FS_PSRAM_BUFF 1
/* sram slice buffer size, usr for psram slice write to sd */
#define STDIO_RWBUF_SIZE 10000
extern int osal_open(const char *filename, int oflags, int mode);
int read(int fd, void *buf, size_t nbytes);
int write(int fd, const void *buf, size_t nbytes);
#define ENV_MAX_CNT (8)
static const char *_env_list_[ENV_MAX_CNT][2];
char *getenv(const char *name)
{
int32 i = 0;
for (i = 0; i < ENV_MAX_CNT; i++) {
if (_env_list_[i][0] == name) {
return (char *)_env_list_[i][1];
}
}
return NULL;
}
int setenv(const char *name, const char *value, int overwrite)
{
int32 i = 0;
int32 j = -1;
for (i = 0; i < ENV_MAX_CNT; i++) {
if (_env_list_[i][0] == name) {
break;
}
if (j == -1 && _env_list_[i][0] == NULL) {
j = i;
}
}
if (i < ENV_MAX_CNT && (overwrite || _env_list_[i][1] == NULL)) {
_env_list_[i][1] = value;
} else if (i >= ENV_MAX_CNT && j != -1) {
_env_list_[j][0] = name;
_env_list_[j][1] = value;
} else {
return -1;
}
return 0;
}
int unsetenv(const char *name)
{
int32 i = 0;
for (i = 0; i < ENV_MAX_CNT; i++) {
if (_env_list_[i][0] == name) {
_env_list_[i][0] = NULL;
_env_list_[i][1] = NULL;
break;
}
}
return 0;
}
int usleep(unsigned long usec)
{
os_sleep_us(usec);
return 0;
}
unsigned int sleep(unsigned int seconds)
{
os_sleep(seconds);
return 0;
}
int access(const char *pathname, int mode)
{
#if FS_EN
return osal_fexist(pathname);
#else
return -1;
#endif
}
int fclose(FILE *stream)
{
#if FS_EN
return osal_fclose((F_FILE *)stream);
#else
return -1;
#endif
}
int feof(FILE *stream)
{
#if FS_EN
return f_eof((F_FILE *)stream);
#else
return -1;
#endif
}
int ferror(FILE *stream)
{
#if FS_EN
return f_error((F_FILE *)stream);
#else
return -1;
#endif
}
int fflush(FILE *stream)
{
#if FS_EN
return fsync((int)stream);
#else
return -1;
#endif
}
FILE *fopen(const char *filename, const char *mode)
{
#if FS_EN
return (FILE *)osal_fopen(filename, mode);
#else
return 0;
#endif
}
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
#if FS_EN
return read((int)stream, ptr, size * nmemb);
#else
return 0;
#endif
}
int fseek(FILE *stream, long int offset, int whence)
{
// TODO: not support whence now
#if FS_EN
return osal_fseek((F_FILE *)stream, offset);
#else
return 0;
#endif
}
// FIXME: 仅支持获取文件大小, 不支持从指针位置开始
long ftell(FILE *stream)
{
#if FS_EN
return f_size((FIL *)stream);
#else
return 0;
#endif
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
#if FS_EN
return write((int)stream, ptr, size *nmemb);
#else
return 0;
#endif
}
// ADD truncate
int fileno(FILE *stream)
{
return (int)stream;
}
int ftruncate(int fd, off_t length)
{
#if FS_EN
return f_truncate((F_FILE *)fd);
#else
return -1;
#endif
}
int remove(char *filename)
{
#if FS_EN
return osal_unlink(filename);
#else
return -1;
#endif
}
int rename(const char *old_filename, const char *new_filename)
{
#if FS_EN
return osal_rename(old_filename, new_filename);
#else
return 0;
#endif
}
void rewind(FILE *stream)
{
#if FS_EN
f_rewind((FIL*)stream);
#else
return;
#endif
}
int vfprintf(FILE *stream, const char *format, va_list arg)
{
#if FS_EN
int f_vprintf (FIL* fp,const TCHAR* fmt,va_list arp);
return f_vprintf((FIL*)stream, format, arg);
#else
return -1;
#endif
}
/*
int fgetc(FILE *stream)
{
uint8 val = 0;
osal_fread(val, 1, 1, stream);
return val;
}
*/
char *fgets(char *str, int n, FILE *stream)
{
#if FS_EN
return f_gets(str, n, (FIL*)stream);
#else
return NULL;
#endif
}
/*
int fputc(int c, FILE *stream)
{
return f_putc(c, stream);
}
int fputs(const char *str, FILE *stream)
{
return f_puts(str, stream);
}
*/
int fsync(int fd)
{
#if FS_EN
return f_sync((F_FILE *)fd) == FR_OK ? 0 : -1;
#else
return -1;
#endif
}
int getc(FILE *stream)
{
uint8 val = 0;
#if FS_EN
osal_fread(&val, 1, 1, (F_FILE *)stream);
#endif
return val;
}
/*
int putc(int c, FILE *stream)
{
return f_putc(c, stream);
}
*/
int stat(const char *path, struct stat *buf)
{
#if FS_EN
FILINFO *file_info = (FILINFO *)os_malloc(sizeof(FILINFO));
f_stat(path, file_info);
buf->st_size = file_info->fsize;
buf->st_mtime = file_info->ftime;
buf->fattrib = file_info->fattrib;
buf->st_mode = (file_info->fattrib & AM_DIR) ? S_IFDIR : S_IFREG;
buf->fname = NULL;
os_free(file_info);
#endif
return 0;
}
// TODO: just support file size for now
int fstat(int fd, struct stat *statbuf)
{
#if FS_EN
F_FILE *file = (F_FILE *)fd;
statbuf->st_size = f_size(file);
#endif
return 0;
}
#if FS_EN && FS_PSRAM_BUFF
int write_from_psram(int fd, const char *psram_buf, size_t nbytes)
{
int left_len = nbytes;
int write_len = 0;
int wlen = 0;
int len = -1;
char *sram_buf = os_malloc(STDIO_RWBUF_SIZE);
if(sram_buf == NULL){
return -ENOMEM;
}
while (left_len) {
wlen = left_len < STDIO_RWBUF_SIZE ? left_len : STDIO_RWBUF_SIZE;
hw_memcpy(sram_buf, psram_buf + write_len, wlen);
len = (int)osal_fwrite(sram_buf, wlen, 1, (F_FILE *)fd);
if (len < wlen) {
os_free(sram_buf);
return write_len + len;
}
left_len -= wlen;
write_len += wlen;
}
os_free(sram_buf);
return write_len;
}
#endif
int write(int fd, const void *buf, size_t nbytes)
{
if (fd > 0 && fd < 256) {
return lwip_write(fd, buf, nbytes);
} else {
#if FS_EN
#if FS_PSRAM_BUFF
return write_from_psram(fd, buf, nbytes);
#else
return osal_fwrite(buf, nbytes, 1, (F_FILE *)fd);
#endif
#else
return -1;
#endif
}
}
#if FS_EN && FS_PSRAM_BUFF
int read_to_psram(int fd, char *psram_buf, size_t nbytes)
{
int left_len = nbytes;
int read_len = 0;
int rlen = 0;
int len = -1;
char *sram_buff = os_malloc(STDIO_RWBUF_SIZE);
if(sram_buff == NULL){
return -ENOMEM;
}
while (left_len) {
rlen = left_len < STDIO_RWBUF_SIZE ? left_len : STDIO_RWBUF_SIZE;
len = (int)osal_fread(sram_buff, rlen, 1, (F_FILE *)fd);
hw_memcpy(psram_buf + read_len, sram_buff, len);
if (len < rlen) {
os_free(sram_buff);
return read_len + len;
}
left_len -= rlen;
read_len += rlen;
}
os_free(sram_buff);
return read_len;
}
#endif
int read(int fd, void *buf, size_t nbytes)
{
if (fd > 0 && fd < 256) {
return lwip_read(fd, buf, nbytes);
} else {
#if FS_EN
#if FS_PSRAM_BUFF
return read_to_psram(fd, buf, nbytes);
#else
return osal_fread(buf, nbytes, 1, (F_FILE *)fd);
#endif
#else
return -1;
#endif
}
}
off_t lseek(int fd, off_t offset, int whence)
{
// TODO: whence not support now
#if FS_EN
return osal_fseek((F_FILE *)fd, offset) == FR_OK ? offset : -1;
#else
return 0;
#endif
}
int open(const char *path, int oflags, ...)
{
int handler = 0;
#if FS_EN
int flags = 0;
#if 0
/* mode is not use */
int mode = 0;
va_list arg;
va_start(arg, oflags);
mode = va_arg(arg, int);
va_end(arg);
#endif
if (ACC_MODE(oflags) == O_RDWR) {
flags = (FA_READ | FA_WRITE);
} else if (ACC_MODE(oflags) == O_RDONLY) {
flags = FA_READ;
} else {
flags = FA_WRITE;
}
if (oflags & O_CREAT) {
flags |= FA_CREATE_ALWAYS;
}
handler = (int)osal_open(path, 0, flags);
#endif
return handler == 0 ? -1 : handler;
}
int close(int fd)
{
if (fd > 0 && fd < 256) {
return lwip_close(fd);
} else {
#if FS_EN
return osal_fclose((F_FILE *)fd);
#else
return -1;
#endif
}
}
int unlink(const char *path)
{
#if FS_EN
return osal_unlink(path);
#else
return -1;
#endif
}
int fcntl(int fd, int cmd, ...)
{
int arg = 0;
va_list ap;
va_start(ap, cmd);
arg = va_arg(ap, int);
va_end(ap);
if (fd > 0 && fd < 256) {
return lwip_fcntl(fd, cmd, arg);
} else {
#if FS_EN
return f_cntl((FIL *)fd, cmd, arg);
#else
return -1;
#endif
}
}
int ioctl(int fd, long cmd, void *argp)
{
if (fd > 0 && fd < 256) {
return lwip_ioctl(fd, cmd, argp);
} else {
#if FS_EN
return f_ioctl((FIL *)fd, cmd, argp);
#else
return -1;
#endif
}
}
ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
{
if (fd > 0 && fd < 256) {
return lwip_readv(fd, iov, iovcnt);
} else {
return -1;
}
}
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
{
if (fd > 0 && fd < 256) {
return lwip_writev(fd, iov, iovcnt);
} else {
return -1;
}
}
int fputs(const char *str, FILE *stream)
{
#if FS_EN
return fwrite(str, 1, os_strlen(str), stream);
#else
return 0;
#endif
}
int _fclose_r (void *rptr, FILE * fp)
{
return fclose(fp);
}
int _fflush_r (void *rptr, FILE *fp)
{
return fflush(fp);
}
#else
int _fclose_r (void *rptr, void * fp)
{
return 0;
}
int _fflush_r (void *rptr, void *fp)
{
return 0;
}
#endif

227
sdk/lib/posix/timer.c Normal file
View File

@@ -0,0 +1,227 @@
#include "sys_config.h"
#include "typesdef.h"
#include "errno.h"
#include "osal/semaphore.h"
#include "osal/task.h"
#include "osal/string.h"
#include "osal/timer.h"
#include "osal/mutex.h"
#include "lib/common/rbuffer.h"
#include "lib/posix/pthread.h"
#include "osal/sleep.h"
#ifdef TXWSDK_POSIX
#define TIMESPEC_IS_ZERO(tm) (tm.tv_sec == 0 && tm.tv_nsec == 0)
#define TIMESPEC_IS_NOT_ZERO(tm) (!(TIMESPEC_IS_ZERO( tm)))
struct posix_timer {
os_timer_t timer;
struct sigevent event;
uint64 period_time;
uint64 expired_time;
};
void posix_timer_cb(void *arg)
{
pthread_t pthd;
struct posix_timer *ptimer = (struct posix_timer *)(arg);
/* Update the timer period, which may need to be set to an it_interval
* argument. This call should not block. */
if (ptimer->period_time > 0) {
os_timer_start(&ptimer->timer, ptimer->period_time);
}
/* Create the timer notification thread if requested. */
if (ptimer->event.sigev_notify == SIGEV_THREAD) {
/* if the user has provided thread attributes, create a thread
* with the provided attributes. Otherwise dispatch callback directly */
if (ptimer->event.sigev_notify_attributes == NULL) {
(*ptimer->event.sigev_notify_function)(ptimer->event.sigev_value);
} else {
pthread_create(&pthd,
ptimer->event.sigev_notify_attributes,
(void *(*)(void *))ptimer->event.sigev_notify_function,
ptimer->event.sigev_value.sival_ptr);
}
}
}
int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
{
int ret = 0;
struct posix_timer *ptimer = NULL;
/* POSIX specifies that when evp is NULL, the behavior shall be as is
* sigev_notify is SIGEV_SIGNAL. SIGEV_SIGNAL is currently not supported. */
if ((evp == NULL) || (evp->sigev_notify == SIGEV_SIGNAL)) {
return -ENOTSUP;
}
ptimer = os_zalloc(sizeof(struct posix_timer));
if (ptimer == NULL) {
pthread_err("alloc fail\r\n");
return -ENOMEM;
}
ptimer->event = *evp;
if (ptimer->event.sigev_notify_attributes && ptimer->event.sigev_notify_attributes->detachstate != PTHREAD_CREATE_DETACHED) {
pthread_err("timer sigev_notify_attributes detachstate is NOT DETACHED\r\n");
ptimer->event.sigev_notify_attributes->detachstate = PTHREAD_CREATE_DETACHED;
}
ret = os_timer_init(&ptimer->timer, posix_timer_cb, OS_TIMER_MODE_ONCE, ptimer);
if (!ret) {
*timerid = (timer_t)ptimer;
} else {
pthread_err("os_timer_init fail\r\n");
os_free(ptimer);
}
return ret;
}
int timer_delete(timer_t timerid)
{
struct posix_timer *ptimer = (struct posix_timer *)(timerid);
os_timer_stop(&ptimer->timer);
while (os_timer_stat(&ptimer->timer)) {
os_sleep_ms(1);
}
os_timer_del(&ptimer->timer);
os_free(ptimer);
return 0;
}
int timer_getoverrun(timer_t timerid)
{
return 0;
}
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue)
{
int ret = 0;
struct posix_timer *ptimer = (struct posix_timer *)(timerid);
uint64 expired_jiff = 0;
uint64 period_jiff = 0;
/* Validate the value argument, but only if the timer isn't being disarmed. */
if (TIMESPEC_IS_NOT_ZERO(value->it_value)) {
if (!timespec_validate(&value->it_interval) || !timespec_validate(&value->it_value)) {
return -EINVAL;
}
}
/* Set ovalue, if given. */
if (ovalue != NULL) {
timer_gettime(timerid, ovalue);
}
/* Stop the timer if it's currently active. */
if (os_timer_stat(&ptimer->timer)) {
os_timer_stop(&ptimer->timer);
}
/* Only restart the timer if it_value is not zero. */
if (TIMESPEC_IS_NOT_ZERO(value->it_value)) {
/* Convert it_interval to ticks, but only if it_interval is not 0. If
* it_interval is 0, then the timer is not periodic. */
if (TIMESPEC_IS_NOT_ZERO(value->it_interval)) {
timespec_to_ticks(&value->it_interval, &period_jiff);
}
/* Set the new timer period. A non-periodic timer will have its period set
* to portMAX_DELAY. */
ptimer->period_time = period_jiff;
/* Convert it_value to ticks, but only if it_value is not 0. If it_value
* is 0, then the timer will remain disarmed. */
if (TIMESPEC_IS_NOT_ZERO(value->it_value)) {
/* Absolute timeout. */
if ((flags & TIMER_ABSTIME) == TIMER_ABSTIME) {
struct timespec cur_tm = { 0 };
/* Get current time */
if (clock_gettime(CLOCK_REALTIME, &cur_tm) != 0) {
ret = -EINVAL;
} else {
ret = timespec_detal_ticks(&value->it_value, &cur_tm, &expired_jiff);
}
/* Make sure expired_jiff is zero in case we got negative time difference */
if (ret != 0) {
expired_jiff = 0;
if (ret == -ETIMEDOUT) {
/* Set Status to 0 as absolute time is past is treated as expiry but not an error */
ret = 0;
}
}
} else {/* Relative timeout. */
timespec_to_ticks(&value->it_value, &expired_jiff);
}
}
/* If expired_jiff is still 0, that means that it_value specified
* an absolute timeout in the past. Per POSIX spec, a notification should be
* triggered immediately. */
if (expired_jiff == 0) {
posix_timer_cb(ptimer);
} else {
ptimer->expired_time = os_jiffies() + expired_jiff;
os_timer_start(&ptimer->timer, os_jiffies_to_msecs(expired_jiff));
}
}
return ret;
}
int timer_gettime(timer_t timerid, struct itimerspec *value)
{
struct posix_timer *ptimer = (struct posix_timer *)(timerid);
uint64 expired_time = ptimer->expired_time - os_jiffies();
uint64 period_time = ptimer->period_time;
/* Set it_value only if the timer is armed. Otherwise, set it to 0. */
if (os_timer_stat(&ptimer->timer)) {
value->it_value.tv_sec = (time_t)(expired_time / OS_SYSTICK_HZ);
value->it_value.tv_nsec = (long)((expired_time % OS_SYSTICK_HZ) * NANOSECONDS_PER_TICK);
} else {
value->it_value.tv_sec = 0;
value->it_value.tv_nsec = 0;
}
/* Set it_interval only if the timer is periodic. Otherwise, set it to 0. */
if (period_time != osWaitForever) {
value->it_interval.tv_sec = (time_t)(period_time / OS_SYSTICK_HZ);
value->it_interval.tv_nsec = (long)((period_time % OS_SYSTICK_HZ) * NANOSECONDS_PER_TICK);
} else {
value->it_interval.tv_sec = 0;
value->it_interval.tv_nsec = 0;
}
return 0;
}
#if 0 //see: include/osal/csky/time.h
void timeradd(struct timeval *a, struct timeval *b, struct timeval *res)
{
res->tv_sec = a->tv_sec + b->tv_sec;
res->tv_usec = a->tv_usec + b->tv_usec;
if (res->tv_usec >= 1000000) {
++res->tv_sec;
res->tv_usec -= 1000000;
}
}
void timersub(struct timeval *a, struct timeval *b, struct timeval *res)
{
res->tv_sec = a->tv_sec - b->tv_sec;
res->tv_usec = a->tv_usec - b->tv_usec;
if (res->tv_usec < 0) {
--res->tv_sec;
res->tv_usec += 1000000;
}
}
#endif
#endif