硬汉嵌入式论坛

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

[LVGL] LTDC双缓冲刷新莫名出总线错误中断

[复制链接]

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2024-11-15 23:36:43 | 显示全部楼层 |阅读模式
参照V6版本的LTDC设置,选择使用双缓冲区刷新屏幕
开发环境 gcc + STM32cubemx+openocd 实验平台 F429 + 800x480 LCD

LVGL配置有DMA2d加速,直接将LVGL的缓存设到SDRAM中,显存也是同样的位置,通过行中断实现垂直消隐。
在FreeRTOS中使用事件组完成消息的同步
以下是相关函数配置

``` ltdc.c

void HAL_LTDC_MspInit(LTDC_HandleTypeDef* ltdcHandle)
{........................
/* LTDC interrupt Init */
HAL_NVIC_SetPriority(LTDC_IRQn, 14, 0);
HAL_NVIC_EnableIRQ(LTDC_IRQn);}



void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *ltdcHandle){

   LTDC->ICR = (uint32_t)LTDC_IER_LIE;

  BaseType_t xHigherPriorityTaskWoken;
  xHigherPriorityTaskWoken = pdFALSE;
  if(xEventGroupSetBitsFromISR(Event_Handle,LTDC_BIT,&xHigherPriorityTaskWoken)!=pdFAIL) {
    // 进行上下文切换
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  }

}


```
```lv_port_disp.c
/* Example for 3) also set disp_drv.full_refresh = 1 below*/
static lv_disp_draw_buf_t draw_buf_dsc_3;
static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES__attribute__((section(".lcd")));            /*A screen sized buffer*/
static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES__attribute__((section(".lcd")));            /*Another screen sized buffer*/
lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2,
                       MY_DISP_VER_RES * MY_DISP_HOR_RES);   /*Initialize the display buffer*/

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    // 等待LTDC传输完成,并改变LTDC显存地址
    xEventGroupWaitBits(Event_Handle,LTDC_BIT,pdTRUE,pdTRUE,portMAX_DELAY);
    // 设置LTDC的显存地址为LVGL已经绘制好的显存区
    __HAL_LTDC_LAYER(&hltdc, 0)->CFBAR =(uint32_t)color_p;
    // 强制更新
    __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hltdc);
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}


```

在调试中发现,进入第一次刷新地址被切换到第二块显存期间一切正常,但当LTDC从第二块显存切到第一块的时候就出现总线错误

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-11-16 11:15:57 | 显示全部楼层
LTDC的配置代码方便的话贴一下,我看下你的行中断位置。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-11-16 15:28:21 | 显示全部楼层
eric2013 发表于 2024-11-16 11:15
LTDC的配置代码方便的话贴一下,我看下你的行中断位置。

C:\Users\Yasusi\Pictures\Screenshots\2024-11-16_15-26-06.png
行中断在LTDC的初始化中设置,是需要在开启中断之前调用吗?
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-11-16 21:17:13 | 显示全部楼层
eric2013 发表于 2024-11-16 11:15
LTDC的配置代码方便的话贴一下,我看下你的行中断位置。

[C] 纯文本查看 复制代码
/* LTDC init function */
void MX_LTDC_Init(void)
{

  /* USER CODE BEGIN LTDC_Init 0 */

  /* USER CODE END LTDC_Init 0 */

  LTDC_LayerCfgTypeDef pLayerCfg = {0};

  /* USER CODE BEGIN LTDC_Init 1 */

  /* USER CODE END LTDC_Init 1 */
  hltdc.Instance = LTDC;
  hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
  hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
  hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
  hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
  hltdc.Init.HorizontalSync = 19;
  hltdc.Init.VerticalSync = 2;
  hltdc.Init.AccumulatedHBP = 159;
  hltdc.Init.AccumulatedVBP = 14;
  hltdc.Init.AccumulatedActiveW = 1118;
  hltdc.Init.AccumulatedActiveH = 508;
  hltdc.Init.TotalWidth = 1278;
  hltdc.Init.TotalHeigh = 520;
  hltdc.Init.Backcolor.Blue = 0;
  hltdc.Init.Backcolor.Green = 0;
  hltdc.Init.Backcolor.Red = 0;
  if (HAL_LTDC_Init(&hltdc) != HAL_OK)
  {
    Error_Handler();
  }
  pLayerCfg.WindowX0 = 0;
  pLayerCfg.WindowX1 = LCD_WIDTH;
  pLayerCfg.WindowY0 = 0;
  pLayerCfg.WindowY1 = LCD_HEIGHT;
  pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
  pLayerCfg.Alpha = 255;
  pLayerCfg.Alpha0 = 0;
  pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
  pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
  pLayerCfg.FBStartAdress = FRAME_BUF_ADDR;
  pLayerCfg.ImageWidth = LCD_WIDTH;
  pLayerCfg.ImageHeight = LCD_HEIGHT;
  pLayerCfg.Backcolor.Blue = 0;
  pLayerCfg.Backcolor.Green = 0;
  pLayerCfg.Backcolor.Red = 0;
  if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LTDC_Init 2 */
  // 启动行中断,要在HAL_LTDC_LineEventCallback实现乒乓
  HAL_LTDC_ProgramLineEvent(&hltdc,VSW+VBP+LCD_HEIGHT);
  /* USER CODE END LTDC_Init 2 */

}

补一下代码,图像好像加载不出去
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-11-17 11:32:36 | 显示全部楼层
Yasusi 发表于 2024-11-16 21:17
[mw_shl_code=c,true]
/* LTDC init function */
void MX_LTDC_Init(void)

中断设置到这个位置试试,如果已经在这个位置了,加大下几个边界参数,让消隐时间加大些,不排除你的绘制没有在消隐时间内完成的问题。

12343’.png
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-11-18 22:19:54 | 显示全部楼层
eric2013 发表于 2024-11-17 11:32
中断设置到这个位置试试,如果已经在这个位置了,加大下几个边界参数,让消隐时间加大些,不排除你的绘制 ...

换了参数没有起作用,我把LVGL的DM2D加速给关了,然后就出现了hardfault,这会不会是LVGL写SDRAM的时候和LTDC的操作冲突了呀?设置像素时钟应该怎么设置?是必须要保持和LVGL中LV_DISP_DEF_REFR_PERIOD绘制周期相匹配吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-11-19 10:10:26 | 显示全部楼层
Yasusi 发表于 2024-11-18 22:19
换了参数没有起作用,我把LVGL的DM2D加速给关了,然后就出现了hardfault,这会不会是LVGL写SDRAM的时候和 ...

1、LVGL(CPU)写SDRAM的时候和LTDC的操作会总线仲裁处理,除非硬件有问题才会有问题。
2、像素时钟就是LTDC时钟。
3、LVGL的双缓冲实现非常考究刷新同步问题。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-11-19 10:37:37 | 显示全部楼层
eric2013 发表于 2024-11-19 10:10
1、LVGL(CPU)写SDRAM的时候和LTDC的操作会总线仲裁处理,除非硬件有问题才会有问题。
2、像素时钟就是 ...

那现在是需要调整LTDC的时钟频率还是继续试着增大行中断?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-11-20 09:49:23 | 显示全部楼层
Yasusi 发表于 2024-11-19 10:37
那现在是需要调整LTDC的时钟频率还是继续试着增大行中断?

两个都测试下。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-25 21:56 , Processed in 0.384533 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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