发 帖  
原厂入驻New
[经验]

【100ASK_IMX6ULL(带屏) 开发板试用体验】开箱上电&烧录系统&编写项目用DEMO代码

2020-10-25 17:11:32  1662 开发板试用 烧录系统
分享
0
       国庆期间收到板子,因为在忙着别的事情以至于一直都没有发帖,现在补上。板子收到之后第一印象就是外设接口非常齐全,有两个USB接口,一个mpcie接口(实际上是走USB接口协议),一个HDMI接口,一个摄像头接口,两个网口以及工业用的CAN/485接口,首先说说我欣赏的地方,那就是HDMI接口,因为使用外置转接芯片引出HDMI接口的imx6UL/IMX6ULL开发板真的非常稀少,除了韦东山老师这款100ask-IMX6UL开发板外,就只有野火的IMX6-pro以及乐美客的一款工控板,而且那款乐美客IMX6UL工控板早已停产,市面上根本买不到,只在乐美客少数几次活动中能见到,在乐美客厂家介绍网站上的piano工控板也是换用了IMX6D/Q主控,以致不需要转接芯片的HDMI接口,如图绿色板子:
4.jpg 5.jpg


对于韦东山老师的CAN和485接口,数量各一个,这个一般是用于评估教学用的,有就行了不需要多,而专业的工控板一般会配备多个CAN/485接口,比如米尔的MYC-IMX6UL和一些国内的工控板厂家就是这样做的:
6.jpg

韦老师的这款板子唯一美中不足的地方就是GPIO接口数量实在是稀少,好在聪明的我——电子发烧友一名普普通通的试用者,另辟蹊径,使用嵌入式平台里面弥补GPIO接口数量不足的绝佳方案——外挂MCU主控,也就是使用一个单片机板子,通过USB接口与嵌入式平台进行通信,所有对于GPIO传感器的采集工作如I2C SPI USART 单总线等,交由单片机板子进行,单片机板子只需要将这些数据通过USB报文上报到嵌入式平台即可,不需要再占用IMX6UL主控本身就吃紧的CPU和内存资源。
      板子拿到手之后烧录的是米尔厂家推出的measy-iot文件系统,这个文件系统跟我的项目格格不入完全冲突,肯定要换掉,好在韦老师提供了一个Ubuntu的EMMC镜像和烧录工具,非常体贴到位,烧录步骤也非常简单,在韦老师提供的网盘地址那里可以下载,打开100ASK_IMX6ULL_Flashing工具,将EMMC烧录固件放到files文件夹里面,这里准备了一个预设的Ubuntu镜像,注意这个镜像是必须要带有分区表/uboot/内核/dtb的,不能只有文件系统,不然烧录完了也没法启动。设置拨码开关为0001即USB启动,再用micro USB线将板子的OTG烧录接口接到电脑上,烧录工具提示设备已连接就可以进行烧录了:
7.jpg 8.jpg IMG_20201025_153609.jpg IMG_20201025_153611.jpg
烧录完毕设置拨码0010即可从EMMC启动,启动画面只有命令行:
IMG_20201025_154057.jpg

后续可以通过apt安装诸多软件,比如xorg+xfce4装一个轻量化桌面,当然这是后话了,板子第一次上电启动要先更新软件库,将/etc/apt/source.list文件的内容替换,阿里云armhf源,适用于所有32位armv7 ubuntu主控的开发板的软件源:
  1. deb http://mirrors.aliyun.com/ubuntu-ports/ xenial main

  2. deb-src http://mirrors.aliyun.com/ubuntu-ports/ xenial main

  3. deb http://mirrors.aliyun.com/ubuntu-ports/ xenial-updates main

  4. deb-src http://mirrors.aliyun.com/ubuntu-ports/ xenial-updates main

  5. deb http://mirrors.aliyun.com/ubuntu-ports/ xenial universe

  6. deb-src http://mirrors.aliyun.com/ubuntu-ports/ xenial universe

  7. deb http://mirrors.aliyun.com/ubuntu-ports/ xenial-updates universe

  8. deb-src http://mirrors.aliyun.com/ubuntu-ports/ xenial-updates universe

  9. deb http://mirrors.aliyun.com/ubuntu-ports/ xenial-security main

  10. deb-src http://mirrors.aliyun.com/ubuntu-ports/ xenial-security main

  11. deb http://mirrors.aliyun.com/ubuntu-ports/ xenial-security universe

  12. deb-src http://mirrors.aliyun.com/ubuntu-ports/ xenial-security universe
复制代码


这样就可以用
  1. apt update
  2. <div>apt upgrade</div>
复制代码
来进行软件库更新:
1.jpg 2.jpg 3.jpg
装好了之后我还要安装gcc g++ make xorg xfce4等常用软件
  1. apt install gcc g++ make xorg xfce4
复制代码

装好了xfce4之后板子就可以在命令行敲startx命令启动xfce4桌面:
IMG_20201025_161013.jpg

当然了,目前的项目DEMO并不需要这种桌面,而IMX6ULL主控跑xfce4图形界面的应用或者QT之类的应用也会非常卡,所以先跳过,先把项目代码跑起来,项目DEMO代码里面有两个外设需要驱动,分别是用于显示的/dev/fb0和用于摄像头图像采集用的/dev/video1,/dev/fb0操作非常简单,不多说,甚至可以直接沿用以前的代码:
  1. #include "lcd.h"
  2. #include "font.h"

  3. static int lcd_buf[LCD_WIDTH*LCD_HEIGHT];
  4. static unsigned int lcd_buff[LCD_HEIGHT][LCD_WIDTH];
  5. static unsigned char bmp_buf[LCD_WIDTH*LCD_HEIGHT*4],*point=bmp_buf;

  6. int tsfd,ret,fd_lcd;
  7. struct input_event myinput;


  8. void Get_Information_Frame_Buffer(char *dev)
  9. {
  10.     struct fb_var_screeninfo vinfo;
  11.     printf("dev=%s\n",dev);
  12.     fd_lcd=open(dev,O_RDWR);
  13.     if(fd_lcd==-1)
  14.     {
  15.          printf("Device open faiLED.\n");
  16.          return ;
  17.     }
  18.     if (ioctl(fd_lcd,FBIOGET_VSCREENINFO,&vinfo))
  19.     {
  20.          printf("Device get information failed.\n");
  21.          return ;
  22.     }
  23.     close(fd_lcd);
  24.     printf("%d %d %d\n",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);

  25. }

  26. void LCD_Effect()
  27. {
  28.         fd_lcd=open("/dev/fb0",O_RDWR);    //  O_RDONLY, O_WRONLY, or  O_RDWR
  29.         if(fd_lcd==-1)
  30.         {
  31.                 printf("open LCD failed!\n");
  32.                 return ;
  33.         }
  34.         write(fd_lcd,lcd_buf,LCD_WIDTH*LCD_HEIGHT*4);
  35.         close(fd_lcd);
  36. }

  37. void LCD_Show_Buffer(char *dev_name,int x1,int y1,int width,int height,unsigned char *frame_buffer)
  38. {
  39.     int fd_lcd,i,j;
  40.         fd_lcd=open(dev_name,O_RDWR);
  41.         if(fd_lcd==-1)
  42.         {
  43.                 printf("open LCD failed!\n");
  44.                 return ;
  45.         }
  46.         for(i=x1;i<LCD_HEIGHT+x1;i++)
  47.         {
  48.             for(j=y1;j<LCD_WIDTH+y1;j++)
  49.                 if(i<=height&&j<=width)
  50.                 {
  51.                     lcd_buf[i*LCD_WIDTH+j]=
  52.                     frame_buffer[(i*width+j)*3]|
  53.                     frame_buffer[(i*width+j)*3+1]<<8|
  54.                     frame_buffer[(i*width+j)*3+2]<<16;
  55.                 }
  56.                 //else lcd_buf[i*LCD_WIDTH+j]=0xffff0000;
  57.         }
  58.         write(fd_lcd,lcd_buf,LCD_WIDTH*LCD_HEIGHT*4);
  59. //                printf("LCD_Show_Buffer OK!\n");
  60.         close(fd_lcd);
  61. }

  62. void LCD_Clear_Screen(long color)
  63. {
  64.         int i;
  65.         fd_lcd=open("/dev/fb0",O_RDWR);    //  O_RDONLY, O_WRONLY, or  O_RDWR
  66.         if(fd_lcd==-1)
  67.         {
  68.                 printf("open LCD failed!\n");
  69.                 return ;
  70.         }

  71.         for(i=0;i<LCD_WIDTH*LCD_HEIGHT;i++)
  72.                 lcd_buf[i]=color;


  73.         ret = write(fd_lcd,lcd_buf,LCD_WIDTH*LCD_HEIGHT*4);
  74.         if(ret == -1)
  75.         {
  76.                 printf("fill frame failed!\n");
  77.                 return ;
  78.         }
  79.         close(fd_lcd);
  80. }

  81. void Open_Touch_Screen()
  82. {
  83.         tsfd=open("/dev/input/event0",O_RDWR);
  84.         if(tsfd==-1)
  85.         {
  86.                 printf("open TS failed!\n");
  87.                 return ;
  88.         }
  89. }

  90. void Get_Touch_Screen(int * x,int * y)
  91. {
  92.         read(tsfd,&myinput,sizeof(myinput));
  93.         if(myinput.type==EV_ABS)
  94.         {

  95.                 if(myinput.code==ABS_X)
  96.                 {
  97.                         *x=myinput.value;
  98.                 }

  99.                 if(myinput.code==ABS_Y)
  100.                 {
  101.                         *y=myinput.value;
  102.                 }
  103.         }
  104. }

  105. int LCD_Show_ASCII_64(int x,int y,int fontcolor,int backcolor,int word)
  106. {
  107.     int i,j,k;
  108.     unsigned char temp;
  109.     word-=0x20;
  110.     for(j=0;j<64;j++)
  111.     {
  112.         for(i=0;i<4;i++)
  113.         {
  114.             temp=ascii_font_64[j*4+i+word*256];
  115.             for(k=0;k<8;k++)
  116.             {
  117.                 if(temp&0x80)
  118.                     lcd_buf[i*8+k+x+LCD_WIDTH*(j+y)]=fontcolor;
  119.                 else
  120.                     lcd_buf[i*8+k+x+LCD_WIDTH*(j+y)]=backcolor;
  121.                 temp<<=1;
  122.             }
  123.         }

  124.     }
  125. }

  126. int LCD_Show_ASCII_String_64(int x,int y,int wordcolor,int backcolor,char s[])
  127. {
  128.         int i=0;
  129.         for(i=0;s[i]!='\0';i++)
  130.                 LCD_Show_ASCII_64(x+i*32,y,wordcolor,backcolor,s[i]);

  131. }

  132. //int LCD_Show_Chinese_64(int x,int y,int fontcolor,int backcolor,int word)
  133. //{
  134. //    int i,j,k;
  135. //    unsigned char temp;
  136. //    for(j=0;j<64;j++)
  137. //    {
  138. //        for(i=0;i<8;i++)
  139. //        {
  140. //            temp=chinese_font_64[j*8+i+word*512];
  141. //            for(k=0;k<8;k++)
  142. //            {
  143. //                if(temp&0x80)
  144. //                    lcd_buf[i*8+k+x+LCD_WIDTH*(j+y)]=fontcolor;
  145. //                else
  146. //                    lcd_buf[i*8+k+x+LCD_WIDTH*(j+y)]=backcolor;
  147. //                temp<<=1;
  148. //            }
  149. //        }
  150. //
  151. //    }
  152. //}

  153. //int LCD_Show_BMP_File(int xpos,int ypos,char* filename)
  154. //{
  155. //        int i,j,fbmp,fd,width,width_mod,height;
  156. //        fd=open("/dev/fb0",O_RDWR);
  157. //        if(fd == -1)
  158. //        {
  159. //                printf("open LCD failed!\n");
  160. //                return -1;
  161. //        }
  162. //
  163. //        fbmp=open(filename,O_RDONLY);
  164. //
  165. //        read(fbmp,bmp_buf,54);
  166. //        width=bmp_buf[21]<<24|bmp_buf[20]<<16|bmp_buf[19]<<8|bmp_buf[18];
  167. //        height=bmp_buf[25]<<24|bmp_buf[24]<<16|bmp_buf[23]<<8|bmp_buf[22];
  168. //
  169. //        fbmp=open(filename,O_RDONLY);
  170. //
  171. //        read(fbmp,bmp_buf,width*height*3+54);
  172. //
  173. //        width_mod=width%4;
  174. //
  175. //        for(i=0;i<LCD_HEIGHT;i++)
  176. //        {
  177. //            for(j=0;j<LCD_WIDTH;j++)
  178. //                if(i<=height&&j<=width)
  179. //                {
  180. //                    lcd_buf[i*LCD_WIDTH+j]=
  181. //                    bmp_buf[(i*width+j)*3+54+i*width_mod]|
  182. //                    bmp_buf[(i*width+j)*3+55+i*width_mod]<<8|
  183. //                    bmp_buf[(i*width+j)*3+56+i*width_mod]<<16;
  184. //                }
  185. //                    else lcd_buf[i*LCD_WIDTH+j]=0;
  186. //        }
  187. //
  188. //        for(i=0;i<LCD_HEIGHT;i++)
  189. //                for(j=0;j<LCD_WIDTH;j++)
  190. //                    lcd_buff[i][j]=lcd_buf[i*LCD_WIDTH+j];
  191. //
  192. //        for(i=0;i<LCD_HEIGHT;i++)
  193. //                for(j=0;j<LCD_WIDTH;j++)
  194. //                    lcd_buff_2[height-i+ypos][j+xpos]=lcd_buff[i][j];
  195. //
  196. //        for(i=0;i<LCD_HEIGHT;i++)
  197. //                for(j=0;j<LCD_WIDTH;j++)
  198. //                    lcd_buf[i*LCD_WIDTH+j]=lcd_buff_2[i][j];
  199. //
  200. //        //ret = write(fd,lcd_buf,LCD_WIDTH*LCD_HEIGHT*4);
  201. //        if(ret == -1)
  202. //        {
  203. //                printf("fill frame failed!\n");
  204. //                return -1;
  205. //        }
  206. //        close(fd);
  207. //}
  208. //
  209. //void LCD_Show_JPG_File(int xpos,int ypos,char *filename)
  210. //{
  211. //    int fd,fjpg,i,j;
  212. //    FILE *input_file=fopen(filename,"rb");
  213. //    struct jpeg_decompress_struct cinfo;
  214. //    //JPEG鍥惧儚鍦ㄨВ鐮佽繃绋嬩腑锛屼娇鐢╦peg_decompress_struct绫诲瀷鐨勭粨鏋勪綋鏉ヨ〃绀猴紝鍥惧儚鐨勬墍鏈変俊鎭兘瀛樺偍鍦ㄧ粨鏋勪綋涓?
  215. //    struct jpeg_error_mgr jerr;
  216. //    //瀹氫箟涓€涓爣鍑嗙殑閿欒缁撴瀯浣擄紝涓€鏃︾▼搴忓嚭鐜伴敊璇氨浼氳皟鐢╡xit()鍑芥暟閫€鍑鸿繘绋?
  217. //    JSAMPARRAY buffer;
  218. //    //鐢ㄤ簬瀛樺彇涓€琛屾暟鎹?
  219. //    fjpg=open((char *)"/home/fa/1.jpg",O_RDONLY);
  220. //    cinfo.err = jpeg_std_error(&jerr);//缁戝畾閿欒澶勭悊缁撴瀯瀵硅薄
  221. //    jpeg_create_decompress(&cinfo);//鍒濆鍖朿info缁撴瀯
  222. //    jpeg_stdio_src(&cinfo,input_file);//鎸囧畾瑙e帇缂╂暟鎹簮
  223. //    jpeg_read_header(&cinfo,TRUE);//鑾峰彇鏂囦欢淇℃伅
  224. //    jpeg_start_decompress(&cinfo);//寮€濮嬭В鍘嬬缉
  225. //
  226. //    int width = cinfo.output_width;//鍥惧儚瀹藉害
  227. //    int height = cinfo.output_height;//鍥惧儚楂樺害
  228. //    int depth = cinfo.output_components;//鍥惧儚娣卞害
  229. //
  230. //    memset(bmp_buf,0,sizeof(unsigned char)*width*height*depth);
  231. //
  232. //    buffer=(*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,JPOOL_IMAGE,width*depth,1);
  233. //    //鍒嗛厤涓€琛屾暟鎹┖闂?
  234. //
  235. //    while(cinfo.output_scanline<height)//閫愯璇诲彇浣嶅浘鏁版嵁
  236. //    {
  237. //        jpeg_read_scanlines(&cinfo,buffer,1);
  238. //        //璇诲彇涓€琛宩pg鍥惧儚鏁版嵁鍒癰uffer
  239. //        memcpy(point,*buffer,width*depth);
  240. //        //灏哹uffer涓殑鏁版嵁閫愯缁檚rc_buff
  241. //        point+=width*3;
  242. //        //鎸囬拡鍋忕Щ涓€琛?
  243. //    }
  244. //
  245. //    jpeg_finish_decompress(&cinfo);//瑙e帇缂╁畬姣?
  246. //
  247. //    fd=open("/dev/fb0",O_RDWR);    //  O_RDONLY, O_WRONLY, or  O_RDWR
  248. //
  249. //
  250. //    for(i=0;i<LCD_HEIGHT;i++)
  251. //    {
  252. //        for(j=0;j<LCD_WIDTH;j++)
  253. //            if(i<=height&&j<=width)
  254. //                lcd_buf[(i+ypos)*(LCD_WIDTH)+j+xpos]=bmp_buf[(i*width+j)*3]<<16|bmp_buf[(i*width+j)*3+1]<<8|bmp_buf[(i*width+j)*3+2];
  255. //
  256. //            else lcd_buf[(i+ypos)*(LCD_WIDTH)+j+xpos]=0;
  257. //    }
  258. //
  259. //    write(fd,lcd_buf,LCD_WIDTH*LCD_HEIGHT*4);
  260. //}

复制代码




然后是/dev/video1,这个是板子连接外置视频输入设备,我这边只接了一个USB摄像头,安装命名顺延规则就是video1:
  1. #include "camera.h"
  2. #include "lcd.h"

  3. static int fd_video;
  4. static struct  v4l2_capability cap;
  5. struct v4l2_fmtdesc fmtdesc;
  6. struct v4l2_format fmt;
  7. struct v4l2_streamparm setfps;
  8. struct v4l2_requestbuffers req;
  9. struct v4l2_buffer buf;
  10. enum v4l2_buf_type type;

  11. unsigned char frame_buffer[IMAGEWIDTH*IMAGEHEIGHT*3];
  12. buffer *buffers;

  13. int V4L2_Init(const char * filename)
  14. {
  15.     int i,ret = 0;

  16.     if ((fd_video=open(filename,O_RDWR))==-1)
  17.     {
  18.         printf("Error opening V4L inteRFace\n");
  19.         return (0);
  20.     }

  21.     if (ioctl(fd_video,VIDIOC_QUERYCAP,&cap) == -1)
  22.     {
  23.         printf("Error opening device %s: unable to query device.\n",filename);
  24.         return (0);
  25.     }
  26.     else
  27.     {
  28.          printf("driver:\t\t%s\n",cap.driver);
  29.          printf("card:\t\t%s\n",cap.card);
  30.          printf("bus_info:\t%s\n",cap.bus_info);
  31.          printf("version:\t%d\n",cap.version);
  32.          printf("capabilities:\t%x\n",cap.capabilities);

  33.          if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE)
  34.          {
  35.             printf("Device %s: supports capture.\n",filename);
  36.         }

  37.         if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING)
  38.         {
  39.             printf("Device %s: supports streaming.\n",filename);
  40.         }
  41.     }

  42.     fmtdesc.index=0;
  43.     fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  44.     printf("Support format:\n");
  45.     while(ioctl(fd_video,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
  46.     {
  47.         printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);
  48.         fmtdesc.index++;
  49.     }

  50.     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  51.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  52.     fmt.fmt.pix.height = IMAGEHEIGHT;
  53.     fmt.fmt.pix.width =  IMAGEWIDTH;
  54.     fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

  55.     if(ioctl(fd_video,VIDIOC_S_FMT, &fmt) == -1)
  56.     {
  57.         printf("Unable to set format\n");
  58.         return 1;
  59.     }
  60.     if(ioctl(fd_video,VIDIOC_G_FMT, &fmt) == -1)
  61.     {
  62.         printf("Unable to get format\n");
  63.         return 2;
  64.     }
  65.     {
  66.          printf("fmt.type:\t\t%d\n",fmt.type);
  67.          printf("pix.pixelformat:\t%c%c%c%c\n",fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,(fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF);
  68.          printf("pix.height:\t\t%d\n",fmt.fmt.pix.height);
  69.          printf("pix.width:\t\t%d\n",fmt.fmt.pix.width);
  70.          printf("pix.field:\t\t%d\n",fmt.fmt.pix.field);
  71.     }
  72.     //set fps
  73.     ioctl(fd_video, VIDIOC_G_PARM, &setfps);
  74.     //setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  75.     //setfps.parm.capture.timeperframe.numerator = 30;
  76.     //setfps.parm.capture.timeperframe.denominator = 30;


  77.     req.count=4;
  78.     req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  79.     req.memory=V4L2_MEMORY_MMAP;
  80.     if(ioctl(fd_video,VIDIOC_REQBUFS,&req)==-1)
  81.     {
  82.         printf("request for buffers error\n");
  83.         return 3;
  84.     }

  85.     printf("init %s \t[OK]\n",filename);

  86.     return 0;
  87. }

  88. int V4l2_Grab()
  89. {
  90.     unsigned int n_buffers;

  91.     buffers =(buffer*)malloc(req.count*sizeof (*buffers));
  92.     if (!buffers)
  93.     {
  94.         printf ("Out of memory\n");
  95.         return 0;
  96.     }

  97.     for (n_buffers = 0; n_buffers < req.count; n_buffers++)
  98.     {
  99.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  100.         buf.memory = V4L2_MEMORY_MMAP;
  101.         buf.index = n_buffers;
  102.         //query buffers
  103.         if (ioctl (fd_video,VIDIOC_QUERYBUF, &buf) == -1)
  104.         {
  105.             printf("query buffer error\n");
  106.             return(0);
  107.         }

  108.         buffers[n_buffers].length = buf.length;
  109.         buffers[n_buffers].start = mmap(NULL,buf.length,PROT_READ |PROT_WRITE, MAP_SHARED,
  110.         fd_video, buf.m.offset);
  111.         if (buffers[n_buffers].start == MAP_FAILED)
  112.         {
  113.             printf("buffer map error\n");
  114.             return 0;
  115.         }
  116.     }

  117.     for (n_buffers = 0; n_buffers < req.count; n_buffers++)
  118.     {
  119.         buf.index = n_buffers;
  120.         ioctl(fd_video, VIDIOC_QBUF, &buf);
  121.     }

  122.     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  123.     ioctl (fd_video, VIDIOC_STREAMON, &type);

  124.     ioctl(fd_video, VIDIOC_DQBUF, &buf);

  125. //    printf("grab yuyv OK!\n");
  126.     return 1;
  127. }

  128. int Yuyv_2_RGB888(buffer* input_buffers,unsigned char *output_buffer)
  129. {
  130.     int i,j,r1,g1,b1,r2,g2,b2;
  131.     unsigned char y1,y2,u,v;
  132.     unsigned char *pointer;

  133.     pointer =(unsigned char*)input_buffers[0].start;

  134.     for(i=0;i<IMAGEHEIGHT;i++)
  135.     {
  136.     for(j=0;j<IMAGEWIDTH/2;j++)
  137.     {
  138.     y1 = *( pointer + (i*IMAGEWIDTH/2+j)*4);
  139.     u  = *( pointer + (i*IMAGEWIDTH/2+j)*4 + 1);
  140.     y2 = *( pointer + (i*IMAGEWIDTH/2+j)*4 + 2);
  141.     v  = *( pointer + (i*IMAGEWIDTH/2+j)*4 + 3);

  142.     r1 = y1 + 1.042*(v-128);
  143.     g1 = y1 - 0.34414*(u-128) - 0.71414*(v-128);
  144.     b1 = y1 + 1.772*(u-128);

  145.     r2 = y2 + 1.042*(v-128);
  146.     g2 = y2 - 0.34414*(u-128) - 0.71414*(v-128);
  147.     b2 = y2 + 1.772*(u-128);

  148.     if(r1>255)
  149.     r1 = 255;
  150.     else if(r1<0)
  151.     r1 = 0;

  152.     if(b1>255)
  153.     b1 = 255;
  154.     else if(b1<0)
  155.     b1 = 0;

  156.     if(g1>255)
  157.     g1 = 255;
  158.     else if(g1<0)
  159.     g1 = 0;

  160.     if(r2>255)
  161.     r2 = 255;
  162.     else if(r2<0)
  163.     r2 = 0;

  164.     if(b2>255)
  165.     b2 = 255;
  166.     else if(b2<0)
  167.     b2 = 0;

  168.     if(g2>255)
  169.     g2 = 255;
  170.     else if(g2<0)
  171.     g2 = 0;

  172.     *(output_buffer + (i*IMAGEWIDTH/2+j)*6    ) = (unsigned char)b1;
  173.     *(output_buffer + (i*IMAGEWIDTH/2+j)*6 + 1) = (unsigned char)g1;
  174.     *(output_buffer + (i*IMAGEWIDTH/2+j)*6 + 2) = (unsigned char)r1;
  175.     *(output_buffer + (i*IMAGEWIDTH/2+j)*6 + 3) = (unsigned char)b2;
  176.     *(output_buffer + (i*IMAGEWIDTH/2+j)*6 + 4) = (unsigned char)g2;
  177.     *(output_buffer + (i*IMAGEWIDTH/2+j)*6 + 5) = (unsigned char)r2;
  178.     }
  179.     }
  180. //        printf("change to RGB OK! \n");
  181.     free(input_buffers);
  182. }

  183. //int Encode_Jpeg(unsigned char *lpbuf,int width,int height,const char *output_filename)
  184. //{
  185. //    struct jpeg_compress_struct cinfo ;
  186. //    struct jpeg_error_mgr jerr ;
  187. //    JSAMPROW  row_pointer[1] ;
  188. //    int row_stride ;
  189. //    char *buf=NULL ;
  190. //    int x ;
  191. //
  192. //    FILE *fptr_jpg = fopen ((char *)output_filename,"wb");
  193. //    if(fptr_jpg==NULL)
  194. //    {
  195. //    printf("Encoder:open file failed!/n") ;
  196. //     return 0;
  197. //    }
  198. //
  199. //    cinfo.err = jpeg_std_error(&jerr);
  200. //    jpeg_create_compress(&cinfo);
  201. //    jpeg_stdio_dest(&cinfo, fptr_jpg);
  202. //
  203. //    cinfo.image_width = width;
  204. //    cinfo.image_height = height;
  205. //    cinfo.input_components = 3;
  206. //    cinfo.in_color_space = JCS_RGB;
  207. //
  208. //    jpeg_set_defaults(&cinfo);
  209. //
  210. //
  211. //    jpeg_set_quality(&cinfo, 80,1);
  212. //
  213. //
  214. //    jpeg_start_compress(&cinfo, 1);
  215. //
  216. //    row_stride = width * 3;
  217. //    buf=(char*)malloc(row_stride);
  218. //    row_pointer[0] =(unsigned char*)buf;
  219. //    while (cinfo.next_scanline < height)
  220. //    {
  221. //     for (x=0;x<row_stride; x+=3)
  222. //    {
  223. //
  224. //    buf[x]   = lpbuf[x];
  225. //    buf[x+1] = lpbuf[x+1];
  226. //    buf[x+2] = lpbuf[x+2];
  227. //
  228. //    }
  229. //    jpeg_write_scanlines (&cinfo, row_pointer, 1);
  230. //    lpbuf += row_stride;
  231. //    }
  232. //
  233. //    jpeg_finish_compress(&cinfo);
  234. //    fclose(fptr_jpg);
  235. //    jpeg_destroy_compress(&cinfo);
  236. //    free(buf);
  237. //    printf("save \"JPEG\"OK\n");
  238. //    return 0 ;
  239. //
  240. //}

  241. int close_v4l2(void)
  242. {
  243.      if(fd_video!=-1)
  244.      {
  245.          close(fd_video);
  246.          return 1;
  247.      }
  248.      return 0;
  249. }

复制代码

编写makefile:
  1. PROG = main
  2. SRCS = main.cc lcd.cc camera.cc

  3. CLEANFILES = $(PROG)

  4. #CFLAGS +=  -lcrypto
  5. #LDFLAGS +=

  6. all: $(PROG)

  7. $(PROG): $(SRCS)
  8.         $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)

  9. clean:
  10.         rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))


复制代码
使用make进行编译:
11.jpg
驱动摄像头效果,由于IMX6UL主控性能确实不怎么高,无论是grab抓取图像还是yuyv解码都非常慢,所以驱动摄像头的效果也不好:

IMG_20201025_170105.jpg
10.jpg
9.jpg
独活草 2020-10-28 13:24:25
哈哈,我看到了ART-Pi 的身影
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表