mirror of
https://github.com/Ai-Thinker-Open/Ai-Thinker-Open_RTL8710BX_ALIOS_SDK.git
synced 2026-07-11 20:55:39 +00:00
rel_1.6.0 init
This commit is contained in:
commit
27b3e2883d
19359 changed files with 8093121 additions and 0 deletions
479
Living_SDK/kernel/vcall/aos/aos_freertos.c
Normal file
479
Living_SDK/kernel/vcall/aos/aos_freertos.c
Normal file
|
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
#include <aos/aos.h>
|
||||
|
||||
#define ms2tick(ms) (((ms)+portTICK_PERIOD_MS-1)/portTICK_PERIOD_MS)
|
||||
|
||||
void aos_reboot(void)
|
||||
{
|
||||
}
|
||||
|
||||
int aos_get_hz(void)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
const char *aos_version_get(void)
|
||||
{
|
||||
return "aos-linux-xxx";
|
||||
}
|
||||
|
||||
#define AOS_MAGIC 0x20171020
|
||||
typedef struct {
|
||||
StaticTask_t fTask;
|
||||
uint32_t key_bitmap;
|
||||
void *keys[4];
|
||||
void *stack;
|
||||
char name[32];
|
||||
uint32_t magic;
|
||||
} AosStaticTask_t;
|
||||
|
||||
struct targ {
|
||||
AosStaticTask_t *task;
|
||||
void (*fn)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void dfl_entry(void *arg)
|
||||
{
|
||||
struct targ *targ = arg;
|
||||
void (*fn)(void *) = targ->fn;
|
||||
void *farg = targ->arg;
|
||||
free(targ);
|
||||
|
||||
fn(farg);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void vPortCleanUpTCB(void *pxTCB)
|
||||
{
|
||||
AosStaticTask_t *task = (AosStaticTask_t *)pxTCB;
|
||||
|
||||
if (task->magic != AOS_MAGIC)
|
||||
return;
|
||||
|
||||
free(task->stack);
|
||||
free(task);
|
||||
}
|
||||
|
||||
int aos_task_new(const char *name, void (*fn)(void *), void *arg,
|
||||
int stack_size)
|
||||
{
|
||||
xTaskHandle xHandle;
|
||||
AosStaticTask_t *task = malloc(sizeof(AosStaticTask_t));
|
||||
struct targ *targ = malloc(sizeof(*targ));
|
||||
void *stack = malloc(stack_size);
|
||||
|
||||
bzero(stack, stack_size);
|
||||
bzero(task, sizeof(*task));
|
||||
task->key_bitmap = 0xfffffff0;
|
||||
task->stack = stack;
|
||||
strncpy(task->name, name, sizeof(task->name)-1);
|
||||
task->magic = AOS_MAGIC;
|
||||
|
||||
targ->task = task;
|
||||
targ->fn = fn;
|
||||
targ->arg = arg;
|
||||
|
||||
stack_size /= sizeof(StackType_t);
|
||||
xHandle = xTaskCreateStatic(dfl_entry, name, stack_size, targ,
|
||||
10, stack, &task->fTask);
|
||||
if (xHandle == NULL) {
|
||||
free(task);
|
||||
free(stack);
|
||||
free(targ);
|
||||
}
|
||||
return xHandle ? 0 : -1;
|
||||
}
|
||||
|
||||
int aos_task_new_ext(aos_task_t *task, const char *name, void (*fn)(void *), void *arg,
|
||||
int stack_size, int prio)
|
||||
{
|
||||
return aos_task_new(name, fn, arg, stack_size);
|
||||
}
|
||||
|
||||
void aos_task_exit(int code)
|
||||
{
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
const char *aos_task_name(void)
|
||||
{
|
||||
AosStaticTask_t *task = (AosStaticTask_t *)xTaskGetCurrentTaskHandle();
|
||||
if (task->magic != AOS_MAGIC)
|
||||
return "unknown";
|
||||
return task->name;
|
||||
}
|
||||
|
||||
int aos_task_key_create(aos_task_key_t *key)
|
||||
{
|
||||
AosStaticTask_t *task = (AosStaticTask_t *)xTaskGetCurrentTaskHandle();
|
||||
int i;
|
||||
|
||||
if (task->magic != AOS_MAGIC)
|
||||
return -1;
|
||||
|
||||
for (i=0;i<4;i++) {
|
||||
if (task->key_bitmap & (1 << i))
|
||||
continue;
|
||||
|
||||
task->key_bitmap |= 1 << i;
|
||||
*key = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void aos_task_key_delete(aos_task_key_t key)
|
||||
{
|
||||
AosStaticTask_t *task = (AosStaticTask_t *)xTaskGetCurrentTaskHandle();
|
||||
if (task->magic != AOS_MAGIC)
|
||||
return;
|
||||
task->key_bitmap &= ~(1 << key);
|
||||
}
|
||||
|
||||
int aos_task_setspecific(aos_task_key_t key, void *vp)
|
||||
{
|
||||
AosStaticTask_t *task = (AosStaticTask_t *)xTaskGetCurrentTaskHandle();
|
||||
if (key >= 4)
|
||||
return -1;
|
||||
|
||||
if (task->magic != AOS_MAGIC)
|
||||
return -1;
|
||||
|
||||
task->keys[key] = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *aos_task_getspecific(aos_task_key_t key)
|
||||
{
|
||||
AosStaticTask_t *task = (AosStaticTask_t *)xTaskGetCurrentTaskHandle();
|
||||
if (key >= 4)
|
||||
return NULL;
|
||||
|
||||
if (task->magic != AOS_MAGIC)
|
||||
return NULL;
|
||||
|
||||
return task->keys[key];
|
||||
}
|
||||
|
||||
int aos_mutex_new(aos_mutex_t *mutex)
|
||||
{
|
||||
SemaphoreHandle_t mux = xSemaphoreCreateMutex();
|
||||
mutex->hdl = mux;
|
||||
return mux != NULL ? 0 : -1;
|
||||
}
|
||||
|
||||
void aos_mutex_free(aos_mutex_t *mutex)
|
||||
{
|
||||
vSemaphoreDelete(mutex->hdl);
|
||||
}
|
||||
|
||||
int aos_mutex_lock(aos_mutex_t *mutex, unsigned int ms)
|
||||
{
|
||||
if (mutex) {
|
||||
xSemaphoreTake(mutex->hdl, ms == AOS_WAIT_FOREVER ? portMAX_DELAY : ms2tick(ms));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_mutex_unlock(aos_mutex_t *mutex)
|
||||
{
|
||||
if (mutex) {
|
||||
xSemaphoreGive(mutex->hdl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_mutex_is_valid(aos_mutex_t *mutex)
|
||||
{
|
||||
return mutex->hdl != NULL;
|
||||
}
|
||||
|
||||
int aos_sem_new(aos_sem_t *sem, int count)
|
||||
{
|
||||
SemaphoreHandle_t s = xSemaphoreCreateCounting(128, count);
|
||||
sem->hdl = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_sem_free(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
vSemaphoreDelete(sem->hdl);
|
||||
}
|
||||
|
||||
int aos_sem_wait(aos_sem_t *sem, unsigned int ms)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = xSemaphoreTake(sem->hdl, ms == AOS_WAIT_FOREVER ? portMAX_DELAY : ms2tick(ms));
|
||||
return ret == pdPASS ? 0 : -1;
|
||||
}
|
||||
|
||||
void aos_sem_signal(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xSemaphoreGive(sem->hdl);
|
||||
}
|
||||
|
||||
int aos_sem_is_valid(aos_sem_t *sem)
|
||||
{
|
||||
return sem && sem->hdl != NULL;
|
||||
}
|
||||
|
||||
void aos_sem_signal_all(aos_sem_t *sem)
|
||||
{
|
||||
aos_sem_signal(sem);
|
||||
}
|
||||
|
||||
int aos_queue_new(aos_queue_t *queue, void *buf, unsigned int size, int max_msg)
|
||||
{
|
||||
xQueueHandle q;
|
||||
q = xQueueCreate(size / max_msg, max_msg);
|
||||
queue->hdl = q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_queue_free(aos_queue_t *queue)
|
||||
{
|
||||
vQueueDelete(queue->hdl);
|
||||
}
|
||||
|
||||
int aos_queue_send(aos_queue_t *queue, void *msg, unsigned int size)
|
||||
{
|
||||
return xQueueSend(queue->hdl, msg, portMAX_DELAY) == pdPASS ? 0 : -1;
|
||||
}
|
||||
|
||||
int aos_queue_recv(aos_queue_t *queue, unsigned int ms, void *msg,
|
||||
unsigned int *size)
|
||||
{
|
||||
return xQueueReceive(queue->hdl, msg, ms == AOS_WAIT_FOREVER ? portMAX_DELAY : ms2tick(ms))
|
||||
== pdPASS ? 0 : -1;
|
||||
}
|
||||
|
||||
int aos_queue_is_valid(aos_queue_t *queue)
|
||||
{
|
||||
return queue && queue->hdl != NULL;
|
||||
}
|
||||
|
||||
void *aos_queue_buf_ptr(aos_queue_t *queue)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int aos_timer_new(aos_timer_t *timer, void (*fn)(void *, void *),
|
||||
void *arg, int ms, int repeat)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void aos_timer_free(aos_timer_t *timer)
|
||||
{
|
||||
}
|
||||
|
||||
int aos_timer_start(aos_timer_t *timer)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_timer_stop(aos_timer_t *timer)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_timer_change(aos_timer_t *timer, int ms)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_workqueue_create(aos_workqueue_t *workqueue, int pri, int stack_size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct work {
|
||||
void (*fn)(void *);
|
||||
void *arg;
|
||||
int dly;
|
||||
};
|
||||
|
||||
int aos_work_init(aos_work_t *work, void (*fn)(void *), void *arg, int dly)
|
||||
{
|
||||
struct work *w = malloc(sizeof(*w));
|
||||
w->fn = fn;
|
||||
w->arg = arg;
|
||||
w->dly = dly;
|
||||
work->hdl = w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_work_destroy(aos_work_t *work)
|
||||
{
|
||||
free(work->hdl);
|
||||
}
|
||||
|
||||
int aos_work_run(aos_workqueue_t *workqueue, aos_work_t *work)
|
||||
{
|
||||
return aos_work_sched(work);
|
||||
}
|
||||
|
||||
static void worker_entry(void *arg)
|
||||
{
|
||||
struct work *w = arg;
|
||||
if (w->dly) {
|
||||
usleep(w->dly * 1000);
|
||||
}
|
||||
w->fn(w->arg);
|
||||
}
|
||||
|
||||
int aos_work_sched(aos_work_t *work)
|
||||
{
|
||||
struct work *w = work->hdl;
|
||||
return aos_task_new("worker", worker_entry, w, 8192);
|
||||
}
|
||||
|
||||
int aos_work_cancel(aos_work_t *work)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *aos_zalloc(unsigned int size)
|
||||
{
|
||||
return calloc(size, 1);
|
||||
}
|
||||
|
||||
void *aos_malloc(unsigned int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *aos_realloc(void *mem, unsigned int size)
|
||||
{
|
||||
return realloc(mem, size);
|
||||
}
|
||||
|
||||
void aos_alloc_trace(void *addr, size_t allocator)
|
||||
{
|
||||
}
|
||||
|
||||
void aos_free(void *mem)
|
||||
{
|
||||
free(mem);
|
||||
}
|
||||
|
||||
#ifndef timercmp
|
||||
#define timercmp(a, b, op) ({ \
|
||||
unsigned long long _v1 = (a)->tv_sec * 1000000ULL + (a)->tv_usec; \
|
||||
unsigned long long _v2 = (b)->tv_sec * 1000000ULL + (b)->tv_usec; \
|
||||
_v1 op _v2; \
|
||||
})
|
||||
|
||||
void timersub(struct timeval *a, struct timeval *b, struct timeval *res)
|
||||
{
|
||||
res->tv_usec = a->tv_usec - b->tv_usec;
|
||||
res->tv_sec = a->tv_sec - b->tv_sec;
|
||||
if (res->tv_usec < 0) {
|
||||
res->tv_usec += 1000000;
|
||||
res->tv_sec -= 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct timeval sys_start_time;
|
||||
long long aos_now(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long long ns;
|
||||
gettimeofday(&tv, NULL);
|
||||
timersub(&tv, &sys_start_time, &tv);
|
||||
ns = tv.tv_sec * 1000000LL + tv.tv_usec;
|
||||
return ns * 1000LL;
|
||||
}
|
||||
|
||||
long long aos_now_ms(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long long ms;
|
||||
gettimeofday(&tv, NULL);
|
||||
timersub(&tv, &sys_start_time, &tv);
|
||||
ms = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
|
||||
return ms;
|
||||
}
|
||||
|
||||
void aos_msleep(int ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
void aos_init(void)
|
||||
{
|
||||
gettimeofday(&sys_start_time, NULL);
|
||||
}
|
||||
|
||||
void aos_start(void)
|
||||
{
|
||||
}
|
||||
|
||||
void dumpsys_task_func(void)
|
||||
{
|
||||
#if configUSE_TRACE_FACILITY
|
||||
TaskStatus_t *pxTaskStatusArray;
|
||||
volatile UBaseType_t uxArraySize, x;
|
||||
uint32_t ulTotalRunTime, ulStatsAsPercentage;
|
||||
|
||||
uxArraySize = uxTaskGetNumberOfTasks();
|
||||
pxTaskStatusArray = malloc( uxArraySize * sizeof( TaskStatus_t ) );
|
||||
if( pxTaskStatusArray == NULL )
|
||||
return;
|
||||
|
||||
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
|
||||
// For percentage calculations.
|
||||
ulTotalRunTime /= 100UL;
|
||||
|
||||
// Avoid divide by zero errors.
|
||||
if( ulTotalRunTime > 0 )
|
||||
{
|
||||
// For each populated position in the pxTaskStatusArray array,
|
||||
// format the raw data as human readable ASCII data
|
||||
for( x = 0; x < uxArraySize; x++ )
|
||||
{
|
||||
// What percentage of the total run time has the task used?
|
||||
// This will always be rounded down to the nearest integer.
|
||||
// ulTotalRunTimeDiv100 has already been divided by 100.
|
||||
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
|
||||
|
||||
if( ulStatsAsPercentage > 0UL )
|
||||
{
|
||||
printf("%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s\t\t%u\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free( pxTaskStatusArray );
|
||||
#endif
|
||||
}
|
||||
436
Living_SDK/kernel/vcall/aos/aos_posix.c
Normal file
436
Living_SDK/kernel/vcall/aos/aos_posix.c
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#undef WITH_LWIP
|
||||
#undef WITH_SAL
|
||||
#include <aos/aos.h>
|
||||
#include <poll.h>
|
||||
|
||||
void aos_reboot(void)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int aos_get_hz(void)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
const char *aos_version_get(void)
|
||||
{
|
||||
return "aos-linux-xxx";
|
||||
}
|
||||
|
||||
struct targ {
|
||||
const char *name;
|
||||
void (*fn)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void *dfl_entry(void *arg)
|
||||
{
|
||||
struct targ *targ = arg;
|
||||
void (*fn)(void *) = targ->fn;
|
||||
void *farg = targ->arg;
|
||||
prctl(PR_SET_NAME, (unsigned long)targ->name, 0, 0, 0);
|
||||
free(targ);
|
||||
|
||||
fn(farg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_task_new(const char *name, void (*fn)(void *), void *arg,
|
||||
int stack_size)
|
||||
{
|
||||
int ret;
|
||||
pthread_t th;
|
||||
struct targ *targ = malloc(sizeof(*targ));
|
||||
targ->name = strdup(name);
|
||||
targ->fn = fn;
|
||||
targ->arg = arg;
|
||||
ret = pthread_create(&th, NULL, dfl_entry, targ);
|
||||
if (ret == 0) ret = pthread_detach(th);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aos_task_new_ext(aos_task_t *task, const char *name, void (*fn)(void *), void *arg,
|
||||
int stack_size, int prio)
|
||||
{
|
||||
return aos_task_new(name, fn, arg, stack_size);
|
||||
}
|
||||
|
||||
void aos_task_exit(int code)
|
||||
{
|
||||
pthread_exit((void *)code);
|
||||
}
|
||||
|
||||
const char *aos_task_name(void)
|
||||
{
|
||||
static char name[16];
|
||||
prctl(PR_GET_NAME, (unsigned long)name, 0, 0, 0);
|
||||
return name;
|
||||
}
|
||||
|
||||
int aos_task_key_create(aos_task_key_t *key)
|
||||
{
|
||||
return pthread_key_create(key, NULL);
|
||||
}
|
||||
|
||||
void aos_task_key_delete(aos_task_key_t key)
|
||||
{
|
||||
pthread_key_delete(key);
|
||||
}
|
||||
|
||||
int aos_task_setspecific(aos_task_key_t key, void *vp)
|
||||
{
|
||||
return pthread_setspecific(key, vp);
|
||||
}
|
||||
|
||||
void *aos_task_getspecific(aos_task_key_t key)
|
||||
{
|
||||
return pthread_getspecific(key);
|
||||
}
|
||||
|
||||
int aos_mutex_new(aos_mutex_t *mutex)
|
||||
{
|
||||
pthread_mutex_t *mtx = malloc(sizeof(*mtx));
|
||||
pthread_mutex_init(mtx, NULL);
|
||||
mutex->hdl = mtx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_mutex_free(aos_mutex_t *mutex)
|
||||
{
|
||||
pthread_mutex_destroy(mutex->hdl);
|
||||
free(mutex->hdl);
|
||||
}
|
||||
|
||||
int aos_mutex_lock(aos_mutex_t *mutex, unsigned int timeout)
|
||||
{
|
||||
if (mutex) {
|
||||
pthread_mutex_lock(mutex->hdl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_mutex_unlock(aos_mutex_t *mutex)
|
||||
{
|
||||
if (mutex) {
|
||||
pthread_mutex_unlock(mutex->hdl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_mutex_is_valid(aos_mutex_t *mutex)
|
||||
{
|
||||
return mutex->hdl != NULL;
|
||||
}
|
||||
|
||||
#include <semaphore.h>
|
||||
int aos_sem_new(aos_sem_t *sem, int count)
|
||||
{
|
||||
sem_t *s = malloc(sizeof(*s));
|
||||
sem_init(s, 0, count);
|
||||
sem->hdl = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_sem_free(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sem_destroy(sem->hdl);
|
||||
free(sem->hdl);
|
||||
}
|
||||
|
||||
int aos_sem_wait(aos_sem_t *sem, unsigned int timeout)
|
||||
{
|
||||
int sec;
|
||||
int nsec;
|
||||
|
||||
if (sem == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (timeout == AOS_WAIT_FOREVER) {
|
||||
return sem_wait(sem->hdl);
|
||||
} else if (timeout == 0) {
|
||||
return sem_trywait(sem->hdl);
|
||||
}
|
||||
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
||||
sec = timeout / 1000;
|
||||
nsec = (timeout % 1000) * 1000;
|
||||
|
||||
ts.tv_nsec += nsec;
|
||||
sec += (ts.tv_nsec / 1000000000);
|
||||
ts.tv_nsec %= 1000000000;
|
||||
ts.tv_sec += sec;
|
||||
|
||||
return sem_timedwait(sem->hdl, &ts);
|
||||
}
|
||||
|
||||
void aos_sem_signal(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sem_post(sem->hdl);
|
||||
}
|
||||
|
||||
int aos_sem_is_valid(aos_sem_t *sem)
|
||||
{
|
||||
return sem && sem->hdl != NULL;
|
||||
}
|
||||
|
||||
void aos_sem_signal_all(aos_sem_t *sem)
|
||||
{
|
||||
sem_post(sem->hdl);
|
||||
}
|
||||
|
||||
struct queue {
|
||||
int fds[2];
|
||||
void *buf;
|
||||
int size;
|
||||
int msg_size;
|
||||
};
|
||||
|
||||
int aos_queue_new(aos_queue_t *queue, void *buf, unsigned int size, int max_msg)
|
||||
{
|
||||
struct queue *q = malloc(sizeof(*q));
|
||||
pipe(q->fds);
|
||||
q->buf = buf;
|
||||
q->size = size;
|
||||
q->msg_size = max_msg;
|
||||
queue->hdl = q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_queue_free(aos_queue_t *queue)
|
||||
{
|
||||
struct queue *q = queue->hdl;
|
||||
close(q->fds[0]);
|
||||
close(q->fds[1]);
|
||||
free(q);
|
||||
}
|
||||
|
||||
int aos_queue_send(aos_queue_t *queue, void *msg, unsigned int size)
|
||||
{
|
||||
struct queue *q = queue->hdl;
|
||||
write(q->fds[1], msg, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_queue_recv(aos_queue_t *queue, unsigned int ms, void *msg,
|
||||
unsigned int *size)
|
||||
{
|
||||
struct queue *q = queue->hdl;
|
||||
struct pollfd rfd = {
|
||||
.fd = q->fds[0],
|
||||
.events = POLLIN,
|
||||
};
|
||||
|
||||
poll(&rfd, 1, ms);
|
||||
if (rfd.revents & POLLIN) {
|
||||
int len = read(q->fds[0], msg, q->msg_size);
|
||||
*size = len;
|
||||
return len < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_queue_is_valid(aos_queue_t *queue)
|
||||
{
|
||||
return queue->hdl != NULL;
|
||||
}
|
||||
|
||||
void *aos_queue_buf_ptr(aos_queue_t *queue)
|
||||
{
|
||||
struct queue *q = queue->hdl;
|
||||
return q->buf;
|
||||
}
|
||||
|
||||
int aos_timer_new(aos_timer_t *timer, void (*fn)(void *, void *),
|
||||
void *arg, int ms, int repeat)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void aos_timer_free(aos_timer_t *timer)
|
||||
{
|
||||
}
|
||||
|
||||
int aos_timer_start(aos_timer_t *timer)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_timer_stop(aos_timer_t *timer)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_timer_change(aos_timer_t *timer, int ms)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aos_workqueue_create(aos_workqueue_t *workqueue, int pri, int stack_size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct work {
|
||||
void (*fn)(void *);
|
||||
void *arg;
|
||||
int dly;
|
||||
};
|
||||
|
||||
int aos_work_init(aos_work_t *work, void (*fn)(void *), void *arg, int dly)
|
||||
{
|
||||
struct work *w = malloc(sizeof(*w));
|
||||
w->fn = fn;
|
||||
w->arg = arg;
|
||||
w->dly = dly;
|
||||
work->hdl = w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_work_destroy(aos_work_t *work)
|
||||
{
|
||||
free(work->hdl);
|
||||
}
|
||||
|
||||
int aos_work_run(aos_workqueue_t *workqueue, aos_work_t *work)
|
||||
{
|
||||
return aos_work_sched(work);
|
||||
}
|
||||
|
||||
static void worker_entry(void *arg)
|
||||
{
|
||||
struct work *w = arg;
|
||||
if (w->dly) {
|
||||
usleep(w->dly * 1000);
|
||||
}
|
||||
w->fn(w->arg);
|
||||
}
|
||||
|
||||
int aos_work_sched(aos_work_t *work)
|
||||
{
|
||||
struct work *w = work->hdl;
|
||||
return aos_task_new("worker", worker_entry, w, 8192);
|
||||
}
|
||||
|
||||
int aos_work_cancel(aos_work_t *work)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *aos_zalloc(unsigned int size)
|
||||
{
|
||||
return calloc(size, 1);
|
||||
}
|
||||
|
||||
void *aos_malloc(unsigned int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *aos_realloc(void *mem, unsigned int size)
|
||||
{
|
||||
return realloc(mem, size);
|
||||
}
|
||||
|
||||
void aos_alloc_trace(void *addr, size_t allocator)
|
||||
{
|
||||
}
|
||||
|
||||
void aos_free(void *mem)
|
||||
{
|
||||
free(mem);
|
||||
}
|
||||
|
||||
static struct timeval sys_start_time;
|
||||
long long aos_now(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long long ns;
|
||||
gettimeofday(&tv, NULL);
|
||||
timersub(&tv, &sys_start_time, &tv);
|
||||
ns = tv.tv_sec * 1000000LL + tv.tv_usec;
|
||||
return ns * 1000LL;
|
||||
}
|
||||
|
||||
long long aos_now_ms(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long long ms;
|
||||
gettimeofday(&tv, NULL);
|
||||
timersub(&tv, &sys_start_time, &tv);
|
||||
ms = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
|
||||
return ms;
|
||||
}
|
||||
|
||||
void aos_msleep(int ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
void aos_init(void)
|
||||
{
|
||||
gettimeofday(&sys_start_time, NULL);
|
||||
}
|
||||
|
||||
void aos_start(void)
|
||||
{
|
||||
while (1) {
|
||||
usleep(1000 * 1000 * 100);
|
||||
}
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
void dumpsys_task_func(void)
|
||||
{
|
||||
DIR *proc = opendir("/proc/self/task");
|
||||
while (1) {
|
||||
struct dirent *ent = readdir(proc);
|
||||
if (!ent) {
|
||||
break;
|
||||
}
|
||||
if (ent->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
char fn[128];
|
||||
snprintf(fn, sizeof fn, "/proc/self/task/%s/comm", ent->d_name);
|
||||
FILE *fp = fopen(fn, "r");
|
||||
if (!fp) {
|
||||
continue;
|
||||
}
|
||||
bzero(fn, sizeof fn);
|
||||
fread(fn, sizeof(fn) - 1, 1, fp);
|
||||
fclose(fp);
|
||||
printf("%8s - %s", ent->d_name, fn);
|
||||
}
|
||||
closedir(proc);
|
||||
}
|
||||
|
||||
926
Living_SDK/kernel/vcall/aos/aos_rhino.c
Executable file
926
Living_SDK/kernel/vcall/aos/aos_rhino.c
Executable file
|
|
@ -0,0 +1,926 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <errno.h>
|
||||
#include <aos/aos.h>
|
||||
#include "errno_mapping.h"
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC == 0)
|
||||
#warning "RHINO_CONFIG_KOBJ_DYN_ALLOC is disabled!"
|
||||
#endif
|
||||
|
||||
#define MS2TICK(ms) krhino_ms_to_ticks(ms)
|
||||
|
||||
static unsigned int used_bitmap;
|
||||
|
||||
|
||||
static int error_mapping(int ret)
|
||||
{
|
||||
switch(ret) {
|
||||
case RHINO_SYS_SP_ERR:
|
||||
case RHINO_NULL_PTR:
|
||||
case RHINO_MM_FREE_ADDR_ERR:
|
||||
return -EFAULT;
|
||||
case RHINO_INV_PARAM:
|
||||
case RHINO_INV_ALIGN:
|
||||
case RHINO_KOBJ_TYPE_ERR:
|
||||
case RHINO_MM_POOL_SIZE_ERR:
|
||||
case RHINO_MM_ALLOC_SIZE_ERR:
|
||||
case RHINO_INV_SCHED_WAY:
|
||||
case RHINO_TASK_INV_STACK_SIZE:
|
||||
case RHINO_BEYOND_MAX_PRI:
|
||||
case RHINO_BUF_QUEUE_INV_SIZE:
|
||||
case RHINO_BUF_QUEUE_SIZE_ZERO:
|
||||
case RHINO_BUF_QUEUE_MSG_SIZE_OVERFLOW:
|
||||
case RHINO_QUEUE_FULL:
|
||||
case RHINO_QUEUE_NOT_FULL:
|
||||
case RHINO_SEM_OVF:
|
||||
case RHINO_WORKQUEUE_EXIST:
|
||||
case RHINO_WORKQUEUE_NOT_EXIST:
|
||||
case RHINO_WORKQUEUE_WORK_EXIST:
|
||||
return -EINVAL;
|
||||
case RHINO_KOBJ_BLK:
|
||||
return -EAGAIN;
|
||||
case RHINO_NO_MEM:
|
||||
return -ENOMEM;
|
||||
case RHINO_KOBJ_DEL_ERR:
|
||||
case RHINO_SCHED_DISABLE:
|
||||
case RHINO_SCHED_ALREADY_ENABLED:
|
||||
case RHINO_SCHED_LOCK_COUNT_OVF:
|
||||
case RHINO_TASK_NOT_SUSPENDED:
|
||||
case RHINO_TASK_DEL_NOT_ALLOWED:
|
||||
case RHINO_TASK_SUSPEND_NOT_ALLOWED:
|
||||
case RHINO_SUSPENDED_COUNT_OVF:
|
||||
case RHINO_PRI_CHG_NOT_ALLOWED:
|
||||
case RHINO_NOT_CALLED_BY_INTRPT:
|
||||
case RHINO_NO_THIS_EVENT_OPT:
|
||||
case RHINO_TIMER_STATE_INV:
|
||||
case RHINO_BUF_QUEUE_FULL:
|
||||
case RHINO_SEM_TASK_WAITING:
|
||||
case RHINO_MUTEX_NOT_RELEASED_BY_OWNER:
|
||||
case RHINO_WORKQUEUE_WORK_RUNNING:
|
||||
return -EPERM;
|
||||
case RHINO_TRY_AGAIN:
|
||||
case RHINO_WORKQUEUE_BUSY:
|
||||
return -EAGAIN;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
extern void hal_reboot(void);
|
||||
void aos_reboot(void)
|
||||
{
|
||||
hal_reboot();
|
||||
}
|
||||
|
||||
int aos_get_hz(void)
|
||||
{
|
||||
return RHINO_CONFIG_TICKS_PER_SECOND;
|
||||
}
|
||||
|
||||
const char *aos_version_get(void)
|
||||
{
|
||||
return SYSINFO_KERNEL_VERSION;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
int aos_task_new(const char *name, void (*fn)(void *), void *arg,
|
||||
int stack_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ktask_t *task_handle = NULL;
|
||||
|
||||
ret = (int)krhino_task_dyn_create(&task_handle, name, arg, AOS_DEFAULT_APP_PRI, 0,
|
||||
stack_size / sizeof(cpu_stack_t), fn, 1u);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_task_new_ext(aos_task_t *task, const char *name, void (*fn)(void *), void *arg,
|
||||
int stack_size, int prio)
|
||||
{
|
||||
int ret;
|
||||
ret = (int)krhino_task_dyn_create((ktask_t **)(&(task->hdl)), name, arg, prio, 0,
|
||||
stack_size / sizeof(cpu_stack_t), fn, 1u);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
void aos_task_exit(int code)
|
||||
{
|
||||
(void)code;
|
||||
|
||||
krhino_task_dyn_del(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *aos_task_name(void)
|
||||
{
|
||||
return krhino_cur_task_get()->task_name;
|
||||
}
|
||||
|
||||
int aos_task_key_create(aos_task_key_t *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = RHINO_CONFIG_TASK_INFO_NUM - 1; i >= 0; i--) {
|
||||
if (!((1 << i) & used_bitmap)) {
|
||||
used_bitmap |= 1 << i;
|
||||
*key = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void aos_task_key_delete(aos_task_key_t key)
|
||||
{
|
||||
if (key >= RHINO_CONFIG_TASK_INFO_NUM) {
|
||||
return;
|
||||
}
|
||||
|
||||
used_bitmap &= ~(1 << key);
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_TASK_INFO > 0)
|
||||
int aos_task_setspecific(aos_task_key_t key, void *vp)
|
||||
{
|
||||
int ret;
|
||||
ret = krhino_task_info_set(krhino_cur_task_get(), key, vp);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
void *aos_task_getspecific(aos_task_key_t key)
|
||||
{
|
||||
void *vp = NULL;
|
||||
|
||||
krhino_task_info_get(krhino_cur_task_get(), key, &vp);
|
||||
|
||||
return vp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
|
||||
int aos_mutex_new(aos_mutex_t *mutex)
|
||||
{
|
||||
kstat_t ret;
|
||||
kmutex_t *m;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
m = aos_malloc(sizeof(kmutex_t));
|
||||
if (m == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = krhino_mutex_create(m, "AOS");
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
aos_free(m);
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
mutex->hdl = m;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_mutex_free(aos_mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_mutex_del(mutex->hdl);
|
||||
|
||||
aos_free(mutex->hdl);
|
||||
|
||||
mutex->hdl = NULL;
|
||||
}
|
||||
|
||||
int aos_mutex_lock(aos_mutex_t *mutex, unsigned int timeout)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (timeout == AOS_WAIT_FOREVER) {
|
||||
ret = krhino_mutex_lock(mutex->hdl, RHINO_WAIT_FOREVER);
|
||||
} else {
|
||||
ret = krhino_mutex_lock(mutex->hdl, MS2TICK(timeout));
|
||||
}
|
||||
|
||||
/* rhino allow nested */
|
||||
if (ret == RHINO_MUTEX_OWNER_NESTED) {
|
||||
ret = RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_mutex_unlock(aos_mutex_t *mutex)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_mutex_unlock(mutex->hdl);
|
||||
/* rhino allow nested */
|
||||
if (ret == RHINO_MUTEX_OWNER_NESTED) {
|
||||
ret = RHINO_SUCCESS;
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_mutex_is_valid(aos_mutex_t *mutex)
|
||||
{
|
||||
kmutex_t *k_mutex;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_mutex = mutex->hdl;
|
||||
|
||||
if (k_mutex == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)&&(RHINO_CONFIG_SEM > 0))
|
||||
int aos_sem_new(aos_sem_t *sem, int count)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t *s;
|
||||
|
||||
if (sem == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s = aos_malloc(sizeof(ksem_t));
|
||||
if (s == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = krhino_sem_create(s, "AOS", count);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
aos_free(s);
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
sem->hdl = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_sem_free(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_sem_del(sem->hdl);
|
||||
|
||||
aos_free(sem->hdl);
|
||||
|
||||
sem->hdl = NULL;
|
||||
}
|
||||
|
||||
int aos_sem_wait(aos_sem_t *sem, unsigned int timeout)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (sem == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (timeout == AOS_WAIT_FOREVER) {
|
||||
ret = krhino_sem_take(sem->hdl, RHINO_WAIT_FOREVER);
|
||||
} else {
|
||||
ret = krhino_sem_take(sem->hdl, MS2TICK(timeout));
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
void aos_sem_signal(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_sem_give(sem->hdl);
|
||||
}
|
||||
|
||||
int aos_sem_is_valid(aos_sem_t *sem)
|
||||
{
|
||||
ksem_t *k_sem;
|
||||
|
||||
if (sem == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_sem = sem->hdl;
|
||||
|
||||
if (k_sem == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void aos_sem_signal_all(aos_sem_t *sem)
|
||||
{
|
||||
if (sem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_sem_give_all(sem->hdl);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_EVENT_FLAG > 0)
|
||||
|
||||
int aos_event_new(aos_event_t *event, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
ret = (int)krhino_event_dyn_create((kevent_t **)(&(event->hdl)), "AOS", flags);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
void aos_event_free(aos_event_t *event)
|
||||
{
|
||||
if (event == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_event_dyn_del(event->hdl);
|
||||
|
||||
event->hdl = NULL;
|
||||
}
|
||||
|
||||
int aos_event_get
|
||||
(
|
||||
aos_event_t *event,
|
||||
unsigned int flags,
|
||||
unsigned char opt,
|
||||
unsigned int *actl_flags,
|
||||
unsigned int timeout
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (event == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (timeout == AOS_WAIT_FOREVER) {
|
||||
ret = krhino_event_get(event->hdl, flags, opt, actl_flags, RHINO_WAIT_FOREVER);
|
||||
} else {
|
||||
ret = krhino_event_get(event->hdl, flags, opt, actl_flags, MS2TICK(timeout));
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_event_set(aos_event_t *event, unsigned int flags, unsigned char opt)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (event == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_event_set(event->hdl, flags, opt);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_BUF_QUEUE > 0)
|
||||
|
||||
int aos_queue_new(aos_queue_t *queue, void *buf, unsigned int size, int max_msg)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t *q;
|
||||
|
||||
if ((queue == NULL) || (buf == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
q = aos_malloc(sizeof(kbuf_queue_t));
|
||||
if (q == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = krhino_buf_queue_create(q, "AOS", buf, size, max_msg);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
aos_free(q);
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
queue->hdl = q;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_queue_free(aos_queue_t *queue)
|
||||
{
|
||||
if (queue == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_buf_queue_del(queue->hdl);
|
||||
|
||||
aos_free(queue->hdl);
|
||||
|
||||
queue->hdl = NULL;
|
||||
}
|
||||
|
||||
int aos_queue_send(aos_queue_t *queue, void *msg, unsigned int size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((queue == NULL) || (msg == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_buf_queue_send(queue->hdl, msg, size);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_queue_recv(aos_queue_t *queue, unsigned int ms, void *msg,
|
||||
unsigned int *size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (queue == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ms == AOS_WAIT_FOREVER) {
|
||||
ret = krhino_buf_queue_recv(queue->hdl, RHINO_WAIT_FOREVER, msg, size);
|
||||
} else {
|
||||
ret = krhino_buf_queue_recv(queue->hdl, MS2TICK(ms), msg, size);
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_queue_is_valid(aos_queue_t *queue)
|
||||
{
|
||||
kbuf_queue_t *k_queue;
|
||||
|
||||
if (queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_queue = queue->hdl;
|
||||
|
||||
if (k_queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *aos_queue_buf_ptr(aos_queue_t *queue)
|
||||
{
|
||||
if (!aos_queue_is_valid(queue)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ((kbuf_queue_t *)queue->hdl)->buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
int aos_timer_new(aos_timer_t *timer, void (*fn)(void *, void *),
|
||||
void *arg, int ms, int repeat)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (timer == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (repeat == 0) {
|
||||
ret = krhino_timer_dyn_create(((ktimer_t **)(&timer->hdl)), "AOS", (timer_cb_t)fn, MS2TICK(ms), 0, arg, 1);
|
||||
} else {
|
||||
ret = krhino_timer_dyn_create(((ktimer_t **)(&timer->hdl)), "AOS", (timer_cb_t)fn, MS2TICK(ms), MS2TICK(ms),
|
||||
arg, 1);
|
||||
}
|
||||
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_timer_new_ext(aos_timer_t *timer, void (*fn)(void *, void *),
|
||||
void *arg, int ms, int repeat, unsigned char auto_run)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (timer == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (repeat == 0) {
|
||||
ret = krhino_timer_dyn_create(((ktimer_t **)(&timer->hdl)), "AOS", (timer_cb_t)fn, MS2TICK(ms), 0, arg, auto_run);
|
||||
} else {
|
||||
ret = krhino_timer_dyn_create(((ktimer_t **)(&timer->hdl)), "AOS", (timer_cb_t)fn, MS2TICK(ms), MS2TICK(ms),
|
||||
arg, auto_run);
|
||||
}
|
||||
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_timer_free(aos_timer_t *timer)
|
||||
{
|
||||
if (timer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_timer_dyn_del(timer->hdl);
|
||||
timer->hdl = NULL;
|
||||
}
|
||||
|
||||
int aos_timer_start(aos_timer_t *timer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (timer == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_timer_start(timer->hdl);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_timer_stop(aos_timer_t *timer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (timer == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_timer_stop(timer->hdl);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_timer_change(aos_timer_t *timer, int ms)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (timer == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_timer_change(timer->hdl, MS2TICK(ms), MS2TICK(ms));
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_WORKQUEUE > 0)
|
||||
int aos_workqueue_create(aos_workqueue_t *workqueue, int pri, int stack_size)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
cpu_stack_t *stk;
|
||||
kworkqueue_t *wq;
|
||||
|
||||
if (workqueue == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stack_size < sizeof(cpu_stack_t)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
stk = aos_malloc(stack_size);
|
||||
if (stk == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
wq = aos_malloc(sizeof(kworkqueue_t));
|
||||
if (wq == NULL) {
|
||||
aos_free(stk);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = krhino_workqueue_create(wq, "AOS", pri, stk,
|
||||
stack_size / sizeof(cpu_stack_t));
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
aos_free(wq);
|
||||
aos_free(stk);
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
workqueue->hdl = wq;
|
||||
workqueue->stk = stk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_work_init(aos_work_t *work, void (*fn)(void *), void *arg, int dly)
|
||||
{
|
||||
kstat_t ret;
|
||||
kwork_t *w;
|
||||
|
||||
if (work == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
w = aos_malloc(sizeof(kwork_t));
|
||||
if (w == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = krhino_work_init(w, fn, arg, MS2TICK(dly));
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
aos_free(w);
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
work->hdl = w;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aos_work_destroy(aos_work_t *work)
|
||||
{
|
||||
kwork_t *w;
|
||||
|
||||
if (work == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
w = work->hdl;
|
||||
|
||||
if (w->timer != NULL) {
|
||||
krhino_timer_stop(w->timer);
|
||||
krhino_timer_dyn_del(w->timer);
|
||||
}
|
||||
|
||||
aos_free(work->hdl);
|
||||
work->hdl = NULL;
|
||||
}
|
||||
|
||||
int aos_work_run(aos_workqueue_t *workqueue, aos_work_t *work)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((workqueue == NULL) || (work == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_work_run(workqueue->hdl, work->hdl);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_work_sched(aos_work_t *work)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (work == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_work_sched(work->hdl);
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ERRNO_MAPPING(ret);
|
||||
}
|
||||
|
||||
int aos_work_cancel(aos_work_t *work)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (work == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = krhino_work_cancel(work->hdl);
|
||||
if (ret != RHINO_SUCCESS) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (RHINO_CONFIG_MM_TLF > 0)
|
||||
void *aos_zalloc(unsigned int size)
|
||||
{
|
||||
void *tmp = NULL;
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
if ((size & AOS_UNSIGNED_INT_MSB) == 0) {
|
||||
tmp = krhino_mm_alloc(size | AOS_UNSIGNED_INT_MSB);
|
||||
|
||||
#ifndef AOS_BINS
|
||||
#if defined (__CC_ARM)
|
||||
krhino_owner_attach(g_kmm_head, tmp, __return_address());
|
||||
#elif defined (__GNUC__)
|
||||
krhino_owner_attach(g_kmm_head, tmp, (size_t)__builtin_return_address(0));
|
||||
#endif /* __CC_ARM */
|
||||
#endif
|
||||
} else {
|
||||
tmp = krhino_mm_alloc(size);
|
||||
}
|
||||
|
||||
#else
|
||||
tmp = krhino_mm_alloc(size);
|
||||
#endif
|
||||
|
||||
if (tmp) {
|
||||
memset(tmp, 0, size);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void *aos_malloc(unsigned int size)
|
||||
{
|
||||
void *tmp = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
if ((size & AOS_UNSIGNED_INT_MSB) == 0) {
|
||||
tmp = krhino_mm_alloc(size | AOS_UNSIGNED_INT_MSB);
|
||||
|
||||
#ifndef AOS_BINS
|
||||
#if defined (__CC_ARM)
|
||||
krhino_owner_attach(g_kmm_head, tmp, __return_address());
|
||||
#elif defined (__GNUC__)
|
||||
krhino_owner_attach(g_kmm_head, tmp, (size_t)__builtin_return_address(0));
|
||||
#endif /* __CC_ARM */
|
||||
#endif
|
||||
} else {
|
||||
tmp = krhino_mm_alloc(size);
|
||||
}
|
||||
|
||||
#else
|
||||
tmp = krhino_mm_alloc(size);
|
||||
#endif
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void *aos_realloc(void *mem, unsigned int size)
|
||||
{
|
||||
void *tmp = NULL;
|
||||
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
if ((size & AOS_UNSIGNED_INT_MSB) == 0) {
|
||||
tmp = krhino_mm_realloc(mem, size | AOS_UNSIGNED_INT_MSB);
|
||||
|
||||
#ifndef AOS_BINS
|
||||
#if defined (__CC_ARM)
|
||||
krhino_owner_attach(g_kmm_head, tmp, __return_address());
|
||||
#elif defined (__GNUC__)
|
||||
krhino_owner_attach(g_kmm_head, tmp, (size_t)__builtin_return_address(0));
|
||||
#endif /* __CC_ARM */
|
||||
#endif
|
||||
} else {
|
||||
tmp = krhino_mm_realloc(mem, size);
|
||||
}
|
||||
|
||||
#else
|
||||
tmp = krhino_mm_realloc(mem, size);
|
||||
#endif
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void aos_alloc_trace(void *addr, size_t allocator)
|
||||
{
|
||||
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
|
||||
krhino_owner_attach(g_kmm_head, addr, allocator);
|
||||
#endif
|
||||
}
|
||||
|
||||
void aos_free(void *mem)
|
||||
{
|
||||
if (mem == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
krhino_mm_free(mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
long long aos_now(void)
|
||||
{
|
||||
return krhino_sys_time_get() * 1000 * 1000;
|
||||
}
|
||||
|
||||
long long aos_now_ms(void)
|
||||
{
|
||||
return krhino_sys_time_get();
|
||||
}
|
||||
|
||||
void aos_msleep(int ms)
|
||||
{
|
||||
krhino_task_sleep(MS2TICK(ms));
|
||||
}
|
||||
|
||||
void aos_init(void)
|
||||
{
|
||||
krhino_init();
|
||||
}
|
||||
|
||||
void aos_start(void)
|
||||
{
|
||||
krhino_start();
|
||||
}
|
||||
|
||||
13
Living_SDK/kernel/vcall/aos/errno_mapping.h
Normal file
13
Living_SDK/kernel/vcall/aos/errno_mapping.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef ERRNO_MAPPING_H
|
||||
#define ERRNO_MAPPING_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <aos/aos.h>
|
||||
|
||||
#define ERRNO_MAPPING(ret) error_mapping(ret)
|
||||
|
||||
#endif /* ERRNO_MAPPING_H */
|
||||
919
Living_SDK/kernel/vcall/cmsis/cmsis_os.c
Normal file
919
Living_SDK/kernel/vcall/cmsis/cmsis_os.c
Normal file
|
|
@ -0,0 +1,919 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* $Date: 5. February 2013
|
||||
* $Revision: V1.02
|
||||
*
|
||||
* Project: CMSIS-RTOS API
|
||||
* Title: cmsis_os.c
|
||||
*
|
||||
* Version 0.02
|
||||
* Initial Proposal Phase
|
||||
* Version 0.03
|
||||
* osKernelStart added, optional feature: main started as thread
|
||||
* osSemaphores have standard behavior
|
||||
* osTimerCreate does not start the timer, added osTimerStart
|
||||
* osThreadPass is renamed to osThreadYield
|
||||
* Version 1.01
|
||||
* Support for C++ interface
|
||||
* - const attribute removed from the osXxxxDef_t typedef's
|
||||
* - const attribute added to the osXxxxDef macros
|
||||
* Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
|
||||
* Added: osKernelInitialize
|
||||
* Version 1.02
|
||||
* Control functions for short timeouts in microsecond resolution:
|
||||
* Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
|
||||
* Removed: osSignalGet
|
||||
*
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* Portions Copyright <EFBFBD> 2016 STMicroelectronics International N.V. All rights reserved.
|
||||
* Portions Copyright (c) 2013 ARM LIMITED
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* - Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file cmsis_os.c
|
||||
* @author AliOS-Things Team
|
||||
* @date 16-Mar-2018
|
||||
* @brief CMSIS-RTOS API implementation for AliOS-Things
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <cmsis_os.h>
|
||||
|
||||
/*
|
||||
* ARM Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
|
||||
#define __ASM __asm
|
||||
#define __INLINE __inline
|
||||
#define __STATIC_INLINE static __inline
|
||||
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
#endif
|
||||
|
||||
/* Convert from CMSIS type osPriority to Rhino priority number */
|
||||
static uint8_t makeRhinoPriority (osPriority priority)
|
||||
{
|
||||
uint8_t fpriority = RHINO_IDLE_PRI;
|
||||
|
||||
if (priority != osPriorityError)
|
||||
{
|
||||
fpriority -= (priority - osPriorityIdle);
|
||||
}
|
||||
|
||||
return fpriority;
|
||||
#if 0
|
||||
typedef enum {
|
||||
osPriorityIdle = -3, -> 62 - ((-3) - (-3))= 62 ///< priority: idle (lowest)
|
||||
osPriorityLow = -2, -> 62 - ((-2) - (-3))= 61 ///< priority: low
|
||||
osPriorityBelowNormal = -1, -> 62 - ((-1) - (-3))= 60 ///< priority: below normal
|
||||
osPriorityNormal = 0, -> 62 - (( 0) - (-3))= 59 ///< priority: normal (default)
|
||||
osPriorityAboveNormal = +1, -> 62 - ((+1) - (-3))= 58 ///< priority: above normal
|
||||
osPriorityHigh = +2, -> 62 - ((+2) - (-3))= 57 ///< priority: high
|
||||
osPriorityRealtime = +3, -> 62 - ((+3) - (-3))= 56 ///< priority: realtime (highest)
|
||||
osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority
|
||||
} osPriority;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Convert from Rhino priority number to CMSIS type osPriority */
|
||||
static osPriority makeCmsisPriority (uint8_t fpriority)
|
||||
{
|
||||
osPriority priority = osPriorityError;
|
||||
|
||||
if ((RHINO_IDLE_PRI - fpriority) <= (osPriorityRealtime - osPriorityIdle))
|
||||
{
|
||||
priority = (osPriority)((int)osPriorityIdle + (int)(RHINO_IDLE_PRI - fpriority));
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
/*********************** Kernel Control Functions *****************************/
|
||||
/**
|
||||
* @brief Initialize the RTOS Kernel for creating objects.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osKernelInitialize (void)
|
||||
{
|
||||
(void)krhino_init();
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the RTOS Kernel with executing the specified thread.
|
||||
* @param thread_def thread definition referenced with \ref osThread.
|
||||
* @param argument pointer that is passed to the thread function as start argument.
|
||||
* @retval status code that indicates the execution status of the function
|
||||
* @note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osKernelStart (void)
|
||||
{
|
||||
krhino_start();
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the RTOS kernel is already started
|
||||
* @param None
|
||||
* @retval (0) RTOS is not started
|
||||
* (1) RTOS is started
|
||||
* (-1) if this feature is disabled
|
||||
* @note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
int32_t osKernelRunning(void)
|
||||
{
|
||||
if (g_sys_stat == RHINO_RUNNING)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
|
||||
/**
|
||||
* @brief Get the value of the Kernel SysTick timer
|
||||
* @param None
|
||||
* @retval None
|
||||
* @note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
uint32_t osKernelSysTick(void)
|
||||
{
|
||||
return (uint32_t)g_tick_count;
|
||||
}
|
||||
#endif // System Timer available
|
||||
|
||||
/*********************** Thread Management *****************************/
|
||||
/**
|
||||
* @brief Create a thread and add it to Active Threads and set it to state READY.
|
||||
* @param thread_def thread definition referenced with \ref osThread.
|
||||
* @param argument pointer that is passed to the thread function as start argument.
|
||||
* @retval thread ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)
|
||||
{
|
||||
ktask_t* ptcb;
|
||||
|
||||
if (RHINO_SUCCESS != krhino_task_create(thread_def->ptcb, thread_def->name, argument,
|
||||
makeRhinoPriority(thread_def->tpriority),
|
||||
thread_def->ticks, thread_def->pstackspace,
|
||||
thread_def->stacksize,
|
||||
(task_entry_t)thread_def->pthread, 1))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptcb = thread_def->ptcb;
|
||||
}
|
||||
|
||||
return (osThreadId)ptcb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the thread ID of the current running thread.
|
||||
* @retval thread ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osThreadId osThreadGetId (void)
|
||||
{
|
||||
return (osThreadId)krhino_cur_task_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Terminate execution of a thread and remove it from Active Threads.
|
||||
* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osThreadTerminate (osThreadId thread_id)
|
||||
{
|
||||
#if (RHINO_CONFIG_TASK_DEL > 0)
|
||||
if (RHINO_SUCCESS == krhino_task_del((ktask_t*)thread_id))
|
||||
return osOK;
|
||||
else
|
||||
return osErrorOS;
|
||||
#else
|
||||
return osErrorOS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pass control to next thread that is in state \b READY.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osThreadYield (void)
|
||||
{
|
||||
krhino_task_yield();
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change priority of an active thread.
|
||||
* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
* @param priority new priority value for the thread function.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority)
|
||||
{
|
||||
#if (RHINO_CONFIG_TASK_PRI_CHG > 0)
|
||||
if (RHINO_SUCCESS == task_pri_change((ktask_t*)thread_id, makeRhinoPriority(priority)))
|
||||
return osOK;
|
||||
else
|
||||
return osErrorOS;
|
||||
#else
|
||||
return osErrorOS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current priority of an active thread.
|
||||
* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
* @retval current priority value of the thread function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osPriority osThreadGetPriority (osThreadId thread_id)
|
||||
{
|
||||
ktask_t * ptcb;
|
||||
|
||||
if (thread_id == NULL)
|
||||
return osPriorityError;
|
||||
|
||||
ptcb = (ktask_t *)thread_id;
|
||||
|
||||
return makeCmsisPriority(ptcb->prio);
|
||||
}
|
||||
|
||||
/*********************** Generic Wait Functions *******************************/
|
||||
/**
|
||||
* @brief Wait for Timeout (Time Delay)
|
||||
* @param millisec time delay value
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
*/
|
||||
osStatus osDelay (uint32_t millisec)
|
||||
{
|
||||
tick_t ticks = millisec / (1000000/RHINO_CONFIG_TICKS_PER_SECOND);
|
||||
|
||||
krhino_task_sleep(ticks ? ticks : 1); /* Minimum delay = 1 tick */
|
||||
}
|
||||
|
||||
#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) /* Generic Wait available */
|
||||
/**
|
||||
* @brief Wait for Signal, Message, Mail, or Timeout
|
||||
* @param millisec timeout value or 0 in case of no time-out
|
||||
* @retval event that contains signal, message, or mail information or error code.
|
||||
* @note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osEvent osWait (uint32_t millisec);
|
||||
|
||||
#endif /* Generic Wait available */
|
||||
|
||||
/*********************** Timer Management Functions ***************************/
|
||||
/**
|
||||
* @brief Create a timer.
|
||||
* @param timer_def timer object referenced with \ref osTimer.
|
||||
* @param type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
|
||||
* @param argument argument to the timer call back function.
|
||||
* @retval timer ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument)
|
||||
{
|
||||
sys_time_t first = 1;
|
||||
sys_time_t round;
|
||||
|
||||
/*
|
||||
* we use the round to save information for : one-shot or periodic,
|
||||
* when type == osTimerPeriodic, round is set to MAX_TIMER_TICKS - 1,
|
||||
* when type == osTimerOnce, round is set to 0.
|
||||
* osTimerStart() will set the right value for round again.
|
||||
*
|
||||
* also the parameter first will be set to 1 here for workround error
|
||||
* in krhino_timer_create(), osTimerStart() will set the right value.
|
||||
*/
|
||||
|
||||
if (type == osTimerPeriodic)
|
||||
round = MAX_TIMER_TICKS - 1;
|
||||
else
|
||||
round = 0;
|
||||
|
||||
if (RHINO_SUCCESS == krhino_timer_create(timer_def->timer,
|
||||
timer_def->name, (timer_cb_t)timer_def->cb,
|
||||
first, round, argument, 0))
|
||||
{
|
||||
return (osTimerId)timer_def->timer;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if (RHINO_CONFIG_TIMER > 0)
|
||||
|
||||
/**
|
||||
* @brief Start or restart a timer.
|
||||
* @param timer_id timer ID obtained by \ref osTimerCreate.
|
||||
* @param millisec time delay value of the timer.
|
||||
* @retval status code that indicates the execution status of the function
|
||||
* @note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec)
|
||||
{
|
||||
osStatus result = osOK;
|
||||
ktimer_t * ptimer = (ktimer_t *)timer_id;
|
||||
tick_t ticks = millisec / (1000000/RHINO_CONFIG_TICKS_PER_SECOND);
|
||||
|
||||
if (ticks == 0)
|
||||
{
|
||||
ticks = 1;
|
||||
}
|
||||
|
||||
ptimer->init_count = ticks;
|
||||
|
||||
/* check the type of timer, osTimerPeriodic or osTimerOnce*/
|
||||
|
||||
if ((MAX_TIMER_TICKS - 1) == ptimer->round_ticks)
|
||||
{
|
||||
ptimer->round_ticks = ticks;
|
||||
}
|
||||
|
||||
if (RHINO_SUCCESS != krhino_timer_start(ptimer))
|
||||
{
|
||||
result = osErrorOS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop a timer.
|
||||
* @param timer_id timer ID obtained by \ref osTimerCreate
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osTimerStop (osTimerId timer_id)
|
||||
{
|
||||
osStatus result = osOK;
|
||||
|
||||
if (RHINO_SUCCESS != krhino_timer_stop((ktimer_t *)timer_id))
|
||||
{
|
||||
result = osErrorOS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a timer.
|
||||
* @param timer_id timer ID obtained by \ref osTimerCreate
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osTimerDelete (osTimerId timer_id)
|
||||
{
|
||||
osStatus result = osOK;
|
||||
|
||||
if (RHINO_SUCCESS != krhino_timer_del((ktimer_t *)timer_id))
|
||||
{
|
||||
result = osErrorOS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* RHINO_CONFIG_TIMER */
|
||||
|
||||
#if (osFeature_Signals > 0)
|
||||
/*************************** Signal Management ********************************/
|
||||
/**
|
||||
* @brief Set the specified Signal Flags of an active thread.
|
||||
* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
* @param signals specifies the signal flags of the thread that should be set.
|
||||
* @retval previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
int32_t osSignalSet (osThreadId thread_id, int32_t signal)
|
||||
{
|
||||
(void) thread_id;
|
||||
(void) signal;
|
||||
|
||||
return 0x80000000; /* Task Notification not supported */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the specified Signal Flags of an active thread.
|
||||
* @param thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
* @param signals specifies the signal flags of the thread that shall be cleared.
|
||||
* @retval previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
int32_t osSignalClear (osThreadId thread_id, int32_t signal);
|
||||
|
||||
/**
|
||||
* @brief Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
|
||||
* @param signals wait until all specified signal flags set or 0 for any single signal flag.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval event flag information or error code.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osEvent osSignalWait (int32_t signals, uint32_t millisec)
|
||||
{
|
||||
osEvent ret;
|
||||
|
||||
(void) signals;
|
||||
(void) millisec;
|
||||
|
||||
ret.status = osErrorOS; /* Task Notification not supported */
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* osFeature_Signals > 0 */
|
||||
|
||||
/**************************** Mutex Management ********************************/
|
||||
/**
|
||||
* @brief Create and Initialize a Mutex object
|
||||
* @param mutex_def mutex definition referenced with \ref osMutex.
|
||||
* @retval mutex ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osMutexId osMutexCreate (const osMutexDef_t *mutex_def)
|
||||
{
|
||||
if (RHINO_SUCCESS != krhino_mutex_create(mutex_def->mutex, mutex_def->name))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (osMutexId)mutex_def->mutex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait until a Mutex becomes available
|
||||
* @param mutex_id mutex ID obtained by \ref osMutexCreate.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec)
|
||||
{
|
||||
tick_t ticks;
|
||||
|
||||
if (mutex_id == NULL)
|
||||
{
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
ticks = 0;
|
||||
if (millisec != 0)
|
||||
{
|
||||
ticks = millisec / (1000000/RHINO_CONFIG_TICKS_PER_SECOND);
|
||||
}
|
||||
|
||||
if (RHINO_SUCCESS != krhino_mutex_lock((kmutex_t*)mutex_id, ticks))
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a Mutex that was obtained by \ref osMutexWait
|
||||
* @param mutex_id mutex ID obtained by \ref osMutexCreate.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osMutexRelease (osMutexId mutex_id)
|
||||
{
|
||||
if (RHINO_SUCCESS == krhino_mutex_unlock((kmutex_t*)mutex_id))
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a Mutex
|
||||
* @param mutex_id mutex ID obtained by \ref osMutexCreate.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osMutexDelete (osMutexId mutex_id)
|
||||
{
|
||||
if (RHINO_SUCCESS == krhino_mutex_del((kmutex_t*)mutex_id))
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
}
|
||||
|
||||
/******************** Semaphore Management Functions **************************/
|
||||
|
||||
#if (RHINO_CONFIG_SEM > 0)
|
||||
|
||||
/**
|
||||
* @brief Create and Initialize a Semaphore object used for managing resources
|
||||
* @param semaphore_def semaphore definition referenced with \ref osSemaphore.
|
||||
* @param count number of available resources.
|
||||
* @retval semaphore ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count)
|
||||
{
|
||||
if (RHINO_SUCCESS != krhino_sem_create(semaphore_def->sem,
|
||||
semaphore_def->name, (sem_count_t)count))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (osSemaphoreId)semaphore_def->sem;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait until a Semaphore token becomes available
|
||||
* @param semaphore_id semaphore object referenced with \ref osSemaphore.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval number of available tokens, or -1 in case of incorrect parameters.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
|
||||
{
|
||||
tick_t ticks;
|
||||
|
||||
if (semaphore_id == NULL)
|
||||
{
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
ticks = 0;
|
||||
if (millisec != 0)
|
||||
{
|
||||
ticks = millisec / (1000000/RHINO_CONFIG_TICKS_PER_SECOND);
|
||||
}
|
||||
|
||||
if (RHINO_SUCCESS != krhino_sem_take((ksem_t*)semaphore_id, ticks))
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a Semaphore token
|
||||
* @param semaphore_id semaphore object referenced with \ref osSemaphore.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
|
||||
{
|
||||
if (RHINO_SUCCESS == krhino_sem_give((ksem_t*)semaphore_id))
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a Semaphore
|
||||
* @param semaphore_id semaphore object referenced with \ref osSemaphore.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osSemaphoreDelete (osSemaphoreId semaphore_id)
|
||||
{
|
||||
if (RHINO_SUCCESS == krhino_sem_del((ksem_t*)semaphore_id))
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Use Semaphores */
|
||||
|
||||
/******************* Memory Pool Management Functions ***********************/
|
||||
|
||||
#if (defined (osFeature_Pool) && (osFeature_Pool != 0))
|
||||
|
||||
//TODO
|
||||
//This is a primitive and inefficient wrapper around the existing AliOS memory management.
|
||||
//A better implementation will have to modify heap_x.c!
|
||||
|
||||
|
||||
typedef struct os_pool_cb {
|
||||
void *pool;
|
||||
uint8_t *markers;
|
||||
uint32_t pool_sz;
|
||||
uint32_t item_sz;
|
||||
uint32_t currentIndex;
|
||||
} os_pool_cb_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create and Initialize a memory pool
|
||||
* @param pool_def memory pool definition referenced with \ref osPool.
|
||||
* @retval memory pool ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osPoolId osPoolCreate (const osPoolDef_t *pool_def)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate a memory block from a memory pool
|
||||
* @param pool_id memory pool ID obtain referenced with \ref osPoolCreate.
|
||||
* @retval address of the allocated memory block or NULL in case of no memory available.
|
||||
* @note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
void *osPoolAlloc (osPoolId pool_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate a memory block from a memory pool and set memory block to zero
|
||||
* @param pool_id memory pool ID obtain referenced with \ref osPoolCreate.
|
||||
* @retval address of the allocated memory block or NULL in case of no memory available.
|
||||
* @note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
void *osPoolCAlloc (osPoolId pool_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return an allocated memory block back to a specific memory pool
|
||||
* @param pool_id memory pool ID obtain referenced with \ref osPoolCreate.
|
||||
* @param block address of the allocated memory block that is returned to the memory pool.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osPoolFree (osPoolId pool_id, void *block)
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
|
||||
#endif /* Use Memory Pool Management */
|
||||
|
||||
/******************* Message Queue Management Functions *********************/
|
||||
|
||||
#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) /* Use Message Queues */
|
||||
|
||||
/**
|
||||
* @brief Create and Initialize a Message Queue
|
||||
* @param queue_def queue definition referenced with \ref osMessageQ.
|
||||
* @param thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
|
||||
* @retval message queue ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id)
|
||||
{
|
||||
(void) thread_id;
|
||||
|
||||
if (RHINO_SUCCESS == krhino_fix_buf_queue_create(queue_def->queue,
|
||||
queue_def->name, queue_def->pool,
|
||||
queue_def->item_sz, queue_def->queue_sz))
|
||||
{
|
||||
return (osMessageQId)queue_def->queue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a Message to a Queue.
|
||||
* @param queue_id message queue ID obtained with \ref osMessageCreate.
|
||||
* @param info message information.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec)
|
||||
{
|
||||
(void)millisec;
|
||||
|
||||
if (RHINO_SUCCESS == krhino_buf_queue_send((kbuf_queue_t *)queue_id, &info, 4))
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return osErrorOS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a Message or Wait for a Message from a Queue.
|
||||
* @param queue_id message queue ID obtained with \ref osMessageCreate.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval event information that includes status code.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec)
|
||||
{
|
||||
osEvent event;
|
||||
tick_t ticks;
|
||||
size_t size;
|
||||
|
||||
ticks = 0;
|
||||
if (millisec == osWaitForever)
|
||||
{
|
||||
ticks = RHINO_WAIT_FOREVER;
|
||||
}
|
||||
else if (millisec != 0)
|
||||
{
|
||||
ticks = millisec / (1000000/RHINO_CONFIG_TICKS_PER_SECOND);
|
||||
if (ticks == 0)
|
||||
{
|
||||
ticks = 1;
|
||||
}
|
||||
}
|
||||
|
||||
event.def.message_id = queue_id;
|
||||
event.value.v = 0;
|
||||
|
||||
if (queue_id == NULL)
|
||||
{
|
||||
event.status = osErrorParameter;
|
||||
return event;
|
||||
}
|
||||
|
||||
if (RHINO_SUCCESS == krhino_buf_queue_recv((kbuf_queue_t *)queue_id,
|
||||
ticks, &event.value.v, &size))
|
||||
{
|
||||
event.status = osEventMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
event.status = (ticks == 0) ? osOK : osEventTimeout;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
#endif /* Use Message Queues */
|
||||
|
||||
/******************** Mail Queue Management Functions ***********************/
|
||||
#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) /* Use Mail Queues */
|
||||
|
||||
typedef struct os_mailQ_cb {
|
||||
const osMailQDef_t *queue_def;
|
||||
QueueHandle_t handle;
|
||||
osPoolId pool;
|
||||
} os_mailQ_cb_t;
|
||||
|
||||
/**
|
||||
* @brief Create and Initialize mail queue
|
||||
* @param queue_def reference to the mail queue definition obtain with \ref osMailQ
|
||||
* @param thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
|
||||
* @retval mail queue ID for reference by other functions or NULL in case of error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate a memory block from a mail
|
||||
* @param queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval pointer to memory block that can be filled with mail or NULL in case error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
void *osMailAlloc (osMailQId queue_id, uint32_t millisec)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Allocate a memory block from a mail and set memory block to zero
|
||||
* @param queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
* @param millisec timeout value or 0 in case of no time-out.
|
||||
* @retval pointer to memory block that can be filled with mail or NULL in case error.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
void *osMailCAlloc (osMailQId queue_id, uint32_t millisec)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put a mail to a queue
|
||||
* @param queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
* @param mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osMailPut (osMailQId queue_id, void *mail)
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a mail from a queue
|
||||
* @param queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
* @param millisec timeout value or 0 in case of no time-out
|
||||
* @retval event that contains mail information or error code.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osEvent osMailGet (osMailQId queue_id, uint32_t millisec)
|
||||
{
|
||||
osEvent event;
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free a memory block from a mail
|
||||
* @param queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
* @param mail pointer to the memory block that was obtained with \ref osMailGet.
|
||||
* @retval status code that indicates the execution status of the function.
|
||||
* @note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
|
||||
*/
|
||||
osStatus osMailFree (osMailQId queue_id, void *mail)
|
||||
{
|
||||
return osOK;
|
||||
}
|
||||
#endif /* Use Mail Queues */
|
||||
|
||||
717
Living_SDK/kernel/vcall/cmsis/cmsis_os.h
Normal file
717
Living_SDK/kernel/vcall/cmsis/cmsis_os.h
Normal file
|
|
@ -0,0 +1,717 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* $Date: 5. February 2013
|
||||
* $Revision: V1.02
|
||||
*
|
||||
* Project: CMSIS-RTOS API
|
||||
* Title: cmsis_os.h template header file
|
||||
*
|
||||
* Version 0.02
|
||||
* Initial Proposal Phase
|
||||
* Version 0.03
|
||||
* osKernelStart added, optional feature: main started as thread
|
||||
* osSemaphores have standard behavior
|
||||
* osTimerCreate does not start the timer, added osTimerStart
|
||||
* osThreadPass is renamed to osThreadYield
|
||||
* Version 1.01
|
||||
* Support for C++ interface
|
||||
* - const attribute removed from the osXxxxDef_t typedef's
|
||||
* - const attribute added to the osXxxxDef macros
|
||||
* Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
|
||||
* Added: osKernelInitialize
|
||||
* Version 1.02
|
||||
* Control functions for short timeouts in microsecond resolution:
|
||||
* Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
|
||||
* Removed: osSignalGet
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) 2013-2017 ARM LIMITED
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _CMSIS_OS_H
|
||||
#define _CMSIS_OS_H
|
||||
|
||||
/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
|
||||
#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0])
|
||||
|
||||
/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
|
||||
#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0])
|
||||
|
||||
/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
|
||||
#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string
|
||||
|
||||
/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
|
||||
|
||||
/* Memory Pools, Mail Queues, Signal is not supported yet */
|
||||
|
||||
#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available
|
||||
/*not support yet*/
|
||||
#define osFeature_Pool 0 ///< Memory Pools: 1=available, 0=not available
|
||||
/*not support yet*/
|
||||
#define osFeature_MailQ 0 ///< Mail Queues: 1=available, 0=not available
|
||||
#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available
|
||||
/*not support yet*/
|
||||
#define osFeature_Signals 0 ///< maximum number of Signal Flags available per thread
|
||||
#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function
|
||||
#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available
|
||||
#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <k_api.h> /* for rhino */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
// ==== Enumeration, structures, defines ====
|
||||
|
||||
/// Priority used for thread control.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
|
||||
typedef enum {
|
||||
osPriorityIdle = -3, ///< priority: idle (lowest)
|
||||
osPriorityLow = -2, ///< priority: low
|
||||
osPriorityBelowNormal = -1, ///< priority: below normal
|
||||
osPriorityNormal = 0, ///< priority: normal (default)
|
||||
osPriorityAboveNormal = +1, ///< priority: above normal
|
||||
osPriorityHigh = +2, ///< priority: high
|
||||
osPriorityRealtime = +3, ///< priority: realtime (highest)
|
||||
osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority
|
||||
} osPriority;
|
||||
|
||||
/// Timeout value.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
|
||||
#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value
|
||||
|
||||
/// Status code values returned by CMSIS-RTOS functions.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
|
||||
typedef enum {
|
||||
osOK = 0, ///< function completed; no error or event occurred.
|
||||
osEventSignal = 0x08, ///< function completed; signal event occurred.
|
||||
osEventMessage = 0x10, ///< function completed; message event occurred.
|
||||
osEventMail = 0x20, ///< function completed; mail event occurred.
|
||||
osEventTimeout = 0x40, ///< function completed; timeout occurred.
|
||||
osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
|
||||
osErrorResource = 0x81, ///< resource not available: a specified resource was not available.
|
||||
osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period.
|
||||
osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
|
||||
osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object.
|
||||
osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority.
|
||||
osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
|
||||
osErrorValue = 0x86, ///< value of a parameter is out of range.
|
||||
osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits.
|
||||
os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
|
||||
} osStatus;
|
||||
|
||||
|
||||
/// Timer type value for the timer definition.
|
||||
/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
|
||||
typedef enum {
|
||||
osTimerOnce = 0, ///< one-shot timer
|
||||
osTimerPeriodic = 1 ///< repeating timer
|
||||
} os_timer_type;
|
||||
|
||||
/// Entry point of a thread.
|
||||
/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
|
||||
typedef void (*os_pthread) (void const *argument);
|
||||
|
||||
/// Entry point of a timer call back function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
|
||||
typedef void (*os_ptimer) (void const *argument);
|
||||
|
||||
// >>> the following data type definitions may shall adapted towards a specific RTOS
|
||||
|
||||
/// Thread ID identifies the thread (pointer to a thread control block).
|
||||
/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef ktask_t *osThreadId;
|
||||
|
||||
/// Timer ID identifies the timer (pointer to a timer control block).
|
||||
/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef ktimer_t *osTimerId;
|
||||
|
||||
/// Mutex ID identifies the mutex (pointer to a mutex control block).
|
||||
/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef kmutex_t *osMutexId;
|
||||
|
||||
/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
|
||||
/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef ksem_t *osSemaphoreId;
|
||||
|
||||
/// Pool ID identifies the memory pool (pointer to a memory pool control block).
|
||||
/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef void *osPoolId;
|
||||
|
||||
/// Message ID identifies the message queue (pointer to a message queue control block).
|
||||
/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef kqueue_t *osMessageQId;
|
||||
|
||||
/// Mail ID identifies the mail queue (pointer to a mail queue control block).
|
||||
/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
|
||||
typedef kqueue_t *osMailQId;
|
||||
|
||||
|
||||
/// Thread Definition structure contains startup information of a thread.
|
||||
/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_thread_def {
|
||||
char *name; ///< Thread name
|
||||
os_pthread pthread; ///< start address of thread function
|
||||
osPriority tpriority; ///< initial thread priority
|
||||
uint32_t instances; ///< maximum number of instances of that thread function
|
||||
uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
|
||||
tick_t ticks;
|
||||
ktask_t *ptcb;
|
||||
cpu_stack_t *pstackspace;
|
||||
} osThreadDef_t;
|
||||
|
||||
/// Timer Definition structure contains timer parameters.
|
||||
/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_timer_def {
|
||||
char * name;
|
||||
os_ptimer cb; ///< start address of a timer function
|
||||
ktimer_t * timer;
|
||||
} osTimerDef_t;
|
||||
|
||||
/// Mutex Definition structure contains setup information for a mutex.
|
||||
/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_mutex_def {
|
||||
char * name;
|
||||
uint32_t dummy; ///< dummy value.
|
||||
kmutex_t * mutex;
|
||||
} osMutexDef_t;
|
||||
|
||||
/// Semaphore Definition structure contains setup information for a semaphore.
|
||||
/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_semaphore_def {
|
||||
char * name;
|
||||
uint32_t dummy; ///< dummy value.
|
||||
ksem_t * sem;
|
||||
} osSemaphoreDef_t;
|
||||
|
||||
/// Definition structure for memory block allocation.
|
||||
/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_pool_def {
|
||||
uint32_t pool_sz; ///< number of items (elements) in the pool
|
||||
uint32_t item_sz; ///< size of an item
|
||||
void *pool; ///< pointer to memory for pool
|
||||
} osPoolDef_t;
|
||||
|
||||
/// Definition structure for message queue.
|
||||
/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_messageQ_def {
|
||||
char *name;
|
||||
uint32_t queue_sz; ///< number of elements in the queue
|
||||
uint32_t item_sz; ///< size of an item
|
||||
void *pool; ///< memory array for messages
|
||||
kbuf_queue_t *queue;
|
||||
} osMessageQDef_t;
|
||||
|
||||
/// Definition structure for mail queue.
|
||||
/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
|
||||
typedef struct os_mailQ_def {
|
||||
uint32_t queue_sz; ///< number of elements in the queue
|
||||
uint32_t item_sz; ///< size of an item
|
||||
void *pool; ///< memory array for mail
|
||||
} osMailQDef_t;
|
||||
|
||||
/// Event structure contains detailed information about an event.
|
||||
/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
|
||||
/// However the struct may be extended at the end.
|
||||
typedef struct {
|
||||
osStatus status; ///< status code: event or error information
|
||||
union {
|
||||
uint32_t v; ///< message as 32-bit value
|
||||
void *p; ///< message or mail as void pointer
|
||||
int32_t signals; ///< signal flags
|
||||
} value; ///< event value
|
||||
union {
|
||||
osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
|
||||
osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
|
||||
} def; ///< event definition
|
||||
} osEvent;
|
||||
|
||||
|
||||
// ==== Kernel Control Functions ====
|
||||
|
||||
/// Initialize the RTOS Kernel for creating objects.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osKernelInitialize (void);
|
||||
|
||||
/// Start the RTOS Kernel.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osKernelStart (void);
|
||||
|
||||
/// Check if the RTOS kernel is already started.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
|
||||
/// \return 0 RTOS is not started, 1 RTOS is started.
|
||||
int32_t osKernelRunning(void);
|
||||
|
||||
#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
|
||||
|
||||
/// Get the RTOS kernel system timer counter
|
||||
/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
|
||||
/// \return RTOS kernel system timer as 32-bit value
|
||||
uint32_t osKernelSysTick (void);
|
||||
|
||||
/// The RTOS kernel system timer frequency in Hz
|
||||
/// \note Reflects the system timer setting and is typically defined in a configuration file.
|
||||
#define osKernelSysTickFrequency 100000000
|
||||
|
||||
/// Convert a microseconds value to a RTOS kernel system timer value.
|
||||
/// \param microsec time value in microseconds.
|
||||
/// \return time value normalized to the \ref osKernelSysTickFrequency
|
||||
#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
|
||||
|
||||
#endif // System Timer available
|
||||
|
||||
// ==== Thread Management ====
|
||||
|
||||
/// Create a Thread Definition with function, priority, and stack requirements.
|
||||
/// \param name name of the thread function.
|
||||
/// \param priority initial priority of the thread function.
|
||||
/// \param instances number of possible thread instances.
|
||||
/// \param stacksz stack size (in bytes) requirements for the thread function.
|
||||
/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osThreadDef(name, priority, instances, stacksz) \
|
||||
extern const osThreadDef_t os_thread_def_##name
|
||||
#else // define the object
|
||||
#define osThreadDef(name, priority, instances, stacksz) \
|
||||
const osThreadDef_t os_thread_def_##name = \
|
||||
{ (name), (priority), (instances), (stacksz) }
|
||||
#endif
|
||||
|
||||
/// Access a Thread definition.
|
||||
/// \param name name of the thread definition object.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osThread(name) \
|
||||
&os_thread_def_##name
|
||||
|
||||
/// Create a thread and add it to Active Threads and set it to state READY.
|
||||
/// \param[in] thread_def thread definition referenced with \ref osThread.
|
||||
/// \param[in] argument pointer that is passed to the thread function as start argument.
|
||||
/// \return thread ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
|
||||
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
|
||||
|
||||
/// Return the thread ID of the current running thread.
|
||||
/// \return thread ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
|
||||
osThreadId osThreadGetId (void);
|
||||
|
||||
/// Terminate execution of a thread and remove it from Active Threads.
|
||||
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osThreadTerminate (osThreadId thread_id);
|
||||
|
||||
/// Pass control to next thread that is in state \b READY.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osThreadYield (void);
|
||||
|
||||
/// Change priority of an active thread.
|
||||
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
/// \param[in] priority new priority value for the thread function.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
|
||||
|
||||
/// Get current priority of an active thread.
|
||||
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
/// \return current priority value of the thread function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
|
||||
osPriority osThreadGetPriority (osThreadId thread_id);
|
||||
|
||||
|
||||
// ==== Generic Wait Functions ====
|
||||
|
||||
/// Wait for Timeout (Time Delay).
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
osStatus osDelay (uint32_t millisec);
|
||||
|
||||
#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available
|
||||
|
||||
/// Wait for Signal, Message, Mail, or Timeout.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
|
||||
/// \return event that contains signal, message, or mail information or error code.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
|
||||
osEvent osWait (uint32_t millisec);
|
||||
|
||||
#endif // Generic Wait available
|
||||
|
||||
|
||||
// ==== Timer Management Functions ====
|
||||
/// Define a Timer object.
|
||||
/// \param name name of the timer object.
|
||||
/// \param function name of the timer call back function.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osTimerDef(name, function) \
|
||||
extern const osTimerDef_t os_timer_def_##name
|
||||
#else // define the object
|
||||
#define osTimerDef(name, function) \
|
||||
const osTimerDef_t os_timer_def_##name = \
|
||||
{ (function) }
|
||||
#endif
|
||||
|
||||
/// Access a Timer definition.
|
||||
/// \param name name of the timer object.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osTimer(name) \
|
||||
&os_timer_def_##name
|
||||
|
||||
/// Create a timer.
|
||||
/// \param[in] timer_def timer object referenced with \ref osTimer.
|
||||
/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
|
||||
/// \param[in] argument argument to the timer call back function.
|
||||
/// \return timer ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
|
||||
osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
|
||||
|
||||
/// Start or restart a timer.
|
||||
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
|
||||
|
||||
/// Stop the timer.
|
||||
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osTimerStop (osTimerId timer_id);
|
||||
|
||||
/// Delete a timer that was created by \ref osTimerCreate.
|
||||
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osTimerDelete (osTimerId timer_id);
|
||||
|
||||
|
||||
// ==== Signal Management ==== not support yet
|
||||
|
||||
/// Set the specified Signal Flags of an active thread.
|
||||
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
/// \param[in] signals specifies the signal flags of the thread that should be set.
|
||||
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
|
||||
int32_t osSignalSet (osThreadId thread_id, int32_t signals);
|
||||
|
||||
/// Clear the specified Signal Flags of an active thread.
|
||||
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
|
||||
/// \param[in] signals specifies the signal flags of the thread that shall be cleared.
|
||||
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
|
||||
int32_t osSignalClear (osThreadId thread_id, int32_t signals);
|
||||
|
||||
/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
|
||||
/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return event flag information or error code.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
|
||||
osEvent osSignalWait (int32_t signals, uint32_t millisec);
|
||||
|
||||
|
||||
// ==== Mutex Management ====
|
||||
|
||||
/// Define a Mutex.
|
||||
/// \param name name of the mutex object.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osMutexDef(name) \
|
||||
extern const osMutexDef_t os_mutex_def_##name
|
||||
#else // define the object
|
||||
#define osMutexDef(name) \
|
||||
const osMutexDef_t os_mutex_def_##name = { 0 }
|
||||
#endif
|
||||
|
||||
/// Access a Mutex definition.
|
||||
/// \param name name of the mutex object.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osMutex(name) \
|
||||
&os_mutex_def_##name
|
||||
|
||||
/// Create and Initialize a Mutex object.
|
||||
/// \param[in] mutex_def mutex definition referenced with \ref osMutex.
|
||||
/// \return mutex ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
|
||||
osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
|
||||
|
||||
/// Wait until a Mutex becomes available.
|
||||
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
|
||||
|
||||
/// Release a Mutex that was obtained by \ref osMutexWait.
|
||||
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osMutexRelease (osMutexId mutex_id);
|
||||
|
||||
/// Delete a Mutex that was created by \ref osMutexCreate.
|
||||
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osMutexDelete (osMutexId mutex_id);
|
||||
|
||||
|
||||
// ==== Semaphore Management Functions ====
|
||||
|
||||
#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available
|
||||
|
||||
/// Define a Semaphore object.
|
||||
/// \param name name of the semaphore object.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osSemaphoreDef(name) \
|
||||
extern const osSemaphoreDef_t os_semaphore_def_##name
|
||||
#else // define the object
|
||||
#define osSemaphoreDef(name) \
|
||||
const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
|
||||
#endif
|
||||
|
||||
/// Access a Semaphore definition.
|
||||
/// \param name name of the semaphore object.
|
||||
/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osSemaphore(name) \
|
||||
&os_semaphore_def_##name
|
||||
|
||||
/// Create and Initialize a Semaphore object used for managing resources.
|
||||
/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore.
|
||||
/// \param[in] count number of available resources.
|
||||
/// \return semaphore ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
|
||||
osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
|
||||
|
||||
/// Wait until a Semaphore token becomes available.
|
||||
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return number of available tokens, or -1 in case of incorrect parameters.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
|
||||
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
|
||||
|
||||
/// Release a Semaphore token.
|
||||
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
|
||||
|
||||
/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
|
||||
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
|
||||
|
||||
#endif // Semaphore available
|
||||
|
||||
|
||||
// ==== Memory Pool Management Functions ==== not support yet
|
||||
|
||||
#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available
|
||||
|
||||
/// \brief Define a Memory Pool.
|
||||
/// \param name name of the memory pool.
|
||||
/// \param no maximum number of blocks (objects) in the memory pool.
|
||||
/// \param type data type of a single block (object).
|
||||
/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osPoolDef(name, no, type) \
|
||||
extern const osPoolDef_t os_pool_def_##name
|
||||
#else // define the object
|
||||
#define osPoolDef(name, no, type) \
|
||||
const osPoolDef_t os_pool_def_##name = \
|
||||
{ (no), sizeof(type), NULL }
|
||||
#endif
|
||||
|
||||
/// \brief Access a Memory Pool definition.
|
||||
/// \param name name of the memory pool
|
||||
/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osPool(name) \
|
||||
&os_pool_def_##name
|
||||
|
||||
/// Create and Initialize a memory pool.
|
||||
/// \param[in] pool_def memory pool definition referenced with \ref osPool.
|
||||
/// \return memory pool ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
|
||||
osPoolId osPoolCreate (const osPoolDef_t *pool_def);
|
||||
|
||||
/// Allocate a memory block from a memory pool.
|
||||
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
|
||||
/// \return address of the allocated memory block or NULL in case of no memory available.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
|
||||
void *osPoolAlloc (osPoolId pool_id);
|
||||
|
||||
/// Allocate a memory block from a memory pool and set memory block to zero.
|
||||
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
|
||||
/// \return address of the allocated memory block or NULL in case of no memory available.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
|
||||
void *osPoolCAlloc (osPoolId pool_id);
|
||||
|
||||
/// Return an allocated memory block back to a specific memory pool.
|
||||
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
|
||||
/// \param[in] block address of the allocated memory block that is returned to the memory pool.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osPoolFree (osPoolId pool_id, void *block);
|
||||
|
||||
#endif // Memory Pool Management available
|
||||
|
||||
|
||||
// ==== Message Queue Management Functions ====
|
||||
|
||||
#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available
|
||||
|
||||
/// \brief Create a Message Queue Definition.
|
||||
/// \param name name of the queue.
|
||||
/// \param queue_sz maximum number of messages in the queue.
|
||||
/// \param type data type of a single message element (for debugger).
|
||||
/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osMessageQDef(name, queue_sz, type) \
|
||||
extern const osMessageQDef_t os_messageQ_def_##name
|
||||
#else // define the object
|
||||
#define osMessageQDef(name, queue_sz, type) \
|
||||
const osMessageQDef_t os_messageQ_def_##name = \
|
||||
{ (queue_sz), sizeof (type) }
|
||||
#endif
|
||||
|
||||
/// \brief Access a Message Queue Definition.
|
||||
/// \param name name of the queue
|
||||
/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osMessageQ(name) \
|
||||
&os_messageQ_def_##name
|
||||
|
||||
/// Create and Initialize a Message Queue.
|
||||
/// \param[in] queue_def queue definition referenced with \ref osMessageQ.
|
||||
/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
|
||||
/// \return message queue ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
|
||||
osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
|
||||
|
||||
/// Put a Message to a Queue.
|
||||
/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
|
||||
/// \param[in] info message information.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
|
||||
|
||||
/// Get a Message or Wait for a Message from a Queue.
|
||||
/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return event information that includes status code.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
|
||||
osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
|
||||
|
||||
#endif // Message Queues available
|
||||
|
||||
|
||||
// ==== Mail Queue Management Functions ==== not support yet
|
||||
|
||||
#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available
|
||||
|
||||
/// \brief Create a Mail Queue Definition.
|
||||
/// \param name name of the queue
|
||||
/// \param queue_sz maximum number of messages in queue
|
||||
/// \param type data type of a single message element
|
||||
/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osMailQDef(name, queue_sz, type) \
|
||||
extern const osMailQDef_t os_mailQ_def_##name
|
||||
#else // define the object
|
||||
#define osMailQDef(name, queue_sz, type) \
|
||||
const osMailQDef_t os_mailQ_def_##name = \
|
||||
{ (queue_sz), sizeof (type) }
|
||||
#endif
|
||||
|
||||
/// \brief Access a Mail Queue Definition.
|
||||
/// \param name name of the queue
|
||||
/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
|
||||
/// macro body is implementation specific in every CMSIS-RTOS.
|
||||
#define osMailQ(name) \
|
||||
&os_mailQ_def_##name
|
||||
|
||||
/// Create and Initialize mail queue.
|
||||
/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ
|
||||
/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
|
||||
/// \return mail queue ID for reference by other functions or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
|
||||
osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
|
||||
|
||||
/// Allocate a memory block from a mail.
|
||||
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
|
||||
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
|
||||
void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
|
||||
|
||||
/// Allocate a memory block from a mail and set memory block to zero.
|
||||
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
|
||||
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
|
||||
void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
|
||||
|
||||
/// Put a mail to a queue.
|
||||
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osMailPut (osMailQId queue_id, void *mail);
|
||||
|
||||
/// Get a mail from a queue.
|
||||
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
|
||||
/// \return event that contains mail information or error code.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
|
||||
osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
|
||||
|
||||
/// Free a memory block from a mail.
|
||||
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
|
||||
/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
|
||||
osStatus osMailFree (osMailQId queue_id, void *mail);
|
||||
|
||||
#endif // Mail Queues available
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _CMSIS_OS_H
|
||||
54
Living_SDK/kernel/vcall/cmsis/test/init_test.c
Normal file
54
Living_SDK/kernel/vcall/cmsis/test/init_test.c
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cmsis_os.h>
|
||||
|
||||
#define DEMO_TASK_STACKSIZE 256 //256*cpu_stack_t = 1024byte
|
||||
#define DEMO_TASK_PRIORITY 20
|
||||
|
||||
extern void stm32_soc_init(void);
|
||||
static ktask_t demo_task_obj;
|
||||
static cpu_stack_t demo_task_buf[DEMO_TASK_STACKSIZE];
|
||||
static osThreadDef_t thread;
|
||||
|
||||
static void demo_task(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
stm32_soc_init();
|
||||
|
||||
printf("demo_task here!\n");
|
||||
printf("rhino memory is %d!\n", krhino_global_space_get());
|
||||
|
||||
while (1)
|
||||
{
|
||||
printf("hello world! count %d\n", count++);
|
||||
|
||||
//sleep 1 second
|
||||
|
||||
osDelay(RHINO_CONFIG_TICKS_PER_SECOND*10000);
|
||||
};
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
osKernelInitialize();
|
||||
|
||||
thread.name = "demo_task";
|
||||
thread.pthread = (os_pthread)demo_task;
|
||||
thread.tpriority = osPriorityNormal;
|
||||
thread.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread.ptcb = &demo_task_obj;
|
||||
thread.pstackspace = demo_task_buf;
|
||||
|
||||
osThreadCreate (&thread, NULL);
|
||||
|
||||
osKernelStart();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
108
Living_SDK/kernel/vcall/cmsis/test/msgqueue_test.c
Normal file
108
Living_SDK/kernel/vcall/cmsis/test/msgqueue_test.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cmsis_os.h>
|
||||
|
||||
#define DEMO_TASK_STACKSIZE 256 //256*cpu_stack_t = 1024byte
|
||||
#define DEMO_TASK_PRIORITY 20
|
||||
|
||||
static ktask_t init_task_obj;
|
||||
static ktask_t demo_task_obj1;
|
||||
static ktask_t demo_task_obj2;
|
||||
static cpu_stack_t init_task_buf[DEMO_TASK_STACKSIZE];
|
||||
static cpu_stack_t demo_task_buf1[DEMO_TASK_STACKSIZE];
|
||||
static cpu_stack_t demo_task_buf2[DEMO_TASK_STACKSIZE];
|
||||
|
||||
static osThreadDef_t thread_init;
|
||||
static osThreadDef_t thread1;
|
||||
static osThreadDef_t thread2;
|
||||
|
||||
static kbuf_queue_t buf_queue;
|
||||
static osMessageQDef_t msg_queue_def;
|
||||
static osMessageQId p_msgqueue;
|
||||
static uint32_t msg_buf_space[32];
|
||||
|
||||
static void init_task(void *arg)
|
||||
{
|
||||
printf("init_task here!\n");
|
||||
|
||||
msg_queue_def.name = "buf_queue";
|
||||
msg_queue_def.queue = &buf_queue;
|
||||
msg_queue_def.queue_sz = 32;
|
||||
msg_queue_def.item_sz = 4;
|
||||
msg_queue_def.pool = msg_buf_space;
|
||||
|
||||
p_msgqueue = osMessageCreate (&msg_queue_def, (osThreadId)NULL);
|
||||
if (p_msgqueue == NULL)
|
||||
{
|
||||
printf("osMessageCreate failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("osMessageCreate ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void demo_task1(void *arg)
|
||||
{
|
||||
osEvent event;
|
||||
|
||||
while (1)
|
||||
{
|
||||
event = osMessageGet(p_msgqueue, osWaitForever);
|
||||
if (event.status == osEventMessage)
|
||||
{
|
||||
printf("demo_task1 get msg %d\n", event.value.v);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("demo_task1 get msg failed\n");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void demo_task2(void *arg)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
osMessagePut(p_msgqueue,count,0xffffffff);
|
||||
|
||||
printf("demo_task2 put msg %d\n", count++);
|
||||
osDelay(RHINO_CONFIG_TICKS_PER_SECOND*10000);
|
||||
};
|
||||
}
|
||||
|
||||
void cmsis_msgqueue_test(void)
|
||||
{
|
||||
thread_init.name = "init_task";
|
||||
thread_init.pthread = (os_pthread)init_task;
|
||||
thread_init.tpriority = osPriorityHigh;
|
||||
thread_init.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread_init.ptcb = &init_task_obj;
|
||||
thread_init.pstackspace = init_task_buf;
|
||||
|
||||
thread1.name = "demo_task1";
|
||||
thread1.pthread = (os_pthread)demo_task1;
|
||||
thread1.tpriority = osPriorityNormal;
|
||||
thread1.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread1.ptcb = &demo_task_obj1;
|
||||
thread1.pstackspace = demo_task_buf1;
|
||||
|
||||
thread2.name = "demo_task2";
|
||||
thread2.pthread = (os_pthread)demo_task2;
|
||||
thread2.tpriority = osPriorityNormal;
|
||||
thread2.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread2.ptcb = &demo_task_obj2;
|
||||
thread2.pstackspace = demo_task_buf2;
|
||||
|
||||
osThreadCreate (&thread_init, NULL);
|
||||
osThreadCreate (&thread1, NULL);
|
||||
osThreadCreate (&thread2, NULL);
|
||||
}
|
||||
|
||||
95
Living_SDK/kernel/vcall/cmsis/test/mutex_test.c
Normal file
95
Living_SDK/kernel/vcall/cmsis/test/mutex_test.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cmsis_os.h>
|
||||
|
||||
#define DEMO_TASK_STACKSIZE 256 //256*cpu_stack_t = 1024byte
|
||||
#define DEMO_TASK_PRIORITY 20
|
||||
|
||||
static ktask_t init_task_obj;
|
||||
static ktask_t demo_task_obj1;
|
||||
static ktask_t demo_task_obj2;
|
||||
static cpu_stack_t init_task_buf[DEMO_TASK_STACKSIZE];
|
||||
static cpu_stack_t demo_task_buf1[DEMO_TASK_STACKSIZE];
|
||||
static cpu_stack_t demo_task_buf2[DEMO_TASK_STACKSIZE];
|
||||
|
||||
static osThreadDef_t thread_init;
|
||||
static osThreadDef_t thread1;
|
||||
static osThreadDef_t thread2;
|
||||
|
||||
static kmutex_t mutex;
|
||||
static osMutexDef_t mutex_def;
|
||||
static osMutexId pMutex;
|
||||
|
||||
static void init_task(void *arg)
|
||||
{
|
||||
mutex_def.name = "mutex";
|
||||
mutex_def.mutex = &mutex;
|
||||
|
||||
pMutex = osMutexCreate (&mutex_def);
|
||||
if (pMutex == NULL)
|
||||
{
|
||||
printf("osMutexCreate failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("osMutexCreate ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void demo_task1(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
osMutexWait(pMutex, 0xffffffff);
|
||||
printf("demo_task1 get mutex %d\n", count++);
|
||||
};
|
||||
}
|
||||
|
||||
static void demo_task2(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
osMutexRelease(pMutex);
|
||||
|
||||
printf("demo_task2 release mutex %d\n", count++);
|
||||
osDelay(RHINO_CONFIG_TICKS_PER_SECOND*10000);
|
||||
};
|
||||
}
|
||||
|
||||
void cmsis_mutex_test(void)
|
||||
{
|
||||
thread_init.name = "init_task";
|
||||
thread_init.pthread = (os_pthread)init_task;
|
||||
thread_init.tpriority= osPriorityHigh;
|
||||
thread_init.stacksize= DEMO_TASK_STACKSIZE;
|
||||
thread_init.ptcb = &init_task_obj;
|
||||
thread_init.pstackspace = init_task_buf;
|
||||
|
||||
thread1.name = "demo_task1";
|
||||
thread1.pthread = (os_pthread)demo_task1;
|
||||
thread1.tpriority= osPriorityNormal;
|
||||
thread1.stacksize= DEMO_TASK_STACKSIZE;
|
||||
thread1.ptcb = &demo_task_obj1;
|
||||
thread1.pstackspace = demo_task_buf1;
|
||||
|
||||
thread2.name = "demo_task2";
|
||||
thread2.pthread = (os_pthread)demo_task2;
|
||||
thread2.tpriority= osPriorityNormal;
|
||||
thread2.stacksize= DEMO_TASK_STACKSIZE;
|
||||
thread2.ptcb = &demo_task_obj2;
|
||||
thread2.pstackspace = demo_task_buf2;
|
||||
|
||||
osThreadCreate (&thread_init, NULL);
|
||||
osThreadCreate (&thread1, NULL);
|
||||
osThreadCreate (&thread2, NULL);
|
||||
}
|
||||
|
||||
95
Living_SDK/kernel/vcall/cmsis/test/sem_test.c
Normal file
95
Living_SDK/kernel/vcall/cmsis/test/sem_test.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cmsis_os.h>
|
||||
|
||||
#define DEMO_TASK_STACKSIZE 256 //256*cpu_stack_t = 1024byte
|
||||
#define DEMO_TASK_PRIORITY 20
|
||||
|
||||
static ktask_t init_task_obj;
|
||||
static ktask_t demo_task_obj1;
|
||||
static ktask_t demo_task_obj2;
|
||||
static cpu_stack_t init_task_buf[DEMO_TASK_STACKSIZE];
|
||||
static cpu_stack_t demo_task_buf1[DEMO_TASK_STACKSIZE];
|
||||
static cpu_stack_t demo_task_buf2[DEMO_TASK_STACKSIZE];
|
||||
|
||||
static osThreadDef_t thread_init;
|
||||
static osThreadDef_t thread1;
|
||||
static osThreadDef_t thread2;
|
||||
|
||||
static ksem_t sem;
|
||||
static osSemaphoreDef_t sem_def;
|
||||
static osSemaphoreId pSem;
|
||||
|
||||
static void init_task(void *arg)
|
||||
{
|
||||
sem_def.name = "sem";
|
||||
sem_def.sem = &sem;
|
||||
|
||||
pSem = osSemaphoreCreate (&sem_def, 0);
|
||||
if (pSem == NULL)
|
||||
{
|
||||
printf("osSemaphoreCreate failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("osSemaphoreCreate ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void demo_task1(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
osSemaphoreWait(pSem, 0xffffffff);
|
||||
printf("demo_task1 get sem %d\n", count++);
|
||||
};
|
||||
}
|
||||
|
||||
static void demo_task2(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
osSemaphoreRelease(pSem);
|
||||
|
||||
printf("demo_task2 release sem %d\n", count++);
|
||||
osDelay(RHINO_CONFIG_TICKS_PER_SECOND*10000);
|
||||
};
|
||||
}
|
||||
|
||||
void cmsis_sem_test(void)
|
||||
{
|
||||
thread_init.name = "init_task";
|
||||
thread_init.pthread = (os_pthread)init_task;
|
||||
thread_init.tpriority = osPriorityHigh;
|
||||
thread_init.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread_init.ptcb = &init_task_obj;
|
||||
thread_init.pstackspace = init_task_buf;
|
||||
|
||||
thread1.name = "demo_task1";
|
||||
thread1.pthread = (os_pthread)demo_task1;
|
||||
thread1.tpriority = osPriorityNormal;
|
||||
thread1.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread1.ptcb = &demo_task_obj1;
|
||||
thread1.pstackspace = demo_task_buf1;
|
||||
|
||||
thread2.name = "demo_task2";
|
||||
thread2.pthread = (os_pthread)demo_task2;
|
||||
thread2.tpriority = osPriorityNormal;
|
||||
thread2.stacksize = DEMO_TASK_STACKSIZE;
|
||||
thread2.ptcb = &demo_task_obj2;
|
||||
thread2.pstackspace = demo_task_buf2;
|
||||
|
||||
osThreadCreate (&thread_init, NULL);
|
||||
osThreadCreate (&thread1, NULL);
|
||||
osThreadCreate (&thread2, NULL);
|
||||
}
|
||||
|
||||
75
Living_SDK/kernel/vcall/cmsis/test/timer_test.c
Normal file
75
Living_SDK/kernel/vcall/cmsis/test/timer_test.c
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cmsis_os.h>
|
||||
|
||||
#define DEMO_TASK_STACKSIZE 256 //256*cpu_stack_t = 1024byte
|
||||
#define DEMO_TASK_PRIORITY 20
|
||||
|
||||
static ktask_t demo_task_obj;
|
||||
static cpu_stack_t demo_task_buf[DEMO_TASK_STACKSIZE];
|
||||
static osThreadDef_t thread;
|
||||
|
||||
static osTimerDef_t timer_def;
|
||||
static ktimer_t timer_space;
|
||||
|
||||
static int timer_cb_count = 0;
|
||||
static void timer_function(void)
|
||||
{
|
||||
timer_cb_count ++;
|
||||
printf("timer cb is called, timer_cb_count = %d\n");
|
||||
}
|
||||
|
||||
static void demo_task(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
osTimerId pTimerId = NULL;
|
||||
|
||||
timer_def.name = "testTimer";
|
||||
timer_def.cb = (os_ptimer)timer_function;
|
||||
timer_def.timer= &timer_space;
|
||||
|
||||
pTimerId = osTimerCreate (&timer_def, osTimerPeriodic, NULL);
|
||||
if (pTimerId == NULL)
|
||||
{
|
||||
printf("osTimerCreate failed, MAX_TIMER_TICKS = %d\n",MAX_TIMER_TICKS);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("osTimerCreate ok\n");
|
||||
}
|
||||
|
||||
osTimerStart (pTimerId, 1000000);
|
||||
|
||||
while (1)
|
||||
{
|
||||
printf("hello world! count %d\n", count++);
|
||||
|
||||
//sleep 1 second
|
||||
|
||||
osDelay(RHINO_CONFIG_TICKS_PER_SECOND*10000);
|
||||
|
||||
if (timer_cb_count > 10)
|
||||
{
|
||||
osTimerStop(pTimerId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void cmsis_timer_test(void)
|
||||
{
|
||||
thread.name = "demo_task";
|
||||
thread.pthread = (os_pthread)demo_task;
|
||||
thread.tpriority= osPriorityNormal;
|
||||
thread.stacksize= DEMO_TASK_STACKSIZE;
|
||||
thread.ptcb = &demo_task_obj;
|
||||
thread.pstackspace = demo_task_buf;
|
||||
|
||||
osThreadCreate (&thread, NULL);
|
||||
}
|
||||
|
||||
11
Living_SDK/kernel/vcall/espos/Kconfig
Normal file
11
Living_SDK/kernel/vcall/espos/Kconfig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
menu "ESPOS"
|
||||
|
||||
config ESPOS
|
||||
bool "Enable Espressif RTOS abstract API"
|
||||
default y
|
||||
help
|
||||
If this feature is enabled, system will use Espressif RTOS abstract APIs instead of RTOS real APIs.
|
||||
|
||||
This option is not currently used anywhere.
|
||||
|
||||
endmenu
|
||||
14
Living_SDK/kernel/vcall/espos/espos.mk
Normal file
14
Living_SDK/kernel/vcall/espos/espos.mk
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
NAME := espos
|
||||
|
||||
GLOBAL_INCLUDES += include
|
||||
$(NAME)_SOURCES := \
|
||||
platform/rhino/espos_misc.c \
|
||||
platform/rhino/espos_mutex.c \
|
||||
platform/rhino/espos_queue.c \
|
||||
platform/rhino/espos_scheduler.c \
|
||||
platform/rhino/espos_semaphore.c \
|
||||
platform/rhino/espos_spinlock.c \
|
||||
platform/rhino/espos_task.c \
|
||||
platform/rhino/espos_time.c \
|
||||
platform/rhino/espos_timer.c
|
||||
|
||||
26
Living_SDK/kernel/vcall/espos/include/arch/espos_arch.h
Normal file
26
Living_SDK/kernel/vcall/espos/include/arch/espos_arch.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_ARCH_H_
|
||||
#define _ESPOS_ARCH_H_
|
||||
|
||||
#if defined(ESPOS_FOR_ESP32)
|
||||
#include "espos_esp32.h"
|
||||
#elif defined(ESPOS_FOR_ESP8266)
|
||||
#include "espos_esp8266.h"
|
||||
#else
|
||||
#error "no espressif platform"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
110
Living_SDK/kernel/vcall/espos/include/arch/espos_esp32.h
Normal file
110
Living_SDK/kernel/vcall/espos/include/arch/espos_esp32.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_ESP32_H_
|
||||
#define _ESPOS_ESP32_H_
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
#define ESPOS_PROCESSORS_NUM 2u
|
||||
#define CONFIG_ESPOS_SMP
|
||||
#else
|
||||
#define ESPOS_PROCESSORS_NUM 1u
|
||||
#endif
|
||||
|
||||
typedef struct espos_spinlock_arch {
|
||||
int lock;
|
||||
} espos_spinlock_arch_t;
|
||||
|
||||
#define ESPOS_SPINLOCK_ARCH_UNLOCK_INITIALIZER \
|
||||
{ \
|
||||
0, \
|
||||
}
|
||||
|
||||
static inline int espos_get_core_id(void)
|
||||
{
|
||||
int id;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" rsr.prid %0\n"
|
||||
" extui %0, %0, 13, 1\n"
|
||||
:"=r"(id));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static inline void espos_spinlock_arch_init(espos_spinlock_arch_t *lock)
|
||||
{
|
||||
lock->lock = 0;
|
||||
}
|
||||
|
||||
static inline void espos_spinlock_arch_deinit(espos_spinlock_arch_t *lock)
|
||||
{
|
||||
lock->lock = 0;
|
||||
}
|
||||
|
||||
static inline void espos_spinlock_arch_lock(espos_spinlock_arch_t *lock)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" movi %0, 0\n"
|
||||
" wsr %0, scompare1\n"
|
||||
"1: movi %0, 1\n"
|
||||
" s32c1i %0, %1, 0\n"
|
||||
" bnez %0, 1b\n"
|
||||
: "=&a" (tmp)
|
||||
: "a" (&lock->lock)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline int espos_spinlock_arch_trylock(espos_spinlock_arch_t *lock)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" movi %0, 0\n"
|
||||
" wsr %0, scompare1\n"
|
||||
" movi %0, 1\n"
|
||||
" s32c1i %0, %1, 0\n"
|
||||
: "=&a" (tmp)
|
||||
: "a" (&lock->lock)
|
||||
: "memory");
|
||||
|
||||
return tmp == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
static inline void espos_spinlock_arch_unlock(espos_spinlock_arch_t *lock)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" movi %0, 0\n"
|
||||
" s32ri %0, %1, 0\n"
|
||||
: "=&a" (tmp)
|
||||
: "a" (&lock->lock)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESPOS_ESP32_H_ */
|
||||
57
Living_SDK/kernel/vcall/espos/include/arch/espos_esp8266.h
Normal file
57
Living_SDK/kernel/vcall/espos/include/arch/espos_esp8266.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_ESP8266_H_
|
||||
#define _ESPOS_ESP8266_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESPOS_PROCESSORS_NUM 1u
|
||||
|
||||
#define ESPOS_SPINLOCK_ARCH_UNLOCK_INITIALIZER \
|
||||
{ \
|
||||
0, \
|
||||
}
|
||||
|
||||
typedef int32_t esp_err_t;
|
||||
|
||||
typedef struct espos_spinlock_arch {
|
||||
int lock;
|
||||
} espos_spinlock_arch_t;
|
||||
|
||||
static inline uintptr_t espos_suspend_interrupt(void)
|
||||
{
|
||||
uintptr_t state;
|
||||
|
||||
__asm__ volatile ("RSIL %0, 5" : "=a" (state) :: "memory");
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static inline void espos_resume_interrupt(uintptr_t state)
|
||||
{
|
||||
__asm__ volatile ("WSR %0, ps" :: "a" (state) : "memory");
|
||||
}
|
||||
|
||||
#define espos_get_core_id() 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESPOS_ESP8266_H_ */
|
||||
17
Living_SDK/kernel/vcall/espos/include/espos_errno.h
Normal file
17
Living_SDK/kernel/vcall/espos/include/espos_errno.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _ESPOS_ERRNO_H_
|
||||
#define _ESPOS_ERRNO_H_
|
||||
|
||||
#include <sys/errno.h>
|
||||
#if defined(ESPOS_FOR_ESP32)
|
||||
#include "esp_err.h"
|
||||
#elif defined(ESPOS_FOR_ESP8266)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
20
Living_SDK/kernel/vcall/espos/include/espos_include.h
Normal file
20
Living_SDK/kernel/vcall/espos/include/espos_include.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef ESPOS_INCLUDE_H
|
||||
#define ESPOS_INCLUDE_H
|
||||
|
||||
#include "espos_errno.h"
|
||||
#include "espos_mutex.h"
|
||||
#include "espos_queue.h"
|
||||
#include "espos_scheduler.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "espos_spinlock.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_time.h"
|
||||
#include "espos_timer.h"
|
||||
#include "espos_types.h"
|
||||
|
||||
#endif /* ESPOS_INCLUDE_H */
|
||||
|
||||
142
Living_SDK/kernel/vcall/espos/include/espos_mutex.h
Normal file
142
Living_SDK/kernel/vcall/espos/include/espos_mutex.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_MUTEX_H_
|
||||
#define _ESPOS_MUTEX_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* use default option to create mutex */
|
||||
typedef enum espos_mutex_opt {
|
||||
|
||||
/* AT this mode, deadlock detection shall not be provided. Attempting to relock the mutex causes deadlock.
|
||||
*
|
||||
* If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked,
|
||||
* undefined behavior results.
|
||||
*/
|
||||
ESPOS_MUTEX_NORMAL = 0,
|
||||
|
||||
ESPOS_MUTEX_RECURSIVE,
|
||||
|
||||
ESPOS_MUTEX_TYPE_MAX
|
||||
} espos_mutex_type_t;
|
||||
|
||||
#define ESPOS_MUTEX_TYPE(type) (type & 0xFF)
|
||||
|
||||
/**
|
||||
* @brief create a mutex
|
||||
*
|
||||
* @param mutex mutex handle point
|
||||
* @param opt mutex option, if you don't know how to do, just use "ESPOS_MUTEX_NORMAL" here
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_mutex_create(espos_mutex_t *mutex, espos_opt_t opt);
|
||||
|
||||
/**
|
||||
* @brief set a mutex name
|
||||
*
|
||||
* @param mutex mutex handle
|
||||
* @param name mutex's name
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_mutex_set_name(espos_mutex_t mutex, const char *name);
|
||||
|
||||
/**
|
||||
* @brief lock a mutex
|
||||
*
|
||||
* @param mutex mutex handle
|
||||
* @param wait_ticks sleep for system ticks if the locked mutex is not unlocked. Otherwise if someone
|
||||
* else unlock the locked mutex, you will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY"
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -ETIMEDOUT : timeout and you have not locked it
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
esp_err_t espos_mutex_lock(espos_mutex_t mutex, espos_tick_t wait_ticks);
|
||||
|
||||
/**
|
||||
* @bref try to lock a mutex and it will return immediately without being blocked
|
||||
*
|
||||
* @param m mutex handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*/
|
||||
#define espos_mutex_trylock(m) espos_mutex_lock(m, ESPOS_NO_DELAY)
|
||||
|
||||
/**
|
||||
* @brief unlock a mutex
|
||||
*
|
||||
* @param mutex mutex handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -EPERM : current task don't lock the mutex
|
||||
*/
|
||||
esp_err_t espos_mutex_unlock(espos_mutex_t mutex);
|
||||
|
||||
/**
|
||||
* @brief get task handle which lock the mutex
|
||||
*
|
||||
* @param mutex mutex handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
espos_task_t espos_mutex_get_holder(espos_mutex_t mutex);
|
||||
|
||||
/**
|
||||
* @brief delete the mutex
|
||||
*
|
||||
* @param mutex mutex handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -EINVAL : input parameter error
|
||||
*
|
||||
* @note if low-level module is YunOS, this function will awake all task blocked at the mutex
|
||||
*/
|
||||
esp_err_t espos_mutex_del(espos_mutex_t mutex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
212
Living_SDK/kernel/vcall/espos/include/espos_queue.h
Normal file
212
Living_SDK/kernel/vcall/espos/include/espos_queue.h
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_QUEUE_H_
|
||||
#define _ESPOS_QUEUE_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum espos_queue_pos {
|
||||
/* send message to the front of the queue */
|
||||
ESPOS_QUEUE_SEND_FRONT = 0,
|
||||
|
||||
/* send message to the back of the queue */
|
||||
ESPOS_QUEUE_SEND_BACK,
|
||||
|
||||
ESPOS_QUEUE_POS_MAX
|
||||
} espos_queue_pos_t;
|
||||
|
||||
typedef enum espos_queue_send_opt {
|
||||
/* send message with normal option */
|
||||
ESPOS_QUEUE_SEND_OPT_NORMAL = 0,
|
||||
|
||||
ESPOS_QUEUE_SEND_OPT_MAX
|
||||
} espos_queue_send_opt_t;
|
||||
|
||||
typedef enum espos_queue_recv_opt {
|
||||
/* receive message with normal option */
|
||||
ESPOS_QUEUE_RECV_OPT_NORMAL = 0,
|
||||
|
||||
ESPOS_QUEUE_RECV_OPT_MAX
|
||||
} espos_queue_recv_opt_t;
|
||||
|
||||
/**
|
||||
* @brief create a queue
|
||||
*
|
||||
* @param queue queue handle point
|
||||
* @param msg_len queue internal message length (bytes)
|
||||
* @param queue_len queue internal message maximum number
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -EINVAL : input parameter error
|
||||
*
|
||||
* @note all input and out message length is fixedly "msg_len"
|
||||
*/
|
||||
esp_err_t espos_queue_create(espos_queue_t *queue, espos_size_t msg_len, espos_size_t queue_len);
|
||||
|
||||
/**
|
||||
* @brief set a queue name
|
||||
*
|
||||
* @param queue queue handle
|
||||
* @param name queue's name
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_queue_set_name(espos_queue_t queue, const char *name);
|
||||
|
||||
/**
|
||||
* @brief send a message to the queue, it is suggested that you had better not use "espos_queue_send" directly,
|
||||
* please use "espos_queue_send_front" or "espos_queue_send_back"
|
||||
*
|
||||
* @param queue queue handle
|
||||
* @param msg message point
|
||||
* @param wait_ticks sleep for system ticks if the queue is full. Otherwise if queue is not full, you will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY"
|
||||
* @param pos position where sending the message
|
||||
* ESPOS_QUEUE_SEND_FRONT : send message to the front of the queue
|
||||
* ESPOS_QUEUE_SEND_BACK : send message to the back of the queue
|
||||
* @param opt sending option
|
||||
* ESPOS_QUEUE_SEND_OPT_NORMAL : wake up blocked task
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : timeout and the queue is full
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
esp_err_t espos_queue_send_generic(espos_queue_t queue, void *msg, espos_tick_t wait_ticks, espos_pos_t pos, espos_opt_t opt);
|
||||
|
||||
/**
|
||||
* @brief send a message to the front of the queue
|
||||
*
|
||||
* @param q queue handle
|
||||
* @param m message point
|
||||
* @param t sleep for system ticks if the queue is full. Otherwise if queue is not full, you will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY"
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : timeout and the queue is full
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
#define espos_queue_send_front(q, m, t) espos_queue_send_generic(q, m, t, ESPOS_QUEUE_SEND_FRONT, ESPOS_QUEUE_SEND_OPT_NORMAL)
|
||||
|
||||
/**
|
||||
* @brief send a message to the back of the queue
|
||||
*
|
||||
* @param q queue handle
|
||||
* @param m message point
|
||||
* @param t sleep for system ticks if the queue is full. Otherwise if queue is not full, you will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY"
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : timeout and the queue is full
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
#define espos_queue_send(q, m, t) espos_queue_send_generic(q, m, t, ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL)
|
||||
|
||||
/**
|
||||
* @brief receive a message of the queue
|
||||
*
|
||||
* @param queue queue handle
|
||||
* @param msg message point
|
||||
* @param wait_ticks sleep for system ticks if the queue is empty. Otherwise if queue is not empty, you will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY", at CPU ISR mode, it is forced to be 0
|
||||
* @param opt queue sending option
|
||||
* ESPOS_QUEUE_RECV_OPT_NORMAL : use wait_ticks to check if it is need be blocked
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : timeout and the queue is empty
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
esp_err_t espos_queue_recv_generic(espos_queue_t queue, void *msg, espos_tick_t wait_ticks, espos_opt_t opt);
|
||||
|
||||
/**
|
||||
* @brief receive a message of the queue with normal option
|
||||
*
|
||||
* @param queue queue handle
|
||||
* @param msg message point
|
||||
* @param wait_ticks sleep for system ticks if the queue is empty. Otherwise if queue is not empty, you will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY", at CPU ISR mode, it is forced to be 0
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : timeout and the queue is empty
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
#define espos_queue_recv(q, m, t) espos_queue_recv_generic(q, m, t, ESPOS_QUEUE_RECV_OPT_NORMAL)
|
||||
|
||||
/**
|
||||
* @brief get current message number of the queue
|
||||
*
|
||||
* @param queue queue handle
|
||||
*
|
||||
* @return current message number of the queue
|
||||
*/
|
||||
espos_size_t espos_queue_msg_waiting(espos_queue_t queue);
|
||||
|
||||
/**
|
||||
* @brief reset the queue
|
||||
*
|
||||
* @param queue queue handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*
|
||||
* @note if low-level module is YunOS, the function will not awake the tasks which is blocked at the queue
|
||||
*/
|
||||
esp_err_t espos_queue_flush(espos_queue_t queue);
|
||||
|
||||
/**
|
||||
* @brief delete the queue
|
||||
*
|
||||
* @param queue queue handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -EINVAL : input parameter error
|
||||
*
|
||||
* @note if low-level module is YunOS, this function will awake all task blocked at the mutex
|
||||
*/
|
||||
esp_err_t espos_queue_del(espos_queue_t queue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
245
Living_SDK/kernel/vcall/espos/include/espos_scheduler.h
Normal file
245
Living_SDK/kernel/vcall/espos/include/espos_scheduler.h
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_SCHEDULER_H_
|
||||
#define _ESPOS_SCHEDULER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_spinlock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ESPOS state
|
||||
*/
|
||||
typedef enum espos_stat {
|
||||
ESPOS_IS_NOT_STARTED = 0,
|
||||
ESPOS_IS_RUNNING,
|
||||
ESPOS_IS_SUSPENDED
|
||||
} espos_stat_t;
|
||||
|
||||
/************************************ internal function ************************************/
|
||||
/**
|
||||
* @brief enter ESPOS system critical state
|
||||
*
|
||||
* @param spinlock spinlock handle point
|
||||
*
|
||||
* @return critical state temple variable(used by "espos_exit_critical")
|
||||
*/
|
||||
espos_critical_t _espos_enter_critical(espos_spinlock_t *spinlock);
|
||||
|
||||
/**
|
||||
* @brief exit ESPOS system critical state
|
||||
*
|
||||
* @param spinlock spinlock handle point
|
||||
* @param tmp critical state temple variable(created by "espos_enter_critical")
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void _espos_exit_critical(espos_spinlock_t *spinlock, espos_critical_t tmp);
|
||||
|
||||
/*******************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief initialize ESPOS system
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
*/
|
||||
esp_err_t espos_init(void);
|
||||
|
||||
/**
|
||||
* @brief start ESPOS system
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EPERM : failed (it will never happen in a general way)
|
||||
*/
|
||||
esp_err_t espos_start(void);
|
||||
|
||||
/**
|
||||
* @brief start ESPOS system CPU port
|
||||
*
|
||||
* @param port CPU port ID
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EPERM : failed (it will never happen in a general way)
|
||||
*/
|
||||
esp_err_t espos_start_port(int port);
|
||||
|
||||
/**
|
||||
* @brief get espos system state
|
||||
*
|
||||
* @return the state
|
||||
* ESPOS_IS_NOT_STARTED : ESPOS is not started
|
||||
* ESPOS_IS_RUNNING : ESPOS is running
|
||||
* ESPOS_IS_SUSPENDED : ESPOS is suspended
|
||||
*/
|
||||
espos_stat_t espos_sched_state_get(void);
|
||||
|
||||
/**
|
||||
* @brief declare espos critical temp data
|
||||
*/
|
||||
#define espos_declare_critical(t) espos_critical_t t
|
||||
|
||||
/**
|
||||
* @brief enter ESPOS system critical state
|
||||
*
|
||||
* @param sl spinlock handle
|
||||
* @param t critical state
|
||||
*
|
||||
* @return critical state temple variable(used by "espos_exit_critical")
|
||||
*/
|
||||
#define espos_enter_critical(t, sl) (t) = _espos_enter_critical(&(sl))
|
||||
|
||||
/**
|
||||
* @brief exit ESPOS system critical state
|
||||
*
|
||||
* @param t critical state temple variable(created by "espos_enter_critical")
|
||||
* @param sl spinlock handle point
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
#define espos_exit_critical(t, sl) _espos_exit_critical(&(sl), t)
|
||||
|
||||
/**
|
||||
* @brief OS internal function enter ESPOS system critical state
|
||||
*
|
||||
* @param sl spinlock handle
|
||||
* @param t critical state
|
||||
*
|
||||
* @return critical state temple variable(used by "espos_exit_critical")
|
||||
*
|
||||
* @note: ESPOS is application level OS API, so it means all APIs call internal
|
||||
* real OS's function, so if OS's or its core hardware's functions want
|
||||
* to call ESPOS, loop nesting will occur, so we should tell ESPOS it's
|
||||
* at OS internal state now.
|
||||
*/
|
||||
#define espos_os_enter_critical(t, sl) \
|
||||
espos_os_enter(); \
|
||||
(t) = _espos_enter_critical(&(sl))
|
||||
|
||||
/**
|
||||
* @brief OS internal function exit ESPOS system critical state
|
||||
*
|
||||
* @param t critical state temple variable(created by "espos_enter_critical")
|
||||
* @param sl spinlock handle point
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
* @note: ESPOS is application level OS API, so it means all APIs call internal
|
||||
* real OS's function, so if OS's or its core hardware's functions want
|
||||
* to call ESPOS, loop nesting will occur, so we should tell ESPOS it's
|
||||
* at OS internal state now.
|
||||
*/
|
||||
#define espos_os_exit_critical(t, sl) \
|
||||
_espos_exit_critical(&(sl), t); \
|
||||
espos_os_exit()
|
||||
|
||||
/**
|
||||
* @brief suspend the local CPU core preempt and the current task
|
||||
* owned by local CPU core will not be preempted
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EAGAIN : preempt suspending maximum number is reached, and fail to do it
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*
|
||||
* @note the function can be used nested
|
||||
*/
|
||||
esp_err_t espos_preempt_suspend_local(void);
|
||||
|
||||
/**
|
||||
* @brief resume the local CPU core preempt
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EAGAIN : preempt resuming maximum number is reached, and fail to do it
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*
|
||||
* @note the function can be used nested
|
||||
*/
|
||||
esp_err_t espos_preempt_resume_local(void);
|
||||
|
||||
/**
|
||||
* @brief enter system interrupt server, the function must be used after entering hardware interrupt
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EAGAIN : nested count is reached
|
||||
*
|
||||
* @note the function can be used nested
|
||||
*/
|
||||
esp_err_t espos_isr_enter (void);
|
||||
|
||||
/**
|
||||
* @brief exit system interrupt server, the function must be used before exiting hardware interrupt
|
||||
*
|
||||
* @return none
|
||||
*
|
||||
* @note the function can be used nested
|
||||
*/
|
||||
void espos_isr_exit(void);
|
||||
|
||||
/**
|
||||
* @brief check if the CPU is at ISR state
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return true if the CPU is at ISR state or false
|
||||
*/
|
||||
bool espos_in_isr(void);
|
||||
|
||||
/**
|
||||
* @brief mark it enters real OS interal function
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EAGAIN : nested count is reached
|
||||
*
|
||||
* @note the function can be used nested
|
||||
*/
|
||||
esp_err_t espos_os_enter(void);
|
||||
|
||||
/**
|
||||
* @brief remove mark it enters real OS interal function
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void espos_os_exit(void);
|
||||
|
||||
/**
|
||||
* @brief check if the function is at real OS internal fucntion
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return true if the CPU is at real OS internal fucntion or false
|
||||
*/
|
||||
bool espos_os_isr(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
119
Living_SDK/kernel/vcall/espos/include/espos_semaphore.h
Normal file
119
Living_SDK/kernel/vcall/espos/include/espos_semaphore.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_SEMAPHORE_H_
|
||||
#define _ESPOS_SEMAPHORE_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief create a semaphore
|
||||
*
|
||||
* @param sem semaphore handle point
|
||||
* @param max_count semaphore maximum count
|
||||
* @param init_count semaphore initialized count
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* ENOMEM : no enough memory
|
||||
* EINVAL : input parameter error
|
||||
*
|
||||
* @note if low-level module is YunOS, "max_count" does not work, and the reachable count is "0xFFFFFFFF"
|
||||
*/
|
||||
esp_err_t espos_sem_create(espos_sem_t *sem, espos_sem_count_t max_count, espos_sem_count_t init_count);
|
||||
|
||||
/**
|
||||
* @brief set a semaphore name
|
||||
*
|
||||
* @param semaphore semaphore handle
|
||||
* @param name semaphore's name
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_sem_set_name(espos_sem_t sem, const char *name);
|
||||
|
||||
/**
|
||||
* @brief take semaphore
|
||||
*
|
||||
* @param sem semaphore handle
|
||||
* @param wait_ticks sleep for system ticks if the semaphore is empty. Otherwise if semaphore is given,
|
||||
* oldest blocked task will wake up.
|
||||
* maximum time is "ESPOS_MAX_DELAY", no time is "ESPOS_NO_DELAY"
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : timeout and not take semaphore
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
esp_err_t espos_sem_take(espos_sem_t sem, espos_tick_t wait_ticks);
|
||||
|
||||
/**
|
||||
* @brief try to take semaphore
|
||||
*
|
||||
* @param s semaphore handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ETIMEDOUT : not take semaphore
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
#define espos_sem_trytake(s) espos_sem_take(s, ESPOS_NO_DELAY)
|
||||
|
||||
/**
|
||||
* @brief give up semaphore
|
||||
*
|
||||
* @param sem semaphore handle
|
||||
* @param wait_ticks no meaning
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -EAGAIN : the maximum count is reached
|
||||
*
|
||||
* @note you can transform the millisecond to ticks by "espos_ms_to_ticks"
|
||||
*/
|
||||
esp_err_t espos_sem_give(espos_sem_t sem);
|
||||
|
||||
/**
|
||||
* @brief delete the semaphore
|
||||
*
|
||||
* @param sem semaphore handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
* -EINVAL : input parameter error
|
||||
*
|
||||
* @note if low-level module is YunOS, this function will awake all task blocked here
|
||||
*/
|
||||
esp_err_t espos_sem_del(espos_sem_t sem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
128
Living_SDK/kernel/vcall/espos/include/espos_spinlock.h
Normal file
128
Living_SDK/kernel/vcall/espos/include/espos_spinlock.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_SPINLOCK_H_
|
||||
#define _ESPOS_SPINLOCK_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct espos_spinlock {
|
||||
espos_spinlock_arch_t lock;
|
||||
espos_task_t holder;
|
||||
} espos_spinlock_t;
|
||||
|
||||
#define ESPOS_SPINLOCK_UNLOCK_INITIALIZER \
|
||||
{ \
|
||||
ESPOS_SPINLOCK_ARCH_UNLOCK_INITIALIZER, \
|
||||
ESPOS_OBJ_NONE, \
|
||||
}
|
||||
|
||||
#define ESPOS_DEFINE_SPINLOCK(l) \
|
||||
espos_spinlock_t l = ESPOS_SPINLOCK_UNLOCK_INITIALIZER
|
||||
|
||||
#define ESPOS_DEFINE_STATIC_SPINLOCK(l) \
|
||||
static espos_spinlock_t l = ESPOS_SPINLOCK_UNLOCK_INITIALIZER
|
||||
|
||||
/**
|
||||
* @brief create a spinlock
|
||||
*
|
||||
* @param spinlock spinlock handle point
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_spinlock_create (espos_spinlock_t *spinlock);
|
||||
|
||||
/**
|
||||
* @brief set a spinlock name
|
||||
*
|
||||
* @param spinlock spinlock handle
|
||||
* @param name spinlock's name
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_spinlock_set_name(espos_spinlock_t *spinlock, const char *name);
|
||||
|
||||
/**
|
||||
* @brief spin to lock a spinlock until successfully
|
||||
*
|
||||
* @param spinlock spinlock handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_spinlock_lock(espos_spinlock_t *spinlock);
|
||||
|
||||
/**
|
||||
* @brief try to lock a spinlock
|
||||
*
|
||||
* @param spinlock spinlock handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EAGAIN : no spinlock is valid
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_spinlock_trylock(espos_spinlock_t *spinlock);
|
||||
|
||||
/**
|
||||
* @brief get spinlock holder task handle
|
||||
*
|
||||
* @param spinlock spinlock handle
|
||||
*
|
||||
* @return holder task handle
|
||||
*/
|
||||
espos_task_t espos_spinlock_get_holder(espos_spinlock_t *spinlock);
|
||||
|
||||
/**
|
||||
* @brief unlock a spinlock
|
||||
*
|
||||
* @param spinlock spinlock handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EAGAIN : no spinlock is locked
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_spinlock_unlock(espos_spinlock_t *spinlock);
|
||||
|
||||
/**
|
||||
* @brief delete a spinlock
|
||||
*
|
||||
* @param spinlock spinlock handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EACCES : failed to do it with some special reason
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_spinlock_del(espos_spinlock_t *spinlock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
209
Living_SDK/kernel/vcall/espos/include/espos_task.h
Normal file
209
Living_SDK/kernel/vcall/espos/include/espos_task.h
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_TASK_H_
|
||||
#define _ESPOS_TASK_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* task will run at any CPU */
|
||||
#define ESPOS_TASK_NO_AFFINITY -1
|
||||
|
||||
/* create task and start it automatically */
|
||||
#define ESPOS_TASK_CREATE_NORMAL 0
|
||||
/* just create task and don't start it */
|
||||
#define ESPOS_TASK_CREATE_SILENCE 1
|
||||
|
||||
/* task delete itself */
|
||||
#define ESPOS_TASK_DELETE_SELF 0
|
||||
|
||||
/*
|
||||
* task priority numbers, we use 26 here because FreeRTOS uses 26 but YunOS uses 62,
|
||||
* we should use minimum one of them to be compatible with the current application
|
||||
*/
|
||||
#ifndef ESPOS_TASK_PRIO_NUM
|
||||
#define ESPOS_TASK_PRIO_NUM espos_task_prio_num()
|
||||
#endif
|
||||
|
||||
/* task maximum priority number */
|
||||
#define ESPOS_TASK_PRIO_MAX (ESPOS_TASK_PRIO_NUM - 1)
|
||||
|
||||
/**
|
||||
* @brief create a task
|
||||
*
|
||||
* @param task task handle point
|
||||
* @param name task name, if name is NULL, we will use "default_task" default
|
||||
* @param arg task entry function inputting parameter
|
||||
* @param prio task priority
|
||||
* @param ticks task time slice
|
||||
* @param stack_size task stack size, its unit is "byte"
|
||||
* @param entry task entry function
|
||||
* @param opt task option
|
||||
* ESPOS_TASK_CREATE_NORMAL : the created task will be started automatically
|
||||
* ESPOS_TASK_CREATE_SILENCE : the created task will not be started automatically
|
||||
* @param cpu_id task CPU id
|
||||
* natural number : the task only runs at the CPU of the number
|
||||
* ESPOS_TASK_NO_AFFINITY : the task runs at any CPU
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
* -EINVAL : input parameter error
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*/
|
||||
esp_err_t espos_task_create_on_cpu(espos_task_t *task, const char *name, void *arg, espos_prio_t prio,
|
||||
espos_tick_t ticks, espos_size_t stack_size, espos_task_entry_t entry, espos_opt_t opt, espos_cpu_t cpu_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief create a task and set its CPU id to be "ESPOS_TASK_NO_AFFINITY"
|
||||
*
|
||||
* @param task task handle point
|
||||
* @param name task name, if name is NULL, we will use "default_task" default
|
||||
* @param arg task entry function inputting parameter
|
||||
* @param prio task priority
|
||||
* @param ticks task time slice
|
||||
* @param stack_size task stack size, its unit is "byte"
|
||||
* @param entry task entry function
|
||||
* @param opt task option
|
||||
* ESPOS_TASK_CREATE_NORMAL : the created task will be started automatically
|
||||
* ESPOS_TASK_CREATE_SILENCE : the created task will not be started automatically
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
* -EINVAL : input parameter error
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*/
|
||||
#define espos_task_create(task, name, arg, prio, ticks, stack_size, entry, opt) \
|
||||
espos_task_create_on_cpu(task, name, arg, prio, ticks, stack_size, entry, opt, ESPOS_TASK_NO_AFFINITY)
|
||||
|
||||
/**
|
||||
* @brief delete a task
|
||||
*
|
||||
* @param task task handle
|
||||
* ESPOS_TASK_DELETE_SELF : task will delete itself
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EACCES : failed to do it with some special reason
|
||||
*/
|
||||
esp_err_t espos_task_del(espos_task_t task);
|
||||
|
||||
/**
|
||||
* @brief let current task sleep for some ticks
|
||||
*
|
||||
* @param delay_ticks system ticks
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_task_delay(const espos_tick_t delay_ticks);
|
||||
|
||||
/**
|
||||
* @brief suspend target task
|
||||
*
|
||||
* @param task task handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_task_suspend(espos_task_t task);
|
||||
|
||||
/**
|
||||
* @brief resume target task
|
||||
*
|
||||
* @param task task handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_task_resume(espos_task_t task);
|
||||
|
||||
/**
|
||||
* @brief yield the cpu once
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EACCES : failed to do it with some special reason
|
||||
*/
|
||||
esp_err_t espos_task_yield(void);
|
||||
|
||||
/**
|
||||
* @brief get current task handle
|
||||
*
|
||||
* @return current task handle
|
||||
*/
|
||||
espos_task_t espos_task_get_current(void);
|
||||
|
||||
/**
|
||||
* @brief get current task name point
|
||||
*
|
||||
* @param task task handle
|
||||
* @param pname pointing at name's point
|
||||
*
|
||||
* @return current task handle
|
||||
*/
|
||||
esp_err_t espos_task_get_name (espos_task_t task, char **pname);
|
||||
|
||||
/**
|
||||
* @brief set task private data
|
||||
*
|
||||
* @param task task handle
|
||||
* @param idx task data index
|
||||
* @param info task private data
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_task_set_private_data(espos_task_t task, int idx, void *info);
|
||||
|
||||
/**
|
||||
* @brief get task private data
|
||||
*
|
||||
* @param task task handle
|
||||
* @param idx task data index
|
||||
* @param info task private data point
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_task_get_private_data(espos_task_t task, int idx, void **info);
|
||||
|
||||
/**
|
||||
* @brief get CPU affinity of task
|
||||
*
|
||||
* @return CPU affinity of task
|
||||
*/
|
||||
espos_cpu_t espos_task_get_affinity(espos_task_t task);
|
||||
|
||||
size_t espos_task_prio_num(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
69
Living_SDK/kernel/vcall/espos/include/espos_time.h
Normal file
69
Living_SDK/kernel/vcall/espos/include/espos_time.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_TIME_H_
|
||||
#define _ESPOS_TIME_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* delay or wait for ticks, it is used by mutex, queue,
|
||||
* semaphore, timer and so on
|
||||
*/
|
||||
/* no delay for ticks, function will return immediately */
|
||||
#define ESPOS_NO_DELAY 0u
|
||||
/* delay forever, function will never return until event triggers */
|
||||
#define ESPOS_MAX_DELAY 0xffffffffu
|
||||
|
||||
espos_time_t espos_get_tick_per_ms(void);
|
||||
|
||||
/**
|
||||
* @brief get current system ticks
|
||||
*
|
||||
* @return current ticks
|
||||
*/
|
||||
espos_tick_t espos_get_tick_count(void);
|
||||
|
||||
/**
|
||||
* @brief transform milliseconds to system ticks
|
||||
*
|
||||
* @param ms milliseconds
|
||||
*
|
||||
* @return system ticks
|
||||
*
|
||||
* @note the function discards the shortage of digits, for example:
|
||||
* 20ms -> 2 ticks ; 21ms -> 2 ticks; 29 -> 2 ticks
|
||||
*/
|
||||
espos_tick_t espos_ms_to_ticks(espos_time_t ms);
|
||||
|
||||
/**
|
||||
* @brief transform system ticks to milliseconds
|
||||
*
|
||||
* @param ticks system ticks
|
||||
*
|
||||
* @return milliseconds
|
||||
*/
|
||||
espos_time_t espos_ticks_to_ms(espos_tick_t ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
174
Living_SDK/kernel/vcall/espos/include/espos_timer.h
Normal file
174
Living_SDK/kernel/vcall/espos/include/espos_timer.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESPOS_TIMER_H_
|
||||
#define _ESPOS_TIMER_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "espos_errno.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* timer just run once after starting it */
|
||||
#define ESPOS_TIMER_NO_AUTO_RUN 0
|
||||
/* timer run cycle after starting it */
|
||||
#define ESPOS_TIMER_AUTO_RUN (1 << 0)
|
||||
|
||||
/* timer configuration command */
|
||||
typedef enum espos_timer_cmd {
|
||||
/* configure time's period */
|
||||
ESPOS_TIMER_CHANGE_PERIOD = 0,
|
||||
/* configure time to be "once" */
|
||||
ESPOS_TIMER_CHANGE_ONCE,
|
||||
/* configure time to be "auto" */
|
||||
ESPOS_TIMER_CHANGE_AUTO,
|
||||
|
||||
ESPOS_TIMER_CMD_MAX
|
||||
} espos_timer_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief create a timer
|
||||
*
|
||||
* @param timer timer handle point
|
||||
* @param name timer name, if name is NULL, we will use "default_timer" default
|
||||
* @param cb timer callback function
|
||||
* @param arg timer entry function inputting parameter
|
||||
* @param period_ticks timer period ticks
|
||||
* @param opt timer option
|
||||
* ESPOS_TIMER_NO_AUTO_RUN : created timer will run once, even if it is started,
|
||||
* ESPOS_TIMER_AUTO_RUN : created timer will run automatically
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -ENOMEM : no enough memory
|
||||
* -EINVAL : input parameter error
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*
|
||||
* @note after starting the created timer by "espos_timer_start", it will only run.
|
||||
*/
|
||||
esp_err_t espos_timer_create(espos_timer_t *timer, const char *name, espos_timer_cb_t cb, void *arg,
|
||||
espos_tick_t period_ticks, espos_opt_t opt);
|
||||
|
||||
/**
|
||||
* @brief start a timer
|
||||
*
|
||||
* @param timer timer handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ECANCELED : failed for some reason depend on low-level OS
|
||||
*
|
||||
* @note after starting the created timer by "espos_timer_start", it will only run
|
||||
*/
|
||||
esp_err_t espos_timer_start(espos_timer_t timer);
|
||||
|
||||
/**
|
||||
* @brief stop a timer
|
||||
*
|
||||
* @param timer timer handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ECANCELED : failed for some reason depend on low-level OS
|
||||
*
|
||||
* @note the timer should be started again, if it is stopped
|
||||
*/
|
||||
esp_err_t espos_timer_stop(espos_timer_t timer);
|
||||
|
||||
/**
|
||||
* @brief configure a timer
|
||||
*
|
||||
* @param timer timer handle
|
||||
* @param opt timer option command
|
||||
* @param arg timer parameter
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ECANCELED : failed for some reason depend on low-level OS
|
||||
*/
|
||||
esp_err_t espos_timer_change(espos_timer_t timer, espos_opt_t opt, void *arg);
|
||||
|
||||
/**
|
||||
* @brief configure period of timer
|
||||
*
|
||||
* @param t timer handle
|
||||
* @param a timer period
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ECANCELED : failed for some reason depend on low-level OS
|
||||
*/
|
||||
#define espos_timer_set_period(t, a) espos_timer_change(t, ESPOS_TIMER_CHANGE_PERIOD, (void *)a)
|
||||
|
||||
/**
|
||||
* @brief configure timer to be "once"
|
||||
*
|
||||
* @param t timer handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ECANCELED : failed for some reason depend on low-level OS
|
||||
*/
|
||||
#define espos_timer_set_once(t) espos_timer_change(t, ESPOS_TIMER_CHANGE_ONCE, NULL)
|
||||
|
||||
/**
|
||||
* @brief configure timer to be "auto"
|
||||
*
|
||||
* @param t timer handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
* -ECANCELED : failed for some reason depend on low-level OS
|
||||
*/
|
||||
#define espos_timer_set_auto(t) espos_timer_change(t, ESPOS_TIMER_CHANGE_AUTO, NULL)
|
||||
|
||||
/**
|
||||
* @brief delete a timer
|
||||
*
|
||||
* @param t timer handle
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EACCES : failed to do it with some special reason
|
||||
* -EINTR : you do this at interrupt state, and it is not supported
|
||||
*/
|
||||
esp_err_t espos_timer_del(espos_timer_t timer);
|
||||
|
||||
/**
|
||||
* @brief get current timer name point
|
||||
*
|
||||
* @param timer timer handle
|
||||
* @param pname pointing at name's point
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_get_timer_name (espos_timer_t timer, char **pname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
42
Living_SDK/kernel/vcall/espos/include/espos_types.h
Normal file
42
Living_SDK/kernel/vcall/espos/include/espos_types.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _ESPOS_TYPES_H_
|
||||
#define _ESPOS_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "arch/espos_arch.h"
|
||||
|
||||
#define ESPOS_OBJ_NONE 0
|
||||
|
||||
#ifdef ARCH64
|
||||
typedef uint64_t espos_obj_t;
|
||||
#else
|
||||
typedef uint32_t espos_obj_t;
|
||||
#endif
|
||||
|
||||
typedef espos_obj_t espos_task_t;
|
||||
typedef espos_obj_t espos_queue_t;
|
||||
typedef espos_obj_t espos_mutex_t;
|
||||
typedef espos_obj_t espos_sem_t;
|
||||
typedef espos_obj_t espos_timer_t;
|
||||
typedef espos_obj_t espos_critical_t;
|
||||
|
||||
typedef size_t espos_size_t;
|
||||
typedef size_t espos_pos_t;
|
||||
typedef uint8_t espos_prio_t;
|
||||
typedef uint32_t espos_opt_t;
|
||||
typedef int32_t espos_cpu_t;
|
||||
|
||||
typedef espos_size_t espos_tick_t;
|
||||
typedef espos_size_t espos_time_t;
|
||||
typedef espos_size_t espos_sem_count_t;
|
||||
|
||||
typedef void (*espos_task_entry_t)(void *p);
|
||||
typedef void (*espos_timer_cb_t)(espos_timer_t timer, void *arg);
|
||||
|
||||
#endif
|
||||
|
||||
13
Living_SDK/kernel/vcall/espos/platform/rhino/espos_err.h
Normal file
13
Living_SDK/kernel/vcall/espos/platform/rhino/espos_err.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef ESPOS_ERR_MAP_H
|
||||
#define ESPOS_ERR_MAP_H
|
||||
|
||||
#define IRAM_ATTR __attribute__((section(".text")))
|
||||
|
||||
int espos_err_map (kstat_t err_code);
|
||||
|
||||
#endif
|
||||
|
||||
22
Living_SDK/kernel/vcall/espos/platform/rhino/espos_misc.c
Normal file
22
Living_SDK/kernel/vcall/espos/platform/rhino/espos_misc.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
|
||||
int IRAM_ATTR espos_err_map (kstat_t err_code)
|
||||
{
|
||||
if (err_code == RHINO_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t espos_get_free_heap_size(void)
|
||||
{
|
||||
extern k_mm_head *g_kmm_head;
|
||||
|
||||
return g_kmm_head->free_size;
|
||||
}
|
||||
111
Living_SDK/kernel/vcall/espos/platform/rhino/espos_mutex.c
Normal file
111
Living_SDK/kernel/vcall/espos/platform/rhino/espos_mutex.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
#include "espos_mutex.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
/**
|
||||
* @brief create a mutex
|
||||
*/
|
||||
esp_err_t espos_mutex_create (
|
||||
espos_mutex_t *mutex,
|
||||
espos_opt_t opt
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kmutex_t **pmutex = (kmutex_t **)mutex;
|
||||
|
||||
ret = krhino_mutex_dyn_create(pmutex, "default_mutex");
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set a mutex name
|
||||
*/
|
||||
esp_err_t espos_mutex_set_name(espos_mutex_t mutex, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief lock a mutex
|
||||
*/
|
||||
esp_err_t espos_mutex_lock (
|
||||
espos_mutex_t mutex,
|
||||
espos_tick_t wait_ticks
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kmutex_t *pmutex = (kmutex_t *)mutex;
|
||||
|
||||
ret = krhino_mutex_lock(pmutex, wait_ticks);
|
||||
|
||||
if (ret == RHINO_MUTEX_OWNER_NESTED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unlock a mutex
|
||||
*/
|
||||
esp_err_t espos_mutex_unlock (
|
||||
espos_mutex_t mutex
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kmutex_t *pmutex = (kmutex_t *)mutex;
|
||||
|
||||
ret = krhino_mutex_unlock(pmutex);
|
||||
if (ret == RHINO_MUTEX_OWNER_NESTED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get task handle whick lock the mutex
|
||||
*/
|
||||
espos_task_t espos_mutex_get_holder (
|
||||
espos_mutex_t mutex
|
||||
)
|
||||
{
|
||||
espos_task_t tmp;
|
||||
|
||||
kmutex_t *pmutex = (kmutex_t *)mutex;
|
||||
tmp = (espos_task_t)(pmutex->mutex_task);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief delete the mutex
|
||||
*/
|
||||
esp_err_t espos_mutex_del (
|
||||
espos_mutex_t mutex
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kmutex_t *pmutex = (kmutex_t *)mutex;
|
||||
|
||||
ret = krhino_mutex_dyn_del(pmutex);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
138
Living_SDK/kernel/vcall/espos/platform/rhino/espos_queue.c
Normal file
138
Living_SDK/kernel/vcall/espos/platform/rhino/espos_queue.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
#include "espos_queue.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
/**
|
||||
* @brief create a queue
|
||||
*/
|
||||
esp_err_t espos_queue_create (
|
||||
espos_queue_t *queue,
|
||||
espos_size_t msg_len,
|
||||
espos_size_t queue_len
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t **pqueue = (kbuf_queue_t **)queue;
|
||||
|
||||
ret = krhino_buf_queue_dyn_create(pqueue, "default_queue", queue_len * (msg_len + COMPRESS_LEN(msg_len)), msg_len);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set a queue name
|
||||
*
|
||||
* @param queue queue handle
|
||||
* @param name queue's name
|
||||
*
|
||||
* @return the result
|
||||
* 0 : successful
|
||||
* -EINVAL : input parameter error
|
||||
*/
|
||||
esp_err_t espos_queue_set_name(espos_queue_t queue, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief send a message to the queue
|
||||
*/
|
||||
esp_err_t IRAM_ATTR espos_queue_send_generic (
|
||||
espos_queue_t queue,
|
||||
void *msg,
|
||||
espos_tick_t wait_ticks,
|
||||
espos_pos_t pos,
|
||||
espos_opt_t opt
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t *pqueue = (kbuf_queue_t *)queue;
|
||||
|
||||
ret = krhino_buf_queue_send(pqueue, msg, pqueue->max_msg_size);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief receive a message of the queue
|
||||
*/
|
||||
esp_err_t espos_queue_recv_generic (
|
||||
espos_queue_t queue,
|
||||
void *msg,
|
||||
espos_tick_t wait_ticks,
|
||||
espos_opt_t opt
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t *pqueue = (kbuf_queue_t *)queue;
|
||||
size_t msg_len;
|
||||
|
||||
ret = krhino_buf_queue_recv(pqueue, wait_ticks, msg, &msg_len);
|
||||
|
||||
return espos_err_map(ret);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get current message number of the queue
|
||||
*/
|
||||
espos_size_t espos_queue_msg_waiting(espos_queue_t queue)
|
||||
{
|
||||
CPSR_ALLOC();
|
||||
espos_size_t item_size;
|
||||
|
||||
kbuf_queue_t *pqueue = (kbuf_queue_t *)queue;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
//item_size = (pqueue->buf_size - pqueue->free_buf_size) / (pqueue->max_msg_size + HEADER_SIZE);
|
||||
item_size = pqueue->cur_num;
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return item_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reset the queue
|
||||
*/
|
||||
esp_err_t espos_queue_flush (
|
||||
espos_queue_t queue
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t *pqueue = (kbuf_queue_t *)queue;
|
||||
|
||||
ret = krhino_buf_queue_flush(pqueue);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief delete the queue
|
||||
*/
|
||||
esp_err_t espos_queue_del (
|
||||
espos_queue_t queue
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t *pqueue = (kbuf_queue_t *)queue;
|
||||
|
||||
ret = krhino_buf_queue_dyn_del(pqueue);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
217
Living_SDK/kernel/vcall/espos/platform/rhino/espos_scheduler.c
Normal file
217
Living_SDK/kernel/vcall/espos/platform/rhino/espos_scheduler.c
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
static espos_size_t s_isr_nested_count[ESPOS_PROCESSORS_NUM];
|
||||
static espos_size_t s_os_nested_count[ESPOS_PROCESSORS_NUM];
|
||||
#if 1
|
||||
static espos_size_t s_critial_count[ESPOS_PROCESSORS_NUM];
|
||||
static espos_critical_t s_critial_status[ESPOS_PROCESSORS_NUM];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief initialize ESPOS system
|
||||
*/
|
||||
esp_err_t espos_init(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_init();
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief start ESPOS system
|
||||
*/
|
||||
esp_err_t espos_start(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_start();
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief start ESPOS system CPU port
|
||||
*/
|
||||
esp_err_t espos_start_port(int port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get ESPOS system state
|
||||
*/
|
||||
espos_stat_t espos_sched_state_get(void)
|
||||
{
|
||||
if (g_sys_stat == RHINO_RUNNING) {
|
||||
return ESPOS_IS_RUNNING;
|
||||
}
|
||||
|
||||
return ESPOS_IS_NOT_STARTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check if the CPU is at ISR state
|
||||
*/
|
||||
bool espos_in_isr(void)
|
||||
{
|
||||
return (s_isr_nested_count[0] > 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check if the function is at real OS internal fucntion
|
||||
*/
|
||||
bool espos_os_isr(void)
|
||||
{
|
||||
return (s_os_nested_count[0] > 0) ? true : false;
|
||||
}
|
||||
|
||||
static inline uint32_t __set_int(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"rsil %0, 2\n"
|
||||
: "=a"(flags)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void __set_ps(uint32_t flags)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"wsr %0, ps\n"
|
||||
"esync"
|
||||
:
|
||||
: "a"(flags)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enter ESPOS system critical state
|
||||
*/
|
||||
espos_critical_t IRAM_ATTR _espos_enter_critical(espos_spinlock_t *spinlock)
|
||||
{
|
||||
espos_critical_t tmp;
|
||||
|
||||
tmp = (espos_critical_t)__set_int();
|
||||
if (!s_critial_count[espos_get_core_id()]) {
|
||||
s_critial_status[espos_get_core_id()] = tmp;
|
||||
}
|
||||
s_critial_count[espos_get_core_id()]++;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief exit ESPOS system critical state
|
||||
*/
|
||||
void IRAM_ATTR _espos_exit_critical(espos_spinlock_t *spinlock, espos_critical_t tmp)
|
||||
{
|
||||
s_critial_count[espos_get_core_id()]--;
|
||||
if (!s_critial_count[espos_get_core_id()]) {
|
||||
tmp = s_critial_status[espos_get_core_id()];
|
||||
__set_ps(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief suspend the preempt and the current task will not be preempted
|
||||
*/
|
||||
esp_err_t espos_preempt_suspend_local(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (g_sys_stat == RHINO_STOPPED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = krhino_sched_disable();
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief resume the preempt
|
||||
*/
|
||||
esp_err_t espos_preempt_resume_local(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (g_sys_stat == RHINO_STOPPED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = krhino_sched_enable();
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enter system interrupt server, the function must be used after entering hardware interrupt
|
||||
*/
|
||||
esp_err_t espos_isr_enter (void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_intrpt_enter();
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief exit system interrupt server, the function must be used before exiting hardware interrupt
|
||||
*/
|
||||
void espos_isr_exit(void)
|
||||
{
|
||||
krhino_intrpt_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mark it enters real OS interal function
|
||||
*/
|
||||
esp_err_t espos_os_enter (void)
|
||||
{
|
||||
s_os_nested_count[espos_get_core_id()]++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief remove mark it enters real OS interal function
|
||||
*/
|
||||
void espos_os_exit(void)
|
||||
{
|
||||
if (!s_os_nested_count[espos_get_core_id()]) {
|
||||
return ;
|
||||
}
|
||||
|
||||
s_os_nested_count[espos_get_core_id()]--;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <k_api.h>
|
||||
#include "espos_err.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
/**
|
||||
* @brief create a semaphore
|
||||
*/
|
||||
esp_err_t espos_sem_create (
|
||||
espos_sem_t *sem,
|
||||
espos_sem_count_t max_count,
|
||||
espos_sem_count_t init_count
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t **psem = (ksem_t **)sem;
|
||||
|
||||
ret = krhino_sem_dyn_create(psem, "default_sem", init_count);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set a semaphore name
|
||||
*/
|
||||
esp_err_t espos_sem_set_name(espos_sem_t sem, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief take semaphore
|
||||
*/
|
||||
esp_err_t espos_sem_take (
|
||||
espos_sem_t sem,
|
||||
espos_tick_t wait_ticks
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t *psem = (ksem_t *)sem;
|
||||
|
||||
ret = krhino_sem_take(psem, wait_ticks);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief give up semaphore
|
||||
*/
|
||||
esp_err_t espos_sem_give (
|
||||
espos_sem_t sem
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t *psem = (ksem_t *)sem;
|
||||
|
||||
ret = krhino_sem_give(psem);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief delete the semaphore
|
||||
*/
|
||||
esp_err_t espos_sem_del (
|
||||
espos_sem_t sem
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ksem_t *psem = (ksem_t *)sem;
|
||||
|
||||
ret = krhino_sem_dyn_del(psem);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
134
Living_SDK/kernel/vcall/espos/platform/rhino/espos_spinlock.c
Normal file
134
Living_SDK/kernel/vcall/espos/platform/rhino/espos_spinlock.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include "espos_spinlock.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
/**
|
||||
* @brief create a spinlock
|
||||
*/
|
||||
esp_err_t espos_spinlock_create (
|
||||
espos_spinlock_t *spinlock
|
||||
)
|
||||
{
|
||||
if (!spinlock) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
espos_spinlock_arch_init(&spinlock->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set a spinlock name
|
||||
*/
|
||||
esp_err_t espos_spinlock_set_name(espos_spinlock_t *spinlock, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief spin to lock a spinlock until sucessfully
|
||||
*/
|
||||
esp_err_t espos_spinlock_lock (
|
||||
espos_spinlock_t *spinlock
|
||||
)
|
||||
{
|
||||
if (!spinlock) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
espos_preempt_suspend_local();
|
||||
|
||||
espos_spinlock_arch_lock(&spinlock->lock);
|
||||
|
||||
spinlock->holder = espos_task_get_current();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief try to lock a spinlock
|
||||
*/
|
||||
esp_err_t espos_spinlock_trylock (
|
||||
espos_spinlock_t *spinlock
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!spinlock) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
espos_preempt_suspend_local();
|
||||
|
||||
ret = espos_spinlock_arch_trylock(&spinlock->lock);
|
||||
if (ret) {
|
||||
ret = -EAGAIN;
|
||||
espos_preempt_resume_local();
|
||||
} else {
|
||||
spinlock->holder = espos_task_get_current();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get spinlock holder task handle
|
||||
*/
|
||||
espos_task_t espos_spinlock_get_holder (
|
||||
espos_spinlock_t *spinlock
|
||||
)
|
||||
{
|
||||
return spinlock->holder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unlock a spinlock
|
||||
*/
|
||||
esp_err_t espos_spinlock_unlock (
|
||||
espos_spinlock_t *spinlock
|
||||
)
|
||||
{
|
||||
if (!spinlock) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spinlock->holder = ESPOS_OBJ_NONE;
|
||||
|
||||
espos_spinlock_arch_unlock(&spinlock->lock);
|
||||
|
||||
espos_preempt_resume_local();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief delete a spinlock
|
||||
*/
|
||||
esp_err_t espos_spinlock_del (
|
||||
espos_spinlock_t *spinlock
|
||||
)
|
||||
{
|
||||
if (!spinlock) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
espos_spinlock_arch_deinit(&spinlock->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
267
Living_SDK/kernel/vcall/espos/platform/rhino/espos_task.c
Normal file
267
Living_SDK/kernel/vcall/espos/platform/rhino/espos_task.c
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
/**
|
||||
* @brief create a task
|
||||
*/
|
||||
esp_err_t espos_task_create_on_cpu (
|
||||
espos_task_t *task,
|
||||
const char *name,
|
||||
void *arg,
|
||||
espos_prio_t prio,
|
||||
espos_tick_t ticks,
|
||||
espos_size_t stack_size,
|
||||
espos_task_entry_t entry,
|
||||
espos_opt_t opt,
|
||||
espos_cpu_t cpu_id
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktask_t **ptask = (ktask_t **)task;
|
||||
uint8_t auto_run;
|
||||
extern void _cleanup_r(struct _reent* r);
|
||||
cpu_stack_t os_task_size;
|
||||
|
||||
if (name == NULL) {
|
||||
name = "default_task";
|
||||
}
|
||||
|
||||
if (prio > ESPOS_TASK_PRIO_NUM)
|
||||
return espos_err_map(RHINO_BEYOND_MAX_PRI);
|
||||
|
||||
if (ESPOS_TASK_CREATE_NORMAL == opt) {
|
||||
auto_run = 1;
|
||||
}
|
||||
else {
|
||||
auto_run = 0;
|
||||
}
|
||||
|
||||
#if defined(ESPOS_FOR_ESP32)
|
||||
os_task_size = stack_size / sizeof(cpu_stack_t);
|
||||
#elif defined(ESPOS_FOR_ESP8266)
|
||||
os_task_size = stack_size;
|
||||
#endif
|
||||
|
||||
prio = RHINO_CONFIG_USER_PRI_MAX - prio;
|
||||
assert(prio > 10);
|
||||
|
||||
if ( strcmp(name,"event_task") == 0 )
|
||||
{
|
||||
/* default event_task size is too small */
|
||||
os_task_size += 64;
|
||||
}
|
||||
|
||||
ret = krhino_task_dyn_create(ptask, name, arg, prio, ticks,
|
||||
os_task_size, entry, auto_run);
|
||||
|
||||
/* The following code may open it later */
|
||||
#if 0
|
||||
if (ret == 0) {
|
||||
struct _reent *r;
|
||||
r = krhino_mm_alloc(sizeof(*r));
|
||||
esp_reent_init(r);
|
||||
ret = krhino_task_info_set(*ptask, 2, r);
|
||||
}
|
||||
#endif
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief delete a task
|
||||
*/
|
||||
esp_err_t espos_task_del (
|
||||
espos_task_t task
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktask_t *ptask = (ktask_t *)task;
|
||||
|
||||
/* Be very careful here user_info[1] is used here */
|
||||
#if 0
|
||||
espos_sem_t *sem = ptask->user_info[1];
|
||||
if (sem && *sem) {
|
||||
espos_sem_del(*sem);
|
||||
}
|
||||
if (sem){
|
||||
krhino_mm_free(sem);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = krhino_task_dyn_del(ptask);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief let current task sleep for some ticks
|
||||
*/
|
||||
esp_err_t espos_task_delay (
|
||||
const espos_tick_t delay_ticks
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_task_sleep(delay_ticks);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief suspend target task
|
||||
*/
|
||||
esp_err_t espos_task_suspend (
|
||||
espos_task_t task
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktask_t *ptask = (ktask_t *)task;
|
||||
|
||||
ret = krhino_task_suspend(ptask);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief resume target task
|
||||
*/
|
||||
esp_err_t espos_task_resume (
|
||||
espos_task_t task
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktask_t *ptask = (ktask_t *)task;
|
||||
|
||||
ret = krhino_task_resume(ptask);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief yield the cpu once
|
||||
*/
|
||||
esp_err_t espos_task_yield(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_task_yield();
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get current task handle
|
||||
*/
|
||||
espos_task_t espos_task_get_current(void)
|
||||
{
|
||||
return (espos_task_t)krhino_cur_task_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get current task name point
|
||||
*/
|
||||
esp_err_t espos_task_get_name (
|
||||
espos_task_t task,
|
||||
char **pname
|
||||
)
|
||||
{
|
||||
ktask_t *ptask = (ktask_t *)task;
|
||||
|
||||
*pname = (char *)ptask->task_name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set task private data
|
||||
*/
|
||||
esp_err_t espos_task_set_private_data (
|
||||
espos_task_t task,
|
||||
int idx,
|
||||
void *info
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ktask_t *ptask = (ktask_t *)task;;
|
||||
ret = krhino_task_info_set(ptask, (size_t)idx, info);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get task private data
|
||||
*/
|
||||
esp_err_t espos_task_get_private_data (
|
||||
espos_task_t task,
|
||||
int idx,
|
||||
void **info
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ktask_t *ptask = (ktask_t *)task;;
|
||||
ret = krhino_task_info_get(ptask, idx, info);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get cpu affinity of task
|
||||
*/
|
||||
espos_cpu_t espos_task_get_affinity(espos_task_t task)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t espos_task_prio_num(void)
|
||||
{
|
||||
return RHINO_CONFIG_USER_PRI_MAX + 1 - 10;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct _reent* __getreent()
|
||||
{
|
||||
void *info;
|
||||
|
||||
ktask_t *task = krhino_cur_task_get();
|
||||
if (task == NULL) {
|
||||
return _GLOBAL_REENT;
|
||||
}
|
||||
else {
|
||||
krhino_task_info_get(task, 2, &info);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ESPOS_FOR_ESP32)
|
||||
struct _reent* __getreent()
|
||||
{
|
||||
ktask_t *task = krhino_cur_task_get();
|
||||
if (task == NULL) {
|
||||
return _GLOBAL_REENT;
|
||||
}
|
||||
else {
|
||||
return _GLOBAL_REENT;;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
57
Living_SDK/kernel/vcall/espos/platform/rhino/espos_time.c
Normal file
57
Living_SDK/kernel/vcall/espos/platform/rhino/espos_time.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
/**
|
||||
* @brief get current system ticks
|
||||
*/
|
||||
espos_tick_t espos_get_tick_count(void)
|
||||
{
|
||||
return (espos_tick_t)krhino_sys_tick_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief transform milliseconds to system ticks
|
||||
*/
|
||||
espos_tick_t espos_ms_to_ticks(espos_time_t ms)
|
||||
{
|
||||
return (ms / (1000 / RHINO_CONFIG_TICKS_PER_SECOND));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief transform system ticks to milliseconds
|
||||
*/
|
||||
espos_time_t espos_ticks_to_ms(espos_tick_t ticks)
|
||||
{
|
||||
return (ticks * (1000 / RHINO_CONFIG_TICKS_PER_SECOND));
|
||||
}
|
||||
|
||||
void espos_add_tick_count(size_t t)
|
||||
{
|
||||
g_tick_count += (sys_time_t)t;
|
||||
}
|
||||
|
||||
size_t espos_get_expected_idle_time(void)
|
||||
{
|
||||
ktask_t *task = krhino_cur_task_get();
|
||||
|
||||
if (!strcmp(task->task_name, "idle_task")) {
|
||||
return task->time_slice;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
129
Living_SDK/kernel/vcall/espos/platform/rhino/espos_timer.c
Normal file
129
Living_SDK/kernel/vcall/espos/platform/rhino/espos_timer.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "k_api.h"
|
||||
#include "espos_err.h"
|
||||
#include "espos_timer.h"
|
||||
#include "espos_scheduler.h"
|
||||
|
||||
/**
|
||||
* @brief create a timer
|
||||
*/
|
||||
esp_err_t espos_timer_create (
|
||||
espos_timer_t *timer,
|
||||
const char *name,
|
||||
espos_timer_cb_t cb,
|
||||
void *arg,
|
||||
espos_tick_t period_ticks,
|
||||
espos_opt_t opt
|
||||
)
|
||||
{
|
||||
kstat_t ret = RHINO_SUCCESS;
|
||||
ktimer_t **ptimer = (ktimer_t **)timer;
|
||||
tick_t round;
|
||||
|
||||
if (opt == ESPOS_TIMER_NO_AUTO_RUN)
|
||||
round = 0;
|
||||
else if (opt == ESPOS_TIMER_AUTO_RUN)
|
||||
round = period_ticks;
|
||||
else
|
||||
return EINVAL;
|
||||
|
||||
ret = krhino_timer_dyn_create(ptimer, name, (timer_cb_t)cb, period_ticks,
|
||||
round, arg, 0);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief start a timer
|
||||
*/
|
||||
esp_err_t espos_timer_start (espos_timer_t timer)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktimer_t *ptimer = (ktimer_t *)timer;
|
||||
|
||||
ret = krhino_timer_start(ptimer);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stop a timer
|
||||
*/
|
||||
esp_err_t espos_timer_stop (
|
||||
espos_timer_t timer
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktimer_t *ptimer = (ktimer_t *)timer;
|
||||
|
||||
ret = krhino_timer_stop(ptimer);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief configure a timer
|
||||
*/
|
||||
esp_err_t espos_timer_change (
|
||||
espos_timer_t timer,
|
||||
espos_opt_t opt,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktimer_t *ptimer = (ktimer_t *)timer;
|
||||
|
||||
if (ESPOS_TIMER_CHANGE_PERIOD == opt) {
|
||||
espos_tick_t period = (espos_tick_t)arg;
|
||||
ret = krhino_timer_change(ptimer, ptimer->init_count, period);
|
||||
} else
|
||||
return EINVAL;
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief delete a timer
|
||||
*/
|
||||
esp_err_t espos_timer_del (
|
||||
espos_timer_t timer
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktimer_t *ptimer = (ktimer_t *)timer;
|
||||
|
||||
ret = krhino_timer_dyn_del(ptimer);
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get current timer name point
|
||||
*/
|
||||
esp_err_t espos_get_timer_name (
|
||||
espos_timer_t timer,
|
||||
char **tname
|
||||
)
|
||||
{
|
||||
kstat_t ret;
|
||||
ktimer_t *ptimer = (ktimer_t *)timer;
|
||||
|
||||
*tname = (char *)ptimer->name;
|
||||
ret = RHINO_SUCCESS;
|
||||
|
||||
return espos_err_map(ret);
|
||||
}
|
||||
|
||||
5
Living_SDK/kernel/vcall/espos/test/component.mk
Normal file
5
Living_SDK/kernel/vcall/espos/test/component.mk
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
#Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
12
Living_SDK/kernel/vcall/espos/test/test_espos_event.c
Normal file
12
Living_SDK/kernel/vcall/espos/test/test_espos_event.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
|
||||
// No event group API yet
|
||||
|
||||
|
||||
126
Living_SDK/kernel/vcall/espos/test/test_espos_mem.c
Normal file
126
Living_SDK/kernel/vcall/espos/test/test_espos_mem.c
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if 0
|
||||
#include "unity.h"
|
||||
#include "espos_mem.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "espos_time.h"
|
||||
|
||||
static espos_sem_t sync_semaphore;
|
||||
|
||||
TEST_CASE("ESPOS mm api test", "[espos]")
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint8_t non_zero = 0;
|
||||
uint32_t i;
|
||||
|
||||
// do malloc
|
||||
buf = espos_malloc(1024);
|
||||
memset(buf, 0xFF, 1024);
|
||||
TEST_ASSERT(buf != NULL);
|
||||
espos_free(buf);
|
||||
|
||||
// do zalloc
|
||||
buf = espos_zalloc(1024);
|
||||
TEST_ASSERT(buf != NULL);
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (buf[i] != 0) {
|
||||
non_zero = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT(non_zero == 0);
|
||||
espos_free(buf);
|
||||
}
|
||||
|
||||
static int tryAllocMem()
|
||||
{
|
||||
int **mem;
|
||||
int i, noAllocated, j;
|
||||
mem = malloc(sizeof(int) * 1024);
|
||||
if (!mem) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 1024; i++) {
|
||||
mem[i] = malloc(1024);
|
||||
if (mem[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < 1024 / 4; j++) {
|
||||
mem[i][j] = (0xdeadbeef);
|
||||
}
|
||||
}
|
||||
noAllocated = i;
|
||||
for (i = 0; i < noAllocated; i++) {
|
||||
for (j = 0; j < 1024 / 4; j++) {
|
||||
TEST_ASSERT(mem[i][j] == (0xdeadbeef));
|
||||
}
|
||||
free(mem[i]);
|
||||
}
|
||||
free(mem);
|
||||
return noAllocated;
|
||||
}
|
||||
|
||||
static void malloc_free_task(void *p)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t *buf;
|
||||
for (i = 0; i < 0xFFFF; i++) {
|
||||
buf = espos_malloc(1024);
|
||||
espos_task_delay(1);
|
||||
espos_free(buf);
|
||||
}
|
||||
espos_sem_give(sync_semaphore);
|
||||
espos_task_del(0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS concurrent use of malloc free test", "[espos]")
|
||||
{
|
||||
uint32_t m1, m2;
|
||||
espos_task_t new_task_handle;
|
||||
|
||||
espos_sem_create(&sync_semaphore, NULL, 2, 0);
|
||||
|
||||
m1 = tryAllocMem();
|
||||
|
||||
espos_task_create(&new_task_handle, "malloc_free_task1", NULL, 1,
|
||||
0, 1024, malloc_free_task, 0);
|
||||
espos_task_create(&new_task_handle, "malloc_free_task2", NULL, 1,
|
||||
0, 1024, malloc_free_task, 0);
|
||||
|
||||
// wait task exit
|
||||
espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY);
|
||||
espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY);
|
||||
espos_sem_del(sync_semaphore);
|
||||
|
||||
m2 = tryAllocMem();
|
||||
|
||||
TEST_ASSERT(m1 == m2);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mm API invalid parameter test", "[espos]")
|
||||
{
|
||||
uint8_t *buf;
|
||||
buf = espos_malloc(0xFFFFFFFF);
|
||||
TEST_ASSERT(buf == NULL);
|
||||
buf = espos_malloc(0);
|
||||
TEST_ASSERT(buf == NULL);
|
||||
buf = espos_zalloc(0xFFFFFFFF);
|
||||
TEST_ASSERT(buf == NULL);
|
||||
buf = espos_zalloc(0);
|
||||
TEST_ASSERT(buf == NULL);
|
||||
|
||||
// TODO: need to check if free invalid pointer will cause exception
|
||||
espos_free(NULL);
|
||||
espos_free((void *)0xFFFF);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// To add more test cases for specific RTOS, like fragment handling
|
||||
|
||||
223
Living_SDK/kernel/vcall/espos/test/test_espos_mutex.c
Normal file
223
Living_SDK/kernel/vcall/espos/test/test_espos_mutex.c
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_mutex.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_queue.h"
|
||||
#include "test_espos_run_in_isr.h"
|
||||
|
||||
#define ESPOS_MUTEX_ADD_TEST_COUNT 0xFFFF
|
||||
#define ESPOS_MUTEX_CREATE_INVALID ESPOS_MUTEX_NORMAL + 10
|
||||
#define ESPOS_MUTEX_INVALID_HANDLE 0
|
||||
|
||||
static espos_sem_t sync_semaphore;
|
||||
static espos_mutex_t global_mutex;
|
||||
static espos_queue_t isr_queue;
|
||||
static int count;
|
||||
|
||||
TEST_CASE("ESPOS mutex create delete test", "[espos]")
|
||||
{
|
||||
uint32_t i;
|
||||
espos_queue_t mutex = 0;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (espos_mutex_create(&mutex, ESPOS_MUTEX_NORMAL) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (espos_mutex_del(mutex) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mutex_test_task(void *p)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ESPOS_MUTEX_ADD_TEST_COUNT; i++) {
|
||||
TEST_ASSERT(espos_mutex_lock(global_mutex, ESPOS_MAX_DELAY) == 0);
|
||||
count++;
|
||||
TEST_ASSERT(espos_mutex_unlock(global_mutex) == 0);
|
||||
}
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mutex lock unlock test", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
|
||||
TEST_ASSERT(espos_mutex_create(&global_mutex, ESPOS_MUTEX_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 2, 0) == 0);
|
||||
count = 0;
|
||||
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "mutex_test_task1", NULL, 1,
|
||||
0, 2048, mutex_test_task, 0) == 0);
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "mutex_test_task2", NULL, 1,
|
||||
0, 2048, mutex_test_task, 0) == 0);
|
||||
|
||||
// wait task exit
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_del(sync_semaphore) == 0);
|
||||
|
||||
TEST_ASSERT(count == (ESPOS_MUTEX_ADD_TEST_COUNT << 1));
|
||||
TEST_ASSERT(espos_mutex_del(global_mutex) == 0);
|
||||
}
|
||||
|
||||
static void mutex_lock_test_task(void *p)
|
||||
{
|
||||
TEST_ASSERT(espos_mutex_lock(global_mutex, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_mutex_unlock(global_mutex) == 0);
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS delete mutex in use test", "[espos]")
|
||||
{
|
||||
// TODO: this case is RTOS dependent
|
||||
espos_task_t new_task_handle;
|
||||
|
||||
TEST_ASSERT(espos_mutex_create(&global_mutex, ESPOS_MUTEX_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_lock(global_mutex, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "mutex_lock_test_task", NULL, ESPOS_TASK_PRIO_MAX,
|
||||
0, 2048, mutex_lock_test_task, 0) == 0);
|
||||
|
||||
|
||||
TEST_ASSERT(espos_mutex_unlock(global_mutex) == 0);
|
||||
|
||||
// wait task exit
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_del(global_mutex) == 0);
|
||||
TEST_ASSERT(espos_sem_del(sync_semaphore) == 0);
|
||||
}
|
||||
|
||||
static void mutex_unlock_test_task(void *p)
|
||||
{
|
||||
TEST_ASSERT(espos_mutex_unlock(global_mutex) == -EPERM);
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mutex unlock by different task test", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
|
||||
TEST_ASSERT(espos_mutex_create(&global_mutex, ESPOS_MUTEX_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_lock(global_mutex, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "mutex_unlock_test_task", NULL, ESPOS_TASK_PRIO_MAX,
|
||||
0, 1024, mutex_unlock_test_task, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_del(global_mutex) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_del(sync_semaphore) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mutex lock timeout test", "[espos]")
|
||||
{
|
||||
espos_queue_t mutex;
|
||||
|
||||
TEST_ASSERT(espos_mutex_create(&mutex, ESPOS_MUTEX_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_lock(mutex, ESPOS_NO_DELAY) == 0);
|
||||
TEST_ASSERT(espos_mutex_lock(mutex, ESPOS_NO_DELAY) == -ETIMEDOUT);
|
||||
|
||||
TEST_ASSERT(espos_mutex_del(mutex) == 0);
|
||||
}
|
||||
|
||||
static void mutex_lock_hold_test_task(void *p)
|
||||
{
|
||||
espos_sem_t sem = (espos_sem_t) p;
|
||||
|
||||
TEST_ASSERT(espos_mutex_lock(global_mutex, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_sem_take(sem, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_del(sem) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mutex lock get holder test", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
espos_sem_t sem;
|
||||
|
||||
TEST_ASSERT(espos_mutex_create(&global_mutex, ESPOS_MUTEX_NORMAL) == 0);
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 1, 0) == 0);
|
||||
TEST_ASSERT(espos_sem_create(&sem, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_lock(global_mutex, ESPOS_NO_DELAY) == 0);
|
||||
TEST_ASSERT(espos_mutex_get_holder(global_mutex) == espos_task_get_current());
|
||||
TEST_ASSERT(espos_mutex_unlock(global_mutex) == 0);
|
||||
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "mutex_lock_hold_test_task", (void *)sem, ESPOS_TASK_PRIO_MAX,
|
||||
0, 2048, mutex_lock_hold_test_task, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_mutex_get_holder(global_mutex) == new_task_handle);
|
||||
TEST_ASSERT(espos_sem_give(sem) == 0);
|
||||
|
||||
TEST_ASSERT(espos_mutex_del(global_mutex) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mutex recursive lock unlock test", "[espos]")
|
||||
{
|
||||
//TODO: to add this case if recursive lock is supported
|
||||
}
|
||||
|
||||
static void IRAM_ATTR mutex_isr_test(void)
|
||||
{
|
||||
uint8_t msg = 0;
|
||||
|
||||
if (espos_mutex_lock(global_mutex, 0) != -EINTR
|
||||
|| espos_mutex_unlock(global_mutex) != -EINTR) {
|
||||
msg = 1;
|
||||
}
|
||||
TEST_ASSERT(espos_queue_send(isr_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS use mutex in ISR test", "[espos]")
|
||||
{
|
||||
uint8_t msg;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&isr_queue, 1, 1) == 0);
|
||||
TEST_ASSERT(espos_mutex_create(&global_mutex, ESPOS_MUTEX_NORMAL) == 0);
|
||||
|
||||
espos_test_run_in_isr(mutex_isr_test);
|
||||
TEST_ASSERT(espos_queue_recv(isr_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(msg == 0);
|
||||
TEST_ASSERT(espos_mutex_del(global_mutex) == 0);
|
||||
TEST_ASSERT(espos_queue_del(isr_queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS mutex API invalid parameter test", "[espos]")
|
||||
{
|
||||
espos_queue_t mutex;
|
||||
|
||||
TEST_ASSERT(espos_mutex_create(NULL, ESPOS_MUTEX_NORMAL) == -EINVAL);
|
||||
TEST_ASSERT(espos_mutex_create(&mutex, ESPOS_MUTEX_CREATE_INVALID) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_mutex_lock(ESPOS_MUTEX_INVALID_HANDLE, 0) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_mutex_unlock(ESPOS_MUTEX_INVALID_HANDLE) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_mutex_del(ESPOS_MUTEX_INVALID_HANDLE) == -EINVAL);
|
||||
}
|
||||
58
Living_SDK/kernel/vcall/espos/test/test_espos_performance.c
Normal file
58
Living_SDK/kernel/vcall/espos/test/test_espos_performance.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_include.h"
|
||||
|
||||
uint32_t tick;
|
||||
|
||||
|
||||
// memory management
|
||||
TEST_CASE("ESPOS malloc free performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// scheduler
|
||||
TEST_CASE("ESPOS task context switch performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS isr context switch performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS critical section performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// spin lock
|
||||
TEST_CASE("ESPOS spin lock performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// queue
|
||||
TEST_CASE("ESPOS queue send recv performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// semaphore
|
||||
TEST_CASE("ESPOS semaphore performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// timer
|
||||
TEST_CASE("ESPOS timer accuracy performance", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
248
Living_SDK/kernel/vcall/espos/test/test_espos_queue.c
Normal file
248
Living_SDK/kernel/vcall/espos/test/test_espos_queue.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_queue.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "espos_time.h"
|
||||
#include "test_espos_run_in_isr.h"
|
||||
|
||||
#define ESPOS_QUEUE_INVALID_OPT (ESPOS_QUEUE_SEND_OPT_NORMAL+10)
|
||||
#define ESPOS_QUEUE_INVALID_POS (ESPOS_QUEUE_SEND_BACK+10)
|
||||
#define ESPOS_QUEUE_INVALID_HANDLE 0
|
||||
|
||||
static espos_sem_t sync_semaphore;
|
||||
static espos_queue_t global_queue;
|
||||
static espos_queue_t isr_queue;
|
||||
|
||||
TEST_CASE("ESPOS queue create delete", "[espos]")
|
||||
{
|
||||
uint32_t i;
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (espos_queue_create(&queue, 16, 50) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (espos_queue_del(queue) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void queue_send_task(void *p)
|
||||
{
|
||||
uint32_t msg = 0xF1F2F3F4;
|
||||
uint8_t *received = (uint8_t *) p;
|
||||
|
||||
TEST_ASSERT(espos_queue_send(global_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
// should switch to recv task and then switch back
|
||||
TEST_ASSERT(*received == 1);
|
||||
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
static void queue_recv_task(void *p)
|
||||
{
|
||||
uint32_t msg;
|
||||
uint8_t *received = (uint8_t *) p;
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(global_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
// check msg value
|
||||
TEST_ASSERT(msg = 0xF1F2F3F4);
|
||||
|
||||
// set received flag
|
||||
*received = 1;
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue send receive", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
uint8_t received = 0;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&global_queue, 4, 10) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 2, 0) == 0);
|
||||
|
||||
// recv task with higher priority, create recv task first
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "queue_recv_task", &received, 2,
|
||||
0, 1024, queue_recv_task, 0, 0) == 0);
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "queue_send_task", &received, 1,
|
||||
0, 1024, queue_send_task, 0, 0) == 0);
|
||||
|
||||
// wait task exit
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_del(sync_semaphore) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(global_queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue flush", "[espos]")
|
||||
{
|
||||
uint32_t msg = 0;
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&queue, 4, 10) == 0);
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, ESPOS_MAX_DELAY,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, ESPOS_MAX_DELAY,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_flush(queue) == 0);
|
||||
TEST_ASSERT(espos_queue_msg_waiting(queue) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_flush(queue) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue send front/end", "[espos]")
|
||||
{
|
||||
uint32_t msg;
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&queue, 4, 10) == 0);
|
||||
msg = 0x01;
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, ESPOS_MAX_DELAY,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
msg = 0x02;
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, ESPOS_MAX_DELAY,
|
||||
ESPOS_QUEUE_SEND_FRONT, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
msg = 0x03;
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, ESPOS_MAX_DELAY,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(msg == 0x02);
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(msg == 0x01);
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(msg == 0x03);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue timeout test", "[espos]")
|
||||
{
|
||||
uint32_t msg;
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&queue, 4, 1) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, 0,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, 0,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == -ETIMEDOUT);
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(queue, &msg, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(queue, &msg, 0) == -ETIMEDOUT);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue create/delete API invalid param test", "[espos]")
|
||||
{
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&queue, 0xFFFF, 0xFFFFFF) == -ENOMEM);
|
||||
TEST_ASSERT(espos_queue_del(queue) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_create(NULL, 4, 10) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_create(&queue, 0, 10) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_create(&queue, 4, 0) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(ESPOS_QUEUE_INVALID_HANDLE) == -EINVAL)
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue send API invalid param test", "[espos]")
|
||||
{
|
||||
uint32_t msg;
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&queue, 4, 10) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, NULL, 0,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, 0,
|
||||
ESPOS_QUEUE_INVALID_POS, ESPOS_QUEUE_SEND_OPT_NORMAL) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_send_generic(queue, &msg, 0,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_INVALID_OPT) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_send_generic(ESPOS_QUEUE_INVALID_HANDLE, &msg, 0,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_INVALID_OPT) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS queue recv/wait/flush API invalid param test", "[espos]")
|
||||
{
|
||||
uint32_t msg;
|
||||
espos_queue_t queue = ESPOS_QUEUE_INVALID_HANDLE;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&queue, 4, 10) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_recv(ESPOS_QUEUE_INVALID_HANDLE, &msg, 0) == -EINVAL);
|
||||
TEST_ASSERT(espos_queue_recv(queue, NULL, 0) == -EINVAL);
|
||||
|
||||
//TODO: don't konw what could happen if passing invalid queue handle
|
||||
TEST_ASSERT(espos_queue_msg_waiting(ESPOS_QUEUE_INVALID_HANDLE) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_flush(ESPOS_QUEUE_INVALID_HANDLE) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(queue) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS deleting a queue in use test", "[espos]")
|
||||
{
|
||||
// TODO: this case is RTOS dependent
|
||||
espos_task_t new_task_handle;
|
||||
uint8_t received = 0;
|
||||
uint32_t msg = 0xF1F2F3F4;
|
||||
|
||||
TEST_ASSERT(espos_queue_create(&global_queue, 4, 1) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "queue_recv_task", &received, 1,
|
||||
0, 1024, queue_recv_task, 0, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_send(global_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
// wait task exit
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(received == 1);
|
||||
TEST_ASSERT(espos_sem_del(sync_semaphore) == 0);
|
||||
|
||||
TEST_ASSERT(espos_queue_del(global_queue) == 0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR queue_isr_test(void)
|
||||
{
|
||||
uint8_t msg = 0;
|
||||
TEST_ASSERT(espos_queue_send_generic(isr_queue, &msg, ESPOS_MAX_DELAY,
|
||||
ESPOS_QUEUE_SEND_BACK, ESPOS_QUEUE_SEND_OPT_NORMAL) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS send to queue in ISR test", "[espos]")
|
||||
{
|
||||
uint8_t msg;
|
||||
espos_queue_create(&isr_queue, 1, 1);
|
||||
espos_test_run_in_isr(queue_isr_test);
|
||||
espos_queue_recv(isr_queue, &msg, ESPOS_MAX_DELAY);
|
||||
TEST_ASSERT(msg == 0);
|
||||
espos_queue_del(isr_queue);
|
||||
}
|
||||
62
Living_SDK/kernel/vcall/espos/test/test_espos_run_in_isr.c
Normal file
62
Living_SDK/kernel/vcall/espos/test/test_espos_run_in_isr.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "esp_types.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_scheduler.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
#include "test_espos_run_in_isr.h"
|
||||
|
||||
#define TIMER_INTR_SEL TIMER_INTR_LEVEL /*!< Timer level interrupt */
|
||||
#define TIMER_GROUP TIMER_GROUP_0 /*!< Test on timer group 0 */
|
||||
#define TIMER_DIVIDER 16 /*!< Hardware timer clock divider */
|
||||
|
||||
static void IRAM_ATTR timer_isr(void *p)
|
||||
{
|
||||
espos_test_isr_routine routine = (espos_test_isr_routine) p;
|
||||
|
||||
espos_isr_enter();
|
||||
|
||||
TIMERG0.int_clr_timers.t0 = 1;
|
||||
|
||||
routine();
|
||||
|
||||
espos_isr_exit();
|
||||
}
|
||||
|
||||
void espos_test_run_in_isr(espos_test_isr_routine routine)
|
||||
{
|
||||
|
||||
int timer_group = TIMER_GROUP_0;
|
||||
int timer_idx = TIMER_0;
|
||||
timer_config_t config;
|
||||
config.alarm_en = 1;
|
||||
config.auto_reload = 0;
|
||||
config.counter_dir = TIMER_COUNT_UP;
|
||||
config.divider = TIMER_DIVIDER;
|
||||
config.intr_type = TIMER_INTR_SEL;
|
||||
config.counter_en = TIMER_PAUSE;
|
||||
/*Configure timer*/
|
||||
timer_init(timer_group, timer_idx, &config);
|
||||
/*Stop timer counter*/
|
||||
timer_pause(timer_group, timer_idx);
|
||||
/*Load counter value */
|
||||
timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL);
|
||||
/*Set alarm value*/
|
||||
timer_set_alarm_value(timer_group, timer_idx, 1);
|
||||
timer_set_auto_reload(timer_group, timer_idx, TIMER_AUTORELOAD_DIS);
|
||||
/*Enable timer interrupt*/
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
/*Set ISR handler*/
|
||||
timer_isr_register(timer_group, timer_idx, timer_isr,
|
||||
(void *) routine, ESP_INTR_FLAG_IRAM, NULL);
|
||||
/*Start timer counter*/
|
||||
timer_start(timer_group, timer_idx);
|
||||
}
|
||||
27
Living_SDK/kernel/vcall/espos/test/test_espos_run_in_isr.h
Normal file
27
Living_SDK/kernel/vcall/espos/test/test_espos_run_in_isr.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef _TEST_ESPOS_RUN_IN_ISR_H_
|
||||
#define _TEST_ESPOS_RUN_IN_ISR_H_
|
||||
|
||||
#include "espos_types.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef void (*espos_test_isr_routine)(void);
|
||||
|
||||
/*
|
||||
* @brief run handler in timer isr
|
||||
*/
|
||||
void espos_test_run_in_isr(espos_test_isr_routine routine);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
52
Living_SDK/kernel/vcall/espos/test/test_espos_scheduler.c
Normal file
52
Living_SDK/kernel/vcall/espos/test/test_espos_scheduler.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_scheduler.h"
|
||||
#include "espos_spinlock.h"
|
||||
#include "test_espos_run_in_isr.h"
|
||||
|
||||
#define ESPOS_SCHEDULER_INVALID_HANDLE -1
|
||||
|
||||
uint32_t count;
|
||||
|
||||
TEST_CASE("ESPOS scheduler critical section test", "[espos]")
|
||||
{
|
||||
//TODO: how to test critical section?
|
||||
}
|
||||
|
||||
static void count_task(void *p)
|
||||
{
|
||||
count ++;
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS scheduler preempt suspend resume test", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
|
||||
count = 0;
|
||||
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "count_task", NULL, 10,
|
||||
0, 1024, count_task, 0, 0) == 0);
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "count_task", NULL, 10,
|
||||
0, 1024, count_task, 0, 0) == 0);
|
||||
|
||||
TEST_ASSERT(count == 2);
|
||||
|
||||
count = 0;
|
||||
|
||||
TEST_ASSERT(espos_preempt_suspend_local() == 0);
|
||||
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "count_task", NULL, 10,
|
||||
0, 1024, count_task, 0, 0) == 0);
|
||||
TEST_ASSERT(espos_task_create_on_cpu(&new_task_handle, "count_task", NULL, 10,
|
||||
0, 1024, count_task, 0, 0) == 0);
|
||||
|
||||
TEST_ASSERT(count == 0);
|
||||
TEST_ASSERT(espos_preempt_resume_local() == 0);
|
||||
}
|
||||
174
Living_SDK/kernel/vcall/espos/test/test_espos_semaphore.c
Normal file
174
Living_SDK/kernel/vcall/espos/test/test_espos_semaphore.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "espos_queue.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_time.h"
|
||||
#include "driver/timer.h"
|
||||
#include "test_espos_run_in_isr.h"
|
||||
|
||||
#define ESPOS_SEM_INVALID_HANDLE 0
|
||||
|
||||
static espos_sem_t sync_semaphore;
|
||||
static espos_sem_t global_sema;
|
||||
static espos_queue_t isr_queue;
|
||||
|
||||
TEST_CASE("ESPOS semaphore create delete test", "[espos]")
|
||||
{
|
||||
uint32_t i;
|
||||
espos_sem_t sem;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (espos_sem_create(&sem, 1, 1) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (espos_sem_del(sem) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sema_give_task(void *p)
|
||||
{
|
||||
uint8_t *taken = (uint8_t *) p;
|
||||
|
||||
TEST_ASSERT(espos_sem_give(global_sema) == 0);
|
||||
|
||||
// should switch to recv task and then switch back
|
||||
TEST_ASSERT(*taken == 1);
|
||||
|
||||
espos_sem_give(sync_semaphore);
|
||||
espos_task_del(0);
|
||||
}
|
||||
|
||||
static void sema_take_task(void *p)
|
||||
{
|
||||
uint8_t *taken = (uint8_t *) p;
|
||||
|
||||
TEST_ASSERT(espos_sem_take(global_sema, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
// set taken flag
|
||||
*taken = 1;
|
||||
|
||||
espos_sem_give(sync_semaphore);
|
||||
espos_task_del(0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS semaphore take give test", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
uint8_t taken = 0;
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&global_sema, 1, 0) == 0);
|
||||
|
||||
espos_sem_create(&sync_semaphore, 2, 0);
|
||||
|
||||
// recv task with higher priority, create recv task first
|
||||
espos_task_create_on_cpu(&new_task_handle, "sema_take_task", &taken, 2,
|
||||
0, 1024, sema_take_task, 0, 0);
|
||||
espos_task_create_on_cpu(&new_task_handle, "sema_give_task", &taken, 1,
|
||||
0, 1024, sema_give_task, 0, 0);
|
||||
|
||||
// wait task exit
|
||||
espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY);
|
||||
espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY);
|
||||
espos_sem_del(sync_semaphore);
|
||||
|
||||
TEST_ASSERT(espos_sem_del(global_sema) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS semaphore count test", "[espos]")
|
||||
{
|
||||
uint8_t i;
|
||||
espos_sem_t sem;
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sem, 5, 1) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sem, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_trytake(sem) == -ETIMEDOUT);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
TEST_ASSERT(espos_sem_give(sem) == 0);
|
||||
}
|
||||
|
||||
TEST_ASSERT(espos_sem_give(sem) == -EAGAIN);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
TEST_ASSERT(espos_sem_trytake(sem) == 0);
|
||||
}
|
||||
|
||||
TEST_ASSERT(espos_sem_del(sem) == 0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR semaphore_isr_test(void)
|
||||
{
|
||||
uint8_t msg = 0;
|
||||
espos_sem_t sem;
|
||||
|
||||
if (espos_sem_create(&sem, 2, 1) != -EINTR) {
|
||||
msg = 1;
|
||||
}
|
||||
|
||||
if (espos_sem_take(global_sema, 0) != 0
|
||||
|| espos_sem_give(global_sema) != 0
|
||||
|| espos_sem_del(global_sema) != -EINTR) {
|
||||
msg = 1;
|
||||
}
|
||||
espos_queue_send(isr_queue, &msg, ESPOS_MAX_DELAY);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS use semaphore in ISR test", "[espos]")
|
||||
{
|
||||
uint8_t msg;
|
||||
|
||||
espos_queue_create(&isr_queue, 1, 1);
|
||||
TEST_ASSERT(espos_sem_create(&global_sema, 2, 1) == 0);
|
||||
|
||||
espos_test_run_in_isr(semaphore_isr_test);
|
||||
espos_queue_recv(isr_queue, &msg, ESPOS_MAX_DELAY);
|
||||
TEST_ASSERT(msg == 0);
|
||||
espos_sem_del(global_sema);
|
||||
espos_queue_del(isr_queue);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS deleting a semaphore in use test", "[espos]")
|
||||
{
|
||||
// TODO: this case is RTOS dependent
|
||||
espos_task_t new_task_handle;
|
||||
uint8_t taken = 0;
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&global_sema, 1, 0) == 0);
|
||||
|
||||
espos_sem_create(&sync_semaphore, 1, 0);
|
||||
|
||||
espos_task_create_on_cpu(&new_task_handle, "sema_take_task", &taken, ESPOS_TASK_PRIO_MAX,
|
||||
0, 1024, sema_take_task, 0, 0);
|
||||
|
||||
espos_sem_give(global_sema);
|
||||
|
||||
// wait task exit
|
||||
espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY);
|
||||
TEST_ASSERT(taken == 1);
|
||||
espos_sem_del(sync_semaphore);
|
||||
|
||||
TEST_ASSERT(espos_sem_del(global_sema) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS semaphore API invalid parameter test", "[espos]")
|
||||
{
|
||||
TEST_ASSERT(espos_sem_create(NULL, 5, 1) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(ESPOS_SEM_INVALID_HANDLE, ESPOS_MAX_DELAY) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_sem_give(ESPOS_SEM_INVALID_HANDLE) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_sem_del(ESPOS_SEM_INVALID_HANDLE) == -EINVAL);
|
||||
}
|
||||
|
||||
119
Living_SDK/kernel/vcall/espos/test/test_espos_spinlock.c
Normal file
119
Living_SDK/kernel/vcall/espos/test/test_espos_spinlock.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_spinlock.h"
|
||||
#include "espos_task.h"
|
||||
#include "espos_queue.h"
|
||||
#include "espos_semaphore.h"
|
||||
#include "test_espos_run_in_isr.h"
|
||||
|
||||
#define ESPOS_SPINLOCK_INVALID_HANDLE NULL
|
||||
|
||||
#define ESPOS_SPINLOCK_ADD_TEST_COUNT 0xFFFF
|
||||
|
||||
static espos_sem_t sync_semaphore;
|
||||
static espos_queue_t isr_queue;
|
||||
static espos_spinlock_t global_spinlock;
|
||||
static int count;
|
||||
|
||||
TEST_CASE("ESPOS spinlock create delete test", "[espos]")
|
||||
{
|
||||
espos_spinlock_t spinlock;
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (espos_spinlock_create(&spinlock) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
}
|
||||
if (espos_spinlock_del(&spinlock) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void spinlock_test_task(void *p)
|
||||
{
|
||||
for (int i = 0; i < ESPOS_SPINLOCK_ADD_TEST_COUNT; i++) {
|
||||
TEST_ASSERT(espos_spinlock_lock(&global_spinlock) == 0);
|
||||
count++;
|
||||
TEST_ASSERT(espos_spinlock_unlock(&global_spinlock) == 0);
|
||||
}
|
||||
TEST_ASSERT(espos_sem_give(sync_semaphore) == 0);
|
||||
TEST_ASSERT(espos_task_del(0) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS spinlock lock unlock test", "[espos]")
|
||||
{
|
||||
espos_task_t new_task_handle;
|
||||
|
||||
TEST_ASSERT(espos_spinlock_create(&global_spinlock) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_semaphore, 2, 0) == 0);
|
||||
count = 0;
|
||||
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "spinlock_test_task1", NULL, 1,
|
||||
0, 1024, spinlock_test_task, 0) == 0);
|
||||
TEST_ASSERT(espos_task_create(&new_task_handle, "spinlock_test_task2", NULL, 1,
|
||||
0, 1024, spinlock_test_task, 0) == 0);
|
||||
|
||||
// wait task exit
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_take(sync_semaphore, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(espos_sem_del(sync_semaphore) == 0);
|
||||
|
||||
TEST_ASSERT(count == (ESPOS_SPINLOCK_ADD_TEST_COUNT << 1));
|
||||
TEST_ASSERT(espos_spinlock_del(&global_spinlock) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS spinlock trylock test", "[espos]")
|
||||
{
|
||||
espos_spinlock_t spinlock;
|
||||
|
||||
TEST_ASSERT(espos_spinlock_create(&spinlock) == 0);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_trylock(&spinlock) == 0);
|
||||
TEST_ASSERT(espos_spinlock_trylock(&spinlock) == -EAGAIN);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_unlock(&spinlock) == 0);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_del(&spinlock) == 0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spinlock_isr_test(void)
|
||||
{
|
||||
uint8_t msg = 0;
|
||||
|
||||
if (espos_spinlock_lock(&global_spinlock) != 0
|
||||
|| espos_spinlock_unlock(&global_spinlock) != 0) {
|
||||
msg = 1;
|
||||
}
|
||||
TEST_ASSERT(espos_queue_send(isr_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS spinlock use in ISR test", "[espos]")
|
||||
{
|
||||
uint8_t msg;
|
||||
TEST_ASSERT(espos_queue_create(&isr_queue, 1, 1) == 0);
|
||||
TEST_ASSERT(espos_spinlock_create(&global_spinlock) == 0);
|
||||
espos_test_run_in_isr(spinlock_isr_test);
|
||||
TEST_ASSERT(espos_queue_recv(isr_queue, &msg, ESPOS_MAX_DELAY) == 0);
|
||||
TEST_ASSERT(msg == 0);
|
||||
TEST_ASSERT(espos_queue_del(isr_queue) == 0);
|
||||
TEST_ASSERT(espos_spinlock_del(&global_spinlock) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS spinlock API invalid parameter test", "[espos]")
|
||||
{
|
||||
TEST_ASSERT(espos_spinlock_create(NULL) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_lock(NULL) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_trylock(NULL) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_unlock(NULL) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_spinlock_del(ESPOS_SPINLOCK_INVALID_HANDLE) == -EINVAL);
|
||||
}
|
||||
73
Living_SDK/kernel/vcall/espos/test/test_espos_task.c
Normal file
73
Living_SDK/kernel/vcall/espos/test/test_espos_task.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_task.h"
|
||||
|
||||
uint32_t count;
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task SMP create delete test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task multi-core test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task yield test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task exit test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task suspend resume test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task sleep test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task private data test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task priority test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task time slice test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task option test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task stack size test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ESPOS task API misc param test", "[espos]")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
30
Living_SDK/kernel/vcall/espos/test/test_espos_time.c
Normal file
30
Living_SDK/kernel/vcall/espos/test/test_espos_time.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_time.h"
|
||||
#include "espos_task.h"
|
||||
|
||||
#define _ESPOS_TIME_DELAY_TICK 100
|
||||
#define _ESPOS_TIME_DELAY_TICK_TH 120
|
||||
|
||||
TEST_CASE("ESPOS get tick test", "[espos]")
|
||||
{
|
||||
espos_tick_t tick1, tick2;
|
||||
tick1 = espos_get_tick_count();
|
||||
espos_task_delay(_ESPOS_TIME_DELAY_TICK);
|
||||
tick2 = espos_get_tick_count();
|
||||
|
||||
TEST_ASSERT(tick2 - tick1 >= _ESPOS_TIME_DELAY_TICK);
|
||||
TEST_ASSERT(tick2 - tick1 < _ESPOS_TIME_DELAY_TICK_TH);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS tick ms convert test", "[espos]")
|
||||
{
|
||||
TEST_ASSERT(espos_ticks_to_ms(espos_ms_to_ticks(10)) == 10);
|
||||
|
||||
TEST_ASSERT(espos_ms_to_ticks(0xFFFFFFFF) == 0xFFFFFFFF / 10);
|
||||
}
|
||||
162
Living_SDK/kernel/vcall/espos/test/test_espos_timer.c
Normal file
162
Living_SDK/kernel/vcall/espos/test/test_espos_timer.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "unity.h"
|
||||
#include "espos_timer.h"
|
||||
#include "espos_semaphore.h"
|
||||
|
||||
#define ESPOS_TIMER_INVALID_OPT 0xFF
|
||||
#define ESPOS_TIMER_INVALID_HANDLE 0
|
||||
#define ESPOS_TIMER_CHANGE_OPT_INVALID 5
|
||||
|
||||
static const char *TIMER_NAME = "timer_test";
|
||||
|
||||
static espos_sem_t sync_sema;
|
||||
static espos_timer_t global_timer;
|
||||
static int count;
|
||||
|
||||
static void espos_test_timer_dummy_cb(espos_timer_t timer, void *arg)
|
||||
{
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS timer create delete test", "[espos]")
|
||||
{
|
||||
uint32_t i;
|
||||
espos_timer_t timer = ESPOS_TIMER_INVALID_HANDLE;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (espos_timer_create(&timer, TIMER_NAME, espos_test_timer_dummy_cb, NULL,
|
||||
1, ESPOS_TIMER_NO_AUTO_RUN) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (espos_timer_del(timer) != 0) {
|
||||
TEST_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void espos_test_timer_cb(espos_timer_t timer, void *arg)
|
||||
{
|
||||
TEST_ASSERT(global_timer == timer);
|
||||
TEST_ASSERT(arg == NULL);
|
||||
count++;
|
||||
TEST_ASSERT(espos_sem_give(sync_sema) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS timer no auto run test", "[espos]")
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_sema, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_create(&global_timer, TIMER_NAME, espos_test_timer_cb, NULL,
|
||||
espos_ms_to_ticks(20), ESPOS_TIMER_NO_AUTO_RUN) == 0);
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
TEST_ASSERT(espos_timer_start(global_timer) == 0);
|
||||
TEST_ASSERT(espos_sem_take(sync_sema, ESPOS_MAX_DELAY) == 0);
|
||||
}
|
||||
|
||||
TEST_ASSERT(count == 100);
|
||||
TEST_ASSERT(espos_sem_del(sync_sema) == 0);
|
||||
TEST_ASSERT(espos_timer_del(global_timer) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS timer auto run test", "[espos]")
|
||||
{
|
||||
uint32_t i;
|
||||
espos_sem_create(&sync_sema, 1, 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_create(&global_timer, TIMER_NAME, espos_test_timer_cb, NULL,
|
||||
espos_ms_to_ticks(20), ESPOS_TIMER_AUTO_RUN) == 0);
|
||||
|
||||
count = 0;
|
||||
TEST_ASSERT(espos_timer_start(global_timer) == 0);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
espos_sem_take(sync_sema, ESPOS_MAX_DELAY);
|
||||
}
|
||||
|
||||
TEST_ASSERT(espos_timer_stop(global_timer) == 0);
|
||||
|
||||
TEST_ASSERT(count == 100);
|
||||
TEST_ASSERT(espos_sem_del(sync_sema) == 0);
|
||||
TEST_ASSERT(espos_timer_del(global_timer) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS timer auto run test", "[espos]")
|
||||
{
|
||||
espos_timer_t timer;
|
||||
|
||||
TEST_ASSERT(espos_sem_create(&sync_sema, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_create(&timer, TIMER_NAME, espos_test_timer_cb, NULL,
|
||||
20, ESPOS_TIMER_NO_AUTO_RUN) == 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_start(timer) == 0);
|
||||
TEST_ASSERT(espos_timer_start(timer) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sync_sema, 200) == 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_stop(timer) == 0);
|
||||
TEST_ASSERT(espos_timer_stop(timer) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sync_sema, 200) == -ETIMEDOUT);
|
||||
|
||||
TEST_ASSERT(espos_timer_del(timer) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS timer change test", "[espos]")
|
||||
{
|
||||
TEST_ASSERT(espos_sem_create(&sync_sema, 1, 0) == 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_create(&global_timer, TIMER_NAME, espos_test_timer_cb, NULL,
|
||||
20, ESPOS_TIMER_AUTO_RUN) == 0);
|
||||
|
||||
count = 0;
|
||||
|
||||
TEST_ASSERT(espos_timer_start(global_timer) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sync_sema, ESPOS_MAX_DELAY) == 0);
|
||||
|
||||
TEST_ASSERT(espos_sem_take(sync_sema, 200) == 0);
|
||||
TEST_ASSERT(espos_sem_take(sync_sema, 200) == 0);
|
||||
|
||||
TEST_ASSERT(espos_timer_stop(global_timer) == 0);
|
||||
|
||||
TEST_ASSERT(count == 3);
|
||||
TEST_ASSERT(espos_sem_del(sync_sema) == 0);
|
||||
TEST_ASSERT(espos_timer_del(global_timer) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("ESPOS timer API param test", "[espos]")
|
||||
{
|
||||
espos_timer_t timer;
|
||||
TEST_ASSERT(espos_timer_create(&timer, NULL, NULL, espos_test_timer_cb,
|
||||
20, ESPOS_TIMER_NO_AUTO_RUN) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_timer_create(NULL, NULL, espos_test_timer_cb, NULL,
|
||||
20, ESPOS_TIMER_AUTO_RUN) == -EINVAL);
|
||||
TEST_ASSERT(espos_timer_create(&timer, NULL, NULL, NULL,
|
||||
20, ESPOS_TIMER_AUTO_RUN) == -EINVAL);
|
||||
TEST_ASSERT(espos_timer_create(&timer, NULL, NULL, espos_test_timer_cb,
|
||||
20, ESPOS_TIMER_INVALID_OPT) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_timer_start(ESPOS_TIMER_INVALID_HANDLE) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_timer_stop(ESPOS_TIMER_INVALID_HANDLE) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_timer_change(ESPOS_TIMER_INVALID_HANDLE,
|
||||
ESPOS_TIMER_CHANGE_ONCE, NULL) == -EINVAL);
|
||||
TEST_ASSERT(espos_timer_change(timer,
|
||||
ESPOS_TIMER_CHANGE_OPT_INVALID, NULL) == -EINVAL);
|
||||
|
||||
TEST_ASSERT(espos_timer_del(ESPOS_TIMER_INVALID_HANDLE) == -EINVAL);
|
||||
}
|
||||
14
Living_SDK/kernel/vcall/espos/ucube.py
Normal file
14
Living_SDK/kernel/vcall/espos/ucube.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
src = Split('''
|
||||
platform/rhino/espos_misc.c
|
||||
platform/rhino/espos_mutex.c
|
||||
platform/rhino/espos_queue.c
|
||||
platform/rhino/espos_scheduler.c
|
||||
platform/rhino/espos_semaphore.c
|
||||
platform/rhino/espos_spinlock.c
|
||||
platform/rhino/espos_task.c
|
||||
platform/rhino/espos_time.c
|
||||
platform/rhino/espos_timer.c
|
||||
''')
|
||||
|
||||
component = aos_component('espos', src)
|
||||
component.add_global_includes('include')
|
||||
712
Living_SDK/kernel/vcall/mico/include/common.h
Normal file
712
Living_SDK/kernel/vcall/mico/include/common.h
Normal file
|
|
@ -0,0 +1,712 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __Common_h__
|
||||
#define __Common_h__
|
||||
|
||||
// ==== STD LIB ====
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined __GNUC__
|
||||
#include "platform_toolchain.h"
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include "EWARM/platform_toolchain.h"
|
||||
#elif defined ( __CC_ARM ) //KEIL
|
||||
#include "RVMDK/platform_toolchain.h"
|
||||
#endif
|
||||
|
||||
//#ifdef CONFIG_PLATFORM_8195A
|
||||
//#include "rtl_lib.h"
|
||||
//#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TARGET_RT_LITTLE_ENDIAN
|
||||
|
||||
/* Use this macro to define an RTOS-aware interrupt handler where RTOS
|
||||
* primitives can be safely accessed
|
||||
*
|
||||
* @usage:
|
||||
* WWD_RTOS_DEFINE_ISR( my_irq_handler )
|
||||
* {
|
||||
* // Do something here
|
||||
* }
|
||||
*/
|
||||
#if defined( __GNUC__ )
|
||||
|
||||
/* Section where IRQ handlers are placed */
|
||||
#define IRQ_SECTION ".text.irq"
|
||||
|
||||
#define MICO_RTOS_DEFINE_ISR( function ) \
|
||||
void function( void ); \
|
||||
__attribute__(( interrupt, used, section(IRQ_SECTION) )) void function( void )
|
||||
|
||||
|
||||
#elif defined ( __IAR_SYSTEMS_ICC__ )
|
||||
|
||||
#define MICO_RTOS_DEFINE_ISR( function ) \
|
||||
__irq __root void function( void ); \
|
||||
__irq __root void function( void )
|
||||
|
||||
#elif defined ( __CC_ARM ) //KEIL
|
||||
|
||||
#define MICO_RTOS_DEFINE_ISR( function ) \
|
||||
void function( void ); \
|
||||
__attribute__(( used )) void function( void )
|
||||
|
||||
#else
|
||||
|
||||
#define MICO_RTOS_DEFINE_ISR( function ) \
|
||||
void function( void );
|
||||
|
||||
#endif
|
||||
|
||||
// ==== COMPATIBILITY TYPES
|
||||
//typedef uint8_t Boolean;
|
||||
typedef uint8_t mico_bool_t;
|
||||
|
||||
#define MICO_FALSE (0)
|
||||
#define MICO_TRUE (1)
|
||||
|
||||
#if( !defined( INT_MAX ) )
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
|
||||
|
||||
// ==== MiCO Timer Typedef ====
|
||||
#define NANOSECONDS 1000000UL
|
||||
#define MICROSECONDS 1000
|
||||
#define MILLISECONDS (1)
|
||||
#define SECONDS (1000)
|
||||
#define MINUTES (60 * SECONDS)
|
||||
#define HOURS (60 * MINUTES)
|
||||
#define DAYS (24 * HOURS)
|
||||
|
||||
typedef uint32_t mico_time_t; /**< Time value in milliseconds */
|
||||
typedef uint32_t mico_utc_time_t; /**< UTC Time in seconds */
|
||||
typedef uint64_t mico_utc_time_ms_t; /**< UTC Time in milliseconds */
|
||||
|
||||
// ==== OSStatus ====
|
||||
typedef int OSStatus;
|
||||
|
||||
#define kNoErr 0 //! No error occurred.
|
||||
#define kGeneralErr -1 //! General error.
|
||||
#define kInProgressErr 1 //! Operation in progress.
|
||||
|
||||
// Generic error codes are in the range -6700 to -6779.
|
||||
|
||||
#define kGenericErrorBase -6700 //! Starting error code for all generic errors.
|
||||
|
||||
#define kUnknownErr -6700 //! Unknown error occurred.
|
||||
#define kOptionErr -6701 //! Option was not acceptable.
|
||||
#define kSelectorErr -6702 //! Selector passed in is invalid or unknown.
|
||||
#define kExecutionStateErr -6703 //! Call made in the wrong execution state (e.g. called at interrupt time).
|
||||
#define kPathErr -6704 //! Path is invalid, too long, or otherwise not usable.
|
||||
#define kParamErr -6705 //! Parameter is incorrect, missing, or not appropriate.
|
||||
#define kUserRequiredErr -6706 //! User interaction is required.
|
||||
#define kCommandErr -6707 //! Command invalid or not supported.
|
||||
#define kIDErr -6708 //! Unknown, invalid, or inappropriate identifier.
|
||||
#define kStateErr -6709 //! Not in appropriate state to perform operation.
|
||||
#define kRangeErr -6710 //! Index is out of range or not valid.
|
||||
#define kRequestErr -6711 //! Request was improperly formed or not appropriate.
|
||||
#define kResponseErr -6712 //! Response was incorrect or out of sequence.
|
||||
#define kChecksumErr -6713 //! Checksum does not match the actual data.
|
||||
#define kNotHandledErr -6714 //! Operation was not handled (or not handled completely).
|
||||
#define kVersionErr -6715 //! Version is not correct or not compatible.
|
||||
#define kSignatureErr -6716 //! Signature did not match what was expected.
|
||||
#define kFormatErr -6717 //! Unknown, invalid, or inappropriate file/data format.
|
||||
#define kNotInitializedErr -6718 //! Action request before needed services were initialized.
|
||||
#define kAlreadyInitializedErr -6719 //! Attempt made to initialize when already initialized.
|
||||
#define kNotInUseErr -6720 //! Object not in use (e.g. cannot abort if not already in use).
|
||||
#define kAlreadyInUseErr -6721 //! Object is in use (e.g. cannot reuse active param blocks).
|
||||
#define kTimeoutErr -6722 //! Timeout occurred.
|
||||
#define kCanceledErr -6723 //! Operation canceled (successful cancel).
|
||||
#define kAlreadyCanceledErr -6724 //! Operation has already been canceled.
|
||||
#define kCannotCancelErr -6725 //! Operation could not be canceled (maybe already done or invalid).
|
||||
#define kDeletedErr -6726 //! Object has already been deleted.
|
||||
#define kNotFoundErr -6727 //! Something was not found.
|
||||
#define kNoMemoryErr -6728 //! Not enough memory was available to perform the operation.
|
||||
#define kNoResourcesErr -6729 //! Resources unavailable to perform the operation.
|
||||
#define kDuplicateErr -6730 //! Duplicate found or something is a duplicate.
|
||||
#define kImmutableErr -6731 //! Entity is not changeable.
|
||||
#define kUnsupportedDataErr -6732 //! Data is unknown or not supported.
|
||||
#define kIntegrityErr -6733 //! Data is corrupt.
|
||||
#define kIncompatibleErr -6734 //! Data is not compatible or it is in an incompatible format.
|
||||
#define kUnsupportedErr -6735 //! Feature or option is not supported.
|
||||
#define kUnexpectedErr -6736 //! Error occurred that was not expected.
|
||||
#define kValueErr -6737 //! Value is not appropriate.
|
||||
#define kNotReadableErr -6738 //! Could not read or reading is not allowed.
|
||||
#define kNotWritableErr -6739 //! Could not write or writing is not allowed.
|
||||
#define kBadReferenceErr -6740 //! An invalid or inappropriate reference was specified.
|
||||
#define kFlagErr -6741 //! An invalid, inappropriate, or unsupported flag was specified.
|
||||
#define kMalformedErr -6742 //! Something was not formed correctly.
|
||||
#define kSizeErr -6743 //! Size was too big, too small, or not appropriate.
|
||||
#define kNameErr -6744 //! Name was not correct, allowed, or appropriate.
|
||||
#define kNotPreparedErr -6745 //! Device or service is not ready.
|
||||
#define kReadErr -6746 //! Could not read.
|
||||
#define kWriteErr -6747 //! Could not write.
|
||||
#define kMismatchErr -6748 //! Something does not match.
|
||||
#define kDateErr -6749 //! Date is invalid or out-of-range.
|
||||
#define kUnderrunErr -6750 //! Less data than expected.
|
||||
#define kOverrunErr -6751 //! More data than expected.
|
||||
#define kEndingErr -6752 //! Connection, session, or something is ending.
|
||||
#define kConnectionErr -6753 //! Connection failed or could not be established.
|
||||
#define kAuthenticationErr -6754 //! Authentication failed or is not supported.
|
||||
#define kOpenErr -6755 //! Could not open file, pipe, device, etc.
|
||||
#define kTypeErr -6756 //! Incorrect or incompatible type (e.g. file, data, etc.).
|
||||
#define kSkipErr -6757 //! Items should be or was skipped.
|
||||
#define kNoAckErr -6758 //! No acknowledge.
|
||||
#define kCollisionErr -6759 //! Collision occurred (e.g. two on bus at same time).
|
||||
#define kBackoffErr -6760 //! Backoff in progress and operation intentionally failed.
|
||||
#define kNoAddressAckErr -6761 //! No acknowledge of address.
|
||||
#define kInternalErr -6762 //! An error internal to the implementation occurred.
|
||||
#define kNoSpaceErr -6763 //! Not enough space to perform operation.
|
||||
#define kCountErr -6764 //! Count is incorrect.
|
||||
#define kEndOfDataErr -6765 //! Reached the end of the data (e.g. recv returned 0).
|
||||
#define kWouldBlockErr -6766 //! Would need to block to continue (e.g. non-blocking read/write).
|
||||
#define kLookErr -6767 //! Special case that needs to be looked at (e.g. interleaved data).
|
||||
#define kSecurityRequiredErr -6768 //! Security is required for the operation (e.g. must use encryption).
|
||||
#define kOrderErr -6769 //! Order is incorrect.
|
||||
#define kUpgradeErr -6770 //! Must upgrade.
|
||||
#define kAsyncNoErr -6771 //! Async operation successfully started and is now in progress.
|
||||
#define kDeprecatedErr -6772 //! Operation or data is deprecated.
|
||||
#define kPermissionErr -6773 //! Permission denied.
|
||||
|
||||
#define kGenericErrorEnd -6779 //! Last generic error code (inclusive)
|
||||
|
||||
|
||||
// ==== C TYPE SAFE MACROS ====
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @group ctype safe macros
|
||||
@abstract Wrappers for the ctype.h macros make them safe when used with signed characters.
|
||||
@discussion
|
||||
|
||||
Some implementations of the ctype.h macros use the character value to directly index into a table.
|
||||
This can lead to crashes and other problems when used with signed characters if the character value
|
||||
is greater than 127 because the values 128-255 will appear to be negative if viewed as a signed char.
|
||||
A negative subscript to an array causes it to index before the beginning and access invalid memory.
|
||||
|
||||
To work around this, these *_safe wrappers mask the value and cast it to an unsigned char.
|
||||
*/
|
||||
|
||||
#define isalnum_safe( X ) isalnum( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isalpha_safe( X ) isalpha( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define iscntrl_safe( X ) iscntrl( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isdigit_safe( X ) isdigit( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isgraph_safe( X ) isgraph( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define islower_safe( X ) islower( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isoctal_safe( X ) isoctal( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isprint_safe( X ) isprint( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define ispunct_safe( X ) ispunct( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isspace_safe( X ) isspace( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isupper_safe( X ) isupper( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define isxdigit_safe( X ) isxdigit( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define tolower_safe( X ) tolower( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
#define toupper_safe( X ) toupper( ( (unsigned char)( ( X ) & 0xFF ) ) )
|
||||
|
||||
|
||||
// ==== SHA DEFINES ====
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
#define SHA_CTX SHA1Context
|
||||
#define SHA1_Init( CTX ) SHA1Reset( (CTX) )
|
||||
#define SHA1_Update( CTX, PTR, LEN ) SHA1Input( (CTX), (PTR), (LEN) )
|
||||
#define SHA1_Final( DIGEST, CTX ) SHA1Result( (CTX), (DIGEST) )
|
||||
#define SHA1( PTR, LEN, DIGEST ) SHA1Direct( (PTR), (LEN), (DIGEST) )
|
||||
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
#define SHA512_CTX SHA512Context
|
||||
#define SHA512_Init( CTX ) SHA512Reset( (CTX) )
|
||||
#define SHA512_Update( CTX, PTR, LEN ) SHA512Input( (CTX), (PTR), (LEN) )
|
||||
#define SHA512_Final( DIGEST, CTX ) SHA512Result( (CTX), (DIGEST) )
|
||||
#define SHA512( PTR, LEN, DIGEST ) SHA512Direct( (PTR), (LEN), (DIGEST) )
|
||||
|
||||
#define SHA3_DIGEST_LENGTH 64
|
||||
#define SHA3_CTX SHA3_CTX_compat
|
||||
#define SHA3_Init( CTX ) SHA3_Init_compat( (CTX) )
|
||||
#define SHA3_Update( CTX, PTR, LEN ) SHA3_Update_compat( (CTX), (PTR), (LEN) )
|
||||
#define SHA3_Final( DIGEST, CTX ) SHA3_Final_compat( (DIGEST), (CTX) )
|
||||
#define SHA3( PTR, LEN, DIGEST ) SHA3_compat( (PTR), (LEN), DIGEST )
|
||||
|
||||
|
||||
// ==== MIN / MAX ====
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @function Min
|
||||
@abstract Returns the lesser of X and Y.
|
||||
*/
|
||||
#if( !defined( Min ) )
|
||||
#define Min( X, Y ) ( ( ( X ) < ( Y ) ) ? ( X ) : ( Y ) )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @function Max
|
||||
@abstract Returns the greater of X and Y.
|
||||
*/
|
||||
#if( !defined( Max ) )
|
||||
#define Max( X, Y ) ( ( ( X ) > ( Y ) ) ? ( X ) : ( Y ) )
|
||||
#endif
|
||||
|
||||
|
||||
// ==== Alignment / Endian safe read/write/swap macros ====
|
||||
#define ReadBig16( PTR ) \
|
||||
( (uint16_t)( \
|
||||
( ( (uint16_t)( (uint8_t *)(PTR) )[ 0 ] ) << 8 ) | \
|
||||
( (uint16_t)( (uint8_t *)(PTR) )[ 1 ] ) ) )
|
||||
|
||||
#define ReadBig32( PTR ) \
|
||||
( (uint32_t)( \
|
||||
( ( (uint32_t)( (uint8_t *)(PTR) )[ 0 ] ) << 24 ) | \
|
||||
( ( (uint32_t)( (uint8_t *)(PTR) )[ 1 ] ) << 16 ) | \
|
||||
( ( (uint32_t)( (uint8_t *)(PTR) )[ 2 ] ) << 8 ) | \
|
||||
( (uint32_t)( (uint8_t *)(PTR) )[ 3 ] ) ) )
|
||||
|
||||
#define ReadBig48( PTR ) \
|
||||
( (uint64_t)( \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) << 40 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 32 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 24 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 16 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 8 ) | \
|
||||
( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) ) )
|
||||
|
||||
#define ReadBig64( PTR ) \
|
||||
( (uint64_t)( \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) << 56 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 48 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 40 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 32 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 24 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) << 16 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 6 ] ) << 8 ) | \
|
||||
( (uint64_t)( (uint8_t *)(PTR) )[ 7 ] ) ) )
|
||||
|
||||
// Big endian Writing
|
||||
#define WriteBig16( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
#define WriteBig32( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
#define WriteBig48( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
#define WriteBig64( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( ( (X) >> 56 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 48 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 6 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 7 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
// Little endian reading
|
||||
#define ReadLittle16( PTR ) \
|
||||
( (uint16_t)( \
|
||||
( (uint16_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
|
||||
( ( (uint16_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) ) )
|
||||
|
||||
#define ReadLittle32( PTR ) \
|
||||
( (uint32_t)( \
|
||||
( (uint32_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
|
||||
( ( (uint32_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) | \
|
||||
( ( (uint32_t)( (uint8_t *)(PTR) )[ 2 ] ) << 16 ) | \
|
||||
( ( (uint32_t)( (uint8_t *)(PTR) )[ 3 ] ) << 24 ) ) )
|
||||
|
||||
#define ReadLittle48( PTR ) \
|
||||
( (uint64_t)( \
|
||||
( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 16 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 24 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 32 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) << 40 ) ) )
|
||||
|
||||
#define ReadLittle64( PTR ) \
|
||||
( (uint64_t)( \
|
||||
( (uint64_t)( (uint8_t *)(PTR) )[ 0 ] ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 1 ] ) << 8 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 2 ] ) << 16 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 3 ] ) << 24 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 4 ] ) << 32 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 5 ] ) << 40 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 6 ] ) << 48 ) | \
|
||||
( ( (uint64_t)( (uint8_t *)(PTR) )[ 7 ] ) << 56 ) ) )
|
||||
|
||||
// Little endian writing
|
||||
#define WriteLittle16( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
#define WriteLittle32( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
#define WriteLittle48( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
#define WriteLittle64( PTR, X ) \
|
||||
do \
|
||||
{ \
|
||||
( (uint8_t *)(PTR) )[ 0 ] = (uint8_t)( (X) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 1 ] = (uint8_t)( ( (X) >> 8 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 2 ] = (uint8_t)( ( (X) >> 16 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 3 ] = (uint8_t)( ( (X) >> 24 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 4 ] = (uint8_t)( ( (X) >> 32 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 5 ] = (uint8_t)( ( (X) >> 40 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 6 ] = (uint8_t)( ( (X) >> 48 ) & 0xFF ); \
|
||||
( (uint8_t *)(PTR) )[ 7 ] = (uint8_t)( ( (X) >> 56 ) & 0xFF ); \
|
||||
\
|
||||
} while( 0 )
|
||||
|
||||
|
||||
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) && !defined( TARGET_RT_BIG_ENDIAN ) )
|
||||
#error unknown byte order - update your Makefile to define the target platform endianness as TARGET_RT_BIG_ENDIAN / TARGET_RT_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
|
||||
#define ReadHost16( PTR ) ReadBig16( (PTR) )
|
||||
#define ReadHost32( PTR ) ReadBig32( (PTR) )
|
||||
#define ReadHost48( PTR ) ReadBig48( (PTR) )
|
||||
#define ReadHost64( PTR ) ReadBig64( (PTR) )
|
||||
|
||||
#define WriteHost16( PTR, X ) WriteBig16( (PTR), (X) )
|
||||
#define WriteHost32( PTR, X ) WriteBig32( (PTR), (X) )
|
||||
#define WriteHost48( PTR, X ) WriteBig48( (PTR), (X) )
|
||||
#define WriteHost64( PTR, X ) WriteBig64( (PTR), (X) )
|
||||
#else
|
||||
#define ReadHost16( PTR ) ReadLittle16( (PTR) )
|
||||
#define ReadHost32( PTR ) ReadLittle32( (PTR) )
|
||||
#define ReadHost48( PTR ) ReadLittle48( (PTR) )
|
||||
#define ReadHost64( PTR ) ReadLittle64( (PTR) )
|
||||
|
||||
#define WriteHost16( PTR, X ) WriteLittle16( (PTR), (X) )
|
||||
#define WriteHost32( PTR, X ) WriteLittle32( (PTR), (X) )
|
||||
#define WriteHost48( PTR, X ) WriteLittle48( (PTR), (X) )
|
||||
#define WriteHost64( PTR, X ) WriteLittle64( (PTR), (X) )
|
||||
#endif
|
||||
|
||||
// Unconditional swap read/write.
|
||||
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
|
||||
#define ReadSwap16( PTR ) ReadLittle16( (PTR) )
|
||||
#define ReadSwap32( PTR ) ReadLittle32( (PTR) )
|
||||
#define ReadSwap48( PTR ) ReadLittle48( (PTR) )
|
||||
#define ReadSwap64( PTR ) ReadLittle64( (PTR) )
|
||||
|
||||
#define WriteSwap16( PTR, X ) WriteLittle16( (PTR), (X) )
|
||||
#define WriteSwap32( PTR, X ) WriteLittle32( (PTR), (X) )
|
||||
#define WriteSwap48( PTR, X ) WriteLittle48( (PTR), (X) )
|
||||
#define WriteSwap64( PTR, X ) WriteLittle64( (PTR), (X) )
|
||||
#else
|
||||
#define ReadSwap16( PTR ) ReadBig16( (PTR) )
|
||||
#define ReadSwap32( PTR ) ReadBig32( (PTR) )
|
||||
#define ReadSwap48( PTR ) ReadBig48( (PTR) )
|
||||
#define ReadSwap64( PTR ) ReadBig64( (PTR) )
|
||||
|
||||
#define WriteSwap16( PTR, X ) WriteBig16( (PTR), (X) )
|
||||
#define WriteSwap32( PTR, X ) WriteBig32( (PTR), (X) )
|
||||
#define WriteSwap48( PTR, X ) WriteBig48( (PTR), (X) )
|
||||
#define WriteSwap64( PTR, X ) WriteBig64( (PTR), (X) )
|
||||
#endif
|
||||
|
||||
// Memory swaps
|
||||
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
|
||||
#define HostToBig16Mem( SRC, LEN, DST ) do {} while( 0 )
|
||||
#define BigToHost16Mem( SRC, LEN, DST ) do {} while( 0 )
|
||||
|
||||
#define LittleToHost16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
|
||||
#define LittleToHost16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
|
||||
#else
|
||||
#define HostToBig16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
|
||||
#define BigToHost16Mem( SRC, LEN, DST ) Swap16Mem( (SRC), (LEN), (DST) )
|
||||
|
||||
#define HostToLittle16Mem( SRC, LEN, DST ) do {} while( 0 )
|
||||
#define LittleToHost16Mem( SRC, LEN, DST ) do {} while( 0 )
|
||||
#endif
|
||||
|
||||
// Unconditional endian swaps
|
||||
#if !defined (Swap16)
|
||||
#define Swap16( X ) \
|
||||
( (uint16_t)( \
|
||||
( ( ( (uint16_t)(X) ) << 8 ) & UINT16_C( 0xFF00 ) ) | \
|
||||
( ( ( (uint16_t)(X) ) >> 8 ) & UINT16_C( 0x00FF ) ) ) )
|
||||
#endif
|
||||
|
||||
#if !defined (Swap32)
|
||||
#define Swap32( X ) \
|
||||
( (uint32_t)( \
|
||||
( ( ( (uint32_t)(X) ) << 24 ) & UINT32_C( 0xFF000000 ) ) | \
|
||||
( ( ( (uint32_t)(X) ) << 8 ) & UINT32_C( 0x00FF0000 ) ) | \
|
||||
( ( ( (uint32_t)(X) ) >> 8 ) & UINT32_C( 0x0000FF00 ) ) | \
|
||||
( ( ( (uint32_t)(X) ) >> 24 ) & UINT32_C( 0x000000FF ) ) ) )
|
||||
#endif
|
||||
|
||||
#if !defined (Swap64)
|
||||
#define Swap64( X ) \
|
||||
( (uint64_t)( \
|
||||
( ( ( (uint64_t)(X) ) << 56 ) & UINT64_C( 0xFF00000000000000 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) << 40 ) & UINT64_C( 0x00FF000000000000 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) << 24 ) & UINT64_C( 0x0000FF0000000000 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) << 8 ) & UINT64_C( 0x000000FF00000000 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) >> 8 ) & UINT64_C( 0x00000000FF000000 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) >> 24 ) & UINT64_C( 0x0000000000FF0000 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) >> 40 ) & UINT64_C( 0x000000000000FF00 ) ) | \
|
||||
( ( ( (uint64_t)(X) ) >> 56 ) & UINT64_C( 0x00000000000000FF ) ) ) )
|
||||
#endif
|
||||
|
||||
// Host<->Network/Big endian swaps
|
||||
#if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
|
||||
#define hton16( X ) (X)
|
||||
#define ntoh16( X ) (X)
|
||||
|
||||
#define hton32( X ) (X)
|
||||
#define ntoh32( X ) (X)
|
||||
|
||||
#define hton64( X ) (X)
|
||||
#define ntoh64( X ) (X)
|
||||
#else
|
||||
#define hton16( X ) Swap16( X )
|
||||
#define ntoh16( X ) Swap16( X )
|
||||
|
||||
#define hton32( X ) Swap32( X )
|
||||
#define ntoh32( X ) Swap32( X )
|
||||
|
||||
#define hton64( X ) Swap64( X )
|
||||
#define ntoh64( X ) Swap64( X )
|
||||
#endif
|
||||
|
||||
#define htons( X ) hton16( X )
|
||||
#define ntohs( X ) ntoh16( X )
|
||||
|
||||
#define htonl( X ) hton32( X )
|
||||
#define ntohl( X ) ntoh32( X )
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @function BitArray
|
||||
@abstract Macros for working with bit arrays.
|
||||
@discussion
|
||||
|
||||
This treats bit numbers starting from the left so bit 0 is 0x80 in byte 0, bit 1 is 0x40 in bit 0,
|
||||
bit 8 is 0x80 in byte 1, etc. For example, the following ASCII art shows how the bits are arranged:
|
||||
|
||||
1 1 1 1 1 1 1 1 1 1 2 2 2 2
|
||||
Bit 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| x |x | x x| = 0x20 0x80 0x41 (bits 2, 8, 17, and 23).
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Byte 0 1 2
|
||||
*/
|
||||
#define BitArray_MinBytes( ARRAY, N_BYTES ) memrlen( (ARRAY), (N_BYTES) )
|
||||
#define BitArray_MaxBytes( BITS ) ( ( (BITS) + 7 ) / 8 )
|
||||
#define BitArray_MaxBits( ARRAY_BYTES ) ( (ARRAY_BYTES) * 8 )
|
||||
#define BitArray_Clear( ARRAY_PTR, ARRAY_BYTES ) memset( (ARRAY_PTR), 0, (ARRAY_BYTES) );
|
||||
#define BitArray_GetBit( PTR, LEN, BIT ) \
|
||||
( ( (BIT) < BitArray_MaxBits( (LEN) ) ) && ( (PTR)[ (BIT) / 8 ] & ( 1 << ( 7 - ( (BIT) & 7 ) ) ) ) )
|
||||
#define BitArray_SetBit( ARRAY, BIT ) ( (ARRAY)[ (BIT) / 8 ] |= ( 1 << ( 7 - ( (BIT) & 7 ) ) ) )
|
||||
#define BitArray_ClearBit( ARRAY, BIT ) ( (ARRAY)[ (BIT) / 8 ] &= ~( 1 << ( 7 - ( (BIT) & 7 ) ) ) )
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @group BitRotates
|
||||
@abstract Rotates X COUNT bits to the left or right.
|
||||
*/
|
||||
#define ROTL( X, N, SIZE ) ( ( (X) << (N) ) | ( (X) >> ( (SIZE) - N ) ) )
|
||||
#define ROTR( X, N, SIZE ) ( ( (X) >> (N) ) | ( (X) << ( (SIZE) - N ) ) )
|
||||
|
||||
#define ROTL32( X, N ) ROTL( (X), (N), 32 )
|
||||
#define ROTR32( X, N ) ROTR( (X), (N), 32 )
|
||||
|
||||
#define ROTL64( X, N ) ROTL( (X), (N), 64 )
|
||||
#define ROTR64( X, N ) ROTR( (X), (N), 64 )
|
||||
|
||||
#define RotateBitsLeft( X, N ) ROTL( (X), (N), sizeof( (X) ) * 8 )
|
||||
#define RotateBitsRight( X, N ) ROTR( (X), (N), sizeof( (X) ) * 8 )
|
||||
|
||||
// ==== Macros for minimum-width integer constants ====
|
||||
#if( !defined( INT8_C ) )
|
||||
#define INT8_C( value ) value
|
||||
#endif
|
||||
|
||||
#if( !defined( INT16_C ) )
|
||||
#define INT16_C( value ) value
|
||||
#endif
|
||||
|
||||
#if( !defined( INT32_C ) )
|
||||
#define INT32_C( value ) value
|
||||
#endif
|
||||
|
||||
#define INT64_C_safe( value ) INT64_C( value )
|
||||
#if( !defined( INT64_C ) )
|
||||
#if( defined( _MSC_VER ) )
|
||||
#define INT64_C( value ) value ## i64
|
||||
#else
|
||||
#define INT64_C( value ) value ## LL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define UINT8_C_safe( value ) UINT8_C( value )
|
||||
#if( !defined( UINT8_C ) )
|
||||
#define UINT8_C( value ) value ## U
|
||||
#endif
|
||||
|
||||
#define UINT16_C_safe( value ) UINT16_C( value )
|
||||
#if( !defined( UINT16_C ) )
|
||||
#define UINT16_C( value ) value ## U
|
||||
#endif
|
||||
|
||||
#define UINT32_C_safe( value ) UINT32_C( value )
|
||||
#if( !defined( UINT32_C ) )
|
||||
#define UINT32_C( value ) value ## U
|
||||
#endif
|
||||
|
||||
#define UINT64_C_safe( value ) UINT64_C( value )
|
||||
#if( !defined( UINT64_C ) )
|
||||
#if( defined( _MSC_VER ) )
|
||||
#define UINT64_C( value ) value ## UI64
|
||||
#else
|
||||
#define UINT64_C( value ) value ## ULL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ==== SOCKET MACROS ====
|
||||
#define IsValidSocket( X ) ( ( X ) >= 0 )
|
||||
|
||||
/* Suppress unused parameter warning */
|
||||
#ifndef UNUSED_PARAMETER
|
||||
#define UNUSED_PARAMETER(x) ( (void)(x) )
|
||||
#endif
|
||||
|
||||
/* Suppress unused variable warning */
|
||||
#ifndef UNUSED_VARIABLE
|
||||
#define UNUSED_VARIABLE(x) ( (void)(x) )
|
||||
#endif
|
||||
|
||||
/* Suppress unused variable warning occurring due to an assert which is disabled in release mode */
|
||||
#ifndef REFERENCE_DEBUG_ONLY_VARIABLE
|
||||
#define REFERENCE_DEBUG_ONLY_VARIABLE(x) ( (void)(x) )
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MICO_ENABLE_MALLOC_DEBUG
|
||||
#include "malloc_debug.h"
|
||||
extern void malloc_print_mallocs ( void );
|
||||
#else
|
||||
#define calloc_named( name, nelems, elemsize) calloc ( nelems, elemsize )
|
||||
#define calloc_named_hideleak( name, nelems, elemsize ) calloc ( nelems, elemsize )
|
||||
#define realloc_named( name, ptr, size ) realloc( ptr, size )
|
||||
#define malloc_named( name, size ) malloc ( size )
|
||||
#define malloc_named_hideleak( name, size ) malloc ( size )
|
||||
#define malloc_set_name( name )
|
||||
#define malloc_leak_set_ignored( global_flag )
|
||||
#define malloc_leak_set_base( global_flag )
|
||||
#define malloc_leak_check( thread, global_flag )
|
||||
#define malloc_transfer_to_curr_thread( block )
|
||||
#define malloc_transfer_to_thread( block, thread )
|
||||
#define malloc_print_mallocs( void )
|
||||
#define malloc_debug_startup_finished( )
|
||||
#endif /* ifdef MICO_ENABLE_MALLOC_DEBUG */
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* Convert a nibble into a hex character
|
||||
*
|
||||
* @param[in] nibble The value of the nibble in the lower 4 bits
|
||||
*
|
||||
* @return The hex character corresponding to the nibble
|
||||
*/
|
||||
static inline ALWAYS_INLINE char nibble_to_hexchar( uint8_t nibble )
|
||||
{
|
||||
if (nibble > 9)
|
||||
{
|
||||
return (char)('A' + (nibble - 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (char) ('0' + nibble);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* Convert a nibble into a hex character
|
||||
*
|
||||
* @param[in] nibble The value of the nibble in the lower 4 bits
|
||||
*
|
||||
* @return The hex character corresponding to the nibble
|
||||
*/
|
||||
static inline ALWAYS_INLINE char hexchar_to_nibble( char hexchar, uint8_t* nibble )
|
||||
{
|
||||
if ( ( hexchar >= '0' ) && ( hexchar <= '9' ) )
|
||||
{
|
||||
*nibble = (uint8_t)( hexchar - '0' );
|
||||
return 0;
|
||||
}
|
||||
else if ( ( hexchar >= 'A' ) && ( hexchar <= 'F' ) )
|
||||
{
|
||||
*nibble = (uint8_t) ( hexchar - 'A' + 10 );
|
||||
return 0;
|
||||
}
|
||||
else if ( ( hexchar >= 'a' ) && ( hexchar <= 'f' ) )
|
||||
{
|
||||
*nibble = (uint8_t) ( hexchar - 'a' + 10 );
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#endif // __Common_h__
|
||||
|
||||
546
Living_SDK/kernel/vcall/mico/include/debug.h
Normal file
546
Living_SDK/kernel/vcall/mico/include/debug.h
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __Debug_h__
|
||||
#define __Debug_h__
|
||||
|
||||
#ifndef MICO_PREBUILT_LIBS
|
||||
#include "platform.h"
|
||||
#include "platform_config.h"
|
||||
#endif
|
||||
|
||||
#include "mico_rtos.h"
|
||||
#include "platform_assert.h"
|
||||
|
||||
// ==== LOGGING ====
|
||||
#ifdef __GNUC__
|
||||
#define SHORT_FILE __FILENAME__
|
||||
#else
|
||||
#define SHORT_FILE strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
|
||||
#endif
|
||||
|
||||
#define YesOrNo(x) (x ? "YES" : "NO")
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef MICO_DISABLE_STDIO
|
||||
#ifndef NO_MICO_RTOS
|
||||
extern int mico_debug_enabled;
|
||||
extern mico_mutex_t stdio_tx_mutex;
|
||||
|
||||
#define custom_log(N, M, ...) do {if (mico_debug_enabled==0)break;\
|
||||
mico_rtos_lock_mutex( &stdio_tx_mutex );\
|
||||
printf("[%ld][%s: %s:%4d] " M "\r\n", mico_rtos_get_time(), N, SHORT_FILE, __LINE__, ##__VA_ARGS__);\
|
||||
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
|
||||
|
||||
#ifndef MICO_ASSERT_INFO_DISABLE
|
||||
#define debug_print_assert(A,B,C,D,E,F) do {if (mico_debug_enabled==0)break;\
|
||||
mico_rtos_lock_mutex( &stdio_tx_mutex );\
|
||||
printf("[%ld][MICO:%s:%s:%4d] **ASSERT** %s""\r\n", mico_rtos_get_time(), D, F, E, (C!=NULL) ? C : "" );\
|
||||
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
|
||||
#else // !MICO_ASSERT_INFO_ENABLE
|
||||
#define debug_print_assert(A,B,C,D,E,F)
|
||||
#endif // MICO_ASSERT_INFO_ENABLE
|
||||
|
||||
#ifdef TRACE
|
||||
#define custom_log_trace(N) do {if (mico_debug_enabled==0)break;\
|
||||
mico_rtos_lock_mutex( &stdio_tx_mutex );\
|
||||
printf("[%s: [TRACE] %s] %s()\r\n", N, SHORT_FILE, __PRETTY_FUNCTION__);\
|
||||
mico_rtos_unlock_mutex( &stdio_tx_mutex );}while(0==1)
|
||||
#else // !TRACE
|
||||
#define custom_log_trace(N)
|
||||
#endif // TRACE
|
||||
#else // NO_MICO_RTOS
|
||||
#define custom_log(N, M, ...) do {printf("[%s: %s:%4d] " M "\r\n", N, SHORT_FILE, __LINE__, ##__VA_ARGS__);}while(0==1)
|
||||
|
||||
|
||||
#ifndef MICO_ASSERT_INFO_DISABLE
|
||||
#define debug_print_assert(A,B,C,D,E,F) do {printf("[MICO:%s:%s:%4d] **ASSERT** %s""\r\n", D, F, E, (C!=NULL) ? C : "" );}while(0==1)
|
||||
#else
|
||||
#define debug_print_assert(A,B,C,D,E,F)
|
||||
#endif
|
||||
|
||||
#ifdef TRACE
|
||||
#define custom_log_trace(N) do {printf("[%s: [TRACE] %s] %s()\r\n", N, SHORT_FILE, __PRETTY_FUNCTION__);}while(0==1)
|
||||
#else // !TRACE
|
||||
#define custom_log_trace(N)
|
||||
#endif // TRACE
|
||||
#endif
|
||||
#else
|
||||
#define custom_log(N, M, ...)
|
||||
|
||||
#define custom_log_trace(N)
|
||||
|
||||
#define debug_print_assert(A,B,C,D,E,F)
|
||||
#endif //MICO_DISABLE_STDIO
|
||||
#else // DEBUG = 0
|
||||
// IF !DEBUG, make the logs NO-OP
|
||||
#define custom_log(N, M, ...)
|
||||
|
||||
#define custom_log_trace(N)
|
||||
|
||||
#define debug_print_assert(A,B,C,D,E,F)
|
||||
#endif // DEBUG
|
||||
|
||||
// ==== PLATFORM TIMEING FUNCTIONS ====
|
||||
#ifdef TIME_PLATFORM
|
||||
#define function_timer_log(M, N, ...) fprintf(stderr, "[FUNCTION TIMER: " N "()] " M "\n", ##__VA_ARGS__)
|
||||
|
||||
#define TIMEPLATFORM( FUNC, FUNC_NAME ) \
|
||||
do \
|
||||
{ \
|
||||
struct timespec startTime; \
|
||||
clock_gettime(CLOCK_MONOTONIC, &startTime); \
|
||||
{ FUNC; } \
|
||||
struct timespec endTime; \
|
||||
clock_gettime(CLOCK_MONOTONIC, &endTime); \
|
||||
struct timespec timeDiff = TimeDifference( startTime, endTime ); \
|
||||
function_timer_log("%lld us", \
|
||||
FUNC_NAME, \
|
||||
ElapsedTimeInMicroseconds( timeDiff )); \
|
||||
} \
|
||||
while( 1==0 )
|
||||
#else
|
||||
#define function_timer_log(M, N, ...)
|
||||
|
||||
#define TIMEPLATFORM( FUNC, FUNC_NAME ) \
|
||||
do \
|
||||
{ \
|
||||
{ FUNC; } \
|
||||
} \
|
||||
while( 1==0 )
|
||||
#endif
|
||||
|
||||
|
||||
// ==== BRANCH PREDICTION & EXPRESSION EVALUATION ====
|
||||
#if( !defined( unlikely ) )
|
||||
//#define unlikely( EXPRESSSION ) __builtin_expect( !!(EXPRESSSION), 0 )
|
||||
#define unlikely( EXPRESSSION ) !!(EXPRESSSION)
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined check
|
||||
@abstract Check that an expression is true (non-zero).
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) using the default debugging output method.
|
||||
|
||||
Code inside check() statements is not compiled into production builds.
|
||||
*/
|
||||
|
||||
#if( !defined( check ) )
|
||||
#define check( X ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined check_string
|
||||
@abstract Check that an expression is true (non-zero) with an explanation.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) using the default debugging output method.
|
||||
|
||||
Code inside check() statements is not compiled into production builds.
|
||||
*/
|
||||
|
||||
#if( !defined( check_string ) )
|
||||
#define check_string( X, STR ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
MICO_ASSERTION_FAIL_ACTION(); \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require
|
||||
@abstract Requires that an expression evaluate to true.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) using the default debugging output method then jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require ) )
|
||||
#define require( X, LABEL ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_string
|
||||
@abstract Requires that an expression evaluate to true with an explanation.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) and a custom explanation string using the default debugging output method then jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_string ) )
|
||||
#define require_string( X, LABEL, STR ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_quiet
|
||||
@abstract Requires that an expression evaluate to true.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this jumps to a label. No debugging information is printed.
|
||||
*/
|
||||
|
||||
#if( !defined( require_quiet ) )
|
||||
#define require_quiet( X, LABEL ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_noerr
|
||||
@abstract Require that an error code is noErr (0).
|
||||
@discussion
|
||||
|
||||
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) using the default debugging output method then jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_noerr ) )
|
||||
#define require_noerr( ERR, LABEL ) \
|
||||
do \
|
||||
{ \
|
||||
OSStatus localErr; \
|
||||
\
|
||||
localErr = (OSStatus)(ERR); \
|
||||
if( unlikely( localErr != 0 ) ) \
|
||||
{ \
|
||||
debug_print_assert( localErr, NULL, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_noerr_string
|
||||
@abstract Require that an error code is noErr (0).
|
||||
@discussion
|
||||
|
||||
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.), and a custom explanation string using the default debugging output method using the
|
||||
default debugging output method then jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_noerr_string ) )
|
||||
#define require_noerr_string( ERR, LABEL, STR ) \
|
||||
do \
|
||||
{ \
|
||||
OSStatus localErr; \
|
||||
\
|
||||
localErr = (OSStatus)(ERR); \
|
||||
if( unlikely( localErr != 0 ) ) \
|
||||
{ \
|
||||
debug_print_assert( localErr, NULL, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_noerr_action_string
|
||||
@abstract Require that an error code is noErr (0).
|
||||
@discussion
|
||||
|
||||
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.), and a custom explanation string using the default debugging output method using the
|
||||
default debugging output method then executes an action and jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_noerr_action_string ) )
|
||||
#define require_noerr_action_string( ERR, LABEL, ACTION, STR ) \
|
||||
do \
|
||||
{ \
|
||||
OSStatus localErr; \
|
||||
\
|
||||
localErr = (OSStatus)(ERR); \
|
||||
if( unlikely( localErr != 0 ) ) \
|
||||
{ \
|
||||
debug_print_assert( localErr, NULL, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
{ ACTION; } \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_noerr_quiet
|
||||
@abstract Require that an error code is noErr (0).
|
||||
@discussion
|
||||
|
||||
If the error code is non-0, this jumps to a label. No debugging information is printed.
|
||||
*/
|
||||
|
||||
#if( !defined( require_noerr_quiet ) )
|
||||
#define require_noerr_quiet( ERR, LABEL ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( (ERR) != 0 ) ) \
|
||||
{ \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_noerr_action
|
||||
@abstract Require that an error code is noErr (0) with an action to execute otherwise.
|
||||
@discussion
|
||||
|
||||
If the error code is non-0, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) using the default debugging output method then executes an action and jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_noerr_action ) )
|
||||
#define require_noerr_action( ERR, LABEL, ACTION ) \
|
||||
do \
|
||||
{ \
|
||||
OSStatus localErr; \
|
||||
\
|
||||
localErr = (OSStatus)(ERR); \
|
||||
if( unlikely( localErr != 0 ) ) \
|
||||
{ \
|
||||
debug_print_assert( localErr, NULL, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
{ ACTION; } \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_noerr_action_quiet
|
||||
@abstract Require that an error code is noErr (0) with an action to execute otherwise.
|
||||
@discussion
|
||||
|
||||
If the error code is non-0, this executes an action and jumps to a label. No debugging information is printed.
|
||||
*/
|
||||
|
||||
#if( !defined( require_noerr_action_quiet ) )
|
||||
#define require_noerr_action_quiet( ERR, LABEL, ACTION ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( (ERR) != 0 ) ) \
|
||||
{ \
|
||||
{ ACTION; } \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_action
|
||||
@abstract Requires that an expression evaluate to true with an action to execute otherwise.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) using the default debugging output method then executes an action and jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_action ) )
|
||||
#define require_action( X, LABEL, ACTION ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
debug_print_assert( 0, #X, NULL, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
{ ACTION; } \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_action_string
|
||||
@abstract Requires that an expression evaluate to true with an explanation and action to execute otherwise.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
|
||||
function name, etc.) and a custom explanation string using the default debugging output method then executes an
|
||||
action and jumps to a label.
|
||||
*/
|
||||
|
||||
#if( !defined( require_action_string ) )
|
||||
#define require_action_string( X, LABEL, ACTION, STR ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
debug_print_assert( 0, #X, STR, SHORT_FILE, __LINE__, __PRETTY_FUNCTION__ ); \
|
||||
{ ACTION; } \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined require_action_quiet
|
||||
@abstract Requires that an expression evaluate to true with an action to execute otherwise.
|
||||
@discussion
|
||||
|
||||
If expression evalulates to false, this executes an action and jumps to a label. No debugging information is printed.
|
||||
*/
|
||||
|
||||
#if( !defined( require_action_quiet ) )
|
||||
#define require_action_quiet( X, LABEL, ACTION ) \
|
||||
do \
|
||||
{ \
|
||||
if( unlikely( !(X) ) ) \
|
||||
{ \
|
||||
{ ACTION; } \
|
||||
goto LABEL; \
|
||||
} \
|
||||
\
|
||||
} while( 1==0 )
|
||||
#endif
|
||||
|
||||
// ==== ERROR MAPPING ====
|
||||
#define global_value_errno( VALUE ) ( errno ? errno : kUnknownErr )
|
||||
|
||||
#define map_global_value_errno( TEST, VALUE ) ( (TEST) ? 0 : global_value_errno(VALUE) )
|
||||
#define map_global_noerr_errno( ERR ) ( !(ERR) ? 0 : global_value_errno(ERR) )
|
||||
#define map_fd_creation_errno( FD ) ( IsValidFD( FD ) ? 0 : global_value_errno( FD ) )
|
||||
#define map_noerr_errno( ERR ) map_global_noerr_errno( (ERR) )
|
||||
|
||||
#define socket_errno( SOCK ) ( errno ? errno : kUnknownErr )
|
||||
#define socket_value_errno( SOCK, VALUE ) socket_errno( SOCK )
|
||||
#define map_socket_value_errno( SOCK, TEST, VALUE ) ( (TEST) ? 0 : socket_value_errno( (SOCK), (VALUE) ) )
|
||||
#define map_socket_noerr_errno( SOCK, ERR ) ( !(ERR) ? 0 : socket_errno( (SOCK) ) )
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
/*! @defined check_ptr_overlap
|
||||
@abstract Checks that two ptrs do not overlap.
|
||||
*/
|
||||
|
||||
#define check_ptr_overlap( P1, P1_SIZE, P2, P2_SIZE ) \
|
||||
do \
|
||||
{ \
|
||||
check( !( ( (uintptr_t)(P1) >= (uintptr_t)(P2) ) && \
|
||||
( (uintptr_t)(P1) < ( ( (uintptr_t)(P2) ) + (P2_SIZE) ) ) ) ); \
|
||||
check( !( ( (uintptr_t)(P2) >= (uintptr_t)(P1) ) && \
|
||||
( (uintptr_t)(P2) < ( ( (uintptr_t)(P1) ) + (P1_SIZE) ) ) ) ); \
|
||||
\
|
||||
} while( 1==0 )
|
||||
|
||||
#define IsValidFD( X ) ( ( X ) >= 0 )
|
||||
|
||||
|
||||
//------------------------------------------Memory debug------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num_of_chunks; /**< number of free chunks*/
|
||||
int total_memory; /**< maximum total allocated space*/
|
||||
int allocted_memory; /**< total allocated space*/
|
||||
int free_memory; /**< total free space*/
|
||||
} micoMemInfo_t;
|
||||
|
||||
#define MicoGetMemoryInfo mico_memory_info
|
||||
|
||||
/**
|
||||
* @brief Get memory usage information
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return Point to structure of memory usage information in heap
|
||||
*/
|
||||
micoMemInfo_t* MicoGetMemoryInfo( void );
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "platform_assert.h"
|
||||
#define MICO_BREAK_IF_DEBUG( ) MICO_ASSERTION_FAIL_ACTION()
|
||||
#else
|
||||
#define MICO_BREAK_IF_DEBUG( )
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_PLATFORM_PERMISSION
|
||||
int platform_wprint_permission(void);
|
||||
#define PRINT_PLATFORM_PERMISSION_FUNC() platform_print_permission()
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
#define PRINT_PLATFORM_PERMISSION_FUNC() 1
|
||||
#else
|
||||
#define PRINT_PLATFORM_PERMISSION_FUNC() 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Print declarations
|
||||
******************************************************/
|
||||
#define PRINT_ENABLE_LIB_INFO
|
||||
#define PRINT_ENABLE_LIB_DEBUG
|
||||
#define PRINT_ENABLE_LIB_ERROR
|
||||
|
||||
#define PRINT_MACRO(args) do {if (PRINT_PLATFORM_PERMISSION_FUNC()) printf args;} while(0==1)
|
||||
|
||||
/* printing macros for general SDK/Library functions*/
|
||||
#ifdef PRINT_ENABLE_LIB_INFO
|
||||
#define WPRINT_LIB_INFO(args) PRINT_MACRO(args)
|
||||
#else
|
||||
#define WPRINT_LIB_INFO(args)
|
||||
#endif
|
||||
#ifdef PRINT_ENABLE_LIB_DEBUG
|
||||
#define WPRINT_LIB_DEBUG(args) PRINT_MACRO(args)
|
||||
#else
|
||||
#define WPRINT_LIB_DEBUG(args)
|
||||
#endif
|
||||
#ifdef PRINT_ENABLE_LIB_ERROR
|
||||
#define WPRINT_LIB_ERROR(args) { PRINT_MACRO(args); MICO_BREAK_IF_DEBUG(); }
|
||||
#else
|
||||
#define WPRINT_LIB_ERROR(args) { MICO_BREAK_IF_DEBUG(); }
|
||||
#endif
|
||||
|
||||
|
||||
#endif // __Debug_h__
|
||||
|
||||
111
Living_SDK/kernel/vcall/mico/include/mico.h
Normal file
111
Living_SDK/kernel/vcall/mico/include/mico.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
/** @mainpage MICO
|
||||
|
||||
This documentation describes the MICO APIs.
|
||||
It consists of:
|
||||
- MICO Core APIs
|
||||
- MICO Hardware Abstract Layer APIs
|
||||
- MICO Algorithm APIs
|
||||
- MICO System APIs
|
||||
- MICO Middleware APIs
|
||||
- MICO Drivers interface
|
||||
*/
|
||||
|
||||
#ifndef __MICO_H_
|
||||
#define __MICO_H_
|
||||
|
||||
/* MiCO SDK APIs */
|
||||
#include "debug.h"
|
||||
#include "common.h"
|
||||
#include <hal/hal.h>
|
||||
|
||||
#include "mico_rtos.h"
|
||||
//#include "mico_socket.h"
|
||||
//#include "mico_security.h"
|
||||
#include "mico_platform.h"
|
||||
//#include "mico_system.h"
|
||||
|
||||
|
||||
#define MicoGetRfVer wlan_driver_version
|
||||
#define MicoGetVer system_lib_version
|
||||
#define MicoInit mxchipInit
|
||||
|
||||
/** @defgroup MICO_Core_APIs MICO Core APIs
|
||||
* @brief MiCO Initialization, RTOS, TCP/IP stack, and Network Management
|
||||
*/
|
||||
|
||||
/** @addtogroup MICO_Core_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \defgroup MICO_Init_Info Initialization and Tools
|
||||
* @brief Get MiCO version or RF version, flash usage information or init MiCO TCPIP stack
|
||||
* @{
|
||||
*/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/**
|
||||
* @brief Get RF driver's version.
|
||||
*
|
||||
* @note Create a memery buffer to store the version characters.
|
||||
* THe input buffer length should be 40 bytes at least.
|
||||
* @note This must be executed after micoInit().
|
||||
* @param inVersion: Buffer address to store the RF driver.
|
||||
* @param inLength: Buffer size.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int MicoGetRfVer( char* outVersion, uint8_t inLength );
|
||||
|
||||
/**
|
||||
* @brief Get MICO's version.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return Point to the MICO's version string.
|
||||
*/
|
||||
char* MicoGetVer( void );
|
||||
|
||||
/**
|
||||
* @brief Initialize the TCPIP stack thread, RF driver thread, and other
|
||||
supporting threads needed for wlan connection. Do some necessary
|
||||
initialization
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return kNoErr: success, kGeneralErr: fail
|
||||
*/
|
||||
OSStatus MicoInit( void );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get an identifier id from device, every id is unique and will not change in life-time
|
||||
*
|
||||
* @param identifier length
|
||||
*
|
||||
* @return Point to the identifier
|
||||
*/
|
||||
const uint8_t* mico_generate_cid( uint8_t *length );
|
||||
|
||||
#endif /* __MICO_H_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
168
Living_SDK/kernel/vcall/mico/include/mico_errno.h
Normal file
168
Living_SDK/kernel/vcall/mico/include/mico_errno.h
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __MICO_ERRNO_H__
|
||||
#define __MICO_ERRNO_H__
|
||||
|
||||
#if defined (__GNUC__)
|
||||
#include <errno.h>
|
||||
#else
|
||||
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Arg list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No child processes */
|
||||
#define EAGAIN 11 /* Try again */
|
||||
#define ENOMEM 12 /* Out of memory */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Device or resource busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* File table overflow */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read-only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math argument out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
#define EDEADLK 35 /* Resource deadlock would occur */
|
||||
#define ENAMETOOLONG 36 /* File name too long */
|
||||
#define ENOLCK 37 /* No record locks available */
|
||||
#define ENOSYS 38 /* Function not implemented */
|
||||
#define ENOTEMPTY 39 /* Directory not empty */
|
||||
#define ELOOP 40 /* Too many symbolic links encountered */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
#define ENOMSG 42 /* No message of desired type */
|
||||
#define EIDRM 43 /* Identifier removed */
|
||||
#define ECHRNG 44 /* Channel number out of range */
|
||||
#define EL2NSYNC 45 /* Level 2 not synchronized */
|
||||
#define EL3HLT 46 /* Level 3 halted */
|
||||
#define EL3RST 47 /* Level 3 reset */
|
||||
#define ELNRNG 48 /* Link number out of range */
|
||||
#define EUNATCH 49 /* Protocol driver not attached */
|
||||
#define ENOCSI 50 /* No CSI structure available */
|
||||
#define EL2HLT 51 /* Level 2 halted */
|
||||
#define EBADE 52 /* Invalid exchange */
|
||||
#define EBADR 53 /* Invalid request descriptor */
|
||||
#define EXFULL 54 /* Exchange full */
|
||||
#define ENOANO 55 /* No anode */
|
||||
#define EBADRQC 56 /* Invalid request code */
|
||||
#define EBADSLT 57 /* Invalid slot */
|
||||
|
||||
#define EDEADLOCK EDEADLK
|
||||
|
||||
#define EBFONT 59 /* Bad font file format */
|
||||
#define ENOSTR 60 /* Device not a stream */
|
||||
#define ENODATA 61 /* No data available */
|
||||
#define ETIME 62 /* Timer expired */
|
||||
#define ENOSR 63 /* Out of streams resources */
|
||||
#define ENONET 64 /* Machine is not on the network */
|
||||
#define ENOPKG 65 /* Package not installed */
|
||||
#define EREMOTE 66 /* Object is remote */
|
||||
#define ENOLINK 67 /* Link has been severed */
|
||||
#define EADV 68 /* Advertise error */
|
||||
#define ESRMNT 69 /* Srmount error */
|
||||
#define ECOMM 70 /* Communication error on send */
|
||||
#define EPROTO 71 /* Protocol error */
|
||||
#define EMULTIHOP 72 /* Multihop attempted */
|
||||
#define EDOTDOT 73 /* RFS specific error */
|
||||
#define EBADMSG 74 /* Not a data message */
|
||||
#define EOVERFLOW 75 /* Value too large for defined data type */
|
||||
#define ENOTUNIQ 76 /* Name not unique on network */
|
||||
#define EBADFD 77 /* File descriptor in bad state */
|
||||
#define EREMCHG 78 /* Remote address changed */
|
||||
#define ELIBACC 79 /* Can not access a needed shared library */
|
||||
#define ELIBBAD 80 /* Accessing a corrupted shared library */
|
||||
#define ELIBSCN 81 /* .lib section in a.out corrupted */
|
||||
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
|
||||
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
|
||||
#define EILSEQ 84 /* Illegal byte sequence */
|
||||
#define ERESTART 85 /* Interrupted system call should be restarted */
|
||||
#define ESTRPIPE 86 /* Streams pipe error */
|
||||
#define EUSERS 87 /* Too many users */
|
||||
#define ENOTSOCK 88 /* Socket operation on non-socket */
|
||||
#define EDESTADDRREQ 89 /* Destination address required */
|
||||
#define EMSGSIZE 90 /* Message too long */
|
||||
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
|
||||
#define ENOPROTOOPT 92 /* Protocol not available */
|
||||
#define EPROTONOSUPPORT 93 /* Protocol not supported */
|
||||
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
|
||||
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
|
||||
#define EADDRINUSE 98 /* Address already in use */
|
||||
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
|
||||
#define ENETDOWN 100 /* Network is down */
|
||||
#define ENETUNREACH 101 /* Network is unreachable */
|
||||
#define ENETRESET 102 /* Network dropped connection because of reset */
|
||||
#define ECONNABORTED 103 /* Software caused connection abort */
|
||||
#define ECONNRESET 104 /* Connection reset by peer */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EISCONN 106 /* Transport endpoint is already connected */
|
||||
#define ENOTCONN 107 /* Transport endpoint is not connected */
|
||||
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
|
||||
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
|
||||
#define ETIMEDOUT 110 /* Connection timed out */
|
||||
#define ECONNREFUSED 111 /* Connection refused */
|
||||
#define EHOSTDOWN 112 /* Host is down */
|
||||
#define EHOSTUNREACH 113 /* No route to host */
|
||||
#define EALREADY 114 /* Operation already in progress */
|
||||
#define EINPROGRESS 115 /* Operation now in progress */
|
||||
#define ESTALE 116 /* Stale NFS file handle */
|
||||
#define EUCLEAN 117 /* Structure needs cleaning */
|
||||
#define ENOTNAM 118 /* Not a XENIX named type file */
|
||||
#define ENAVAIL 119 /* No XENIX semaphores available */
|
||||
#define EISNAM 120 /* Is a named type file */
|
||||
#define EREMOTEIO 121 /* Remote I/O error */
|
||||
#define EDQUOT 122 /* Quota exceeded */
|
||||
|
||||
#define ENOMEDIUM 123 /* No medium found */
|
||||
#define EMEDIUMTYPE 124 /* Wrong medium type */
|
||||
|
||||
|
||||
#define ENSROK 0 /* DNS server returned answer with no data */
|
||||
#define ENSRNODATA 160 /* DNS server returned answer with no data */
|
||||
#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
|
||||
#define ENSRSERVFAIL 162 /* DNS server returned general failure */
|
||||
#define ENSRNOTFOUND 163 /* Domain name not found */
|
||||
#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */
|
||||
#define ENSRREFUSED 165 /* DNS server refused query */
|
||||
#define ENSRBADQUERY 166 /* Misformatted DNS query */
|
||||
#define ENSRBADNAME 167 /* Misformatted domain name */
|
||||
#define ENSRBADFAMILY 168 /* Unsupported address family */
|
||||
#define ENSRBADRESP 169 /* Misformatted DNS reply */
|
||||
#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
|
||||
#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
|
||||
#define ENSROF 172 /* End of file */
|
||||
#define ENSRFILE 173 /* Error reading file */
|
||||
#define ENSRNOMEM 174 /* Out of memory */
|
||||
#define ENSRDESTRUCTION 175 /* Application terminated lookup */
|
||||
#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */
|
||||
#define ENSRCNAMELOOP 177 /* Domain name is too long */
|
||||
|
||||
#endif
|
||||
|
||||
#undef errno
|
||||
extern int errno;
|
||||
|
||||
#endif //__MICO_ERRNO_H__
|
||||
|
||||
|
||||
159
Living_SDK/kernel/vcall/mico/include/mico_platform.h
Normal file
159
Living_SDK/kernel/vcall/mico/include/mico_platform.h
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __MICOPLATFORM_H__
|
||||
#define __MICOPLATFORM_H__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
//#include "platform.h" /* This file is unique for each platform */
|
||||
#include "platform_peripheral.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef platform_spi_slave_config_t mico_spi_slave_config_t;
|
||||
|
||||
typedef platform_spi_slave_transfer_direction_t mico_spi_slave_transfer_direction_t;
|
||||
|
||||
typedef platform_spi_slave_transfer_status_t mico_spi_slave_transfer_status_t;
|
||||
|
||||
typedef platform_spi_slave_command_t mico_spi_slave_command_t;
|
||||
|
||||
typedef platform_spi_slave_data_buffer_t mico_spi_slave_data_buffer_t;
|
||||
|
||||
|
||||
#if 0
|
||||
#include "MiCODrivers/MiCODriverI2c.h"
|
||||
#include "MiCODrivers/MiCODriverSpi.h"
|
||||
#include "MiCODrivers/MiCODriverUart.h"
|
||||
#include "MiCODrivers/MiCODriverGpio.h"
|
||||
#include "MiCODrivers/MiCODriverPwm.h"
|
||||
#include "MiCODrivers/MiCODriverRtc.h"
|
||||
#include "MiCODrivers/MiCODriverWdg.h"
|
||||
#include "MiCODrivers/MiCODriverAdc.h"
|
||||
#include "MiCODrivers/MiCODriverRng.h"
|
||||
#include "MiCODrivers/MiCODriverFlash.h"
|
||||
#include "MiCODrivers/MiCODriverMFiAuth.h"
|
||||
#endif
|
||||
|
||||
#define mico_mcu_powersave_config MicoMcuPowerSaveConfig
|
||||
|
||||
|
||||
/** @defgroup MICO_PLATFORM MICO Hardware Abstract Layer APIs
|
||||
* @brief Control hardware peripherals on different platfroms using standard HAL API functions
|
||||
*
|
||||
*/
|
||||
/** @addtogroup MICO_PLATFORM
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup platform_misc Task switching, reboot, and standby
|
||||
* @brief Provide task switching,reboot and standby functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define ENABLE_INTERRUPTS __asm("CPSIE i") /**< Enable interrupts to start task switching in MICO RTOS. */
|
||||
#define DISABLE_INTERRUPTS __asm("CPSID i") /**< Disable interrupts to stop task switching in MICO RTOS. */
|
||||
|
||||
|
||||
/** @brief Software reboot the MICO hardware
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
void MicoSystemReboot(void);
|
||||
|
||||
|
||||
/** @brief Software reboot the MICO hardware
|
||||
*
|
||||
* @param timeToWakeup: MICO will wakeup after secondsToWakeup (seconds)
|
||||
* @return none
|
||||
*/
|
||||
void MicoSystemStandBy(uint32_t secondsToWakeup);
|
||||
|
||||
|
||||
/** @brief Enables the MCU to enter deep sleep mode when all threads are suspended.
|
||||
*
|
||||
* @note: When all threads are suspended, mcu can shut down some peripherals to
|
||||
* save power. For example, STM32 enters STOP mode in this condition,
|
||||
* its peripherals are not working and needs to be wake up by an external
|
||||
* interrupt or MICO core's internal timer. So if you are using a peripherals,
|
||||
* you should disable this function temporarily.
|
||||
* To make this function works, you should not disable the macro in MicoDefault.h:
|
||||
* MICO_DISABLE_MCU_POWERSAVE
|
||||
*
|
||||
* @param enable : 1 = enable MCU powersave, 0 = disable MCU powersave
|
||||
* @return none
|
||||
*/
|
||||
void MicoMcuPowerSaveConfig( int enable );
|
||||
|
||||
|
||||
/** @brief Set MiCO system led on/off state
|
||||
*
|
||||
* @param onff: State of syetem LED,0: OFF,1:ON
|
||||
* @return none
|
||||
*/
|
||||
void MicoSysLed(bool onoff);
|
||||
|
||||
/** @brief Set MiCO RF led on/off state
|
||||
*
|
||||
* @param onff: State of RF LED,0: OFF,1:ON
|
||||
* @return none
|
||||
*/
|
||||
void MicoRfLed(bool onoff);
|
||||
|
||||
/** @brief add
|
||||
*
|
||||
* @param add
|
||||
* @return none
|
||||
*/
|
||||
bool MicoShouldEnterMFGMode(void);
|
||||
|
||||
|
||||
/** @brief add
|
||||
*
|
||||
* @param add
|
||||
* @return none
|
||||
*/
|
||||
bool MicoShouldEnterATEMode(void);
|
||||
|
||||
|
||||
/** @brief add
|
||||
*
|
||||
* @param add
|
||||
* @return none
|
||||
*/
|
||||
bool MicoShouldEnterBootloader(void);
|
||||
|
||||
|
||||
/** @brief add
|
||||
*
|
||||
* @param add
|
||||
* @return none
|
||||
*/
|
||||
char *mico_get_bootloader_ver(void);
|
||||
|
||||
|
||||
#ifdef BOOTLOADER
|
||||
void mico_set_bootload_ver(void);
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
654
Living_SDK/kernel/vcall/mico/include/mico_rtos.h
Normal file
654
Living_SDK/kernel/vcall/mico/include/mico_rtos.h
Normal file
|
|
@ -0,0 +1,654 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __MICORTOS_H__
|
||||
#define __MICORTOS_H__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/** @addtogroup MICO_Core_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS MICO RTOS Operations
|
||||
* @brief Provide management APIs for Thread, Mutex, Timer, Semaphore and FIFO
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MICO_HARDWARE_IO_WORKER_THREAD ( (mico_worker_thread_t*)&mico_hardware_io_worker_thread)
|
||||
#define MICO_NETWORKING_WORKER_THREAD ( (mico_worker_thread_t*)&mico_worker_thread )
|
||||
#define MICO_WORKER_THREAD ( (mico_worker_thread_t*)&mico_worker_thread )
|
||||
|
||||
#define MICO_NETWORK_WORKER_PRIORITY (3)
|
||||
#define MICO_DEFAULT_WORKER_PRIORITY (5)
|
||||
#define MICO_DEFAULT_LIBRARY_PRIORITY (5)
|
||||
#define MICO_APPLICATION_PRIORITY (7)
|
||||
|
||||
#define kNanosecondsPerSecond 1000000000UUL
|
||||
#define kMicrosecondsPerSecond 1000000UL
|
||||
#define kMillisecondsPerSecond 1000
|
||||
|
||||
#define MICO_NEVER_TIMEOUT (0xFFFFFFFF)
|
||||
#define MICO_WAIT_FOREVER (0xFFFFFFFF)
|
||||
#define MICO_NO_WAIT (0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WAIT_FOR_ANY_EVENT,
|
||||
WAIT_FOR_ALL_EVENTS,
|
||||
} mico_event_flags_wait_option_t;
|
||||
|
||||
typedef uint32_t mico_event_flags_t;
|
||||
typedef void * mico_semaphore_t;
|
||||
typedef void * mico_mutex_t;
|
||||
typedef void * mico_thread_t;
|
||||
typedef void * mico_queue_t;
|
||||
typedef void * mico_event_t;// MICO OS event: mico_semaphore_t, mico_mutex_t or mico_queue_t
|
||||
typedef void (*timer_handler_t)( void* arg );
|
||||
typedef OSStatus (*event_handler_t)( void* arg );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * handle;
|
||||
timer_handler_t function;
|
||||
void * arg;
|
||||
}mico_timer_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mico_thread_t thread;
|
||||
mico_queue_t event_queue;
|
||||
} mico_worker_thread_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
event_handler_t function;
|
||||
void* arg;
|
||||
mico_timer_t timer;
|
||||
mico_worker_thread_t* thread;
|
||||
} mico_timed_event_t;
|
||||
|
||||
typedef uint32_t mico_thread_arg_t;
|
||||
typedef void (*mico_thread_function_t)( mico_thread_arg_t arg );
|
||||
|
||||
extern mico_worker_thread_t mico_hardware_io_worker_thread;
|
||||
extern mico_worker_thread_t mico_worker_thread;
|
||||
|
||||
/* Legacy definitions */
|
||||
#define mico_thread_sleep mico_rtos_thread_sleep
|
||||
#define mico_thread_msleep mico_rtos_thread_msleep
|
||||
#define mico_rtos_init_timer mico_init_timer
|
||||
#define mico_rtos_start_timer mico_start_timer
|
||||
#define mico_rtos_stop_timer mico_stop_timer
|
||||
#define mico_rtos_reload_timer mico_reload_timer
|
||||
#define mico_rtos_deinit_timer mico_deinit_timer
|
||||
#define mico_rtos_is_timer_running mico_is_timer_running
|
||||
#define mico_rtos_init_event_fd mico_create_event_fd
|
||||
#define mico_rtos_deinit_event_fd mico_delete_event_fd
|
||||
|
||||
#define mico_rtos_thread_msleep mico_rtos_delay_milliseconds
|
||||
|
||||
/** @addtogroup MICO_Core_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS MICO RTOS Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_RTOS_COMMON MICO RTOS Common Functions
|
||||
* @brief Provide Generic RTOS Functions.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS_Thread MICO RTOS Thread Management Functions
|
||||
* @brief Provide thread creation, delete, suspend, resume, and other RTOS management API
|
||||
* @verbatim
|
||||
* MICO thread priority table
|
||||
*
|
||||
* +----------+-----------------+
|
||||
* | Priority | Thread |
|
||||
* |----------|-----------------|
|
||||
* | 0 | MICO | Highest priority
|
||||
* | 1 | Network |
|
||||
* | 2 | |
|
||||
* | 3 | Network worker |
|
||||
* | 4 | |
|
||||
* | 5 | Default Library |
|
||||
* | | Default worker |
|
||||
* | 6 | |
|
||||
* | 7 | Application |
|
||||
* | 8 | |
|
||||
* | 9 | Idle | Lowest priority
|
||||
* +----------+-----------------+
|
||||
* @endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @brief Creates and starts a new thread
|
||||
*
|
||||
* @param thread : Pointer to variable that will receive the thread handle (can be null)
|
||||
* @param priority : A priority number.
|
||||
* @param name : a text name for the thread (can be null)
|
||||
* @param function : the main thread function
|
||||
* @param stack_size : stack size for this thread
|
||||
* @param arg : argument which will be passed to thread function
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_create_thread( mico_thread_t* thread, uint8_t priority, const char* name, mico_thread_function_t function, uint32_t stack_size, mico_thread_arg_t arg );
|
||||
|
||||
/** @brief Deletes a terminated thread
|
||||
*
|
||||
* @param thread : the handle of the thread to delete, , NULL is the current thread
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_delete_thread( mico_thread_t* thread );
|
||||
|
||||
/** @brief Creates a worker thread
|
||||
*
|
||||
* Creates a worker thread
|
||||
* A worker thread is a thread in whose context timed and asynchronous events
|
||||
* execute.
|
||||
*
|
||||
* @param worker_thread : a pointer to the worker thread to be created
|
||||
* @param priority : thread priority
|
||||
* @param stack_size : thread's stack size in number of bytes
|
||||
* @param event_queue_size : number of events can be pushed into the queue
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_create_worker_thread( mico_worker_thread_t* worker_thread, uint8_t priority, uint32_t stack_size, uint32_t event_queue_size );
|
||||
|
||||
|
||||
/** @brief Deletes a worker thread
|
||||
*
|
||||
* @param worker_thread : a pointer to the worker thread to be created
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_delete_worker_thread( mico_worker_thread_t* worker_thread );
|
||||
|
||||
|
||||
/** @brief Suspend a thread
|
||||
*
|
||||
* @param thread : the handle of the thread to suspend, NULL is the current thread
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
void mico_rtos_suspend_thread(mico_thread_t* thread);
|
||||
|
||||
|
||||
|
||||
/** @brief Suspend all other thread
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void mico_rtos_suspend_all_thread(void);
|
||||
|
||||
|
||||
/** @brief Rresume all other thread
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
long mico_rtos_resume_all_thread(void);
|
||||
|
||||
|
||||
/** @brief Sleeps until another thread has terminated
|
||||
*
|
||||
* @Details Causes the current thread to sleep until the specified other thread
|
||||
* has terminated. If the processor is heavily loaded with higher priority
|
||||
* tasks, this thread may not wake until significantly after the thread termination.
|
||||
*
|
||||
* @param thread : the handle of the other thread which will terminate
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_thread_join( mico_thread_t* thread );
|
||||
|
||||
|
||||
/** @brief Forcibly wakes another thread
|
||||
*
|
||||
* @Details Causes the specified thread to wake from suspension. This will usually
|
||||
* cause an error or timeout in that thread, since the task it was waiting on
|
||||
* is not complete.
|
||||
*
|
||||
* @param thread : the handle of the other thread which will be woken
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_thread_force_awake( mico_thread_t* thread );
|
||||
|
||||
|
||||
/** @brief Checks if a thread is the current thread
|
||||
*
|
||||
* @Details Checks if a specified thread is the currently running thread
|
||||
*
|
||||
* @param thread : the handle of the other thread against which the current thread
|
||||
* will be compared
|
||||
*
|
||||
* @return true : specified thread is the current thread
|
||||
* @return false : specified thread is not currently running
|
||||
*/
|
||||
bool mico_rtos_is_current_thread( mico_thread_t* thread );
|
||||
|
||||
|
||||
|
||||
/** @brief Suspend current thread for a specific time
|
||||
*
|
||||
* @param num_ms : A time interval (Unit: millisecond)
|
||||
*
|
||||
* @return kNoErr.
|
||||
*/
|
||||
OSStatus mico_rtos_delay_milliseconds( uint32_t num_ms );
|
||||
|
||||
|
||||
/** @brief Print Thread status into buffer
|
||||
*
|
||||
* @param buffer, point to buffer to store thread status
|
||||
* @param length, length of the buffer
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
OSStatus mico_rtos_print_thread_status( char* buffer, int length );
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS_SEM MICO RTOS Semaphore Functions
|
||||
* @brief Provide management APIs for semaphore such as init,set,get and dinit.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Initialises a counting semaphore and set count to 0
|
||||
*
|
||||
* @param semaphore : a pointer to the semaphore handle to be initialised
|
||||
* @param count : the max count number of this semaphore
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_init_semaphore( mico_semaphore_t* semaphore, int count );
|
||||
|
||||
|
||||
/** @brief Set (post/put/increment) a semaphore
|
||||
*
|
||||
* @param semaphore : a pointer to the semaphore handle to be set
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_set_semaphore( mico_semaphore_t* semaphore );
|
||||
|
||||
|
||||
/** @brief Get (wait/decrement) a semaphore
|
||||
*
|
||||
* @Details Attempts to get (wait/decrement) a semaphore. If semaphore is at zero already,
|
||||
* then the calling thread will be suspended until another thread sets the
|
||||
* semaphore with @ref mico_rtos_set_semaphore
|
||||
*
|
||||
* @param semaphore : a pointer to the semaphore handle
|
||||
* @param timeout_ms: the number of milliseconds to wait before returning
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_get_semaphore( mico_semaphore_t* semaphore, uint32_t timeout_ms );
|
||||
|
||||
|
||||
/** @brief De-initialise a semaphore
|
||||
*
|
||||
* @Details Deletes a semaphore created with @ref mico_rtos_init_semaphore
|
||||
*
|
||||
* @param semaphore : a pointer to the semaphore handle
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_deinit_semaphore( mico_semaphore_t* semaphore );
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS_MUTEX MICO RTOS Mutex Functions
|
||||
* @brief Provide management APIs for Mutex such as init,lock,unlock and dinit.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Initialises a mutex
|
||||
*
|
||||
* @Details A mutex is different to a semaphore in that a thread that already holds
|
||||
* the lock on the mutex can request the lock again (nested) without causing
|
||||
* it to be suspended.
|
||||
*
|
||||
* @param mutex : a pointer to the mutex handle to be initialised
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_init_mutex( mico_mutex_t* mutex );
|
||||
|
||||
|
||||
/** @brief Obtains the lock on a mutex
|
||||
*
|
||||
* @Details Attempts to obtain the lock on a mutex. If the lock is already held
|
||||
* by another thead, the calling thread will be suspended until the mutex
|
||||
* lock is released by the other thread.
|
||||
*
|
||||
* @param mutex : a pointer to the mutex handle to be locked
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_lock_mutex( mico_mutex_t* mutex );
|
||||
|
||||
|
||||
/** @brief Releases the lock on a mutex
|
||||
*
|
||||
* @Details Releases a currently held lock on a mutex. If another thread
|
||||
* is waiting on the mutex lock, then it will be resumed.
|
||||
*
|
||||
* @param mutex : a pointer to the mutex handle to be unlocked
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_unlock_mutex( mico_mutex_t* mutex );
|
||||
|
||||
|
||||
/** @brief De-initialise a mutex
|
||||
*
|
||||
* @Details Deletes a mutex created with @ref mico_rtos_init_mutex
|
||||
*
|
||||
* @param mutex : a pointer to the mutex handle
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_deinit_mutex( mico_mutex_t* mutex );
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS_QUEUE MICO RTOS FIFO Queue Functions
|
||||
* @brief Provide management APIs for FIFO such as init,push,pop and dinit.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Initialises a FIFO queue
|
||||
*
|
||||
* @param queue : a pointer to the queue handle to be initialised
|
||||
* @param name : a text string name for the queue (NULL is allowed)
|
||||
* @param message_size : size in bytes of objects that will be held in the queue
|
||||
* @param number_of_messages : depth of the queue - i.e. max number of objects in the queue
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_init_queue( mico_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages );
|
||||
|
||||
|
||||
/** @brief Pushes an object onto a queue
|
||||
*
|
||||
* @param queue : a pointer to the queue handle
|
||||
* @param message : the object to be added to the queue. Size is assumed to be
|
||||
* the size specified in @ref mico_rtos_init_queue
|
||||
* @param timeout_ms: the number of milliseconds to wait before returning
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error or timeout occurred
|
||||
*/
|
||||
OSStatus mico_rtos_push_to_queue( mico_queue_t* queue, void* message, uint32_t timeout_ms );
|
||||
|
||||
|
||||
/** @brief Pops an object off a queue
|
||||
*
|
||||
* @param queue : a pointer to the queue handle
|
||||
* @param message : pointer to a buffer that will receive the object being
|
||||
* popped off the queue. Size is assumed to be
|
||||
* the size specified in @ref mico_rtos_init_queue , hence
|
||||
* you must ensure the buffer is long enough or memory
|
||||
* corruption will result
|
||||
* @param timeout_ms: the number of milliseconds to wait before returning
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error or timeout occurred
|
||||
*/
|
||||
OSStatus mico_rtos_pop_from_queue( mico_queue_t* queue, void* message, uint32_t timeout_ms );
|
||||
|
||||
|
||||
/** @brief De-initialise a queue created with @ref mico_rtos_init_queue
|
||||
*
|
||||
* @param queue : a pointer to the queue handle
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_deinit_queue( mico_queue_t* queue );
|
||||
|
||||
|
||||
/** @brief Check if a queue is empty
|
||||
*
|
||||
* @param queue : a pointer to the queue handle
|
||||
*
|
||||
* @return true : queue is empty.
|
||||
* @return false : queue is not empty.
|
||||
*/
|
||||
bool mico_rtos_is_queue_empty( mico_queue_t* queue );
|
||||
|
||||
|
||||
/** @brief Check if a queue is full
|
||||
*
|
||||
* @param queue : a pointer to the queue handle
|
||||
*
|
||||
* @return true : queue is empty.
|
||||
* @return false : queue is not empty.
|
||||
*/
|
||||
bool mico_rtos_is_queue_full( mico_queue_t* queue );
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_RTOS_EVENT MICO RTOS Event Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sends an asynchronous event to the associated worker thread
|
||||
*
|
||||
* @param worker_thread :the worker thread in which context the callback should execute from
|
||||
* @param function : the callback function to be called from the worker thread
|
||||
* @param arg : the argument to be passed to the callback function
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_send_asynchronous_event( mico_worker_thread_t* worker_thread, event_handler_t function, void* arg );
|
||||
|
||||
/** Requests a function be called at a regular interval
|
||||
*
|
||||
* This function registers a function that will be called at a regular
|
||||
* interval. Since this is based on the RTOS time-slice scheduling, the
|
||||
* accuracy is not high, and is affected by processor load.
|
||||
*
|
||||
* @param event_object : pointer to a event handle which will be initialised
|
||||
* @param worker_thread : pointer to the worker thread in whose context the
|
||||
* callback function runs on
|
||||
* @param function : the callback function that is to be called regularly
|
||||
* @param time_ms : the time period between function calls in milliseconds
|
||||
* @param arg : an argument that will be supplied to the function when
|
||||
* it is called
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_register_timed_event( mico_timed_event_t* event_object, mico_worker_thread_t* worker_thread, event_handler_t function, uint32_t time_ms, void* arg );
|
||||
|
||||
|
||||
/** Removes a request for a regular function execution
|
||||
*
|
||||
* This function de-registers a function that has previously been set-up
|
||||
* with @ref mico_rtos_register_timed_event.
|
||||
*
|
||||
* @param event_object : the event handle used with @ref mico_rtos_register_timed_event
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_deregister_timed_event( mico_timed_event_t* event_object );
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_RTOS_TIMER MICO RTOS Timer Functions
|
||||
* @brief Provide management APIs for timer such as init,start,stop,reload and dinit.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Gets time in miiliseconds since RTOS start
|
||||
*
|
||||
* @note: Since this is only 32 bits, it will roll over every 49 days, 17 hours.
|
||||
*
|
||||
* @returns Time in milliseconds since RTOS started.
|
||||
*/
|
||||
uint32_t mico_rtos_get_time(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize a RTOS timer
|
||||
*
|
||||
* @note Timer does not start running until @ref mico_start_timer is called
|
||||
*
|
||||
* @param timer : a pointer to the timer handle to be initialised
|
||||
* @param time_ms : Timer period in milliseconds
|
||||
* @param function : the callback handler function that is called each time the
|
||||
* timer expires
|
||||
* @param arg : an argument that will be passed to the callback function
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_init_timer( mico_timer_t* timer, uint32_t time_ms, timer_handler_t function, void* arg );
|
||||
|
||||
|
||||
/** @brief Starts a RTOS timer running
|
||||
*
|
||||
* @note Timer must have been previously initialised with @ref mico_rtos_init_timer
|
||||
*
|
||||
* @param timer : a pointer to the timer handle to start
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_start_timer( mico_timer_t* timer );
|
||||
|
||||
|
||||
/** @brief Stops a running RTOS timer
|
||||
*
|
||||
* @note Timer must have been previously started with @ref mico_rtos_init_timer
|
||||
*
|
||||
* @param timer : a pointer to the timer handle to stop
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_stop_timer( mico_timer_t* timer );
|
||||
|
||||
|
||||
/** @brief Reloads a RTOS timer that has expired
|
||||
*
|
||||
* @note This is usually called in the timer callback handler, to
|
||||
* reschedule the timer for the next period.
|
||||
*
|
||||
* @param timer : a pointer to the timer handle to reload
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_reload_timer( mico_timer_t* timer );
|
||||
|
||||
|
||||
/** @brief De-initialise a RTOS timer
|
||||
*
|
||||
* @note Deletes a RTOS timer created with @ref mico_rtos_init_timer
|
||||
*
|
||||
* @param timer : a pointer to the RTOS timer handle
|
||||
*
|
||||
* @return kNoErr : on success.
|
||||
* @return kGeneralErr : if an error occurred
|
||||
*/
|
||||
OSStatus mico_rtos_deinit_timer( mico_timer_t* timer );
|
||||
|
||||
|
||||
/** @brief Check if an RTOS timer is running
|
||||
*
|
||||
* @param timer : a pointer to the RTOS timer handle
|
||||
*
|
||||
* @return true : if running.
|
||||
* @return false : if not running
|
||||
*/
|
||||
bool mico_rtos_is_timer_running( mico_timer_t* timer );
|
||||
|
||||
int SetTimer(unsigned long ms, void (*psysTimerHandler)(void));
|
||||
int SetTimer_uniq(unsigned long ms, void (*psysTimerHandler)(void));
|
||||
int UnSetTimer(void (*psysTimerHandler)(void));
|
||||
|
||||
/** @brief Initialize an endpoint for a RTOS event, a file descriptor
|
||||
* will be created, can be used for select
|
||||
*
|
||||
* @param event_handle : mico_semaphore_t, mico_mutex_t or mico_queue_t
|
||||
*
|
||||
* @retval On success, a file descriptor for RTOS event is returned.
|
||||
* On error, -1 is returned.
|
||||
*/
|
||||
int mico_rtos_init_event_fd(mico_event_t event_handle);
|
||||
|
||||
/** @brief De-initialise an endpoint created from a RTOS event
|
||||
*
|
||||
* @param fd : file descriptor for RTOS event
|
||||
*
|
||||
* @retval 0 for success. On error, -1 is returned.
|
||||
*/
|
||||
int mico_rtos_deinit_event_fd(int fd);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
52
Living_SDK/kernel/vcall/mico/include/mico_rtos_common.h
Normal file
52
Living_SDK/kernel/vcall/mico/include/mico_rtos_common.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
#define rtos_log(M, ...) custom_log("RTOS", M, ##__VA_ARGS__)
|
||||
#define rtos_log_trace() custom_log_trace("RTOS")
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
/* MiCO <-> RTOS API */
|
||||
extern OSStatus mico_rtos_init ( void );
|
||||
extern OSStatus mico_rtos_deinit( void );
|
||||
|
||||
/* Entry point for user Application */
|
||||
extern void application_start ( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
717
Living_SDK/kernel/vcall/mico/include/mico_security.h
Normal file
717
Living_SDK/kernel/vcall/mico/include/mico_security.h
Normal file
|
|
@ -0,0 +1,717 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "Curve25519/curve25519-donna.h"
|
||||
#include "SHAUtils/sha.h"
|
||||
#include "stdint.h"
|
||||
#include "CheckSumUtils.h"
|
||||
|
||||
/** \defgroup MICO_Algorithm_APIs MICO Algorithm APIs
|
||||
* @brief Provide commonly used Algorithm APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup MICO_Algorithm_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_Security_MD5 MICO MD5 Encryption
|
||||
* @brief MiCO MD5 Encryption Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word16;
|
||||
typedef unsigned int word32;
|
||||
typedef unsigned long long word64;
|
||||
|
||||
/**
|
||||
* @brief Constant data during MD5 Encryption
|
||||
*/
|
||||
enum {
|
||||
MD5 = 0, /** hash type unique */
|
||||
MD5_BLOCK_SIZE = 64,
|
||||
MD5_DIGEST_SIZE = 16,
|
||||
MD5_PAD_SIZE = 56
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief MD5 Context definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t state[4]; /** state (ABCD) */
|
||||
uint32_t count[2]; /** number of bits, modulo 2^64 (lsb first) */
|
||||
uint32_t buffer[64]; /** input buffer */
|
||||
} md5_context;
|
||||
|
||||
|
||||
/**
|
||||
* @brief MD5 context setup
|
||||
*
|
||||
* @param ctx context to be initialized
|
||||
*/
|
||||
void InitMd5(md5_context *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* @brief MD5 process buffer
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
* @param input buffer holding the data
|
||||
* @param ilen length of the input data
|
||||
*/
|
||||
void Md5Update(md5_context *ctx, unsigned char *input, int ilen);
|
||||
|
||||
|
||||
/**
|
||||
* @brief MD5 final digest
|
||||
*
|
||||
* @param ctx MD5 context
|
||||
* @param output MD5 checksum result
|
||||
*/
|
||||
void Md5Final(md5_context *ctx, unsigned char output[16]);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_Security_HAMC_MD5 MICO HMAC_MD5 Encryption
|
||||
* @brief MiCO HMAC_MD5 Encryption Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Constant data during HAMC_MD5 Encryption
|
||||
*/
|
||||
enum{
|
||||
HMAC_BLOCK_SIZE = 64,
|
||||
INNER_HASH_SIZE = 128,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Hash union during HMAC_MD5 Encryption
|
||||
*/
|
||||
typedef union {
|
||||
md5_context md5;
|
||||
} Hash;
|
||||
|
||||
/**
|
||||
* @brief Hmac digest during HMAC_MD5 Encription
|
||||
*/
|
||||
typedef struct Hmac {
|
||||
Hash hash;
|
||||
word32 ipad[HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/
|
||||
word32 opad[HMAC_BLOCK_SIZE / sizeof(word32)];
|
||||
word32 innerHash[INNER_HASH_SIZE / sizeof(word32)]; /* max size */
|
||||
byte macType; /* md5 */
|
||||
byte innerHashKeyed; /* keyed flag */
|
||||
} Hmac;
|
||||
|
||||
/**
|
||||
* @brief HMAC_MD5 extend external key into a longer bit string
|
||||
*
|
||||
* @param hmac Hmac context
|
||||
* @param type hash type(only include MD5)
|
||||
* @param key key
|
||||
* @param keysz length of key
|
||||
* @retval None
|
||||
*/
|
||||
void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief HMAC_MD5 process buffer
|
||||
*
|
||||
* @param Hmac hmac context
|
||||
* @param byte* buffer holding the input data
|
||||
* @param inLen length of the input data.
|
||||
* Note: The length is arbitrary.
|
||||
* @retval None
|
||||
*/
|
||||
void HmacUpdate(Hmac* hmac, const byte* input, word32 inLen);
|
||||
|
||||
|
||||
/**
|
||||
* @brief HMAC Final Digest
|
||||
*
|
||||
* @param hmac Hmac context
|
||||
* @param output buffer holding the output data
|
||||
* @retval None
|
||||
*/
|
||||
void HmacFinal(Hmac* hmac, byte* output);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_Security_DES MICO DES Encryption Algorithm
|
||||
* @brief MiCO DES Encryption and Decryption Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Constant data during DES Encryption
|
||||
*/
|
||||
enum {
|
||||
DES_ENC_TYPE = 2, /* cipher unique type */
|
||||
DES3_ENC_TYPE = 3, /* cipher unique type */
|
||||
DES_BLOCK_SIZE = 8,
|
||||
DES_KS_SIZE = 32,
|
||||
DES_ENCRYPTION = 0,
|
||||
DES_DECRYPTION = 1
|
||||
};
|
||||
/**
|
||||
* @brief Des context
|
||||
*/
|
||||
typedef struct Des {
|
||||
word32 key[DES_KS_SIZE];
|
||||
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
|
||||
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
|
||||
} Des;
|
||||
|
||||
/**
|
||||
* @brief Des3 context
|
||||
*/
|
||||
typedef struct Des3 {
|
||||
word32 key[3][DES_KS_SIZE];
|
||||
word32 reg[DES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */
|
||||
word32 tmp[DES_BLOCK_SIZE / sizeof(word32)]; /* same */
|
||||
} Des3;
|
||||
|
||||
/**
|
||||
* @brief DES extend external key into a longer bit string
|
||||
*
|
||||
* @param des Des context
|
||||
* @param key external key defined by user,the length must be 64 bits
|
||||
* @param iv extension key defined by user,must be the same size with key
|
||||
* @param dir Specify the process of encryption or decryption
|
||||
* @retval None
|
||||
*/
|
||||
void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir);
|
||||
|
||||
|
||||
/**
|
||||
* @brief DES encryption process in Cbc mode
|
||||
*
|
||||
* @param des Des context
|
||||
* @param output buffer to hold output - Cipher Text. It has the same size with input
|
||||
* @param input buffer to hold input - Plain Text.
|
||||
* Note: The size of input must be the multiple of DES_BLOCK_SIZE 64 bits
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief DES decryption process in Cbc mode
|
||||
*
|
||||
* @param des Des context
|
||||
* @param output buffer to hold output - Plain Text.
|
||||
* @param input buffer to hold input - Cipher Text.
|
||||
* Note: The size of input - Cipher Text must be with 2^64 bits
|
||||
* And it must be the multiple of DES_BLOCK_SIZE 8 bytes
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval None
|
||||
*/
|
||||
void Des_CbcDecrypt(Des* des, byte* output, const byte* input, word32 sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief DES3 extend external key into a longer bit string
|
||||
*
|
||||
* @param des Des3 context
|
||||
* @param key external key defined by user,the length must be 192 bits<EFBFBD><EFBFBD>24 bytes<EFBFBD><EFBFBD>
|
||||
* @param iv extension key defined by user,must be the same size with key
|
||||
* @param dir Specify the process of encryption or decryption
|
||||
* @retval None
|
||||
*/
|
||||
void Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir);
|
||||
|
||||
|
||||
/**
|
||||
* @brief DES3 encryption process in Cbc mode
|
||||
*
|
||||
* @param des Des3 context
|
||||
* @param output buffer to hold output - Cipher Text. It has the same size with input
|
||||
* @param input buffer to hold input - Plain Text.
|
||||
* Note: The size of input must be the multiple of DES_BLOCK_SIZE 64 bits
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval None
|
||||
*/
|
||||
void Des3_CbcEncrypt(Des3* des, byte* output, const byte* input,word32 sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief DES3 decryption process in Cbc mode
|
||||
*
|
||||
* @param des Des3 context
|
||||
* @param output buffer to hold output - Plain Text.
|
||||
* @param input buffer to hold input - Cipher Text.
|
||||
* Note: The size of input - Cipher Text must be with 2^64 bits
|
||||
* And it must be the multiple of DES_BLOCK_SIZE 8 bytes
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval None
|
||||
*/
|
||||
void Des3_CbcDecrypt(Des3* des, byte* output, const byte* input,word32 sz);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_Security_AES MICO AES Encryption Algorytm
|
||||
* @brief MiCO AES Encryption and Decryption Function
|
||||
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Constant data during AES Encription
|
||||
*/
|
||||
enum {
|
||||
AES_ENC_TYPE = 1, /* cipher unique type */
|
||||
AES_ENCRYPTION = 0,
|
||||
AES_DECRYPTION = 1,
|
||||
AES_BLOCK_SIZE = 16
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Aes context
|
||||
*/
|
||||
typedef struct Aes {
|
||||
/* AESNI needs key first, rounds 2nd, not sure why yet */
|
||||
word32 key[60];
|
||||
word32 rounds;
|
||||
word32 reg[AES_BLOCK_SIZE / sizeof(word32)];
|
||||
word32 tmp[AES_BLOCK_SIZE / sizeof(word32)];
|
||||
} Aes;
|
||||
|
||||
/**
|
||||
* @brief AES extend external key into a longer bit string
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param key external key defined by user,must be 128 bits
|
||||
* @param ilen size of AES_BLOCK_SIZE
|
||||
* @param iv extension key defined by user,must be the same size with key
|
||||
* @param dir Specify the process of encryption or decryption
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int AesSetKey(Aes* aes, const byte* key, word32 ilen, const byte* iv,int dir);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES encryption process in Cbc mode
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param output buffer to hold output - Cipher Text.
|
||||
* @param input buffer to hold input - Plain Text.
|
||||
* Note: The size of input - Plain Text must be the multiple of AES_BLOCK_SIZE 128 bits
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int AesCbcEncrypt(Aes* aes, byte* output, const byte* input, word32 sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES decryption process in Cbc mode
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param output buffer to hold output - Plain Text. It has the same size with input
|
||||
* @param input buffer to hold input - Cipher Text.
|
||||
* Note: The size of input must be the multiple of AES_BLOCK_SIZE 128 bits
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int AesCbcDecrypt(Aes* aes, byte* output, const byte* input, word32 sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES encryption process in Cbc mode with PKCS#5 padding
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param output buffer to hold output - Cipher Text.
|
||||
* @param input buffer to hold input - Plain Text.
|
||||
* @param sz size of input
|
||||
* @retval the Cipher Text size, should be the multiple of AES_BLOCK_SIZE 128 bits
|
||||
*/
|
||||
word32 AesCbcEncryptPkcs5Padding(Aes* aes, byte* output, const byte* input, word32 sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES decryption process in Cbc mode with PKCS#5 padding
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param output buffer to hold output - Plain Text.
|
||||
* @param input buffer to hold input - Cipher Text.
|
||||
* @param sz size of input, must be the multiple of AES_BLOCK_SIZE 128 bits
|
||||
* @retval the Plain Text size
|
||||
*/
|
||||
word32 AesCbcDecryptPkcs5Padding(Aes* aes, byte* output, const byte* input, word32 sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES extend external key into a longer bit string
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param key external key defined by user,must be 128 bits
|
||||
* @param ilen size of AES_BLOCK_SIZE.
|
||||
* @param out buffer to put cipher text.
|
||||
* @param dir Specify the process of encryption or decryption
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int AesSetKeyDirect(Aes* aes, const byte* key, word32 ilen,const byte* out, int dir);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES encryption process in ecb mode
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param output buffer to hold output - Plain Text. It has the same size with input
|
||||
* @param input buffer to hold input - Cipher Text.
|
||||
* Note: The size of input must be the multiple of AES_BLOCK_SIZE 128 bits
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval None.
|
||||
*/
|
||||
void AesEncryptDirect(Aes* aes, byte* out, const byte* in);
|
||||
|
||||
|
||||
/**
|
||||
* @brief AES decryption process in ecb mode
|
||||
*
|
||||
* @param aes AES context
|
||||
* @param output buffer to hold output - Plain Text. It has the same size with input
|
||||
* @param input buffer to hold input - Cipher Text.
|
||||
* Note: The size of input must be the multiple of AES_BLOCK_SIZE 128 bits
|
||||
* @param sz size of input
|
||||
* Note: input and output have the same size.
|
||||
* @retval None.
|
||||
*/
|
||||
void AesDecryptDirect(Aes* aes, byte* out, const byte* in);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_Security_ARC4 MICO ARC4 Encryption Algorytm
|
||||
* @brief MiCO ARC4 Encryption and Decryption Fucntion
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Constant data during Arc4 Encription
|
||||
*/
|
||||
enum {
|
||||
ARC4_ENC_TYPE = 4, /* cipher unique type */
|
||||
ARC4_STATE_SIZE = 256
|
||||
};
|
||||
/**
|
||||
* @brief Arc4 context
|
||||
*/
|
||||
typedef struct Arc4 {
|
||||
byte x;
|
||||
byte y;
|
||||
byte state[ARC4_STATE_SIZE];
|
||||
} Arc4;
|
||||
|
||||
|
||||
/**
|
||||
* @brief ARC4 extend external key
|
||||
*
|
||||
* @param arc4 ARC4 context
|
||||
* @param key external key defined by user
|
||||
* @param keylen length of the key, range is 1-256 bits.
|
||||
* Note: 0 is illegal.
|
||||
* @retval None.
|
||||
*/
|
||||
void Arc4SetKey(Arc4 *arc4, const byte *key, word32 keylen );
|
||||
|
||||
|
||||
/**
|
||||
* @brief ARC4 encryption or decription process
|
||||
*
|
||||
* @param arc4 ARC4 context
|
||||
* @param output buffer to hold output - Cipher Text.It has the same size with input
|
||||
* @param input buffer to hold input - Plain Text.
|
||||
* Note: The length must be within 1 to 20 bytes.
|
||||
* @param outlen size of output.
|
||||
* @retval None.
|
||||
*/
|
||||
void Arc4Process(Arc4 *arc4, byte *output, const byte *input, word32 outlen);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_Security_Rabbit MICO Rabbit Encryption Algorithm
|
||||
* @brief MiCO Rabbit Encryption and Decryption Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Constant data during Rabbit Encryption
|
||||
*/
|
||||
enum {
|
||||
RABBIT_ENC_TYPE = 5 /* cipher unique type */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Rabbit Context
|
||||
*/
|
||||
typedef struct RabbitCtx {
|
||||
word32 x[8];
|
||||
word32 c[8];
|
||||
word32 carry;
|
||||
} RabbitCtx;
|
||||
|
||||
/**
|
||||
* @brief Rabbit stream cipher
|
||||
*/
|
||||
typedef struct Rabbit {
|
||||
RabbitCtx masterCtx;
|
||||
RabbitCtx workCtx;
|
||||
} Rabbit;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Rabbit extend external key into a longer bit string
|
||||
*
|
||||
* @param rabbit Rabbit context
|
||||
* @param key Key Seed defined by user, but length must be 128 bits
|
||||
* @param iv initial vector - IV, but length must be 64 bits
|
||||
*/
|
||||
int RabbitSetKey(Rabbit* rabbit, const byte* key, const byte* iv);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Rabbit encryption or decryption process
|
||||
*
|
||||
* @param rabbit Rabbit context
|
||||
* @param output buffer to hold output - Cipher Text.
|
||||
* Note: The size of output is the same with input.
|
||||
* @param input buffer to hold input.
|
||||
* Note: The size must be within 1 to 16bytes
|
||||
* @param sz size of output.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int RabbitProcess(Rabbit* rabbit, byte* output, const byte* input, word32 sz);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup MICO_Security_RSA MICO RSA Encryption Algorithm
|
||||
* @brief MiCO RSA Encryption and Decryption Function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Constant data during RSA Encryption
|
||||
*/
|
||||
#define DBRG_SEED_LEN (440/8)
|
||||
enum {
|
||||
RSA_PUBLIC = 0,
|
||||
RSA_PRIVATE = 1
|
||||
};
|
||||
/**
|
||||
* @brief OS specific seeder
|
||||
*/
|
||||
typedef struct OS_Seed {
|
||||
int fd;
|
||||
} OS_Seed;
|
||||
|
||||
|
||||
/**
|
||||
* @brief the infamous mp_int structure
|
||||
*/
|
||||
typedef struct {
|
||||
int used, alloc, sign;
|
||||
unsigned short *dp;
|
||||
} mp_int;
|
||||
|
||||
/**
|
||||
* @brief rsakey define
|
||||
*/
|
||||
typedef struct RsaKey {
|
||||
mp_int n, e, d, p, q, dP, dQ, u;
|
||||
int type; /* public or private */
|
||||
void* heap; /* for user memory overrides */
|
||||
} RsaKey;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Constant data during RSA Encryption
|
||||
*/
|
||||
enum {
|
||||
SHA256_BLOCK_SIZE = 64,
|
||||
SHA256_DIGEST_SIZE = 32,
|
||||
SHA256_PAD_SIZE = 56
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief ha256 digest
|
||||
*/
|
||||
typedef struct Sha256 {
|
||||
word32 buffLen; /* in bytes */
|
||||
word32 loLen; /* length in bytes */
|
||||
word32 hiLen; /* length in bytes */
|
||||
word32 digest[SHA256_DIGEST_SIZE / sizeof(word32)];
|
||||
word32 buffer[SHA256_BLOCK_SIZE / sizeof(word32)];
|
||||
} Sha256;
|
||||
|
||||
/**
|
||||
* @brief RNG definition used for RSA
|
||||
*/
|
||||
typedef struct CyaSSL_RNG {
|
||||
OS_Seed seed;
|
||||
Sha256 sha;
|
||||
byte digest[SHA256_DIGEST_SIZE];
|
||||
byte V[DBRG_SEED_LEN];
|
||||
byte C[DBRG_SEED_LEN];
|
||||
word64 reseed_ctr;
|
||||
} CyaSSL_RNG;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize RsaKey
|
||||
*
|
||||
* @param key RsaKey context
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void InitRsaKey(RsaKey* key, void*);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Free RsaKey
|
||||
*
|
||||
* @param key RsaKey context
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void FreeRsaKey(RsaKey* key);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize Rng for RSA
|
||||
*
|
||||
* @param key CyaSSL_RNG context
|
||||
*
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int InitRng(CyaSSL_RNG *);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Encrypt the string with the public key
|
||||
*
|
||||
* @param in string need to be encrypted
|
||||
* @param inLen string length
|
||||
* @param out used to store the result of encryption
|
||||
* @param outLen length of out
|
||||
* @param key RsaKey context
|
||||
* @param rng CyaSSL_RNG context
|
||||
*
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key, CyaSSL_RNG* rng);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decrypt the string with the private key
|
||||
*
|
||||
* @param in string need to be decrypted
|
||||
* @param inLen string length
|
||||
* @param out used to store the result of decryption
|
||||
* @param outLen length of out
|
||||
* @param key RsaKey context
|
||||
*
|
||||
* @retval Return the length in bytes written to out or a negative
|
||||
number in case of an error.
|
||||
*/
|
||||
int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sign data using RSA
|
||||
* @param in string need to be signed
|
||||
* @param inLen string length
|
||||
* @param out used to store the result of signing
|
||||
* @param outLen length of out
|
||||
* @param key RsaKey context
|
||||
* @param rng rng used to sign
|
||||
*
|
||||
* @retval return the length in bytes written to out or a negative
|
||||
number in case of an error.
|
||||
*/
|
||||
int RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key, CyaSSL_RNG* rng);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Verify data using RSA
|
||||
*
|
||||
* @param in string need to be verify
|
||||
* @param inLen string length
|
||||
* @param out used to store the result of verifying
|
||||
* @param outLen length of out
|
||||
* @param key RsaKey context
|
||||
*
|
||||
* @retval return the length in bytes written to out or a negative
|
||||
number in case of an error.
|
||||
*/
|
||||
int RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
|
||||
word32 outLen, RsaKey* key);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decode the private key
|
||||
*
|
||||
* @param input holds the raw data from the key
|
||||
* @param inOutIdx start address
|
||||
* @param key RsaKey context
|
||||
* @param length length to decode
|
||||
*
|
||||
* @retval return the index or error
|
||||
*/
|
||||
int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
word32 length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decode the public key
|
||||
*
|
||||
* @param input holds the raw data from the key
|
||||
* @param inOutIdx start address
|
||||
* @param key RsaKey context
|
||||
* @param length length to decode
|
||||
*
|
||||
* @retval return the index or error
|
||||
*/
|
||||
int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey *key,word32);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
720
Living_SDK/kernel/vcall/mico/include/mico_socket.h
Normal file
720
Living_SDK/kernel/vcall/mico/include/mico_socket.h
Normal file
|
|
@ -0,0 +1,720 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef __MICOSOCKET_H__
|
||||
#define __MICOSOCKET_H__
|
||||
|
||||
#if defined __GNUC__
|
||||
#include <sys/time.h>
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include "mico_errno.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/** @addtogroup MICO_Core_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup MICO_SOCKET MICO Socket Operations
|
||||
* @brief Communicate with other device using TCP or UDP over MICO network
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** For compatibility with BSD code */
|
||||
struct in_addr {
|
||||
uint32_t s_addr;
|
||||
};
|
||||
|
||||
/** 255.255.255.255 */
|
||||
#define INADDR_NONE ((uint32_t)0xffffffffUL)
|
||||
/** 127.0.0.1 */
|
||||
#define INADDR_LOOPBACK ((uint32_t)0x7f000001UL)
|
||||
/** 0.0.0.0 */
|
||||
#define INADDR_ANY ((uint32_t)0x00000000UL)
|
||||
/** 255.255.255.255 */
|
||||
#define INADDR_BROADCAST ((uint32_t)0xffffffffUL)
|
||||
|
||||
/* members are in network byte order */
|
||||
struct sockaddr_in {
|
||||
uint8_t sin_len;
|
||||
uint8_t sin_family;
|
||||
uint16_t sin_port;
|
||||
struct in_addr sin_addr;
|
||||
char sin_zero[8];
|
||||
};
|
||||
|
||||
struct sockaddr {
|
||||
uint8_t sa_len;
|
||||
uint8_t sa_family;
|
||||
uint8_t sa_data[14];
|
||||
};
|
||||
|
||||
#ifndef socklen_t
|
||||
# define socklen_t uint32_t
|
||||
#endif
|
||||
|
||||
struct hostent {
|
||||
char *h_name; /* Official name of the host. */
|
||||
char **h_aliases; /* A pointer to an array of pointers to alternative host names,
|
||||
terminated by a null pointer. */
|
||||
int h_addrtype; /* Address type. */
|
||||
int h_length; /* The length, in bytes, of the address. */
|
||||
char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
|
||||
network byte order) for the host, terminated by a null pointer. */
|
||||
#define h_addr h_addr_list[0] /* for backward compatibility */
|
||||
};
|
||||
|
||||
|
||||
struct addrinfo {
|
||||
int ai_flags; /* Input flags. */
|
||||
int ai_family; /* Address family of socket. */
|
||||
int ai_socktype; /* Socket type. */
|
||||
int ai_protocol; /* Protocol of socket. */
|
||||
socklen_t ai_addrlen; /* Length of socket address. */
|
||||
struct sockaddr *ai_addr; /* Socket address of socket. */
|
||||
char *ai_canonname; /* Canonical name of service location. */
|
||||
struct addrinfo *ai_next; /* Pointer to next in list. */
|
||||
};
|
||||
|
||||
/* Socket protocol types (TCP/UDP/RAW) */
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_RAW 3
|
||||
|
||||
#define SOL_SOCKET 0xfff /* options for socket level */
|
||||
|
||||
#define AF_UNSPEC 0
|
||||
#define AF_INET 2
|
||||
#define PF_INET AF_INET
|
||||
#define PF_UNSPEC AF_UNSPEC
|
||||
|
||||
#define IPPROTO_IP 0
|
||||
#define IPPROTO_TCP 6
|
||||
#define IPPROTO_UDP 17
|
||||
#define IPPROTO_UDPLITE 136
|
||||
|
||||
/*
|
||||
* Options for level IPPROTO_IP
|
||||
*/
|
||||
#define IP_TOS 1
|
||||
#define IP_TTL 2
|
||||
|
||||
typedef struct ip_mreq {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
} ip_mreq;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Socket option types, level: SOL_SOCKET
|
||||
*/
|
||||
typedef enum {
|
||||
SO_DEBUG = 0x0001, /**< Unimplemented: turn on debugging info recording */
|
||||
SO_ACCEPTCONN = 0x0002, /**< socket has had listen() */
|
||||
SO_REUSEADDR = 0x0004, /**< Allow local address reuse */
|
||||
SO_KEEPALIVE = 0x0008, /**< keep connections alive */
|
||||
SO_DONTROUTE = 0x0010, /**< Just use interface addresses */
|
||||
SO_BROADCAST = 0x0020, /**< Permit to send and to receive broadcast messages */
|
||||
SO_USELOOPBACK = 0x0040, /**< Bypass hardware when possible */
|
||||
SO_LINGER = 0x0080, /**< linger on close if data present */
|
||||
SO_OOBINLINE = 0x0100, /**< Leave received OOB data in line */
|
||||
SO_REUSEPORT = 0x0200, /**< Allow local address & port reuse */
|
||||
SO_BLOCKMODE = 0x1000, /**< set socket as block(optval=0)/non-block(optval=1) mode.
|
||||
Default is block mode. */
|
||||
SO_SNDBUF = 0x1001,
|
||||
SO_SNDTIMEO = 0x1005, /**< Send timeout in block mode. block for ever in dafault mode. */
|
||||
SO_RCVTIMEO = 0x1006, /**< Recv timeout in block mode. block 1 second in default mode. */
|
||||
SO_ERROR = 0x1007, /**< Get socket error number. */
|
||||
SO_TYPE = 0x1008, /**< Get socket type. */
|
||||
SO_NO_CHECK = 0x100a /**< Don't create UDP checksum. */
|
||||
|
||||
} SOCK_OPT_VAL;
|
||||
|
||||
struct pollfd {
|
||||
int fd; /**< fd related to */
|
||||
short events; /**< which POLL... events to respond to */
|
||||
short revents; /**< which POLL... events occurred */
|
||||
};
|
||||
#define POLLIN 0x0001
|
||||
#define POLLPRI 0x0002
|
||||
#define POLLOUT 0x0004
|
||||
#define POLLERR 0x0008
|
||||
#define POLLHUP 0x0010
|
||||
#define POLLNVAL 0x0020
|
||||
|
||||
|
||||
/**
|
||||
* @brief IP option types, level: IPPROTO_IP
|
||||
*/
|
||||
typedef enum {
|
||||
IP_ADD_MEMBERSHIP = 0x0003, /**< Join multicast group. */
|
||||
IP_DROP_MEMBERSHIP = 0x0004, /**< Leave multicast group. */
|
||||
IP_MULTICAST_TTL = 0x0005,
|
||||
IP_MULTICAST_IF = 0x0006,
|
||||
IP_MULTICAST_LOOP = 0x0007
|
||||
} IP_OPT_VAL;
|
||||
|
||||
/**
|
||||
* @brief TCP option types, level: IPPROTO_TCP
|
||||
*/
|
||||
typedef enum {
|
||||
TCP_NODELAY = 0x0001,
|
||||
TCP_KEEPALIVE = 0x0002,
|
||||
TCP_CONN_NUM = 0x0006, /**< Read the current connected TCP client number. */
|
||||
TCP_MAX_CONN_NUM = 0x0007, /**< Set the max number of TCP client that server can support. */
|
||||
TCP_KEEPIDLE = 0x0003, /**< set pcb->keep_idle - send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
|
||||
TCP_KEEPINTVL = 0x0004, /**< set pcb->keep_intvl - Use seconds for get/setsockopt */
|
||||
TCP_KEEPCNT = 0x0005, /**< set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
|
||||
} TCP_OPT_VAL;
|
||||
|
||||
|
||||
#if !defined(FIONREAD) || !defined(FIONBIO)
|
||||
#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
|
||||
#define IOC_VOID 0x20000000UL /* no parameters */
|
||||
#define IOC_OUT 0x40000000UL /* copy out parameters */
|
||||
#define IOC_IN 0x80000000UL /* copy in parameters */
|
||||
#define IOC_INOUT (IOC_IN|IOC_OUT)
|
||||
/* 0x20000000 distinguishes new &
|
||||
old ioctl's */
|
||||
#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
|
||||
|
||||
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
|
||||
|
||||
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
|
||||
#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
|
||||
|
||||
#ifndef FIONREAD
|
||||
#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
|
||||
#endif
|
||||
#ifndef FIONBIO
|
||||
#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
|
||||
#endif
|
||||
|
||||
typedef void* mico_ssl_t;
|
||||
|
||||
/**
|
||||
* @brief Supported SSL protocol version
|
||||
*/
|
||||
enum ssl_version_type_e
|
||||
{
|
||||
SSL_V3_MODE = 1,
|
||||
TLS_V1_0_MODE = 2,
|
||||
TLS_V1_1_MODE = 3,
|
||||
TLS_V1_2_MODE = 4,
|
||||
};
|
||||
typedef uint8_t ssl_version_type_t;
|
||||
|
||||
#if !defined __GNUC__
|
||||
|
||||
struct timeval {
|
||||
long tv_sec; /* seconds */
|
||||
long tv_usec; /* and microseconds */
|
||||
};
|
||||
|
||||
#define FD_SETSIZE 64 /**< MAX fd number is 64 in MICO. */
|
||||
#define howmany(x, y) (((x) + ((y) - 1)) / (y))
|
||||
|
||||
#define NBBY 8 /**< number of bits in a byte. */
|
||||
#define NFDBITS (sizeof(unsigned long) * NBBY) /**< bits per mask */
|
||||
|
||||
#define _fdset_mask(n) ((unsigned long)1 << ((n) % NFDBITS))
|
||||
|
||||
typedef struct fd_set {
|
||||
unsigned long fds_bits[howmany(FD_SETSIZE, NFDBITS)];
|
||||
} fd_set;
|
||||
|
||||
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= _fdset_mask(n)) /**< Add a fd to FD set. */
|
||||
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~_fdset_mask(n)) /**< Remove fd from FD set. */
|
||||
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & _fdset_mask(n)) /**< Check if the fd is set in FD set. */
|
||||
#define FD_ZERO(p) memset(p, 0, sizeof(*(p))) /**< Clear FD set. */
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 1
|
||||
#define SHUT_WR 2
|
||||
#define SHUT_RDWR 3
|
||||
#endif
|
||||
|
||||
#define MAX_TCP_CLIENT_PER_SERVER 5
|
||||
|
||||
|
||||
/** @defgroup MICO_SOCKET_GROUP_1 MICO BSD-like Socket Functions
|
||||
* @brief Provide basic APIs for socket function
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Create an endpoint for communication
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @param domain: Specifies a communication domain; this selects the protocol
|
||||
* family which will be used for communication.
|
||||
* This parameter can be one value:
|
||||
* @arg AF_INET: IPv4 Internet protocols.
|
||||
* @param type: Specifies the communication semantics.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg SOCK_STREAM: Provides sequenced, reliable, two-way,
|
||||
* connection-based byte streams. An out-of-band data
|
||||
* transmission mechanism may be supported. (TCP)
|
||||
* @arg SOCK_DGRAM: Supports datagrams (connectionless, unreliable
|
||||
* messages of a fixed maximum length).(UDP)
|
||||
* @param protocol: specifies a particular protocol to be used with the socket.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg IPPROTO_TCP: TCP protocol
|
||||
* @arg IPPROTO_UDP: UDP protocol
|
||||
* @retval On success, a file descriptor for the new socket is returned.
|
||||
On error, -1 is returned.
|
||||
*/
|
||||
int socket(int domain, int type, int protocol);
|
||||
|
||||
/**
|
||||
* @brief Set options on sockets
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @param socket: A file descriptor
|
||||
* @param level: This parameter can be : IPPROTO_IP, SOL_SOCKET, IPPROTO_TCP, IPPROTO_UDP
|
||||
* @param optname: This parameter is defined in SOCK_OPT_VAL
|
||||
* @param optval: address of buffer in which the value for the requested option(s)
|
||||
* are to be set.
|
||||
* @param optlen: containing the size of the buffer pointed to by optval
|
||||
* @retval On success, zero is returned. On error, -1 is returned.
|
||||
*/
|
||||
int setsockopt (int socket, int level, int optname, void *optval, socklen_t optlen);
|
||||
|
||||
/**
|
||||
* @brief Get options on sockets
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @param socket: A file descriptor
|
||||
* @param level: This parameter can be : IPPROTO_IP, SOL_SOCKET, IPPROTO_TCP, IPPROTO_UDP
|
||||
* @param optname: This parameter is defined in SOCK_OPT_VAL
|
||||
* @param optval: address of buffer in which the value for the requested option(s)
|
||||
* are to be returned.
|
||||
* @param optlen_ptr: This is a value-result argument, initially containing the size
|
||||
* of the buffer pointed to by optval, and modified on return to indicate
|
||||
* the actual size of the value returned.
|
||||
* @retval On success, zero is returned. On error, -1 is returned.
|
||||
*/
|
||||
int getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen_ptr);
|
||||
|
||||
/**
|
||||
* @brief bind a name to a socket
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @note Assigns the address specified by addr to the socket referred to by the file
|
||||
* descriptor socket.
|
||||
* @param socket: A file descriptor
|
||||
* @param addr: Point to the target address to be binded
|
||||
* @param length: This parameter containing the size of the buffer pointed to by addr
|
||||
* @retval On success, zero is returned. On error, -1 is returned.
|
||||
*/
|
||||
int bind (int socket, struct sockaddr *addr, socklen_t length);
|
||||
|
||||
/**
|
||||
* @brief Initiate a connection on a socket
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details The connect() system call connects the socket referred to by the file
|
||||
* descriptor socket to the address specified by addr.
|
||||
* @param socket: A file descriptor
|
||||
* @param addr: Point to the target address to be binded
|
||||
* @param length: This parameter containing the size of the buffer pointed to by addr
|
||||
* @retval On success, zero is returned. On error, -1 is returned.
|
||||
*/
|
||||
int connect (int socket, struct sockaddr *addr, socklen_t length);
|
||||
|
||||
/**
|
||||
* @brief Listen for connections on a socket
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details listen() marks the socket referred to by socket as a passive socket,
|
||||
* that is, as a socket that will be used to accept incoming connection
|
||||
* requests using accept().
|
||||
* @param socket: a file descriptor.
|
||||
* @param n: Defines the maximum length to which the queue of pending
|
||||
* connections for socket may grow. This parameter is not used in MICO,
|
||||
* use 0 is fine.
|
||||
* @retval On success, zero is returned. On error, -1 is returned.
|
||||
*/
|
||||
int listen (int socket, int n);
|
||||
|
||||
/**
|
||||
* @brief Accept a connection on a socket
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details The accept() system call is used with connection-based socket types
|
||||
* (SOCK_STREAM). It extracts the first connection request on the queue
|
||||
* of pending connections for the listening socket, sockfd, creates a
|
||||
* new connected socket, and returns a new file descriptor referring to
|
||||
* that socket. The newly created socket is not in the listening state.
|
||||
* The original socket socket is unaffected by this call.
|
||||
* @param socket: A file descriptor.
|
||||
* @param addr: Point to the buffer to store the address of the accepted client.
|
||||
* @param length_ptr: This parameter containing the size of the buffer pointed to
|
||||
* by addr.
|
||||
* @retval On success, zero is returned. On error, -1 is returned.
|
||||
*/
|
||||
int accept (int socket, struct sockaddr *addr, socklen_t *length_ptr);
|
||||
|
||||
/**
|
||||
* @brief Monitor multiple file descriptors, waiting until one or more of the
|
||||
* file descriptors become "ready" for some class of I/O operation
|
||||
* (e.g., input possible).
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @note A file descriptor is considered ready if it is possible to perform
|
||||
* the corresponding I/O operation (e.g., read()) without blocking.
|
||||
* @param nfds: is the highest-numbered file descriptor in any of the three
|
||||
* sets, plus 1. In MICO, the mount of file descriptors is fewer, so
|
||||
* MICO use the MAX number of these file descriptors inside, and this
|
||||
* parameter is cared.
|
||||
* @param readfds: A file descriptor sets will be watched to see if characters
|
||||
* become available for reading
|
||||
* @param writefds: A file descriptor sets will be watched to see if a write
|
||||
* will not block.
|
||||
* @param exceptfds: A file descriptor sets will be watched for exceptions.
|
||||
* @param timeout: The timeout argument specifies the interval that select()
|
||||
* should block waiting for a file descriptor to become ready.
|
||||
* If timeout is NULL (no timeout), select() can block indefinitely.
|
||||
* @retval On success, return the number of file descriptors contained in the
|
||||
* three returned descriptor sets (that is, the total number of bits
|
||||
* that are set in readfds, writefds, exceptfds) which may be zero if
|
||||
* the timeout expires before anything interesting happens. On error,
|
||||
* -1 is returned, the file descriptor sets are unmodified, and timeout
|
||||
* becomes undefined.
|
||||
*/
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
|
||||
|
||||
int poll(struct pollfd *fds, int nfds, int timeout);
|
||||
|
||||
/**
|
||||
* @brief Send a message on a socket
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details The send() call may be used only when the socket is in a connected
|
||||
* state (so that the intended recipient is known). The only difference
|
||||
* between send() and write() is the presence of flags. With a zero
|
||||
* flags argument, send() is equivalent to write().
|
||||
* @note When the message does not fit into the send buffer of the socket,
|
||||
* send() normally blocks, unless the socket has been placed in
|
||||
* nonblocking I/O mode. In nonblocking mode it would fail. The select()
|
||||
* call may be used to determine when it is possible to send more data.
|
||||
* @param socket: A file descriptor.
|
||||
* @param buffer: Point to the send data buffer.
|
||||
* @param size: Length of the send data buffer.
|
||||
* @param flags: Zero in MICO.
|
||||
* @retval On success, these calls return the number of bytes sent. On error,
|
||||
* -1 is returned,
|
||||
*/
|
||||
int send (int socket, const void *buffer, size_t size, int flags);
|
||||
|
||||
/**
|
||||
* @brief Send a message on a socket
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @note Refer send() for details.
|
||||
*/
|
||||
ssize_t write (int filedes, const void *buffer, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a message on a socket to a specific target address.
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details Refer send() for details. If sendto() is used on a connection-mode
|
||||
* (SOCK_STREAM, SOCK_SEQPACKET) socket, the arguments dest_addr and
|
||||
* addrlen are ignored. Otherwise, the address of the target is given by
|
||||
* dest_addr with addrlen specifying its size.
|
||||
* @param socket: Refer send() for details.
|
||||
* @param buffer: Refer send() for details.
|
||||
* @param size: Refer send() for details.
|
||||
* @param flags: Refer send() for details.
|
||||
* @param addr: Point to the target address.
|
||||
* @param length: This parameter containing the size of the buffer pointed to
|
||||
* by addr.
|
||||
* @retval On success, these calls return the number of bytes sent. On error,
|
||||
* -1 is returned,
|
||||
*/
|
||||
int sendto (int socket, const void *buffer, size_t size, int flags, const struct sockaddr *addr, socklen_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Receive a message from a socket.
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details If no messages are available at the socket, the receive calls wait
|
||||
* for a message to arrive, unless the socket is nonblocking, in
|
||||
* which case the value -1 is returned. The receive calls normally
|
||||
* return any data available, up to the requested amount, rather than
|
||||
* waiting for receipt of the full amount requested.
|
||||
* @param socket: A file descriptor.
|
||||
* @param buffer: Point to the send data buffer.
|
||||
* @param size: Length of the send data buffer.
|
||||
* @param flags: Zero in MICO.
|
||||
* @retval These calls return the number of bytes received, or -1 if an error
|
||||
* occurred.
|
||||
* When a stream socket peer has performed an orderly shutdown, the
|
||||
* return value will be 0 (the traditional "end-of-file" return).
|
||||
* The value 0 may also be returned if the requested number of bytes to
|
||||
* receive from a stream socket was 0.
|
||||
*/
|
||||
int recv (int socket, void *buffer, size_t size, int flags);
|
||||
|
||||
/**
|
||||
* @brief Receive a message from a socket.
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @note Refer recv() for details.
|
||||
*/
|
||||
ssize_t read (int filedes, void *buffer, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Receive a message from a socket and get the source address.
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details If src_addr is not NULL, and the underlying protocol provides
|
||||
* the source address of the message, that source address is placed
|
||||
* in the buffer pointed to by src_addr. In this case, addrlen is
|
||||
* a value-result argument. Before the call, it should be
|
||||
* initialized to the size of the buffer associated with src_addr.
|
||||
* Upon return, addrlen is updated to contain the actual size of
|
||||
* the source address. The returned address is truncated if the
|
||||
* buffer provided is too small; in this case, addrlen will return
|
||||
* a value greater than was supplied to the call.
|
||||
* If the caller is not interested in the source address, src_addr
|
||||
* should be specified as NULL and addrlen should be specified as 0.
|
||||
* @param sockfd: Refer recv() for details.
|
||||
* @param buf: Refer recv() for details.
|
||||
* @param len: Refer recv() for details.
|
||||
* @param flags: Refer recv() for details.
|
||||
* @param src_addr: Point to the buffer to store the source address.
|
||||
* @param addrlen: This parameter containing the size of the buffer pointed to
|
||||
* by src_addr.
|
||||
* @retval These calls return the number of bytes received, or -1 if an
|
||||
* error occurred.
|
||||
* When a stream socket peer has performed an orderly shutdown, the
|
||||
* return value will be 0 (the traditional "end-of-file" return).
|
||||
* The value 0 may also be returned if the requested number of bytes to
|
||||
* receive from a stream socket was 0.
|
||||
*/
|
||||
int recvfrom (int socket, void *buffer, size_t size, int flags, struct sockaddr *addr, socklen_t *length_ptr);
|
||||
|
||||
/**
|
||||
* @brief Close a file descriptor.
|
||||
* @attention Never doing operations on one socket in different MICO threads
|
||||
* @details closes a file descriptor, so that it no longer refers to any
|
||||
* file and may be reused.the resources associated with the
|
||||
* open file description are freed.
|
||||
* @param filedes: A file descriptor.
|
||||
* @retval Returns zero on success. On error, -1 is returned.
|
||||
*/
|
||||
int close (int filedes);
|
||||
|
||||
int shutdown(int s, int how);
|
||||
int ioctl(int s, long cmd, void *argp);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup MICO_SOCKET_GROUP_2 MICO Socket Tool Functions
|
||||
* @brief Provide APIs for MiCO Socket Tool functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief converts the Internet host address from IPv4 numbers-and-dots
|
||||
* notation into binary data in network byte order
|
||||
* @note If the input is invalid, INADDR_NONE (usually -1) is returned.
|
||||
* @param name: Internet host address from IPv4 numbers-and-dots.
|
||||
* @retval Returns zero on success. On error, -1 is returned.
|
||||
*/
|
||||
uint32_t inet_addr (const char *name);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Converts the Internet host address in, given in network byte
|
||||
* order, to a string in IPv4 dotted-decimal notation.
|
||||
* @note The returned string is stored in a given buffer, and the buffer
|
||||
* size should larger than 16.
|
||||
* @param s: Point to a buffer to store the returned string in IPv4
|
||||
* dotted-decimal
|
||||
* @param x: the Internet host address in.
|
||||
* @retval Returns the same value as param s.
|
||||
*/
|
||||
extern char *inet_ntoa (struct in_addr addr);
|
||||
|
||||
|
||||
|
||||
/** @brief Get the IP address from a host name.
|
||||
*
|
||||
* @note Different to stand BSD function type, this function in MICO do
|
||||
* not return a buffer that contain the result, but write the result
|
||||
* to a buffer provided by application. Also this function simplify
|
||||
* the return value compared to the standard BSD version.
|
||||
* This functon runs under block mode.
|
||||
*
|
||||
* @param name: This parameter is either a hostname, or an IPv4 address in
|
||||
* standard dot notation.
|
||||
* @param addr: Point to a buffer to store the returned string in IPv4
|
||||
* dotted-decimal
|
||||
* @param addrLen: This parameter containing the size of the buffer pointed
|
||||
* to by addr, 16 is recommended.
|
||||
* @retval kNoerr or kGeneralErr
|
||||
*/
|
||||
struct hostent* gethostbyname(const char *name);
|
||||
int getaddrinfo(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
void freeaddrinfo(struct addrinfo *ai);
|
||||
int getpeername (int s, struct sockaddr *name, socklen_t *namelen);
|
||||
int getsockname (int s, struct sockaddr *name, socklen_t *namelen);
|
||||
|
||||
|
||||
/** @brief Set TCP keep-alive mechanism parameters.
|
||||
*
|
||||
* @details When TCP data is not transimitting for a certain time (defined by seconds),
|
||||
* MICO send keep-alive package over the TCP socket, and the remote device
|
||||
* should return the keep-alive back to MICO. This is a basic TCP function
|
||||
* deployed on every TCP/IP stack and application's interaction is not required.
|
||||
* If the remote device doesn't return the keep-alive package, MICO add 1 to an
|
||||
* internal counter, and close the current socket connection once this count has
|
||||
* reached the maxErrNum (defined in parm: maxErrNum).
|
||||
*
|
||||
* @param inMaxErrNum: The max possible count that the remote device doesn't return the
|
||||
* keep-alive package. If remote device returns, the internal count is cleared
|
||||
* to 0.
|
||||
* @param inSeconds: The time interval between two keep-alive package
|
||||
*
|
||||
* @retval kNoerr or kGeneralErr
|
||||
*/
|
||||
void set_tcp_keepalive(int inMaxErrNum, int inSeconds);
|
||||
|
||||
|
||||
/** @brief Get TCP keep-alive mechanism parameters. Refer to @ref set_tcp_keepalive
|
||||
*
|
||||
* @param outMaxErrNum: Point to the address that store the maxErrNumber.
|
||||
* @param outSeconds: Point to the address that store the time interval between two
|
||||
* keep-alive package.
|
||||
*
|
||||
* @retval kNoerr or kGeneralErr
|
||||
*/
|
||||
void get_tcp_keepalive(int *outMaxErrNum, int *outSeconds);
|
||||
|
||||
|
||||
/* SSL */
|
||||
/** @brief Used to set the ssl protocol version for both ssl client and ssl server
|
||||
*
|
||||
* @note This function should be called before ssl is ready to function (before
|
||||
* ssl_connect and ssl_accept is called by application ).
|
||||
*
|
||||
* @param version: SSL protocol version, Refer SSL_VERSION for details.
|
||||
*
|
||||
* @retval void
|
||||
*/
|
||||
void ssl_set_client_version( ssl_version_type_t version );
|
||||
|
||||
|
||||
/** @brief Get the internal socket fire description
|
||||
*
|
||||
* @note This function should be called after ssl connection is established.
|
||||
*
|
||||
* @param ssl: SSL handler.
|
||||
*
|
||||
* @retval File descriptor for the SSL connection.
|
||||
*/
|
||||
int ssl_socket( mico_ssl_t ssl );
|
||||
|
||||
|
||||
/** @brief Used by the SSL server. Set the certificate and private key for a SSL server.
|
||||
*
|
||||
* @details This function is called on the server side to set it's certifact and private key.
|
||||
* It must be called before ssl_accept. These two arguments must be global
|
||||
* string buffer, library will not create a copy for them.
|
||||
*
|
||||
* @param _cert_pem: Point to the certificate string in PEM format.
|
||||
* @param private_key_pem: Point to the private key string in PEM format.
|
||||
*
|
||||
* @retval void
|
||||
*/
|
||||
void ssl_set_cert(const char *_cert_pem, const char *private_key_pem);
|
||||
|
||||
/** @brief SSL client create a SSL connection.
|
||||
*
|
||||
* @details This function is called on the client side and initiates an SSL/TLS handshake with a
|
||||
* server. When this function is called, the underlying communication channel has already
|
||||
* been set up. This function is called after TCP 3-way handshak finished.
|
||||
*
|
||||
* @param fd: The fd number for a connected TCP socket.
|
||||
* @param calen: the string length of ca. 0=do not verify server's certificate.
|
||||
* @param ca: pointer to the CA certificate string, used to verify server's certificate.
|
||||
* @param errno: return the errno if ssl_connect return NULL.
|
||||
*
|
||||
* @retval return the SSL context pointer on success or NULL for fail.
|
||||
*/
|
||||
mico_ssl_t ssl_connect(int fd, int calen, char*ca, int *errno);
|
||||
|
||||
/** @brief SSL Server accept a SSL connection
|
||||
*
|
||||
* @param fd: The fd number for a connected TCP socket.
|
||||
*
|
||||
* @retval return the SSL context pointer on success or NULL for fail.
|
||||
*/
|
||||
mico_ssl_t ssl_accept(int fd);
|
||||
|
||||
|
||||
/** @brief SSL send data
|
||||
*
|
||||
* @param ssl: Point to the SSL context.
|
||||
* @param data: Point to send data.
|
||||
* @param len: data length.
|
||||
*
|
||||
* @retval On success, these calls return the number of bytes sent. On error,
|
||||
* -1 is returned,
|
||||
*/
|
||||
int ssl_send(mico_ssl_t ssl, void* data, size_t len);
|
||||
|
||||
/** @brief SSL receive data
|
||||
*
|
||||
* @param ssl: Point to the SSL context.
|
||||
* @param data: Point to buffer to receive SSL data.
|
||||
* @param len: max receive buffer length.
|
||||
*
|
||||
* @retval On success, these calls return the number of bytes received. On error,
|
||||
* -1 is returned,
|
||||
*/
|
||||
int ssl_recv(mico_ssl_t ssl, void* data, size_t len);
|
||||
|
||||
/** @brief Close the SSL session, release resource.
|
||||
*
|
||||
* @param ssl: Point to the SSL context.
|
||||
*
|
||||
* @retval kNoerr or kGeneralErr
|
||||
*/
|
||||
int ssl_close(mico_ssl_t ssl);
|
||||
|
||||
|
||||
int ssl_pending(void*ssl);
|
||||
int ssl_get_error(void* ssl, int ret);
|
||||
void ssl_set_using_nonblock(void* ssl, int nonblock);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__MICO_SOCKET_H__*/
|
||||
|
||||
|
||||
|
||||
754
Living_SDK/kernel/vcall/mico/include/mico_system.h
Normal file
754
Living_SDK/kernel/vcall/mico/include/mico_system.h
Normal file
|
|
@ -0,0 +1,754 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
#if 0
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "system.h"
|
||||
#include "command_console/mico_cli.h"
|
||||
#include "json_c/json.h"
|
||||
|
||||
#ifndef MICO_PREBUILT_LIBS
|
||||
#include "mico_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef system_state_t mico_system_state_t;
|
||||
typedef system_config_t mico_Context_t;
|
||||
typedef system_status_wlan_t mico_system_status_wlan_t;
|
||||
|
||||
/** @defgroup MICO_SYSTEM_APIs MICO System APIs
|
||||
* @brief MiCO System provide a basic framework for application based on MiCO core APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup MICO_SYSTEM_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup System_General System General Tools
|
||||
* @brief Read MiCO system's version
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Read MiCO SDK version.
|
||||
* @param major: Major version number.
|
||||
* @param minor: Minor version number.
|
||||
* @param revision: Revision nember.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
void mico_sdk_version( uint8_t *major, uint8_t *minor, uint8_t *revision );
|
||||
|
||||
/**
|
||||
* @brief Read MiCO Application information.
|
||||
* @param p_info: Point to the memory to store the info.
|
||||
* @param len_info: Size of the menory.
|
||||
* @retval none.
|
||||
*/
|
||||
void mico_app_info(char *p_info, int len_info);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup system_context Core Data Functions
|
||||
* @brief System core data management, should initialized before other system functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Parameter section store in flash */
|
||||
typedef enum
|
||||
{
|
||||
PARA_BOOT_TABLE_SECTION,
|
||||
PARA_MICO_DATA_SECTION,
|
||||
#ifdef MICO_BLUETOOTH_ENABLE
|
||||
PARA_BT_DATA_SECTION,
|
||||
#endif
|
||||
PARA_SYS_END_SECTION,
|
||||
PARA_APP_DATA_SECTION,
|
||||
PARA_END_SECTION
|
||||
} para_section_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize core data used by MiCO system framework. System and
|
||||
* application's configuration are read from non-volatile storage:
|
||||
* flash etc.
|
||||
* @param size_of_user_data: The length of config data used by application
|
||||
* @retval Address of core data.
|
||||
*/
|
||||
void* mico_system_context_init( uint32_t size_of_user_data );
|
||||
|
||||
/**
|
||||
* @brief Get the address of the core data.
|
||||
* @param none
|
||||
* @retval Address of core data.
|
||||
*/
|
||||
mico_Context_t* mico_system_context_get( void );
|
||||
|
||||
/**
|
||||
* @brief Get the address of the application's config data.
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval Address of the application's config data.
|
||||
*/
|
||||
void* mico_system_context_get_user_data( mico_Context_t* const in_context );
|
||||
|
||||
/**
|
||||
* @brief Restore configurations to default settings, it will cause a delegate
|
||||
* function: appRestoreDefault_callback( ) to give a default value for
|
||||
* application's config data.
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_context_restore( mico_Context_t* const in_context );
|
||||
|
||||
/**
|
||||
* @brief Application should give a default value for application's config data
|
||||
* on address: user_config_data
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @param user_config_data: The address of the application's config data.
|
||||
* @param size: The size of the application's config data.
|
||||
* @retval None
|
||||
*/
|
||||
void appRestoreDefault_callback(void * const user_config_data, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Write config data hosted by core data to non-volatile storage
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_context_update( mico_Context_t* const in_context );
|
||||
|
||||
OSStatus mico_system_para_read(void** info_ptr, int section, uint32_t offset, uint32_t size);
|
||||
OSStatus mico_system_para_write(const void* info_ptr, int section, uint32_t offset, uint32_t size);
|
||||
OSStatus mico_system_para_read_release( void* info_ptr );
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @defgroup MiCO OTA Functions
|
||||
* @brief MiCO firmware updation functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Active downloaded firmware that stored in MICO_PARTITION_OTA_TEMP
|
||||
* @param ota_data_len: the length of the new firmware
|
||||
* @param ota_data_crc: the crc result of the new firmware
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_ota_switch_to_new_fw(int ota_data_len, uint16_t ota_data_crc);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @defgroup system System Framework Functions
|
||||
* @brief Initialize MiCO system functions defined in mico_config.h
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Wlan configuration source */
|
||||
typedef enum{
|
||||
CONFIG_BY_NONE, /**< Default value */
|
||||
CONFIG_BY_EASYLINK_V2, /**< Wlan configured by EasyLink revision 2.0 */
|
||||
CONFIG_BY_EASYLINK_PLUS, /**< Wlan configured by EasyLink Plus */
|
||||
CONFIG_BY_EASYLINK_MINUS, /**< Wlan configured by EasyLink Minus */
|
||||
CONFIG_BY_AIRKISS, /**< Wlan configured by airkiss from wechat Tencent inc. */
|
||||
CONFIG_BY_SOFT_AP, /**< Wlan configured by EasyLink soft ap mode */
|
||||
CONFIG_BY_WAC, /**< Wlan configured by wireless accessory configuration from Apple inc. */
|
||||
CONFIG_BY_USER, /**< Wlan configured by user defined functions. */
|
||||
} mico_config_source_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize MiCO system functions according to mico_config.h
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_init( mico_Context_t* const in_context );
|
||||
|
||||
/**
|
||||
* @brief Get IP, MAC, driver info for wlan interface
|
||||
* @param status: The memory to store wlan status's address.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_wlan_get_status( mico_system_status_wlan_t** status );
|
||||
|
||||
/**
|
||||
* @brief Start wlan configuration mode, EasyLink, SoftAP, Airkiss...
|
||||
* according to macro: MICO_WLAN_CONFIG_MODE
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_wlan_start_autoconf( void );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that EasyLink configuration will start
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @retval None
|
||||
*/
|
||||
void mico_system_delegate_config_will_start( void );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that EasyLink configuration will stop
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @retval None
|
||||
*/
|
||||
void mico_system_delegate_config_will_stop( void );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that EasyLink soft ap mode will start
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @retval None
|
||||
*/
|
||||
void mico_system_delegate_soft_ap_will_start( void );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that ssid and key are received from
|
||||
* EasyLink client
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @param ssid: The address of the SSID string.
|
||||
* @param key: The address of the Key string.
|
||||
* @retval None
|
||||
*/
|
||||
void mico_system_delegate_config_recv_ssid ( char *ssid, char *key );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that auth data has received from
|
||||
* EasyLink client
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @param userInfo: Authentication data string.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_delegate_config_recv_auth_data( char * userInfo );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that Easylink configuration is success.
|
||||
* (MiCO has connect to wlan with the ssid and key)
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @param source: The configuration mode used by EasyLink client
|
||||
* @retval None
|
||||
*/
|
||||
void mico_system_delegate_config_success( mico_config_source_t source );
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
||||
/** @defgroup system_monitor System Monitor Functions
|
||||
* @brief Create monitors in MiCO. Monitors should be updated periodically,
|
||||
* if not, a system reboot will perform.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @brief Structure to hold information about a system monitor item
|
||||
* Application should not destroy or modify a system monitor item
|
||||
*/
|
||||
typedef struct _mico_system_monitor_t
|
||||
{
|
||||
uint32_t last_update; /**< Time of the last system monitor update */
|
||||
uint32_t longest_permitted_delay; /**< Longest permitted delay between checkins with the system monitor */
|
||||
} mico_system_monitor_t;
|
||||
|
||||
/**
|
||||
* @brief Start the system monitor daemon
|
||||
* @note This function can be called automatically by mico_system_init( )
|
||||
* if macro: MICO_SYSTEM_MONITOR_ENABLE is defined
|
||||
* @retval None
|
||||
*/
|
||||
OSStatus mico_system_monitor_daemen_start( void );
|
||||
|
||||
/**
|
||||
* @brief Register a system monitor point
|
||||
* @param system_monitor: The address of a system monitor item.
|
||||
* @param initial_permitted_delay: Longest permitted delay between checkins with the system monitor.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_monitor_register( mico_system_monitor_t* system_monitor, uint32_t initial_permitted_delay );
|
||||
|
||||
/**
|
||||
* @brief Perform a system monitor point checkin
|
||||
* @param system_monitor: The address of a system monitor item.
|
||||
* @param permitted_delay: The next permitted delay on the next checkin with the system monitor.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_monitor_update ( mico_system_monitor_t* system_monitor, uint32_t permitted_delay );
|
||||
|
||||
/**
|
||||
*
|
||||
@}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup system_power System Power Management Functions
|
||||
* @brief Perform a safety power status change on MiCO.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Perform a system power change.
|
||||
* @note This function can be used only after power management daemon is started
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_power_perform( mico_Context_t* const in_context, mico_system_state_t new_state );
|
||||
/** @} */
|
||||
|
||||
/*****************************************************************************/
|
||||
/** @defgroup system_notify System Notify Functions
|
||||
* @brief Register a user function to a MiCO notification, this function will
|
||||
* be called when a MiCO notification is triggered
|
||||
* @{
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef notify_wlan_t WiFiEvent;
|
||||
|
||||
/** @brief MICO system defined notifications */
|
||||
typedef enum{
|
||||
|
||||
mico_notify_WIFI_SCAN_COMPLETED, /**< A wlan scan is completed, type: void (*function)(ScanResult *pApList, void* arg)*/
|
||||
mico_notify_WIFI_STATUS_CHANGED, /**< Wlan connection status is changed, type: void (*function)(WiFiEvent status, void* arg)*/
|
||||
mico_notify_WiFI_PARA_CHANGED, /**< Wlan parameters has received (channel, BSSID, key...), called when connect to a wlan, type: void (*function)(apinfo_adv_t *ap_info, char *key, int key_len, void* arg)*/
|
||||
mico_notify_DHCP_COMPLETED, /**< MiCO has get the IP address from DHCP server, type: void (*function)(IPStatusTypedef *pnet, void* arg)*/
|
||||
mico_notify_EASYLINK_WPS_COMPLETED, /**< EasyLink receive SSID, Key, type: void (*function)(network_InitTypeDef_st *nwkpara, void* arg)*/
|
||||
mico_notify_EASYLINK_GET_EXTRA_DATA, /**< EasyLink receive extra data, type: void (*function)(int datalen, char*data, void* arg)*/
|
||||
mico_notify_TCP_CLIENT_CONNECTED, /**< A tcp client has connected to TCP server, type: void (*function)(int fd, void* arg)*/
|
||||
mico_notify_DNS_RESOLVE_COMPLETED, /**< A DNS host address has resolved, type: void (*function)(uint8_t *hostname, uint32_t ip, void* arg)*/
|
||||
mico_notify_SYS_WILL_POWER_OFF, /**< System power will be turned off, type: void (*function)(void* arg)*/
|
||||
mico_notify_WIFI_CONNECT_FAILED, /**< A wlan connection attemption is failed, type: void join_fail(OSStatus err, void* arg)*/
|
||||
mico_notify_WIFI_SCAN_ADV_COMPLETED, /**< A anvanced wlan scan is completed, type: void (*function)(ScanResult_adv *pApList, void* arg)*/
|
||||
mico_notify_WIFI_Fatal_ERROR, /**< A fatal error occured when communicating with wlan sub-system, type: void (*function)(void* arg)*/
|
||||
mico_notify_Stack_Overflow_ERROR, /**< A MiCO RTOS thread's stack is over-flowed, type: void (*function)(char *taskname, void* arg)*/
|
||||
|
||||
} mico_notify_types_t;
|
||||
|
||||
/**
|
||||
* @brief Register a user function to a MiCO notification.
|
||||
* @param notify_type: The type of MiCO notification.
|
||||
* @param functionAddress: The address of user function.
|
||||
* @param arg: The address of argument, which will be called by registered user function.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_notify_register( mico_notify_types_t notify_type, void* functionAddress, void* arg );
|
||||
|
||||
/**
|
||||
* @brief Remove a user function from a MiCO notification.
|
||||
* @param notify_type: The type of MiCO notification.
|
||||
* @param functionAddress: The address of user function.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_notify_remove( mico_notify_types_t notify_type, void *functionAddress );
|
||||
|
||||
/**
|
||||
* @brief Remove all user function from a MiCO notification.
|
||||
* @param notify_type: The type of MiCO notification.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mico_system_notify_remove_all( mico_notify_types_t notify_type);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup config_server System Config Server Daemon
|
||||
* @brief Local network service, used to change MiCO system's configurations
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start local config server.
|
||||
* @note This function can be called automatically by mico_system_init( )
|
||||
* if macro: MICO_CONFIG_SERVER_ENABLE is defined.
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_start ( void );
|
||||
|
||||
/**
|
||||
* @brief Stop local config server.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_stop ( void );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that configuration data is received from
|
||||
* config client
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @param key: The name of a configuration item.
|
||||
* @param value: The value of a configuration item, can be read use a json_object_get_xxx
|
||||
* function from json_c library.
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval None.
|
||||
*/
|
||||
void config_server_delegate_recv( const char *key, json_object *value, bool *need_reboot, mico_Context_t *in_context );
|
||||
|
||||
/**
|
||||
* @brief Inform the application that configuration server is collecting application's config data
|
||||
* @note This a delegate function, can be completed by developer.
|
||||
* @param config_cell_list: The UI element container to store application's config data.
|
||||
* Developer can use config_server_create_xxx_cell functions to add customized UI element
|
||||
* to config_cell_list.
|
||||
* @param in_context: The address of the core data.
|
||||
* @retval None.
|
||||
*/
|
||||
void config_server_delegate_report( json_object *config_cell_list, mico_Context_t *in_context );
|
||||
|
||||
/**
|
||||
* @brief Add a cell UI holds a string value. config_cell_list(1)<=config_cell(1).
|
||||
* @param config_cell_list: The config cell container.
|
||||
* @param name: String indicate the name of a config data.
|
||||
* @param content: String value of a config data.
|
||||
* @param privilege: The privilege of a value on config client.
|
||||
* @arg "RO": Read only. @arg "RW": Read or write.
|
||||
* @param secectionArray: Generate a selection list for possible value, input NULL if not exist
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_create_string_cell (json_object* config_cell_list, char* const name, char* const content, char* const privilege, json_object* secectionArray);
|
||||
|
||||
/**
|
||||
* @brief Add a cell UI holds a integer value. config_cell_list(1)<=config_cell(1).
|
||||
* @param config_cell_list: The config cell container.
|
||||
* @param name: String indicate the name of a config data.
|
||||
* @param content: Integer value of a config data.
|
||||
* @param privilege: The privilege of a value on config client.
|
||||
* @arg "RO": Read only. @arg "RW": Read or write.
|
||||
* @param secectionArray: Generate a selection list for possible value, input NULL if not exist
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_create_number_cell (json_object* config_cell_list, char* const name, int content, char* const privilege, json_object* secectionArray);
|
||||
|
||||
/**
|
||||
* @brief Add a cell UI holds a float value. config_cell_list(1)<=config_cell(1).
|
||||
* @param config_cell_list: The config cell container.
|
||||
* @param name: String indicate the name of a config data.
|
||||
* @param content: Float value of a config data.
|
||||
* @param privilege: The privilege of a value on config client.
|
||||
* @arg "RO": Read only. @arg "RW": Read or write.
|
||||
* @param secectionArray: Generate a selection list for possible value
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_create_float_cell (json_object* config_cell_list, char* const name, float content, char* const privilege, json_object* secectionArray);
|
||||
|
||||
/**
|
||||
* @brief Add a cell UI holds a bool value. config_cell_list(1)<=config_cell(1).
|
||||
* @param config_cell_list: The config cell container.
|
||||
* @param name: String indicate the name of a config data.
|
||||
* @param content: Bool value of a config data.
|
||||
* @param privilege: The privilege of a value on config client.
|
||||
* @arg "RO": Read only. @arg "RW": Read or write.
|
||||
* @param secectionArray: Generate a selection list for possible value
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_create_bool_cell (json_object* config_cell_list, char* const name, boolean content, char* const privilege);
|
||||
|
||||
/**
|
||||
* @brief Add a cell UI holds a sub menu, config_cell_list(1)<=sub_menu_array(1).
|
||||
* @param config_cell_list: The config cell container.
|
||||
* @param name: String indicate the name of a sub menu.
|
||||
* @param sub_menu_array: An array that buids a sub menu list.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_create_sub_menu_cell (json_object* config_cell_list, char* const name, json_object* sub_menu_array);
|
||||
|
||||
/**
|
||||
* @brief Create a new config cell list to an exist menu. sub_menu_array(1)<=config_cell_list(n)
|
||||
* @param sub_menu_array: An array that buids a sub menu list.
|
||||
* @param name: String indicate the name of a config cell list.
|
||||
* @param config_cell_list: The config cell container.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus config_server_create_sector (json_object* sub_menu_array, char* const name, json_object *config_cell_list);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** \defgroup cli System Command Line Interface
|
||||
* @brief MiCO command console
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the CLI module
|
||||
* @note This function can be called automatically by mico_system_init( )
|
||||
* if macro: MICO_CLI_ENABLE is defined.
|
||||
* @retval 0 is returned on success, otherwise, -1 is returned.
|
||||
*/
|
||||
//int cli_init(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
/** @defgroup system_mdns System mDNS service functions
|
||||
* @brief Multicast DNS is a way of using familiar DNS programming interfaces,
|
||||
* packet formats and operating semantics, in a small network.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @brief Structure to store mDNS record data
|
||||
*/
|
||||
|
||||
enum mdns_record_state_e{
|
||||
RECORD_REMOVED, /**< The service and resources are removed. */
|
||||
RECORD_UPDATE, /**< The service record is updating, mdns routine will announce the new service content. */
|
||||
RECORD_REMOVE, /**< The service record is removing, mdns routine will announce the service with TTL = 0 for
|
||||
1 second, resources will be removed after the announce period */
|
||||
RECORD_SUSPEND, /**< The service record is suspended, mdns routine will announce the service with TTL = 0 for
|
||||
1 second and not respond the mdns query. */
|
||||
RECORD_NORMAL, /**< The service can respond to mdns query . */
|
||||
};
|
||||
typedef uint8_t mdns_record_state_t;
|
||||
|
||||
typedef struct _mdns_init_t
|
||||
{
|
||||
char *service_name; /**< The service name of a mDNS record, example: "_easylink_config._tcp.local." */
|
||||
char *host_name; /**< The host name of a mDNS record, example: "device_name.local." */
|
||||
char *instance_name; /**< The instance name of a mDNS record, example: "device_name" */
|
||||
char *txt_record; /**< Txt record holds customized info, every info is seperated by '.',
|
||||
the orginal '.' is replaced by "/.", example: "record/.1=1.record/.2=2/.3" */
|
||||
uint16_t service_port; /**< Service port */
|
||||
} mdns_init_t;
|
||||
|
||||
/**
|
||||
* @brief Add a new mDNS record, a mDNS service daemon will be start if necessary
|
||||
* @param record: mDNS record data.
|
||||
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
|
||||
* @param time_to_live: The TTL of a mDNS record.
|
||||
* @retval kNoErr is returned on success, otherwise, kXXXErr is returned.
|
||||
*/
|
||||
OSStatus mdns_add_record( mdns_init_t record, hal_wifi_type_t interface, uint32_t time_to_live );
|
||||
|
||||
/**
|
||||
* @brief Suspend a mDNS record, announce the TTL of this record equal to zero, and do not respond mDNS request
|
||||
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
|
||||
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
|
||||
* @param will_remove: Destory record info from memory after announced.
|
||||
* @retval None.
|
||||
*/
|
||||
void mdns_suspend_record( char *service_name, hal_wifi_type_t interface, bool will_remove );
|
||||
|
||||
/**
|
||||
* @brief Resume a suspended mDNS record, announce the TTL of this record to orginal value, and respond to following mDNS request
|
||||
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
|
||||
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
|
||||
* @retval None.
|
||||
*/
|
||||
void mdns_resume_record( char *service_name, hal_wifi_type_t interface );
|
||||
|
||||
/**
|
||||
* @brief Update txt record with a new value
|
||||
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
|
||||
* @param interface: Which network interface, the IP info will be read from when response a nDNS request.
|
||||
* @param txt_record: Txt record holds customized info, every info is seperated by '.', the orginal '.' is
|
||||
* replaced by "/.", example: "record/.1=1.record/.2=2/.3" = "record.1=1" and "record.2=2.3"
|
||||
* @retval None.
|
||||
*/
|
||||
void mdns_update_txt_record( char *service_name, hal_wifi_type_t interface, char *txt_record );
|
||||
|
||||
/**
|
||||
* @brief Get mdns service status
|
||||
* @param service_name: The service name of a mDNS record. example: "_easylink_config._tcp.local."
|
||||
* @param interface: network interface, the mdns service is bonded
|
||||
* @retval @ref mdns_record_state_t.
|
||||
*/
|
||||
mdns_record_state_t mdns_get_record_status( char *service_name, hal_wifi_type_t interface);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @defgroup system_time MiCO System time functions
|
||||
* @brief Functions to get and set the real-time-clock time.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** ISO8601 Time Structure
|
||||
*/
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char year[4]; /**< Year */
|
||||
char dash1; /**< Dash1 */
|
||||
char month[2]; /**< Month */
|
||||
char dash2; /**< Dash2 */
|
||||
char day[2]; /**< Day */
|
||||
char T; /**< T */
|
||||
char hour[2]; /**< Hour */
|
||||
char colon1; /**< Colon1 */
|
||||
char minute[2]; /**< Minute */
|
||||
char colon2; /**< Colon2 */
|
||||
char second[2]; /**< Second */
|
||||
char decimal; /**< Decimal */
|
||||
char sub_second[6]; /**< Sub-second */
|
||||
char Z; /**< UTC timezone */
|
||||
} iso8601_time_t;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/** Get the current system tick time in milliseconds
|
||||
*
|
||||
* @note The time will roll over every 49.7 days
|
||||
*
|
||||
* @param[out] time : A pointer to the variable which will receive the time value
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_get_time( mico_time_t* time );
|
||||
|
||||
|
||||
/** Set the current system tick time in milliseconds
|
||||
*
|
||||
* @param[in] time : the time value to set
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_set_time( const mico_time_t* time );
|
||||
|
||||
|
||||
/** Get the current UTC time in seconds
|
||||
*
|
||||
* This will only be accurate if the time has previously been set by using @ref mico_time_set_utc_time_ms
|
||||
*
|
||||
* @param[out] utc_time : A pointer to the variable which will receive the time value
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_get_utc_time( mico_utc_time_t* utc_time );
|
||||
|
||||
|
||||
/** Get the current UTC time in milliseconds
|
||||
*
|
||||
* This will only be accurate if the time has previously been set by using @ref mico_time_set_utc_time_ms
|
||||
*
|
||||
* @param[out] utc_time_ms : A pointer to the variable which will receive the time value
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_get_utc_time_ms( mico_utc_time_ms_t* utc_time_ms );
|
||||
|
||||
|
||||
/** Set the current UTC time in milliseconds
|
||||
*
|
||||
* @param[in] utc_time_ms : the time value to set
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_set_utc_time_ms( const mico_utc_time_ms_t* utc_time_ms );
|
||||
|
||||
|
||||
/** Get the current UTC time in iso 8601 format e.g. "2012-07-02T17:12:34.567890Z"
|
||||
*
|
||||
* @note The time will roll over every 49.7 days
|
||||
*
|
||||
* @param[out] iso8601_time : A pointer to the structure variable that
|
||||
* will receive the time value
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_get_iso8601_time( iso8601_time_t* iso8601_time );
|
||||
|
||||
|
||||
/** Convert a time from UTC milliseconds to iso 8601 format e.g. "2012-07-02T17:12:34.567890Z"
|
||||
*
|
||||
* @param[in] utc_time_ms : the time value to convert
|
||||
* @param[out] iso8601_time : A pointer to the structure variable that
|
||||
* will receive the time value
|
||||
*
|
||||
* @return @ref OSStatus
|
||||
*/
|
||||
OSStatus mico_time_convert_utc_ms_to_iso8601( mico_utc_time_ms_t utc_time_ms, iso8601_time_t* iso8601_time );
|
||||
|
||||
|
||||
#define MicoNanosendDelay mico_nanosecond_delay
|
||||
/** Delay a period of time
|
||||
*
|
||||
* @param[in] delayus : the time value to set ( unit: nanosecond )
|
||||
*
|
||||
* @return none: this function will block until target time is reached
|
||||
*/
|
||||
void mico_nanosecond_delay( uint64_t delayus );
|
||||
|
||||
/** Get current nanosecond time
|
||||
*
|
||||
* @return current nanosecond time
|
||||
*/
|
||||
uint64_t mico_nanosecond_clock_value( void );
|
||||
|
||||
/** Set current nanosecond time to zero
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void mico_nanosecond_reset( void );
|
||||
|
||||
/** Initialisse nanosecond counter function
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void mico_nanosecond_init( void );
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup tftp_ota Firmware Update From a TFTP Server
|
||||
* @brief Provide an easy way to download firmware from tftp server, use a
|
||||
* predefined wlan and server address. It is used under factory environment
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get new firmware from a TFTP Server, and replace the old one
|
||||
* @retval None.
|
||||
*/
|
||||
void tftp_ota(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define MICO_BT_PARA_LOCAL_KEY_DATA 65 /* BTM_SECURITY_LOCAL_KEY_DATA_LEN */
|
||||
|
||||
#define MICO_BT_DCT_NAME 249
|
||||
#define MICO_BT_DCT_MAX_KEYBLOBS 146 /* Maximum size of key blobs to be stored := size of BR-EDR link keys + size of BLE keys*/
|
||||
#define MICO_BT_DCT_ADDR_FIELD 6
|
||||
#define MICO_BT_DCT_LENGTH_FIELD 2
|
||||
#ifndef MICO_BT_DCT_MAX_DEVICES
|
||||
#define MICO_BT_DCT_MAX_DEVICES 10 /* Maximum number of device records stored in nvram */
|
||||
#endif
|
||||
#define MICO_BT_DCT_ADDR_TYPE 1
|
||||
#define MICO_BT_DCT_DEVICE_TYPE 1
|
||||
|
||||
/* Length of BD_ADDR + 2bytes length field */
|
||||
#define MICO_BT_DCT_ENTRY_HDR_LENGTH (MICO_BT_DCT_ADDR_FIELD + MICO_BT_DCT_LENGTH_FIELD + MICO_BT_DCT_ADDR_TYPE + MICO_BT_DCT_DEVICE_TYPE)
|
||||
|
||||
#define MICO_BT_DCT_LOCAL_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_local_key )
|
||||
#define MICO_BT_DCT_REMOTE_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_remote_key )
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
// uint8_t bluetooth_local_addeess[6];
|
||||
// uint8_t bluetooth_local_name[249]; /* including null termination */
|
||||
uint8_t bluetooth_local_key[MICO_BT_PARA_LOCAL_KEY_DATA];
|
||||
uint8_t bluetooth_remote_key[MICO_BT_DCT_ENTRY_HDR_LENGTH + MICO_BT_DCT_MAX_KEYBLOBS][MICO_BT_DCT_MAX_DEVICES];
|
||||
uint8_t padding[1]; /* to ensure 32-bit aligned size */
|
||||
} mico_bt_config_t;
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
90
Living_SDK/kernel/vcall/mico/include/platform_toolchain.h
Normal file
90
Living_SDK/kernel/vcall/mico/include/platform_toolchain.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Macros
|
||||
******************************************************/
|
||||
|
||||
#ifndef WEAK
|
||||
#ifndef __MINGW32__
|
||||
#define WEAK __attribute__((weak))
|
||||
#else
|
||||
/* MinGW doesn't support weak */
|
||||
#define WEAK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USED
|
||||
#define USED __attribute__((used))
|
||||
#endif
|
||||
|
||||
#ifndef MAY_BE_UNUSED
|
||||
#define MAY_BE_UNUSED __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef NORETURN
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGNED
|
||||
#define ALIGNED(size) __attribute__((aligned(size)))
|
||||
#endif
|
||||
|
||||
#ifndef SECTION
|
||||
#define SECTION(name) __attribute__((section(name)))
|
||||
#endif
|
||||
|
||||
#ifndef NEVER_INLINE
|
||||
#define NEVER_INLINE __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
#ifndef ALWAYS_INLINE
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* Constants
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Enumerations
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Type Definitions
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Structures
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Global Variables
|
||||
******************************************************/
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
|
||||
void *memrchr( const void *s, int c, size_t n );
|
||||
|
||||
|
||||
/* Windows doesn't come with support for strlcpy */
|
||||
#ifdef WIN32
|
||||
size_t strlcpy (char *dest, const char *src, size_t size);
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
595
Living_SDK/kernel/vcall/mico/mico_rhino.c
Normal file
595
Living_SDK/kernel/vcall/mico/mico_rhino.c
Normal file
|
|
@ -0,0 +1,595 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <k_api.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "mico_rtos.h"
|
||||
#include "mico_rtos_common.h"
|
||||
#include "common.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
event_handler_t function;
|
||||
void* arg;
|
||||
} mico_event_message_t;
|
||||
|
||||
OSStatus mico_rtos_create_thread( mico_thread_t* thread, uint8_t priority, const char* name, mico_thread_function_t function, uint32_t stack_size, mico_thread_arg_t arg )
|
||||
{
|
||||
kstat_t ret;
|
||||
ktask_t *task_tmp;
|
||||
|
||||
if (thread == NULL) {
|
||||
ret = krhino_task_dyn_create(&task_tmp, name, (void *)arg, priority, 0, stack_size/4, (task_entry_t)function, 1);
|
||||
} else {
|
||||
ret = krhino_task_dyn_create((ktask_t **)thread, name, (void *)arg, priority, 0, stack_size/4, (task_entry_t)function, 1);
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_delete_thread( mico_thread_t* thread )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (thread == NULL) {
|
||||
ret = krhino_task_dyn_del(NULL);
|
||||
} else {
|
||||
ret = krhino_task_dyn_del(*((ktask_t **)thread));
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
void mico_rtos_suspend_thread(mico_thread_t* thread)
|
||||
{
|
||||
if (thread == NULL) {
|
||||
krhino_task_suspend(krhino_cur_task_get());
|
||||
}
|
||||
else {
|
||||
krhino_task_suspend(*((ktask_t **)thread));
|
||||
}
|
||||
}
|
||||
|
||||
void mico_rtos_suspend_all_thread(void)
|
||||
{
|
||||
krhino_sched_disable();
|
||||
}
|
||||
|
||||
long mico_rtos_resume_all_thread(void)
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sched_enable();
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_thread_join( mico_thread_t* thread )
|
||||
{
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus mico_rtos_thread_force_awake( mico_thread_t* thread )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_task_wait_abort(*((ktask_t **)thread));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
|
||||
bool mico_rtos_is_current_thread( mico_thread_t* thread )
|
||||
{
|
||||
ktask_t *t;
|
||||
|
||||
t = *((ktask_t **)thread);
|
||||
|
||||
if (t == krhino_cur_task_get()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_delay_milliseconds( uint32_t num_ms )
|
||||
{
|
||||
uint32_t ticks;
|
||||
|
||||
ticks = krhino_ms_to_ticks(num_ms);
|
||||
if (ticks == 0) {
|
||||
ticks = 1;
|
||||
}
|
||||
|
||||
krhino_task_sleep(ticks);
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_print_thread_status( char* pcWriteBuffer, int xWriteBufferLen )
|
||||
{
|
||||
pcWriteBuffer[0] = 'n';
|
||||
pcWriteBuffer[1] = '\0';
|
||||
|
||||
(void)xWriteBufferLen;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_init_semaphore( mico_semaphore_t* semaphore, int count )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sem_dyn_create((ksem_t **)semaphore, "sema", 0);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_set_semaphore( mico_semaphore_t* semaphore )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sem_give(*((ksem_t **)semaphore));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_get_semaphore( mico_semaphore_t* semaphore, uint32_t timeout_ms )
|
||||
{
|
||||
kstat_t ret;
|
||||
tick_t ticks;
|
||||
|
||||
if (timeout_ms == MICO_NEVER_TIMEOUT) {
|
||||
ret = krhino_sem_take(*((ksem_t **)semaphore), RHINO_WAIT_FOREVER);
|
||||
}
|
||||
else {
|
||||
ticks = krhino_ms_to_ticks(timeout_ms);
|
||||
ret = krhino_sem_take(*((ksem_t **)semaphore), ticks);
|
||||
}
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_deinit_semaphore( mico_semaphore_t* semaphore )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_sem_dyn_del(*((ksem_t **)semaphore));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_init_mutex( mico_mutex_t* mutex )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mutex_dyn_create((kmutex_t **)mutex, "mutex");
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_lock_mutex( mico_mutex_t* mutex )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mutex_lock(*((kmutex_t **)mutex), RHINO_WAIT_FOREVER);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_unlock_mutex( mico_mutex_t* mutex )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mutex_unlock(*((kmutex_t **)mutex));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_deinit_mutex( mico_mutex_t* mutex )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_mutex_dyn_del(*((kmutex_t **)mutex));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_init_queue( mico_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
if (name == NULL) {
|
||||
name = "default_queue";
|
||||
}
|
||||
|
||||
ret = krhino_buf_queue_dyn_create((kbuf_queue_t **)queue, name, number_of_messages * (message_size + COMPRESS_LEN(message_size)), message_size);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus mico_rtos_push_to_queue( mico_queue_t* queue, void* message, uint32_t timeout_ms )
|
||||
{
|
||||
kstat_t ret;
|
||||
kbuf_queue_t *q = *((kbuf_queue_t **)queue);
|
||||
|
||||
timeout_ms = timeout_ms;
|
||||
|
||||
ret = krhino_buf_queue_send(q, message, q->max_msg_size);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_pop_from_queue( mico_queue_t* queue, void* message, uint32_t timeout_ms )
|
||||
{
|
||||
kstat_t ret;
|
||||
size_t msg_len;
|
||||
|
||||
ret = krhino_buf_queue_recv(*((kbuf_queue_t **)queue), krhino_ms_to_ticks(timeout_ms), message, &msg_len);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_deinit_queue( mico_queue_t* queue )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_buf_queue_dyn_del(*((kbuf_queue_t **)queue));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
|
||||
bool mico_rtos_is_queue_empty( mico_queue_t* queue )
|
||||
{
|
||||
bool ret;
|
||||
CPSR_ALLOC();
|
||||
|
||||
kbuf_queue_t *q = *((kbuf_queue_t **)queue);
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
if (q->cur_num == 0) {
|
||||
ret = true;
|
||||
}
|
||||
else {
|
||||
ret = false;;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool mico_rtos_is_queue_full( mico_queue_t* queue )
|
||||
{
|
||||
bool ret;
|
||||
CPSR_ALLOC();
|
||||
|
||||
kbuf_queue_t *q = *((kbuf_queue_t **)queue);
|
||||
uint32_t max_msg_num;
|
||||
|
||||
RHINO_CRITICAL_ENTER();
|
||||
|
||||
max_msg_num = (q->ringbuf.end - q->ringbuf.buf) / (q->max_msg_size + COMPRESS_LEN(q->max_msg_size));
|
||||
|
||||
if (q->cur_num == max_msg_num) {
|
||||
ret = true;
|
||||
}
|
||||
else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
RHINO_CRITICAL_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
mico_time_t mico_rtos_get_time( void )
|
||||
{
|
||||
return krhino_ticks_to_ms(krhino_sys_tick_get());
|
||||
}
|
||||
|
||||
static void timmer_wrapper(void *timer, void *arg)
|
||||
{
|
||||
(void)timer;
|
||||
|
||||
mico_timer_t *timer_arg = arg;
|
||||
|
||||
if (timer_arg->function != 0) {
|
||||
timer_arg->function(timer_arg->arg);
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_init_timer( mico_timer_t* timer, uint32_t time_ms, timer_handler_t function, void* arg )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
timer->function = function;
|
||||
timer->arg = arg;
|
||||
|
||||
ret = krhino_timer_dyn_create((ktimer_t **)(&timer->handle),"timer", timmer_wrapper,
|
||||
krhino_ms_to_ticks(time_ms), krhino_ms_to_ticks(time_ms), timer, 0);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_init_oneshot_timer( mico_timer_t* timer, uint32_t time_ms, timer_handler_t function, void* arg )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
timer->function = function;
|
||||
timer->arg = arg;
|
||||
|
||||
ret = krhino_timer_dyn_create((ktimer_t **)(&timer->handle),"timer", timmer_wrapper,
|
||||
krhino_ms_to_ticks(time_ms), 0, timer, 0);
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus mico_rtos_start_timer( mico_timer_t* timer )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_timer_start((ktimer_t *)(timer->handle));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_stop_timer( mico_timer_t* timer )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
ret = krhino_timer_stop((ktimer_t *)(timer->handle));
|
||||
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
|
||||
OSStatus mico_rtos_reload_timer( mico_timer_t* timer )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
|
||||
krhino_timer_stop((ktimer_t *)(timer->handle));
|
||||
|
||||
ret = krhino_timer_start((ktimer_t *)(timer->handle));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_deinit_timer( mico_timer_t* timer )
|
||||
{
|
||||
kstat_t ret;
|
||||
|
||||
|
||||
krhino_timer_stop((ktimer_t *)(timer->handle));
|
||||
ret = krhino_timer_dyn_del((ktimer_t *)(timer->handle));
|
||||
|
||||
if (ret == RHINO_SUCCESS) {
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
bool mico_rtos_is_timer_running( mico_timer_t* timer )
|
||||
{
|
||||
ktimer_t *t;
|
||||
|
||||
t = (ktimer_t *)timer->handle;
|
||||
|
||||
if (t->timer_state == TIMER_ACTIVE) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mico_rtos_is_timer_init( mico_timer_t* timer )
|
||||
{
|
||||
if (timer == NULL)
|
||||
return false;
|
||||
if (timer->handle == NULL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void worker_thread_main( uint32_t arg )
|
||||
{
|
||||
mico_worker_thread_t* worker_thread = (mico_worker_thread_t*) arg;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
mico_event_message_t message;
|
||||
|
||||
if ( mico_rtos_pop_from_queue( &worker_thread->event_queue, &message, MICO_WAIT_FOREVER ) == kNoErr )
|
||||
{
|
||||
message.function( message.arg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_create_worker_thread( mico_worker_thread_t* worker_thread, uint8_t priority, uint32_t stack_size, uint32_t event_queue_size )
|
||||
{
|
||||
memset( worker_thread, 0, sizeof( *worker_thread ) );
|
||||
|
||||
if ( mico_rtos_init_queue( &worker_thread->event_queue, "worker queue", sizeof(mico_event_message_t), event_queue_size ) != kNoErr )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
if ( mico_rtos_create_thread( &worker_thread->thread, priority , "worker thread", worker_thread_main, stack_size, (mico_thread_arg_t) worker_thread ) != kNoErr )
|
||||
{
|
||||
mico_rtos_deinit_queue( &worker_thread->event_queue );
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_delete_worker_thread( mico_worker_thread_t* worker_thread )
|
||||
{
|
||||
if ( mico_rtos_delete_thread( &worker_thread->thread ) != kNoErr )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
if ( mico_rtos_deinit_queue( &worker_thread->event_queue ) != kNoErr )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_send_asynchronous_event( mico_worker_thread_t* worker_thread, event_handler_t function, void* arg )
|
||||
{
|
||||
mico_event_message_t message;
|
||||
|
||||
if( worker_thread->thread == NULL )
|
||||
return kNotInitializedErr;
|
||||
|
||||
message.function = function;
|
||||
message.arg = arg;
|
||||
|
||||
return mico_rtos_push_to_queue( &worker_thread->event_queue, &message, MICO_NO_WAIT );
|
||||
}
|
||||
|
||||
static void timed_event_handler( void* arg )
|
||||
{
|
||||
mico_timed_event_t* event_object = (mico_timed_event_t*) arg;
|
||||
mico_event_message_t message;
|
||||
|
||||
message.function = event_object->function;
|
||||
message.arg = event_object->arg;
|
||||
|
||||
mico_rtos_push_to_queue( &event_object->thread->event_queue, &message, MICO_NO_WAIT );
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_register_timed_event( mico_timed_event_t* event_object, mico_worker_thread_t* worker_thread, event_handler_t function, uint32_t time_ms, void* arg )
|
||||
{
|
||||
if( worker_thread->thread == NULL )
|
||||
return kNotInitializedErr;
|
||||
|
||||
if ( mico_rtos_init_timer( &event_object->timer, time_ms, timed_event_handler, (void*) event_object ) != kNoErr )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
event_object->function = function;
|
||||
event_object->thread = worker_thread;
|
||||
event_object->arg = arg;
|
||||
|
||||
if ( mico_rtos_start_timer( &event_object->timer ) != kNoErr )
|
||||
{
|
||||
mico_rtos_deinit_timer( &event_object->timer );
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_rtos_deregister_timed_event( mico_timed_event_t* event_object )
|
||||
{
|
||||
if ( mico_rtos_deinit_timer( &event_object->timer ) != kNoErr )
|
||||
{
|
||||
return kGeneralErr;
|
||||
}
|
||||
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
29
Living_SDK/kernel/vcall/ucube.py
Normal file
29
Living_SDK/kernel/vcall/ucube.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
src = []
|
||||
|
||||
component = aos_component('vcall', src)
|
||||
component.add_global_includes('mico/include')
|
||||
|
||||
if aos_global_config.arch == 'ARM968E-S':
|
||||
component.add_cflags('-marm')
|
||||
|
||||
@pre_config('vcall')
|
||||
def vcall_pre(comp):
|
||||
vcall = aos_global_config.get('vcall', 'rhino')
|
||||
if vcall == 'freertos':
|
||||
comp.add_global_macros('VCALL_FREERTOS')
|
||||
comp.add_sources('aos/aos_freertos.c')
|
||||
elif vcall == 'posix':
|
||||
comp.add_global_macros('VCALL_POSIX')
|
||||
comp.add_sources('aos/aos_posix.c')
|
||||
else:
|
||||
comp.add_global_macros('VCALL_RHINO')
|
||||
comp.add_comp_deps('kernel/rhino')
|
||||
|
||||
if aos_global_config.mcu_family == 'esp32' or aos_global_config.mcu_family == 'esp8266':
|
||||
comp.add_comp_deps('kernel/vcall/espos')
|
||||
|
||||
if aos_global_config.board == 'linuxhost' or aos_global_config.board == 'mk3060' \
|
||||
or aos_global_config.board == 'mk3239' or aos_global_config.board == 'mk3166' or aos_global_config.board == 'mk3165':
|
||||
comp.add_sources('mico/mico_rhino.c')
|
||||
comp.add_sources('aos/aos_rhino.c')
|
||||
vcall_pre(component)
|
||||
54
Living_SDK/kernel/vcall/vcall.mk
Normal file
54
Living_SDK/kernel/vcall/vcall.mk
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
NAME := vcall
|
||||
|
||||
$(NAME)_TYPE := kernel
|
||||
$(NAME)_MBINS_TYPE := share
|
||||
|
||||
GLOBAL_INCLUDES += ./mico/include
|
||||
|
||||
#default gcc
|
||||
ifeq ($(COMPILER),)
|
||||
$(NAME)_CFLAGS += -Wall -Werror
|
||||
else ifeq ($(COMPILER),gcc)
|
||||
$(NAME)_CFLAGS += -Wall -Werror
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_ARCH),ARM968E-S)
|
||||
$(NAME)_CFLAGS += -marm
|
||||
endif
|
||||
|
||||
vcall ?= rhino
|
||||
|
||||
ifeq ($(vcall),freertos)
|
||||
GLOBAL_DEFINES += VCALL_FREERTOS
|
||||
|
||||
$(NAME)_SOURCES += \
|
||||
aos/aos_freertos.c
|
||||
endif
|
||||
|
||||
ifeq ($(vcall),posix)
|
||||
GLOBAL_DEFINES += VCALL_POSIX
|
||||
|
||||
$(NAME)_SOURCES += \
|
||||
aos/aos_posix.c
|
||||
endif
|
||||
|
||||
ifeq ($(vcall),rhino)
|
||||
GLOBAL_DEFINES += VCALL_RHINO
|
||||
$(NAME)_COMPONENTS += rhino
|
||||
|
||||
ifeq ($(HOST_MCU_FAMILY),esp32)
|
||||
$(NAME)_COMPONENTS += vcall.espos
|
||||
else
|
||||
ifeq ($(HOST_MCU_FAMILY),esp8266)
|
||||
$(NAME)_COMPONENTS += vcall.espos
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(PLATFORM), linuxhost mk3060 mk3239 mk3166 mk3165))
|
||||
$(NAME)_SOURCES += mico/mico_rhino.c
|
||||
endif
|
||||
|
||||
$(NAME)_SOURCES += \
|
||||
aos/aos_rhino.c
|
||||
endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue