前言
由于工作原因,最近在调研MaixII这款开发板,Sipeed是自己非常喜欢的一个团队,极客精神下的各种开源开发板,用起来相当顺畅。
MaixII是一款基于全志V831的一款开发板,自带NPU,具有0.2T的算力,当然完整的nn工具链,我现在还没有看到。
作为前期调研,在官网示例程序跑完后,觉得还是不够带劲,既然是一款跑linux系统的板子,从底层纯C开发程序,当然是最佳选择。
为MaixII编译程序需要用到SIpeed提供的交叉编译包,这个环境是为他们的MaixPy准备的,我们只需要用到其中的gcc即可
下载链接为:
其中,toolchain下的bin文件中,包含了全志的完整工具链。
看见了gcc,g++,熟悉Linux开发的应该就知道,稳了。
接下来,我们设计一个程序,为在屏幕上点亮一个渐变的小方块,我非常喜欢用图形图像的例子来作为hello world。
在Linux系统中,屏幕对应的设备文件为“fb0”,在/dev目录下,我们通过操纵fb0达到对屏幕的framebuffer操控的目的。
实际代码为:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
int main () {
int fp=0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long screensize=0;
char *fbp = 0;
int x = 0, y = 0;
long location = 0;
fp = open ("/dev/fb0",O_RDWR);
if (fp < 0){
printf("Error : Can not open framebuffer device/n");
exit(1);
}
if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
printf("Error reading fixed information/n");
exit(2);
}
if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
printf("Error reading variable information/n");
exit(3);
}
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; //单帧画面空间
/*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/
fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
if ((int) fbp == -1)
{
printf ("Error: failed to map framebuffer device to memory./n");
exit (4);
}
/*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/
for(x=100;x<150;x++)
{
for(y=100;y<150;y++)
{
location = x * (vinfo.bits_per_pixel / 8) + y * finfo.line_length;
#if 0
*(fbp + location) = 255; /* 蓝色的色深 */ /*直接赋值来改变屏幕上某点的颜色*/
*(fbp + location + 1) = 0; /* 绿色的色深*/ /*注明:这几个赋值是针对每像素四字节来设置的,如果针对每像素2字节,*/
*(fbp + location + 2) = 0; /* 红色的色深*/ /*比如RGB565,则需要进行转化*/
*(fbp + location + 3) = 0; /* 是否透明*/
#endif
*(fbp + location) = 0; //16位位深的写法控制
*(fbp + location + 1) = 0;
*(fbp + location + 2) = 5*(y-100);
}
}
munmap (fbp, screensize); /*解除映射*/
close (fp); /*关闭文件*/
return 0;
}
接下来是编译过程
我们把代码创建为一个hello.c的文件,然后借助gcc去编译它
toolchain/bin/arm-openwrt-linux-gcc -g -O2 hello.c
编译成功,生成一个a.out的文件
将a.out发送到板子中,更改权限为777之后,开始执行
执行效果为