刚开始kernel屏幕旋转还是很顺利的,但是因为使用芯片自带的G2d翻转,所有会出现uboot的图片加载kernel进行了旋转。为了解决这问题花了大量的时间研究源代码将kernel旋转的图片手动旋转旋转回来了。
- 先将boot-resource的bootlogo.bmp图标翻转90度
- 将kernel配置为支持g2d模式
#CONFIG_SUNXI_DISP2_FB_DISABLE_ROTATE=y
CONFIG_SUNXI_G2D=y
CONFIG_SUNXI_G2D_MIXER=y
CONFIG_SUNXI_G2D_ROTATE=y
CONFIG_SUNXI_DISP2_FB_HW_ROTATION_SUPPORT=y
3.设备树更改
3.1启用g2d
g2d: g2d@5410000 {
compatible = "allwinner,sunxi-g2d";
reg = <0x0 0x05410000 0x0 0x3ffff>;
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_G2D>, <&ccu CLK_G2D>, <&ccu CLK_MBUS_G2D>;
clock-names = "bus", "g2d", "mbus_g2d";
resets = <&ccu RST_BUS_G2D>;
iommus = <&mmu_aw 3 1>;
status = "okay";
};
3.2显示节点更改
disp_rotation_used = <1>;
degree0 = <1>;
fb0_format = <5>;
fb0_buffer_num = <1>;
fb0_width = <1280>;
fb0_height = <800>;
3.3更改触摸节点
ctp_screen_max_x = <0x500>;
ctp_screen_max_y = <0x320>;
ctp_revert_x_flag = <0x0>;
ctp_revert_y_flag = <0x0>;
ctp_exchange_x_y_flag = <0x0>;
3.4在kernel drivers/video/fbdev/sunxi/disp2/disp/dev_fb.c 添加函数
void rotateBmp90(char* src_addr, int width, int height, int bpp, int stride) {
// 计算每行像素数据的字节数
int bbpNum=(bpp/8);
int column = height * bbpNum;
// 创建临时缓冲区用于保存旋转后的图像数据
char* temp_data = vmalloc(column * width);
int y=0,x=0;
// 复制旋转后的图像数据到临时缓冲区
for (y = 0; y < height; y++) {
char* src_row_start = src_addr + (y * stride);
char* dest_row_start = temp_data + (y* bbpNum);
// 复制像素数据并进行左右翻转
for ( x = 0; x < width; x++) {
char* src_pixel = src_row_start + (x * bbpNum);
char* dest_pixel = dest_row_start + (width - 1 - x)*column;//*row_bytes
// 复制像素值
memcpy(dest_pixel, src_pixel, bbpNum);
}
}
// 将旋转后的图像数据写回原始内存地址
for (y = 0; y < width; y++) { //循环复制每一行
memcpy((void *)src_addr, (void *)temp_data, column);
temp_data += column; //地址是增加地址宽度
src_addr += stride;
}
// 释放临时缓冲区
vfree(temp_data);
}
在 static int Fb_copy_boot_fb(u32 sel, struct fb_info *info)添加rotateBmp90函数
src_addr_b = src_addr + map_offset;
if ((src_crop_b > src_crop_t) &&
(src_height > src_crop_b - src_crop_t) && (src_crop_t >= 0) &&
(src_height >= src_crop_b)) {
src_height = src_crop_b - src_crop_t;
src_addr_b += (src_stride * src_crop_t);
}
if ((src_crop_r > src_crop_l) &&
(src_width > src_crop_r - src_crop_l) && (src_crop_l >= 0) &&
(src_width >= src_crop_r)) {
src_width = src_crop_r - src_crop_l;
src_addr_b += (src_crop_l * src_bpp >> 3);
}
//先更旋转好图标 旋转90需要更改长宽
rotateBmp90(src_addr_b, src_width, src_height, src_bpp, src_stride);
ret=src_height;
src_height=src_width;
src_width=ret;
if (src_height < dst_height) {
int dst_crop_t = (dst_height - src_height) >> 1;
dst_addr += (dst_stride * dst_crop_t);
} else if (src_height > dst_height) {
__wrn("src_height(%d) > dst_height(%d),please cut the height\n",
src_height, dst_height);
Fb_unmap_kernel(src_addr);
return -1;
}
4 lvgl适配
4.1 8.3.6版本lv_drivers/display/fbdev.c
在void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)函数末尾添加
lv_disp_flush_ready(drv);
ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo);
4.2 9.1.0版本lvgl/src/drivers/display/fb/lv_linux_fbdev.c
在static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p)函数末尾添加
lv_display_flush_ready(disp);
ioctl(dsc->fbfd, FBIOPAN_DISPLAY, &(dsc->vinfo));
452

被折叠的 条评论
为什么被折叠?



