硬汉嵌入式论坛

 找回密码
 立即注册
查看: 611|回复: 3
收起左侧

[TouchGFX] 请教一个TouchGFX运行卡住的问题

[复制链接]

2

主题

13

回帖

19

积分

新手上路

积分
19
发表于 2023-4-14 11:54:27 | 显示全部楼层 |阅读模式
本帖最后由 蜗牛snail 于 2023-4-14 21:22 编辑

按照官方文档,网上一些文档,TouchGFX里面的G071的一个例程,自己做了个修改移植。

使用的是STM32G070,SPI屏幕240*240,没有外部FLASH。
spi2+dma做屏幕驱动,由于原来板子PCB设计问题,没有做TE信号,暂不考虑撕裂处理。
CubeMX设置Partial Buffer,3 blocks,1920 bytes,没有用os


[C] 纯文本查看 复制代码
touchgfxDisplayDriverTransmitActive();

这个函数是返回一个标志位,标志位在DMA传输前置1,DMA中断里面清零。

[C] 纯文本查看 复制代码
extern "C"
void DisplayDriver_TransferCompleteCallback()
{
  // After completed transmission start new transfer if blocks are ready.
    touchgfx::startNewTransfer();
}
}

这个函数也是在dma中断里面调用,这里哈原来G071例程不一样,原来G071例程这里面是 PartialFrameBufferManager::tryTransmitBlockFromIRQ();

[C] 纯文本查看 复制代码
touchgfxDisplayDriverTransmitBlock();

这个函数里面流程是先设置图像区域,然后将图像数组通过DMA开始传输。

[C] 纯文本查看 复制代码
touchgfxSignalVSync();

这个在SysTick_Handler中断里面调用,中断是1ms,自己做个变量计数16次之后调用该函数。

最后效果,程序卡在Application/User/TouchGFX/target里面的FrameBufferAllocator.hpp里面的 while (state[drawingBlock] != EMPTY),屏幕也只显示了最上面几行的而已。
[C] 纯文本查看 复制代码
virtual uint16_t allocateBlock(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t** block)
    {
        drawingBlock++;
        if (drawingBlock == blocks)
        {
            drawingBlock = 0;
        }
        while (state[drawingBlock] != EMPTY)
        {
            FrameBufferAllocatorWaitOnTransfer();
        }
        assert(state[drawingBlock] == EMPTY);
        state[drawingBlock] = ALLOCATED;
        const int32_t stride = width * bytes_pr_pixel;
        const int32_t lines = block_size / stride;
        *block = (uint8_t*)&memory[drawingBlock][0];
        blockRect[drawingBlock].x = x;
        blockRect[drawingBlock].y = y;
        blockRect[drawingBlock].width = width;
        blockRect[drawingBlock].height = MIN(height, lines);
        return blockRect[drawingBlock].height;
    }


看例程里面有个通过TE信号中断来设置或清除VSYNC的,而且也是在这个中断里面调用touchgfxSignalVSync,看一些文章这个是一个虚拟IO,这里不是很清楚这个是做什么用的。
不知道是不是因为没有设置或清除这个导致的。

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
发表于 2023-4-14 16:06:53 | 显示全部楼层
帮顶。
回复

使用道具 举报

2

主题

13

回帖

19

积分

新手上路

积分
19
 楼主| 发表于 2023-5-6 18:52:04 | 显示全部楼层
前段时间去搞其他东西,加上放假,这两天重新调查,终于找到了问题的根源。
先说下之前卡住在那里,那是一个查询块是不是空的判断。下面会说到这个查询为什么不是空的。
用cubeMX生成工程的时候,在TouchGFXGenerateHal.cpp里面有两个函数
[C] 纯文本查看 复制代码
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
    HAL::flushFrameBuffer(rect);
    // Once flushFrameBuffer() is called by the framework a block is already for transfer
    // Mark it ready for transfer and transmit it if user defined method isTransmittingData() does not return false
    // If data is not being transmitted, transfer the data with user defined method transmitFrameBufferBlock().
    frameBufferAllocator->markBlockReadyForTransfer();
    if (!touchgfxDisplayDriverTransmitActive())
    {
        touchgfx::Rect r;
        // Get pointer to block buffer and coordinates of the rect
        const uint8_t* pixels = frameBufferAllocator->getBlockForTransfer(r);
        // Start transmission of the block
        touchgfxDisplayDriverTransmitBlock((uint8_t*)pixels, r.x, r.y, r.width, r.height);
    }
}


[C] 纯文本查看 复制代码
// A user must call touchgfx::startNewTransfer(); once transmitFrameBufferBlock() has successfully sent a block.
void startNewTransfer()
{
    FrameBufferAllocator* fba = HAL::getInstance()->getFrameBufferAllocator();

  // Free the previous transmitted block, marking it ready for rendering
    fba->freeBlockAfterTransfer();
    if (fba->hasBlockReadyForTransfer())
    {
        touchgfx::Rect r;
        // Get pointer to block buffer and coordinates of the rect
        const uint8_t* pixels = fba->getBlockForTransfer(r);
        // Start transmission of the block
        touchgfxDisplayDriverTransmitBlock((uint8_t*)pixels, r.x, r.y, r.width, r.height);
    }
}

这两个函数是一样功能的,不知道为什么工具要生成后面这个startNewTransfer函数。
这个函数,是在另一个函数里面调用的
[C] 纯文本查看 复制代码
extern "C"
void DisplayDriver_TransferCompleteCallback()
{
  // After completed transmission start new transfer if blocks are ready.
    touchgfx::startNewTransfer();
}

这个函数是在spi,或者dma传输完成后调用的。这里的功能只是告诉touchGFX传输完成了,可以去清理掉那个块。
但由于startNewTransfer这个还加了
[C] 纯文本查看 复制代码
    if (fba->hasBlockReadyForTransfer())
    {
        touchgfx::Rect r;
        // Get pointer to block buffer and coordinates of the rect
        const uint8_t* pixels = fba->getBlockForTransfer(r);
        // Start transmission of the block
        touchgfxDisplayDriverTransmitBlock((uint8_t*)pixels, r.x, r.y, r.width, r.height);
    }

这一段,所以这里会将下一块的状态改为SENDING,也就是执行了 fba->getBlockForTransfer(r)这个。
所以解决办法就是将这一段函数里面的if后面全部屏蔽掉。这个只做释放当前块的操作就行。
[C] 纯文本查看 复制代码
// A user must call touchgfx::startNewTransfer(); once transmitFrameBufferBlock() has successfully sent a block.
void startNewTransfer()
{
    FrameBufferAllocator* fba = HAL::getInstance()->getFrameBufferAllocator();

  // Free the previous transmitted block, marking it ready for rendering
    fba->freeBlockAfterTransfer();
//    if (fba->hasBlockReadyForTransfer())
//    {
//        touchgfx::Rect r;
//        // Get pointer to block buffer and coordinates of the rect
//        const uint8_t* pixels = fba->getBlockForTransfer(r);
//        // Start transmission of the block
//        touchgfxDisplayDriverTransmitBlock((uint8_t*)pixels, r.x, r.y, r.width, r.height);
//    }
}

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106828
QQ
发表于 2023-5-7 11:52:08 | 显示全部楼层
蜗牛snail 发表于 2023-5-6 18:52
前段时间去搞其他东西,加上放假,这两天重新调查,终于找到了问题的根源。
先说下之前卡住在那里,那是一 ...

谢谢告知最终原因。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-6 13:20 , Processed in 0.305557 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表