首页 > 技术知识 > 正文

前言

项目上使用了sil9136做BT1120转HDMI,这货最大支持到4k@30,板子回来后交给同事调试,折腾了半天没搞完,搞好周末加班就抽了点时间看了下,主要是因为Hi3520dv200是64位架构的CPU,另外内核比较新是linux-4.19.x的了。。。

修改方法

1.修改Makefile

废话不多说,从其他平台搞了分代码,丢到Hi3531DV200_SDK_V2.0.0.3/drv/extdrv目录修改Makefile,如下:

ifeq ($(EXTDRV_PARAM_FILE), ) EXTDRV_PARAM_FILE:=../Makefile.param include $(EXTDRV_PARAM_FILE) endif SRCS := sil9136.c INC += -I$(OSAL_ROOT)/linux/kernel/himedia INC += -I$(OSAL_ROOT)/include INC += -I$(REL_INC) INC += -I$(DRV_ROOT)/extdrv/$(HIARCH)/sil9136 EXTRA_CFLAGS += -DI2C_INTERNAL EXTDRV_CFLAGS += $(INC) EXTDRV_CFLAGS += $(INC) #************************************************************************* TARGET := hi_sil9136 #************************************************************************* # compile linux or HuaweiLite include $(PWD)/../Make.$(OSTYPE)

2.编译调试代码

在终端里面make,很不友好的报了一推错误

/home/lwx/workspace/sdk_all/hisi/Hi3531DV200_SDK_V2.0.0.3/drv/extdrv/sil9136-3/sil9136.c: At top level: /home/lwx/workspace/sdk_all/hisi/Hi3531DV200_SDK_V2.0.0.3/drv/extdrv/sil9136-3/sil9136.c:2512:21: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .unlocked_ioctl = sil9136_ioctl, ^~~~~~~~~~~~~ /home/lwx/workspace/sdk_all/hisi/Hi3531DV200_SDK_V2.0.0.3/drv/extdrv/sil9136-3/sil9136.c:2512:21: note: (near initialization for sil9136_fops.unlocked_ioctl) /home/lwx/workspace/sdk_all/hisi/Hi3531DV200_SDK_V2.0.0.3/drv/extdrv/sil9136-3/sil9136.c: In function sil9136_device_init: /home/lwx/workspace/sdk_all/hisi/Hi3531DV200_SDK_V2.0.0.3/drv/extdrv/sil9136-3/sil9136.c:2763:2: warning: implicit declaration of function init_timer; did you mean init_timers? [-Wimplicit-function-declaration] init_timer(&sil9136_timer); ^~~~~~~~~~ init_timers /home/lwx/workspace/sdk_all/hisi/Hi3531DV200_SDK_V2.0.0.3/drv/extdrv/sil9136-3/sil9136.c:2764:25: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types] sil9136_timer.function = siHdmiTx_TPI_Poll; ^

报错的地方有2个一个sil9136_ioctl提示不兼容的指针,翻看了头文件,发现问题,按如下修改(声明和定义都要修改,有好几处):

static int sil9136_ioctl(struct file *file, unsigned int cmd, unsigned long arg); //改成下面的 static long sil9136_ioctl(struct file *file, unsigned int cmd, unsigned long arg);

第二个是定时器问题,新版本的定时改动还是蛮大的,细节我就不展开讲,感兴趣就自己查头文件和Google. 第一处是回调函数

void siHdmiTx_TPI_Poll (void) //改成如下: void siHdmiTx_TPI_Poll (struct timer_list *list)

第二处是函数宏删除

init_timer(&sil9136_timer); sil9136_timer.function = siHdmiTx_TPI_Poll; //改成下面的 timer_setup(&sil9136_timer, siHdmiTx_TPI_Poll, 0); sil9136_timer.function = siHdmiTx_TPI_Poll;

额外问题,对下自己的原理图,看IC挂载了哪个I2C上,修改下对应的地址我的是挂载了I2C0上:

struct i2c_adapter* i2c_adap; // use i2c2 i2c_adap = i2c_get_adapter(2); sil9136_client = i2c_new_device(i2c_adap, &sil9136_i2c_info); …… //改成如下 此处不改,轻则报错,重则车毁人亡,系统卡死,切记切记 struct i2c_adapter* i2c_adap; // use i2c2 i2c_adap = i2c_get_adapter(0); sil9136_client = i2c_new_device(i2c_adap, &sil9136_i2c_info); ……

再次编译,编译成功了,哇塞,此时外面走过了一个大长腿小.姐.姐。。。。。

运行

驱动模式使用的是1080P@60,支持所有分辨参数如下:

MODULE_PARM_DESC(norm,”5:720p@60, 6:720p@50, 7:1080i@60, 8:1080i@50, 9:1080p@60(default), 10:1080p@50, 11:1080p@25, 12:1080p@30, 13:4K@30″);

执行 insmod hi_sil9136.ko norm=13 然后,终端,刷的一下报错了:

/mnt/3531dv200 # insmod hi_sil9136.ko norm=13 sil9136 HDMI_4Kx2K@30! /mnt/3531dv200 # WARNING: CPU: 3 PID: 0 at kernel/locking/rtmutex.c:1586 rt_mutex_trylock+0x18/0x110 Modules linked in: hi_sil9136(O) hi_user(O) hi3531dv200_hdmi(PO) hi3531dv200_adec(PO) hi3531dv200_aenc(PO) hi3531dv200_ao(PO) hi3531dv200_ai(PO) hi3531dv200_aio(PO) hi_mipi_rx(O) hi3531dv200_mau(PO) hi3531dv200_nnie(PO) hi3531dv200_ive(PO) hi3531dv200_vda(PO) hi3531dv200_vdec(PO) hi3531dv200_vfmw(PO) hi3531dv200_jpegd(PO) hi3531dv200_jpege(PO) hi3531dv200_h265e(PO) hi3531dv200_h264e(PO) hi3531dv200_venc(PO) hi3531dv200_rc(PO) hi3531dv200_vedu(PO) hi3531dv200_chnl(PO) hifb(O) hi3531dv200_vo(PO) hi3531dv200_vpss(PO) hi3531dv200_vi(PO) hi3531dv200_vgs(PO) hi3531dv200_rgn(PO) hi3531dv200_tde(PO) hi3531dv200_sys(PO) hi3531dv200_base(PO) hi_osal(O) sys_config(O) CPU: 3 PID: 0 Comm: swapper/3 Tainted: P O 4.19.41 #2 Hardware name: Hisilicon Hi3531DV200 DEMO Board (DT) pstate: 40000005 (nZcv daif -PAN -UAO) pc : rt_mutex_trylock+0x18/0x110 lr : i2c_adapter_trylock_bus+0x10/0x18 sp : ffffff800801bd00 x29: ffffff800801bd00 x28: 0000000000000005 x27: ffffff800801be88 x26: ffffff80089b8000 x25: ffffff80089b6000 x24: 0000000000000000 x23: dead000000000200 x22: 0000000000000000 x21: 0000000000000002 x20: ffffff8000de14a8 x19: ffffffc01de05088 x18: 0000000000000400 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000400 x14: 0000000000000400 x13: 0000000000000400 x12: 0000000000000000 x11: 0000000000000000 x10: ffffffc01fbce728 x9 : 0000000000000001 x8 : ffffff800801bd88 x7 : ffffff800801bd90 x6 : 0000000000010001 x5 : ffffffc01c79e800 x4 : ffffff8000de1448 x3 : 0000000000000100 x2 : ffffff80085c2e60 x1 : ffffffc01e492100 x0 : ffffffc01de050b0 Call trace: rt_mutex_trylock+0x18/0x110 i2c_adapter_trylock_bus+0x10/0x18 i2c_transfer+0x4c/0xc8 _hi_i2c_read_byte+0x84/0xb8 [hi_sil9136] siHdmiTx_TPI_Poll+0x30/0x1a8 [hi_sil9136] call_timer_fn+0x20/0x78 run_timer_softirq+0x1bc/0x250 __do_softirq+0x108/0x200 irq_exit+0x74/0x78 __handle_domain_irq+0x60/0xb8 gic_handle_irq+0xa0/0x1cc el1_irq+0xb0/0x140 arch_cpu_idle+0x10/0x18 do_idle+0xb0/0x118 cpu_startup_entry+0x20/0x28 secondary_start_kernel+0x18c/0x1d8 —[ end trace 4f3b65da3d067664 ]—
<

我擦,有报错,严重怀疑这个代码是不是有问题啊,奶奶的,改完这报哪个,很能不能好好的玩耍了。从报的错误来分析,是I2C读取函数有问题函数的调用流程如下:

siHdmiTx_TPI_Poll->_hi_i2c_read_byte->i2c_transfer->i2c_adapter_trylock_bus->rt_mutex_trylock

既然知道了错误的地方,自然又是各种看代码,分析,调试。。。。最后搞定。 最后买个关子,具体的原因请下载代码自己看。

原始代码下载地址: https://www.ebaina.com/resources/240000028611 改下的代码下载地址: https://www.ebaina.com/resources/240000028612

猜你喜欢