建设个直播网站要多少钱百度搜索引擎的使用方法
编写使用多buffer的应用程序
文章目录
- 编写使用多buffer的应用程序
- 一、 编写一个支持单buffer、多buffer的APP
- 二、 编译程序
- 2.1 设置工具链
- 2.2 编译
- 三、上机测试
- 3.1 恢复内核使用自带的LCD驱动
- 3.2 禁止开发板自带的GUI程序
- 3.3 把测试程序放到板子上、执行
- 四、 LCD自动黑屏
- 致谢
一、 编写一个支持单buffer、多buffer的APP
循环显示整屏幕的红、绿、蓝、黑、白。
二、 编译程序
2.1 设置工具链
-
对于IMX6ULL
export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- export PATH=$PATH:/work/imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
2.2 编译
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <time.h>static int fd_fb;
static struct fb_fix_screeninfo fix; /* Current fix */
static struct fb_var_screeninfo var; /* Current var */
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;/******************************************************************************** @FunctionName: lcd_put_pixel* @Author: Hilbert* @DateTime: 2023年2月23日T12:38:51+0800* @Purpose: 在LCD指定位置上输出指定颜色(描点)* @param: x坐标,y坐标,颜色
*******************************************************************************/
void lcd_put_pixel(void *fb_base, int x, int y, unsigned int color)
{unsigned char *pen_8 = fb_base+y*line_width+x*pixel_width;unsigned short *pen_16; unsigned int *pen_32; unsigned int red, green, blue; pen_16 = (unsigned short *)pen_8;pen_32 = (unsigned int *)pen_8;switch (var.bits_per_pixel){case 8:{*pen_8 = color;break;}case 16:{/* 565 */red = (color >> 16) & 0xff;green = (color >> 8) & 0xff;blue = (color >> 0) & 0xff;color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);*pen_16 = color;break;}case 32:{*pen_32 = color;break;}default:{printf("can't surport %dbpp\n", var.bits_per_pixel);break;}}
}void lcd_draw_screen(void *fb_base, unsigned int color)
{int x, y;for (x = 0; x < var.xres; x++)for (y = 0; y < var.yres; y++)lcd_put_pixel(fb_base, x, y, color);
}/* ./multi_framebuffer_test single* ./multi_framebuffer_test double*/
int main(int argc, char **argv)
{int i;int ret;int nBuffers;int nNextBuffer = 1;char *pNextBuffer;unsigned int colors[] = {0x00FF0000, 0x0000FF00, 0x000000FF, 0, 0x00FFFFFF}; /* 0x00RRGGBB */struct timespec time;time.tv_sec = 0;time.tv_nsec = 100000000;if (argc != 2){printf("Usage : %s <single|double>\n", argv[0]);return -1;}fd_fb = open("/dev/fb0", O_RDWR);if (fd_fb < 0){printf("can't open /dev/fb0\n");return -1;}if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix)){printf("can't get fix\n");return -1;}if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)){printf("can't get var\n");return -1;}line_width = var.xres * var.bits_per_pixel / 8;pixel_width = var.bits_per_pixel / 8;screen_size = var.xres * var.yres * var.bits_per_pixel / 8;nBuffers = fix.smem_len / screen_size;printf("nBuffers = %d\n", nBuffers);fb_base = (unsigned char *)mmap(NULL , fix.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);if (fb_base == (unsigned char *)-1){printf("can't mmap\n");return -1;}if ((argv[1][0] == 's') || (nBuffers == 1)){while (1){/* use single buffer */for (i = 0; i < sizeof(colors)/sizeof(colors[0]); i++){lcd_draw_screen(fb_base, colors[i]);nanosleep(&time, NULL);}}}else{/* use double buffer *//* a. enable use multi buffers */var.yres_virtual = nBuffers * var.yres;ioctl(fd_fb, FBIOPUT_VSCREENINFO, &var);while (1){for (i = 0; i < sizeof(colors)/sizeof(colors[0]); i++){/* get buffer */pNextBuffer = fb_base + nNextBuffer * screen_size;/* set buffer */lcd_draw_screen(pNextBuffer, colors[i]);/* switch buffer */var.yoffset = nNextBuffer * var.yres;ioctl(fd_fb, FBIOPAN_DISPLAY, &var);ret = 0;ioctl(fd_fb, FBIO_WAITFORVSYNC, &ret);nNextBuffer = !nNextBuffer;nanosleep(&time, NULL);}}}munmap(fb_base , screen_size);close(fd_fb);return 0;
}
设置好工具链后,把use_multi_framebuffer
上传到Ubuntu,在该目录下执行make
即可
三、上机测试
3.1 恢复内核使用自带的LCD驱动
- 恢复驱动程序:修改
drivers/video/fbdev/Makefile
,恢复内核自带的mxsfb.c,如下:
obj-$(CONFIG_FB_MXS) += mxsfb.o
#obj-$(CONFIG_FB_MXS) += lcd_drv.o
-
编译设备树
- 把设备村文件复制到内核arch/arm/boo/dts目录
-
重新编译内核、设备树
make zImage make dtbs
-
替换内核、设备树
- 把编译出来的
arch/arm/boot/zImage
、arch/arm/boot/dts/imx6ull-14x14.dtb
- 放到开发板的/boot目录
- 把编译出来的
3.2 禁止开发板自带的GUI程序
在开发板上执行以下命令:
[original@ubuntu:~]# mv /etc/init.d/S99myirhmi2 /etc/
[original@ubuntu:~]# reboot
3.3 把测试程序放到板子上、执行
以下命令在开发板中执行。
-
挂载NFS
-
vmware使用NAT(假设windowsIP为192.168.1.100)
[original@ubuntu:~]# mount -t nfs -o nolock,vers=3,port=2049,mountport=9999 192.168.1.100:/work/nfs_rootfs /mnt
-
vmware使用桥接,或者不使用vmware而是直接使用服务器:假设Ubuntu IP为192.168.19.25
[original@ubuntu:~]# mount -t nfs -o nolock,vers=3 192.168.96.25:/work/nfs_rootfs /mnt
-
-
复制、执行程序
[original@ubuntu:~]# cp /mnt/multi_framebuffer_test /bin [original@ubuntu:~]# multi_framebuffer_test single 或 multi_framebuffer_test double
四、 LCD自动黑屏
为了省电,LCD在10分钟左右会自动黑屏。
如果你正在运行multi_framebuffer_test程序,可能会有如下提示(以IMX6ULL为例):
[ 961.147548] mxsfb 21c8000.lcdif: can't wait for VSYNC when fb is blank
这表示:当屏幕为blank(黑屏)时,无法等待VSYNC。
我们可以禁止LCD自动黑屏,执行以下命令即可:
#close lcd sleep
echo -e "\033[9;0]" > /dev/tty1
echo -e "\033[?25l" > /dev/tty1
致谢
以上笔记源自
韦东山
老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!
在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬!