电子量产工具:输入系统-输入管理器-环形缓冲区

软件总框架:


输入管理

怎样避免丢失数据

环形缓冲区图解

环形缓冲区实现

#define BUFFLEN 20
static int g_iRead;
static int g_iWrite;
static InputEvent g_tInputEvent[BUFFLEN];

static int IsInputBufferFull(void)
{
    return (g_iRead == ((g_iWrite + 1) % BUFFLEN));
}

static int IsInputBufferEmpty(void)
{
    return (g_iRead == g_iWrite);
}

static void PutInputEventToBuffer(PInputEvent ptInputEvent)
{
    if (!IsInputBufferFull())
    {
        g_tInputEvent[g_iWrite] = *ptInputEvent;
        g_iWrite = (g_iWrite + 1) % BUFFLEN;
    }
}

static int GetInputEventFromBuffer(PInputEvent ptInputEvent)
{
    if (!IsInputBufferEmpty())
    {
        *ptInputEvent = g_tInputEvent[g_iRead];
        g_iRead = (g_iRead + 1) % BUFFLEN;
        return 1;
    }
    else
    {
        return 0;
    }
}

设备线程(触摸屏和网络输入线程)等待数据,保存数据并唤醒等待数据的线程:GetInputEvent

static void *input_recv_thread_func(void *data)
{
    PInputDevice tInputDev = (PInputDevice)data;
    InputEvent tEvent;
    int ret;

    while (1)
    {
        /* 读数据 */
        ret = tInputDev->GetInputEvent(&tEvent);
        if (!ret)
        {
            /* 保存数据 */
            pthread_mutex_lock(&g_tMutex);
            PutInputEventToBuffer(&tEvent);

            /* 唤醒等待数据的线程 */
            pthread_cond_signal(&g_tConVar); /* 通知接收线程 */
            pthread_mutex_unlock(&g_tMutex);
        }
    }
}

GetInputEvent()线程内容

int GetInputEvent(PInputEvent ptInputEvent)
{
    InputEvent tEvent;
    int ret;
    /* 无数据则休眠 */
    pthread_mutex_lock(&g_tMutex);
    if (GetInputEventFromBuffer(&tEvent))
    {
        *ptInputEvent = tEvent;
        pthread_mutex_unlock(&g_tMutex);
        ret = 0;
    }
    else
    {
        /* 休眠等待 */
        pthread_cond_wait(&g_tConVar, &g_tMutex); //将线程设置为等待状态(阻塞)
        if (GetInputEventFromBuffer(&tEvent))
        {
            *ptInputEvent = tEvent;
            ret = 0;
        }
        else
        {
            ret = -1;
        }
        pthread_mutex_unlock(&g_tMutex);
    }
    return ret;
}

总结:
本节实现以下内容

  1. 实现环形缓冲区,通过PutInputEventToBuffer()将数据放入buff,通过GetInputEventFromBuffer()从buffer中读取数据。
  2. 完成设备线程:通过tInputDev->GetInputEvent(&tEvent)读设备数据,通过PutInputEventToBuffer()将数据放入buff,通过pthread_cond_signal()通知接收数据的线程。
  3. 完成GetInputEvent()线程:通过GetInputEventFromBuffer()从buffer读取数据,如果没有数据则通过pthread_cond_wait()设置为等待状态,待收到信号后,再次通过GetInputEventFromBuffer()从buffer读取数据。

注意:在读写buffer时需要加互斥锁。

再次回顾输入管理器完成的工作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值