这是indexloc提供的服务,不要输入任何密码
Skip to content

建议添加异步发送数据功能 #16

@zcj20080882

Description

@zcj20080882

文档中说明建议不要打开RT_DEVICE_FLAG_DMA_TX,现实情况是一定不能打开该标志。原因是RTT串口发送时,是直接将数据地址传送给DMA(在打开DMA时并且开启RT_DEVICE_FLAG_DMA_TX),这样在DMA发送数据时,一定不能修改传给serial层的数据,如果是动态分配的内存更不能释放该内存,否则会导致发送数据出错或者崩溃。
但是,某些情况下,需要开启DMA以节省CPU资源,这时需要ppp_device能够保证数据不出错而且还能异步(DMA)发送,这就需要简单实现一下异步发送的功能。我简单写了一个串口异步发送数据的示例,你看是否可行或者是否有必要:

#define MIN(a,b)            (((a) > (b)) ? (b) : (a))
#define SEND_TIMEOUT 1000
uint8_t ppp_tx_buf[1500] = {0};
/*发送完成信号*/
rt_sem_t tx_sem;

rt_inline rt_err_t __send_complete_callback(rt_device_t dev, void *buffer)
{
    rt_sem_release(tx_sem);
    return RT_EOK;
}

int ppp_serial_write(rt_device_t dev, const uint8_t *data, int data_len)
{
    int ret = RT_EOK;

    if (!dev)
    {
        return -RT_EINVAL;
    }
    if (!data || data_len == 0)
    {
        log_w("Invalid data!");
        return 0;
    }
    
    ret = rt_sem_take(tx_sem, SEND_TIMEOUT);
    if (RT_EOK != ret)
    {
        log_e("Write %s failed,err: %d", uart->name, ret);
        return -RT_EBUSY;
    }
    ret = MIN(data_len,sizeof(ppp_tx_buf));
    memcpy(ppp_tx_buf, data, ret);
    
    ret = rt_device_write(dev, 0,tx_buf, ret);
    if (ret <= 0)
    {
        log_e("Write %s failed,err: %d", uart->name, ret);
    }
    else if (ret < data_len)
    {
       //待优化,连续发送大量数据可能导致栈溢出
        ret = ppp_serial_write(fd, data + ret, data_len - ret);
    }
    return ret;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions