This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

omapl138共享内存,数据传输问题



我有关于omapl138共享内存,数据传输问题,请教。

1.

it can't write immediately to shared ram.

code list delow:

static bool server_upp_data_transfer(Server *server) {
 if(server->ad_started == false) return true;
    while (ListMP_empty(server->list_free))  /* wait */
        Task_sleep(10000);

    DataNode *node = (DataNode *)ListMP_getTail(server->list_free); /* get free node */
    int *data = (int *)SharedRegion_getPtr(node->SR_buffer);

    server->transposeParA.WindowAddress     = (unsigned int *)data;  /* set taget */
    server->transposeParA.LineCount   = node->buffer_height;
    server->transposeParA.ByteCount   = node->buffer_pitch;
    server->transposeParA.LineOffsetAddress = node->buffer_pitch;

    upp_error_count = 0;
    upp_dmai_int_cut = 0;

    /* fill in data */
    uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &server->transposeParA);

    /* wait */
    while (upp_dmai_int_cut < 1 && upp_error_count == 0);

    if (upp_error_count != 0) {
        LOG_ERROR("data mismatch in buffers");
        LOG_ERROR("upp_error_count=%d",upp_error_count);
    }

    /* make data node in busy list */
    ListMP_putHead(server->list_busy, (ListMP_Elem *)node);

    return true;
}

......................................................

2.

我的程序是:
            dsp:通过dma方式“uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &server->transposeParA)”从upp_A口读入数据48kB数据,存在共享内存中(起始地址0xc200-0000,共20块,块大小16KB,);
            arm:从共享内存中读取数据,写入disk。
           问题:共享内存块中出现的数据,与我从upp口送入的数据不一致,且数量有缺少。
           不知什么原因?烦请帮忙分析一下。
          代码如下:
         1)、arm申请共享内存块:

    /* heap for malloc list node */
    IHeap_Handle heap_node = (IHeap_Handle)SharedRegion_getHeap(SYS_CFG_SR_ID_LIST_HEAP);
    /* heap for malloc buffer for upp data */
    IHeap_Handle heap_data = (IHeap_Handle)SharedRegion_getHeap(SYS_CFG_SR_ID_UPP_HEAP);
    /* create data nodes */
    DataNode *nodes[SYS_CFG_LIST_NODES];
    int i;
    for (i = 0; i < SYS_CFG_LIST_NODES; i++) {
        DataNode *node = (DataNode *)Memory_alloc(heap_node, sizeof(DataNode), 0, NULL);
        UInt32* data = (UInt32 *)Memory_alloc(heap_data, SR_BUFFER_SIZE, 0, NULL);
        node->SR_buffer = SharedRegion_getSRPtr(data, SYS_CFG_SR_ID_UPP_HEAP);
        node->size = SR_BUFFER_SIZE;
        node->buffer_pitch = BUFFER_PITCH;
        node->buffer_height = BUFFER_HEIGHT;
        nodes[i] = node;
    }
    /* create free list */
    ListMP_Params params_list;
    ListMP_Params_init(&params_list);
    params_list.name = SYS_CFG_LIST_FREE;
    params_list.regionId = SYS_CFG_SR_ID_LIST_HEAP;
    ListMP_Handle list_free = ListMP_create(&params_list);
    for (i = 0; i < SYS_CFG_LIST_NODES; i++)   /* init free list */
  ListMP_putHead(list_free, (ListMP_Elem *)nodes[i]);
    /* create busy list */
    params_list.name = SYS_CFG_LIST_BUSY;
    ListMP_Handle list_busy = ListMP_create(&params_list);

 2)、arm等待数据块有效,并写入disk:

  /* get upp data from busy list and save them to file */
    while (! quit) {
        while (ListMP_empty(list_busy) && ! quit)  // wait data
            usleep(1000);
        if (quit)
            continue;
        /* get data node */
        DataNode *node = (DataNode *)ListMP_getTail(list_busy);
        /* get upp data */
        uint16_t *data = (uint16_t *)SharedRegion_getPtr(node->SR_buffer);
        LOG_DEBUG("data[0]=%x", data[0]);
        /* save upp data */
        file_saver_save(file_saver, (void *)data, node->size);
        /* make free node in free list again */
        ListMP_putHead(list_free, (ListMP_Elem *)node);
    }
    3)、dsp用dma方式从upp读入数据,放入共享内存:
static bool server_upp_data_transfer(Server *server) {
 if(server->ad_started == false) return true;
    while (ListMP_empty(server->list_free))  /* wait */
        Task_sleep(10000);
    DataNode *node = (DataNode *)ListMP_getTail(server->list_free); /* get free node */
    int *data = (int *)SharedRegion_getPtr(node->SR_buffer);
    server->transposeParA.WindowAddress     = (unsigned int *)data;  /* set taget */
    server->transposeParA.LineCount   = node->buffer_height;
    server->transposeParA.ByteCount   = node->buffer_pitch;
    server->transposeParA.LineOffsetAddress = node->buffer_pitch;
    upp_error_count = 0;
    upp_dmai_int_cut = 0;
    /* fill in data */
    uPPDMATransfer(SOC_UPP_0_REGS, uPP_DMA_CHI, &server->transposeParA);
    /* wait */
    while (upp_dmai_int_cut < 1 && upp_error_count == 0);
    if (upp_error_count != 0) {
        LOG_ERROR("data mismatch in buffers");
        LOG_ERROR("upp_error_count=%d",upp_error_count);
    }
    /* make data node in busy list */
    ListMP_putHead(server->list_busy, (ListMP_Elem *)node);
    return true;
}
.....................................
3.
我从upp口重复发数据48kB给dsp,从arm端检查共享内存中的数据,第一次发送的数据没有,第二次发送的数据,只有第一块(16KB/一块;正确时应当收到3块)。
不知什么原因?
  • 代码看不大懂,但有几个疑问:

    #1. 你提到分成几块,那么应该会有几个uPP DMA的配置,没看到检测pending位更新uPP_DMA参数过程。

    #2。 不明白为什么要task sleep 1000,如果外部在连续的发数据,这时侯task在sleep,upp_DMA参数没有配置,数据谁来接收?

    #3。中断ISR呢?如果实现的?是在ISR里更新uPP DMA参数的吗?


  • void uPPIsr(void)
    {
    unsigned int intr_dmai_status, intr_dmaq_status;

    // 取?? DMA ?卸?状态
    intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
    intr_dmaq_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHQ);

    while(intr_dmai_status != 0 || intr_dmaq_status != 0)
    {
    if (intr_dmai_status & uPP_INT_EOL)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOL);
    }

    if (intr_dmai_status & uPP_INT_EOW)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_EOW);
    upp_dmai_int_cut++;
    }

    if (intr_dmai_status & uPP_INT_ERR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_ERR);
    upp_error_count++;
    }

    if (intr_dmai_status & uPP_INT_UOR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_UOR);
    upp_error_count++;
    }

    if (intr_dmai_status & uPP_INT_DPE)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHI, uPP_INT_DPE);
    upp_error_count++;
    }

    if (intr_dmaq_status & uPP_INT_EOL)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOL);
    }

    if (intr_dmaq_status & uPP_INT_EOW)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_EOW);
    upp_dmaq_int_cut++;
    }

    if (intr_dmaq_status & uPP_INT_ERR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_ERR);
    upp_error_count++;
    }

    if (intr_dmaq_status & uPP_INT_UOR)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_UOR);
    upp_error_count++;
    }

    if (intr_dmaq_status & uPP_INT_DPE)
    {
    uPPIntClear(SOC_UPP_0_REGS, uPP_DMA_CHQ, uPP_INT_DPE);
    upp_error_count++;
    }

    // uPP ?卸辖??????录?????为同一?卸?源
    // ?卸??欠?全?????楸????????
    intr_dmai_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHI);
    intr_dmaq_status = uPPIntStatus(SOC_UPP_0_REGS, uPP_DMA_CHQ);
    }

    // 通知 CPU uPP ?卸洗????????员??????录????圆???
    uPPEndOfInt(SOC_UPP_0_REGS);
    }