简体中文
简体中文
English
联系我们
注册
登录
layout空间导航

API 函数接口介绍

更新时间:2022-03-29 02:19:35下载pdf

教程主要介绍和 Tuya IoT OS API 相关的函数接口,内容主要包括:

Log 打印和错误码介绍
线程
软件定时器
内存管理
信号量
互斥量
队列

本文 Github 仓库地址:https://github.com/Tuya-Community/tuya-os-api-examples

如何编译这些 examples 呢?

下面以编译 log_print_demo 为例进行演示。

API 函数接口介绍


log 打印和错误码介绍

错误码

错误码的作用:当在 SDK 开发过程中遇到程序执行错误的时,可以根据返回的错误码判断程序出现的问题。

错误码的位置:在 tuya_iot_sdk 下的 /sdk/include/tuya_error_code.h 中找到对应的 error code。


log 日志

log 日志存放位置:在 tuya iot sdk 中和日志相关的文件为 uni_log.h,该文件位置通常在 tuya_iot_sdk 下的 /sdk/include/uni_log.h

日志打印接口和日志等级接口: log 打印中常用到的函数接口为日志打印接口和日志等级接口。日志打印接口可以根据输出信息的等级不同选择不同的打印接口,还可以通过修改 log 输出等级从而控制不同等级信息的输出;同时可以用日志等级接口设置调整打印输出等级,SDK 中默认的日志等级为 DEBUG ,打印输出的东西越多系统占用的资源也就越多,会拖慢系统运行的速度和占用更多的内存,所以在功能开发完成后的正式版本中建议将日志等级设置为 NOTICE

日志打印接口如下:

函数接口 函数说明
PR_ERR(fmt, ...) 用于打印错误信息,程序正常运行不应发生的信息
PR_WARN(fmt, ...) 用于打印警告信息
PR_NOTICE(fmt, ...) 用于打印需要注意的信息
PR_INFO(fmt, ...) 用于打印通知信息
PR_DEBUG(fmt, ...) 用于打印程序运行调试信息
PR_TRACE(fmt, ...) 用于打印程序运行路径信息

日志等级接口如下:



OPERATE_RET SetLogManageAttr(IN CONST LOG_LEVEL curLogLevel);

设置 log 日志输出等级,等级越高输出信息越多。也就是说如果日志等级设置为 TY_LOG_LEVEL_TRACE 就会打印所有信息,设置为 TY_LOG_LEVEL_NOTICE 则只会打印 NOTICE, WARN, ERR 三种日志信息。

Parameters:

  • curLogLevel: 设置的 log 等级。可设置值为:

    #define TY_LOG_LEVEL_ERR       0
    #define TY_LOG_LEVEL_WARN      1
    #define TY_LOG_LEVEL_NOTICE    2
    #define TY_LOG_LEVEL_INFO      3
    #define TY_LOG_LEVEL_DEBUG     4
    #define TY_LOG_LEVEL_TRACE     5
    

Return:

  • OPRT_OK: 函数执行成功
  • other: 函数执行失败


应用示例

日志打印和设置不同日志等级的输出情况示例:根据执行的日志截图可以发现,当把日志等级设置为 TY_LOG_LEVEL_NOTICE 时,只有PR_NOTICE, PR_WARNPR_ERR 可以打印出来,而其他三个无法输出;当把日志等级设置为 TY_LOG_LEVEL_DEBUG 时,只有 PR_DEBUG, PR_INFO, PR_NOTICE, PR_WARNPR_ERR 可以打印出来,而PR_TRACE 无法输出。

点击到 GitHub 查看完整工程代码

void log_printf_demo(void)
{
    PR_NOTICE("*************************************************");
    SetLogManageAttr(TY_LOG_LEVEL_NOTICE);
    PR_NOTICE("log level is NOTICE");
    PR_ERR("This is error log");
    PR_WARN("This is warn log");
    PR_NOTICE("This is notice log");
    PR_INFO("This is info log");
    PR_DEBUG("This is debug log");
    PR_TRACE("This is trace log");
    PR_NOTICE("*************************************************");
    SetLogManageAttr(TY_LOG_LEVEL_DEBUG);
    PR_NOTICE("log level is DEBUG");
    PR_ERR("This is error log");
    PR_WARN("This is warn log");
    PR_NOTICE("This is notice log");
    PR_INFO("This is info log");
    PR_DEBUG("This is debug log");
    PR_TRACE("This is trace log");
    PR_NOTICE("*************************************************");
}

API 函数接口介绍


线程(系统)

线程的文件位置:在 tuya_iot_sdk 下的 /sdk/include/tuya_hal_thread.h

在 TuyaOS 中与线程相关的函数主要有四个接口可用,创建线程
tuya_hal_thread_create() ,释放线程 tuya_hal_thread_release() ,检查线程是否是本身 tuya_hal_thread_is_self() 和设置自身线程名称
tuya_hal_thread_set_self_name()

tuya_hal_thread_create()


int tuya_hal_thread_create(THREAD_HANDLE* thread,
                           const char* name,
                           uint32_t stack_size,
                           uint32_t priority,
                           THREAD_FUNC_T func,
                           void* const arg);

在 TuyaOS 中最常使用的便是该函数了,该函数的功能是用来创建一个线程。

Parameters:

  • thread: [out]线程句柄。

  • name: 线程的名字。

  • stack_size: 线程的栈大小,单位:bit。

  • priority: 线程的优先级。

    /* 这些关于优先级的宏定义在 /sdk/include/uni_thread.h 中,所以使用它们的时候,注意添加  uni_thread.h  的头文件 */
    #define TRD_PRIO_0     5    /* High */
    #define TRD_PRIO_1     4
    #define TRD_PRIO_2     3
    #define TRD_PRIO_3     2
    #define TRD_PRIO_4     1
    #define TRD_PRIO_5     0
    #define TRD_PRIO_6     0    /* low */
    
  • func: 线程入口函数。

  • arg: 线程入口函数的参数,可以为NULL

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_thread_release()


int tuya_hal_thread_release(THREAD_HANDLE thread);

释放创建的线程。

Parameters:

  • thread: 线程句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_thread_is_self()


int tuya_hal_thread_is_self(THREAD_HANDLE thread, BOOL_T* is_self);

用于判断当前执行线程是否为 thread 线程。

Parameters:

  • thread: 线程句柄。
  • is_self: [out] is_self == 1 当前执行的线程是 thread (这里的 thread 是指调用该函数时具体输入的线程句柄,而并非真的就是 thread);is_self == 0 当前执行的线程不是 thread

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_thread_set_self_name()


int tuya_hal_thread_set_self_name(const char* name);

更改自身线程的名字。

Parameters:

  • name: 该线程要设置的名字。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


应用示例

实际开发中创建线程和释放线程函数比较常用,检查线程是否是本身和设置自身线程名称函数使用较少。下面 Demo 主要演示如何创建和释放线程:

在 Demo 中创建了名叫 thread demo 的线程,该线程的作用是打印运行提示和线程运行的计数值 thread_demo_count ,当计数大于10的时会将 thread demo 线程释放掉,不会再打印。

点击到 GitHub 查看完整工程代码

#include "uni_log.h"
#include "uni_thread.h"
#include "tuya_error_code.h"
#include "tuya_hal_system.h"

#include "thread_demo.h"

THREAD_HANDLE thread_demo_handle = NULL;
static thread_demo_count = 0;

void thread_demo_task_func(void)
{
    OPERATE_RET op_ret = OPRT_OK;

    for (;;) {
        PR_NOTICE("thread demo is running, count: %d", thread_demo_count);
        if (thread_demo_count >= 10) {
            break;
        }

        thread_demo_count++;
        tuya_hal_system_sleep(1000);
    }

    PR_NOTICE("thread demo task will release");
    op_ret = tuya_hal_thread_release(thread_demo_handle);
    if (OPRT_OK != op_ret) {
        PR_ERR("release thread demo task failed, err_num:%d", op_ret);
        return;
    }
}

void thread_demo_init(void) 
{
    OPERATE_RET op_ret = OPRT_OK;

    op_ret = tuya_hal_thread_create(&thread_demo_handle, "thread demo", 64*8, TRD_PRIO_4, thread_demo_task_func, NULL);
    if (op_ret != OPRT_OK) {
        PR_ERR("creat thread demo task failed, err_num:%d", op_ret);
        return;
    }
}

API 函数接口介绍


软件定时器(系统)

软件定时器的文件位置:在 tuya_iot_sdk 下的 /sdk/include/sys_timer.h

在 TuyaOS 中与软件定时器相关的接口一共有 12 个,下面对其进行简单的分类介绍。

第一部分:软件定时器的初始化和释放。

第二部分:软件定时器的常用功能。如软件定时器的添加、启动、停止、删除和判断软件定时器是否在运行。

第三部分: TuyaOS 软件定时器的其他功能。如触发一个软件定时器、得到软件定时器的个数、得到和设置软件定时器的休眠间隔和设置软件定时器的栈大小。

软件定时器的初始化和释放

软件定时器的初始化在 SDK 中就已经完成,后续建议不要再对软件定时器进行初始化和释放,以下两个函数在开发过程中一般无需调用。

system_timer_init()


OPERATE_RET system_timer_init(void);

软件定时器初始化。 SDK 启动过程中已经完成初始化,用户在使用过程中不用再次进行初始化。

Parameters:

  • NULL

Return:

  • OPRT_OK: 函数执行成功。

  • other: 函数执行失败。



system_timer_release()


OPERATE_RET system_timer_release(void);

释放软件定时器的资源。该接口与 system_timer_init 相对应的。

Parameters:

  • NULL

Return:

  • OPRT_OK: 函数执行成功。

  • other: 函数执行失败。



软件定时器的常用功能

以下函数接口在实际开发中使用频率较高。

sys_add_timer()


OPERATE_RET sys_add_timer(IN CONST P_TIMER_FUNC pTimerFunc,\
                          IN CONST PVOID_T pTimerArg,\
                          OUT TIMER_ID *p_timerID);

添加一个软件定时器。

Parameters:

  • pTimerFunc: 回调函数。
  • pTimerArg: 回调函数参数。
  • p_timerID: [OUT]软件定时器ID。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


sys_start_timer()


OPERATE_RET sys_start_timer(IN CONST TIMER_ID timerID,\
                            IN CONST TIME_MS timeCycle,\
                            IN CONST TIMER_TYPE timer_type);

启动一个软件定时器。

Parameters:

  • timerID: 软件定时器 ID。
  • timeCycle: 定时时间,单位:MS。
  • timer_type: 定时器类型,可通过这里配置定时器是单次模式 TIMER_ONCE ,还是循环模式 TIMER_CYCLE

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


sys_stop_timer()


OPERATE_RET sys_stop_timer(IN CONST TIMER_ID timerID);

停止一个定时器。与删除不同的是,定时器停止后可以使用
sys_start_timer() 而不用添加定时器就再次启动该定时器,当然相关资源的占用依然存在。

Parameters:

  • timerID: 软件定时器ID。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


sys_delete_timer()


OPERATE_RET sys_delete_timer(IN CONST TIMER_ID timerID);

删除一个定时器。删除后,如果想要再次启动该定时器,需要先使用
sys_add_timer() 成功添加定时器,才能再次启动。

Parameters:

  • timerID: 软件定时器 ID 。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


IsThisSysTimerRun()


BOOL_T IsThisSysTimerRun(IN CONST TIMER_ID timer_id);

判断一个定时器是否在运行。

Parameters:

  • timer_id: 软件定时器 ID 。

Return:

  • TRUE: 定时器在运行。
  • FAIL: 定时器没有在运行。


应用示例

应用示例功能说明:添加并启动一个软件定时器,等到软件定时器执行10次后,关闭软件定时器。

点击到 GitHub 查看完整工程代码

#include "software_timer.h"
#include "uni_log.h"
#include "uni_thread.h"
#include "sys_timer.h"

TIMER_ID my_timer_id;
static int sw_run_count = 0;

void my_timer_cb(UINT_T timerID, PVOID_T pTimerArg)
{
    OPERATE_RET op_ret = OPRT_OK;

    PR_NOTICE("------this is timer %d callback, count: %d", timerID, sw_run_count);
    sw_run_count++;

    if (sw_run_count >= 10) {
        if (IsThisSysTimerRun(my_timer_id)) {
            op_ret = sys_stop_timer(my_timer_id);
            if (OPRT_OK != op_ret) {
                PR_ERR("sys stop timer failed, error code %d", op_ret);
                return;
            }
            PR_NOTICE("timer %d is stop.", my_timer_id);
        }
    }
}

void sw_timer_task(void)
{
    OPERATE_RET op_ret = OPRT_OK;

    op_ret = sys_add_timer(my_timer_cb, NULL, &my_timer_id);
    if (OPRT_OK != op_ret) {
        PR_ERR("sys add timer failed, error code %d", op_ret);
        return;
    }
    PR_NOTICE("timer add success, timer id: %d.", my_timer_id);

    op_ret = sys_start_timer(my_timer_id, 2000, TIMER_CYCLE);
    if (OPRT_OK != op_ret) {
        PR_ERR("sys start timer failed, error code %d", op_ret);
        return;
    }
    PR_NOTICE("timer %d start success.", my_timer_id);
}

API 函数接口介绍


软件定时器的其他功能

以下函数接口使用频率较低,可做了解。

sys_trigger_timer()


OPERATE_RET sys_trigger_timer(IN CONST TIMER_ID timerID);

立刻触发该定时器。

Parameters:

  • timerID: 软件定时器 ID 。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


sys_get_timer_num()


INT_T sys_get_timer_num(void);

得到当前活跃的软件定时器个数(启动的定时器个数,停止和删除的定时器不算)。

Parameters:

  • NULL

Return:

  • 当前活跃的定时器个数。


system_timer_get_sleep_interval()


ULONG_T system_timer_get_sleep_interval(VOID);

获取定时器的最小间隔。

Parameters:

  • NULL

Return:

  • 获取定时器的最小间隔。


system_timer_set_sleep_interval()


VOID system_timer_set_sleep_interval(ULONG_T interval);

设置定时的最小休眠间隔。

Parameters:

  • interval: 要设置的最小睡眠间隔。

Return:

  • NULL


system_timer_cfg_stack_size()


OPERATE_RET system_timer_cfg_stack_size(UINT_T stack_size);

设置软件定时器的栈大小。一般默认即可,非必要不要进行修改。

Parameters:

  • stack_size: 配置软件定时器的栈大小。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


内存管理(系统)

内存管理的文件位置:在 tuya_iot_sdk 下的
/sdk/include/tuya_hal_memory.h

TuyaOS 中关于内存管理的 API 特别简单,只有申请和释放两个。

tuya_hal_system_malloc()


VOID_T *tuya_hal_system_malloc(CONST SIZE_T size);

用于分配内存。

Parameters:

  • size: 要申请的栈空间大小。

Return:

  • NULL: 内存申请失败。
  • other: 内存成功申请到的地址。


tuya_hal_system_free()


VOID_T tuya_hal_system_free(VOID_T* ptr);

释放申请到的内存。

Parameters:

  • ptr: 需要释放的内存指针。

Return:

NULL



应用示例

应用示例说明:演示内存申请和释放函数的使用方法。在 Demo 中会申请3个 int 的内存大小,然后把前两个进行赋值,打印申请到的地址和内存中存的数据。

点击到 GitHub 查看完整工程代码

OPERATE_RET device_init(VOID) 
{
    int *str;

    PR_NOTICE("******************** memory demo begin ********************");
    str = tuya_hal_system_malloc(5*sizeof(int));
    if (NULL == str) {
        PR_ERR("tuya_hal_system_malloc is error");
        return;
    }
    PR_NOTICE("memset");
    memset(str, 0, 5*sizeof(int));
    str[0] = 300;
    str[1] = 200;
    PR_NOTICE("str address: %x", str);
    PR_NOTICE("str[0]:%d, str[1]:%d, str[2]:%d", str[0], str[1], str[2]);
    if (NULL != str) {
        PR_NOTICE("memory will free");
        tuya_hal_system_free(str);
        str = NULL;
        PR_NOTICE("******************** memory demo end ********************");
    }

    return OPRT_OK;
}

API 函数接口介绍


信号量(系统)

信号量的文件位置:在 tuya_iot_sdk 下的 /sdk/include/tuya_hal_semaphore.h

信号量常用于对共享资源的访问控制和任务同步。

tuya_hal_semaphore_create_init()


INT_T tuya_hal_semaphore_create_init(SEM_HANDLE *pHandle, CONST UINT_T semCnt, CONST UINT_T sem_max);

创建并初始化一个信号量。

Parameters:

  • pHandle: [OUT] 信号量句柄。
  • semCnt: 开始时的信号量个数。
  • sem_max: 信号量的最大个数。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_semaphore_release()


INT_T tuya_hal_semaphore_release(CONST SEM_HANDLE semHandle);

释放一个信号量的资源,与 tuya_hal_semaphore_create_init() 函数相对应。

Parameters:

  • semHandle: 要释放资源的信号量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_semaphore_wait()


INT_T tuya_hal_semaphore_wait(CONST SEM_HANDLE semHandle);

等待一个信号量。调用该函数会消耗一个信号量(信号量-1),如果信号量为 0 时调用就会阻塞信号量(信号量不能为负的)。

Parameters:

  • semHandle: 信号量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_semaphore_waittimeout()


INT_T tuya_hal_semaphore_waittimeout(CONST SEM_HANDLE semHandle, unsigned int timeout);

等待一个信号量,带有超时功能。和其它函数不同的是,此函数多一个超时设定,当函数发生阻塞时不会等待信号量到达,超过时间就不再阻塞等待。

Parameters:

  • semHandle: 信号量句柄。
  • timeout: 等待超时时间。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_semaphore_post()


INT_T tuya_hal_semaphore_post(CONST SEM_HANDLE semHandle);

放入一个信号量。(信号量+1)

Parameters:

  • semHandle: 信号量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


应用示例

需要关注的是 tuya_hal_semaphore_create_init( )
tuya_hal_semaphore_release() 两个函数。 creat 函数创建信号量, release 函数则是在信号量使用完成后释放信号量,进行删除。

应用示例说明:创建两个任务,分别为创建一个信号量并每 5s post 一个信号量;和等待信号量,并在接收到信号量后打印 hello 字样。

点击到 GitHub 查看完整工程代码

#include "sem.h"
#include "uni_log.h"
#include "uni_thread.h"
#include "tuya_hal_system.h"
#include "tuya_hal_semaphore.h"

SEM_HANDLE my_sem;

void sem_wait_task_handle(void)
{
    for (;;) {
        tuya_hal_semaphore_wait(my_sem);
        PR_NOTICE("HELLO");
    }
}

void sem_release_task_handle(void)
{
    tuya_hal_semaphore_create_init(&my_sem, 0, 1);
    for (;;) {
        tuya_hal_semaphore_post(my_sem);
        PR_NOTICE("sem is posted.");
        tuya_hal_system_sleep(5000);
    }
}

void sem_task_init(void)
{
    tuya_hal_thread_create(NULL, "sem release", 64*8, TRD_PRIO_5, sem_release_task_handle, NULL);
    tuya_hal_thread_create(NULL, "sem wait", 64*8, TRD_PRIO_5, sem_wait_task_handle, NULL);
}

API 函数接口介绍


互斥量(系统)

互斥量的文件位置:在 tuya_iot_sdk 下的 /sdk/include/tuya_hal_mutex.h

互斥量也叫互斥型信号量,和二值型信号量类似,但互斥型信号量用于资源保护,能避免出现优先级反转现象。


tuya_hal_mutex_create_init()


OPERATE_RET tuya_hal_mutex_create_init(MUTEX_HANDLE *pMutexHandle);

创造并初始化一个互斥量。

Parameters:

  • pMutexHandle: [OUT] 互斥量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_mutex_release()


OPERATE_RET tuya_hal_mutex_release(const MUTEX_HANDLE mutexHandle);

释放一个信号量的资源(与 tuya_hal_mutex_create_init() 相对应)。

Parameters:

  • mutexHandle: 信号量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_mutex_lock()


OPERATE_RET tuya_hal_mutex_lock(const MUTEX_HANDLE mutexHandle);

互斥量上锁。

Parameters:

  • mutexHandle: 信号量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


tuya_hal_mutex_unlock()


OPERATE_RET tuya_hal_mutex_unlock(const MUTEX_HANDLE mutexHandle);

互斥量解锁。

Parameters:

  • mutexHandle: 信号量句柄。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


应用示例

应用示例说明:创建两个任务,使两个使用互斥量进行一些打印输出。

点击到 GitHub 查看完整工程代码

#include "mutex.h"
#include "uni_log.h"
#include "tuya_hal_mutex.h"
#include "uni_thread.h"
#include "tuya_hal_system.h"
#include "tuya_hal_thread.h"

MUTEX_HANDLE my_mutex;

int demo_value = 0;

void task_1_handle(void) 
{
    for (;;) {
        PR_NOTICE("task 1 wait unlock");
        tuya_hal_mutex_lock(my_mutex);
        PR_NOTICE("task 1 lock");

        demo_value = demo_value + 2;
        PR_NOTICE("task 1 demo value:%d", demo_value);
        tuya_hal_system_sleep(3000);

        tuya_hal_mutex_unlock(my_mutex);
        PR_NOTICE("task 1 unlock");
        tuya_hal_system_sleep(100);
    }
}

void task_2_handle(void) 
{
    for (;;) {
        PR_NOTICE("task 2 wait unlock");
        tuya_hal_mutex_lock(my_mutex);
        PR_NOTICE("task 2 lock");

        demo_value--;
        PR_NOTICE("task 2 demo value:%d", demo_value);
        tuya_hal_system_sleep(5000);

        tuya_hal_mutex_unlock(my_mutex);
        PR_NOTICE("task 2 unlock");
        tuya_hal_system_sleep(100);
    }
}

void mutex_task_init(void)
{
    tuya_hal_mutex_create_init(&my_mutex);
    tuya_hal_thread_create(NULL, "task 1", 64*8, TRD_PRIO_5, task_1_handle, NULL);
    tuya_hal_thread_create(NULL, "task 2", 64*8, TRD_PRIO_5, task_2_handle, NULL);
}

通过下面的日志可以发现,在 task 2 上锁的时候, task 1 会先等待互斥量解锁,等 task 1 一解锁便马上开始下面的操作。

API 函数接口介绍


队列(系统)

队列的文件位置:在 tuya_iot_sdk 下的 /sdk/include/uni_queue.h

创建队列时需要设定队列深度(队列可以保存的最大单元数目)和每个单元的大小,队列的规则是先进先出。

下面将对 TuyaOS 中和队列功能相关的 API 函数接口进行分类介绍:

  • 第一部分:队列的创建和释放(去初始化)。

  • 第二部分:队列的最基本的功能,入队列和出队列。

  • 第三部分:其他一些函数功能的介绍。如得到队列的剩余空间、得到当前队列中的入列数、清空队列和删除队列中的部分数。

队列的创建和释放

CreateQueueObj()


P_QUEUE_CLASS CreateQueueObj(const unsigned int queTolNum, const unsigned int queUnitSize);

创建一个队列。

Parameters:

  • queTolNum: 队列的个数。
  • queUnitSize:队列中单个数占用的内存大小。

Return:

  • NULL: 队列创建失败。
  • other: 队列创建成功,返回创建的队列的地址。


** ReleaseQueueObj()**


void ReleaseQueueObj(P_QUEUE_CLASS pQueObj);

释放一个队列,和 CreateQueueObj 相对应。

Parameters:

  • pQueObj: 要释放队列。

Return:

NULL



队列的基本功能

** InQueue()**


unsigned char InQueue(P_QUEUE_CLASS pQueObj, const unsigned char *pQueUnit, const unsigned int queNum);

数据入队。

Parameters:

  • pQueObj: 要入队的目标队列。
  • pQueUnit: 要入队的数据首地址。
  • queNum: 要入队数据个数。

Return:

  • 1: 函数执行成功。
  • other: 函数执行失败。


OutQueue()


unsigned char OutQueue(P_QUEUE_CLASS pQueObj,unsigned char *pQueUnit, const unsigned int queNum);

数据出队。

Parameters:

  • pQueObj: 要出队的队列。
  • pQueUnit: 出队数据存放的空间地址。
  • queNum: 要出队的数据个数。

Return:

  • 1: 函数执行成功。
  • other: 函数执行失败。


队列的其他功能

GetQueueMember()


unsigned char GetQueueMember(P_QUEUE_CLASS pQueObj, const unsigned int start, unsigned char *pQueUnit, const unsigned int queNum);

得到队列中的数据。该函数和出队不同的是可以从任何位置开始获取指定长度的数据,获取完成后并不会导致获取到的数据丢失。

Parameters:

  • pQueObj: 要操作的队列。
  • start: 获取数据的开始。从首个数据开始的话就填1。
  • pQueUnit: 获取到的数据存放的buffer地址。
  • queNum: 获取数据的个数。

Return:

  • 1: 函数执行成功。
  • other: 函数执行失败。


GetCurQueNum()


unsigned int GetCurQueNum(P_QUEUE_CLASS pQueObj);

得到当前队列中数据的个数。

Parameters:

  • pQueObj: 要操作的队列。

Return:

  • 1: 函数执行成功。
  • other: 函数执行失败。


GetCurFreeQueNum()


unsigned int GetCurFreeQueNum(P_QUEUE_CLASS pQueObj);

得到当前队列中空闲个数。

Parameters:

  • pQueObj: 要操作的队列。

Return:

  • 1: 函数执行成功。
  • other: 函数执行失败。


DelQueueMember()


unsigned char DelQueueMember(P_QUEUE_CLASS pQueObj, const unsigned int queNum);

删除队列中指定数目的数据。

Parameters:

  • pQueObj: 要操作的队列。
  • queNum: 删除的数据个数

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


ClearQueue()


unsigned char ClearQueue(P_QUEUE_CLASS pQueObj);

清空队列中的数据。

Parameters:

  • pQueObj: 要操作的队列。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。


应用示例

队列一般用在进程间通信,为了方便我们将所有队列的功能放在一个线程进行演示。

Demo 创建了有 5 个单元,每个单元大小为 int 的队列,打印当前队列已经使用的单元个数和未使用的单元个数。随后队列入了8个数,并打印出队列当前剩余(未使用)的单元个数。队列出一个数,打印输出数的值和剩余单元个数。得到队列从第一个单元开始的4个单元的数值,输出这4个单元的数值和剩余单元的个数,可以发现的是通过
GetQueueMember() 和出列不同的是使用出列输出数值后,对应的剩余单元也会增加,而调用 GetQueueMember() 拿到的数值不会改变剩余的单元个数。随后又从队列中删掉了一个单元,输出剩余单元个数,清除该队列,输出单元个数,可以发现清除后,所以单元都是可以的。最后释放了该队列。

点击到 GitHub 查看完整工程代码

#include "queue_demo.h"
#include "uni_log.h"
#include "tuya_hal_thread.h"
#include "uni_queue.h"
#include "uni_thread.h"

P_QUEUE_CLASS my_queue;
int in_number[] = {31, 32, 33, 5, 7};
int out_number[5];

void queue_task(void)
{
    unsigned char ret;
    int i;

    /* create queue */
    my_queue = CreateQueueObj(5, SIZEOF(int));
    if (NULL == my_queue) {
        PR_ERR("creat queue failed.");
        return;
    }
    PR_NOTICE("create queue success.");
    PR_NOTICE("cur queue num: %d", GetCurQueNum(my_queue));
    PR_NOTICE("cur free num: %d", GetCurFreeQueNum(my_queue));

    /* in queue */
    ret = InQueue(my_queue, in_number, 5);
    if (1 != ret) {
        PR_ERR("in queue failed.");
    } else {
        PR_NOTICE("queue input 5 numbers success.");
    }
    PR_NOTICE("cur free num: %d", GetCurFreeQueNum(my_queue));

    /* out queue */
    ret = OutQueue(my_queue, out_number, 1);
    if (1 != ret) {
        PR_ERR("out queue failed.");
    } else {
        PR_NOTICE("queue out 1 number success.");
    }
    PR_NOTICE("out_number[0]: %d", out_number[0]);
    PR_NOTICE("cur free num: %d", GetCurFreeQueNum(my_queue));

    /* GetQueueMember */
    ret = GetQueueMember(my_queue, 1, out_number, 4);
    if (1 != ret) {
        PR_ERR("queue get member failed.");
    } else {
        PR_NOTICE("GetQueueMember success.");
    }
    for (i=0; i<4; i++) {
        PR_NOTICE("out_number[%d]:%d", i, out_number[i]);
    }
    PR_NOTICE("cur free num: %d", GetCurFreeQueNum(my_queue));

    /* delete 1 queue number */
    ret = DelQueueMember(my_queue, 1);
    if (1 != ret) {
        PR_ERR("delete queue number error.");
    } else {
        PR_NOTICE("delete queue number success.");
    }
    PR_NOTICE("cur free num: %d", GetCurFreeQueNum(my_queue));

    /* clean queue */
    ret = ClearQueue(my_queue);
    if (1 != ret) {
        PR_ERR("clean queue failed.");
    } else {
        PR_NOTICE("clean queue success.");
    }
    PR_NOTICE("cur free num: %d", GetCurFreeQueNum(my_queue));

    /* release queue */
    ReleaseQueueObj(my_queue);
    PR_NOTICE("queue is release.");
}

API 函数接口介绍