核心内容摘要
DLSS智能切换工具:无缝管理游戏深度学习超级采样版本的创新方案
SPI-OLED测试OLED的D/C引脚电平逻辑电平状态模式名称作用描述例子低电平 (Low /
Command (命令)写入控制寄存器设置屏幕的工作状态。
设置亮度、开启滚动、设置起始页。
高电平 (High /
Data (数据)写入显存 (GDDRAM)直接改变屏幕显示的图像。
发送图片点阵、发送字符字模。
设备树定义ecspi1{pinctrl-namesdefault;pinctrl-0pinctrl_ecspi1;fsl,spi-num-chipselects2;cs-gpiosgpio426GPIO_ACTIVE_LOW,gpio424GPIO_ACTIVE_LOW;statusokay;oled:oled{compatiblespidev;r
;spi-max-frequency10000000;};};D/C引脚接在了GPIO4_20即116号引脚在APP程序中控制即可不需要写进驱动。
因此可直接使用内核通用SPI驱动spidev.c。
首先在内核目录中打开menuconfigbook100ask:~/100ask_imx6ull-sdk/Linux-
4.
88$ make menuconfig搜索SPIDEV搜索结果之前已经被设置为了M因此会被编译成模块book100ask:~/100ask_imx6ull-sdk/Linux-
4.
88$ make modules然后上传到开发板的/root目录下book100ask:~/100ask_imx6ull-sdk/Linux-
4.
88$ adb push drivers/spi/spidev.ko/root在APP程序中D/C引脚初始化及控制函数voiddc_pin_init(intnumber){charcmd[100];sprintf(cmd,echo %d /sys/class/gpio/export,number);system(cmd);sprintf(cmd,echo out /sys/class/gpio/gpio%d/direction,number);system(cmd);}voidoled_set_dc_pin(intval){charcmd[100];sprintf(cmd,echo %d /sys/class/gpio/gpio%d/value,val,dc_pin_num);system(cmd);}voiddc_pin_exit(intnumber){charcmd[100];sprintf(cmd,echo %d /sys/class/gpio/unexport,number);system(cmd);}实验结果屏幕显示数据的速率肉眼可见地缓慢性能太差。
原因分析**设置位置 (OLED_DIsp_Set_Pos)**时它内部调用了3 次oled_write_cmd_data。
每次oled_write_cmd_data都会执行system(echo ...)创建进程很慢执行write(fd_spidev, uc_data,
1 字节写入小计发 3 字节命令却搞了 3 次进程创建 3 次 1 字节写。
发送数据 (oled_write_datas)时执行oled_set_dc_pin(
又是一次system()创建进程。
执行write(fd, buf,
8 字节写。
总计显示一个8bitx16bit字符一共执行了8 次进程创建(system调用)6 次 1 字节写入(设置坐标)2 次 8 字节写入(实际像素数据)优化 OLED 性能的核心思路减少系统调用次数和消除高开销操作。
目前代码中 导致性能低的最大原因是system()函数其次是碎片化的write()操作system()函数优化步骤修改dc_pin_init提前打开文件。
修改oled_set_dc_pin直接写文件描述符。
staticintfd_dc_value;// 定义为静态全局变量voiddc_pin_init(intnumber){charcmd[100];charpath[100];dc_pin_numnumber;sprintf(cmd,echo %d /sys/class/gpio/export,number);system(cmd);sprintf(cmd,echo out /sys/class/gpio/gpio%d/direction,number);system(cmd);// 【关键优化】提前打开 value 文件sprintf(path,/sys/class/gpio/gpio%d/value,number);fd_dc_valueopen(path,O_WRONLY);}voidoled_set_dc_pin(intval){if(val)write(fd_dc_value,1,
;elsewrite(fd_dc_value,0,
;}其次是 oled_write_cmd_data目前每写 1 字节就要切换一次 DC 引脚并执行一次 write。
优化逻辑尽量将连续的命令或连续的数据打包在一起发送。
优化Set_Pos函数原函数执行了 3 次write可以合并为 1 次。
voidOLED_DIsp_Set_Pos(intx,inty){unsignedcharbuf[3];buf[0]0xb0y;buf[1](x0x0f);buf[2]((x0xf
0)
|0x10;oled_set_dc_pin(
;// 只切换一次 DCspi_write_datas(buf,
;// 一次性发送 3 字节命令}优化后瞬间显示一整帧字符无卡顿、无闪烁。
之后再试试显存缓冲区 (Frame Buffer)的优化路线。