LCD驱动在装载后,出现段错误。麻烦老师看一下

log:

代码:
/*

  • knowledge/drv/lcd_rgb_driver.c – Atari builtin chipset frame buffer device
  • Copyright (C) 2022 leth
  • This file is subject to the terms and conditions of the GNU General Public
  • License. See the file COPYING in the main directory of this archive
  • for more details.
  • History:
    • 2022/08/08: leth: add lcd driver frame
      */

#include <linux/module.h>
#include <linux/fb.h>
#include <linux/errno.h>
#include <linux/dma-mapping.h>

static struct fb_info *stfb_info = NULL;

static struct fb_ops stfp_ops ={
.owner = THIS_MODULE,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
};

static int __init STD70TFT_drv_init(void)
{
int ret = 0;
dma_addr_t stphy_addr = {0};

pr_info("insmod STD70TFT driver\n");

/*申请分配fb_info*/
stfb_info = framebuffer_alloc(0, NULL);
if (!stfb_info)
{
    pr_err("%s +%d:fb_info alloc err", __FILE__, __LINE__);
    ret = -ENOMEM;
    goto E_INFOMALLOCFAILED;
}

pr_info("%s +%d:---------\n", __FILE__, __LINE__);

/*配置fb_info*/
/*1.1 配置var 分辩率、颜色格式*/
/*xres yres 是可视区间大小,对应着LCD的显示尺寸
xres_virtual yres_virtual定义了framebuffer内存中一帧的尺寸
xres_virtual yres_virtual必须大于或等于xres yres,可以通过pan
操作来显示xres_virtual和yres_virtual定义的显示区域*/
stfb_info->var.xres = 1024;
stfb_info->var.yres = 600;

stfb_info->var.bits_per_pixel = 16;/*rgb565*/

stfb_info->var.red.length = 5;
stfb_info->var.red.offset = 11;
stfb_info->var.green.length = 6;
stfb_info->var.green.offset = 5;
stfb_info->var.blue.length  = 5;
stfb_info->var.green.offset = 0;
pr_info("%s +%d:---------\n", __FILE__, __LINE__);

/*配置fix 显存相关 长度、起始地址、类型、*/
stfb_info->fix.smem_len = stfb_info->var.xres * stfb_info->var.yres * stfb_info->var.bits_per_pixel / 8;
if (stfb_info->var.bits_per_pixel == 24)
    stfb_info->fix.smem_len = stfb_info->var.xres * stfb_info->var.yres * 4;
pr_info("%s +%d:---------\n", __FILE__, __LINE__);


/*fb的虚拟地址*/
stfb_info->screen_base = dma_alloc_wc(NULL, stfb_info->fix.smem_len, &stphy_addr, GFP_KERNEL);
if (!stfb_info->screen_base)
{
    pr_err("%s +%d:dma_alloc_wc err", __FILE__, __LINE__);
    ret = -ENOMEM;
    goto E_DMA_ALLOC_WC;
}
pr_info("%s +%d:---------\n", __FILE__, __LINE__);


/*fb的物理地址*/
stfb_info->fix.smem_start = stphy_addr;
stfb_info->fix.type = FB_TYPE_PACKED_PIXELS;
stfb_info->fix.visual = FB_VISUAL_DIRECTCOLOR;

/*配置操作方法*/
stfb_info->fbops = &stfp_ops;

pr_info("%s +%d:---------\n", __FILE__, __LINE__);

ret = register_framebuffer(stfb_info);
if (!ret)
{
    pr_err("%s +%d:register_framebuffer err ret = %d\n", __FILE__, __LINE__, ret);
    goto E_REGISTER_INFO;
}

/*注册fb_info*/
pr_info("%s +%d:---------\n", __FILE__, __LINE__);
return ret;

E_REGISTER_INFO:
dma_free_wc(NULL, stfb_info->fix.smem_len, stfb_info->screen_base, stfb_info->fix.smem_start);
E_DMA_ALLOC_WC:
framebuffer_release(stfb_info);
E_INFOMALLOCFAILED:
return ret;
}

static void __exit STD70TFT_drv_exit(void)
{
pr_info(“rmmod STD70TFT driver\n”);
/反注册fb_info/
unregister_framebuffer(stfb_info);

/*释放内存*/
dma_free_wc(NULL, stfb_info->fix.smem_len, stfb_info->screen_base, stfb_info->fix.smem_start);

/*释放fb_info*/
framebuffer_release(stfb_info);

}

module_init(STD70TFT_drv_init);

module_exit(STD70TFT_drv_exit);

MODULE_LICENSE(“GPL”);

这是我们提供的哪个示例代码?

不是,不过和示例代码差不多。我用过显示代码,也有这个问题。

用的哪一个示例代码?
我们去跑一下看看。

image

这个就是用上面代码跑的结果:

你不要跑这前面的代码,这些代码是老师录视频时备份的代码,并不全都是可以运行的完整的代码。
你去跑“11_lcd_drv_imx6ull_ok”这个代码看看。

对于驱动大全里面的某个模块,建议先完整看一遍视频,稍加理解后,再自己去实现,不要跳着看跳着做,不然总会出现这样那样的问题的。

目前有些东西不理解,所以尝试去做,我理解的是驱动框架出来后,最起码的装载卸载功能就可以实现的,毕竟这和硬件无关。

框架和功能实现是两回事。
框架出来了,功能不一定就实现了,是一点一点的将功能完成来填充框架,有了框架只是让开发者明确要做什么。
另外,代码是备份代码,韦老师习惯按照知识点分阶段分节奏的备份,不一定就是实现了并且调试通了的代码。

好的,了解了。 :grinning: