 
                        自制的,有问题麻烦说一下
适用于 https://whycan.com/t_7522.html 中的mipi-v3x
链接:
https://pan.baidu.com/s/1GhGtAKwBWQI940ZrbjnovA 
提取码:pjs3
注意:
镜像连不上wifi会一直卡在那里
建议烧录完镜像后,在虚拟机里改下wifi名称和密码,顺便扩容
或者把手机热点wifi的名称密码改成楼下图里的
最近编辑记录 资本家大善人 (2021-12-18 15:54:56)
离线
账号密码都是root
修改wifi密码
vim /etc/wpa_supplicant.conf
离线
时钟
./clock
天气钟
./weather
NES游戏 键盘可用 wasd jk
./InfoNes hdl.nes /dev/input/event1
播放视频
mplayer badapple.mp4
usb摄像头
 ./cam /dev/video0
语音识别 usb麦克风 键盘A按下录音 A松下识别
./baiduSpeech最近编辑记录 资本家大善人 (2021-12-18 14:13:43)
离线
usb摄像头源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <math.h>
#include <wchar.h>
#include <time.h>
#include <stdbool.h>
#define CAM_WIDTH 320
#define CAM_HEIGHT 240
static char *dev_video;
static char *dev_fb0;
static char *yuv_buffer;
static char *rgb_buffer;
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define YUVToRGB(Y)                                                            \
	((u16)((((u8)(Y) >> 3) << 11) | (((u8)(Y) >> 2) << 5) | ((u8)(Y) >> 3)))
struct v4l2_buffer video_buffer;
/*全局变量*/
int lcd_fd;
int video_fd;
unsigned char *lcd_mem_p = NULL; //保存LCD屏映射到进程空间的首地址
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
char *video_buff_buff[4]; /*保存摄像头缓冲区的地址*/
int video_height = 0;
int video_width = 0;
unsigned char *lcd_display_buff; //LCD显存空间
unsigned char *lcd_display_buff2; //LCD显存空间
static void errno_exit(const char *s)
{
	fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
	exit(EXIT_FAILURE);
}
static int xioctl(int fh, int request, void *arg)
{
	int r;
	do {
		r = ioctl(fh, request, arg);
	} while (-1 == r && EINTR == errno);
	return r;
}
static int video_init(void)
{
	struct v4l2_capability cap;
	ioctl(video_fd, VIDIOC_QUERYCAP, &cap);
	struct v4l2_fmtdesc dis_fmtdesc;
	dis_fmtdesc.index = 0;
	dis_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	// printf("-----------------------支持格式---------------------\n");
	// while (ioctl(video_fd, VIDIOC_ENUM_FMT, &dis_fmtdesc) != -1) {
	// 	printf("\t%d.%s\n", dis_fmtdesc.index + 1,
	// 	       dis_fmtdesc.description);
	// 	dis_fmtdesc.index++;
	// }
	struct v4l2_format video_format;
	video_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	video_format.fmt.pix.width = CAM_WIDTH;
	video_format.fmt.pix.height = CAM_HEIGHT;
	video_format.fmt.pix.pixelformat =
		V4L2_PIX_FMT_YUYV; //使用JPEG格式帧,用于静态图像采集
	ioctl(video_fd, VIDIOC_S_FMT, &video_format);
	printf("当前摄像头支持的分辨率:%dx%d\n", video_format.fmt.pix.width,
	       video_format.fmt.pix.height);
	if (video_format.fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV) {
		printf("当前摄像头不支持YUYV格式输出.\n");
		video_height = video_format.fmt.pix.height;
		video_width = video_format.fmt.pix.width;
		//return -3;
	} else {
		video_height = video_format.fmt.pix.height;
		video_width = video_format.fmt.pix.width;
		printf("当前摄像头支持YUYV格式输出.width %d height %d\n",
		       video_height, video_height);
	}
	/*3. 申请缓冲区*/
	struct v4l2_requestbuffers video_requestbuffers;
	memset(&video_requestbuffers, 0, sizeof(struct v4l2_requestbuffers));
	video_requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	video_requestbuffers.count = 4;
	video_requestbuffers.memory = V4L2_MEMORY_MMAP;
	if (ioctl(video_fd, VIDIOC_REQBUFS, &video_requestbuffers))
		return -4;
	printf("成功申请的缓冲区数量:%d\n", video_requestbuffers.count);
	/*4. 得到每个缓冲区的地址: 将申请的缓冲区映射到进程空间*/
	struct v4l2_buffer video_buffer;
	memset(&video_buffer, 0, sizeof(struct v4l2_buffer));
	int i;
	for (i = 0; i < video_requestbuffers.count; i++) {
		video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		video_buffer.index = i;
		video_buffer.memory = V4L2_MEMORY_MMAP;
		if (ioctl(video_fd, VIDIOC_QUERYBUF, &video_buffer))
			return -5;
		/*映射缓冲区的地址到进程空间*/
		video_buff_buff[i] =
			mmap(NULL, video_buffer.length, PROT_READ | PROT_WRITE,
			     MAP_SHARED, video_fd, video_buffer.m.offset);
		printf("第%d个缓冲区地址:%#X\n", i, video_buff_buff[i]);
	}
	/*5. 将缓冲区放入到采集队列*/
	memset(&video_buffer, 0, sizeof(struct v4l2_buffer));
	for (i = 0; i < video_requestbuffers.count; i++) {
		video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		video_buffer.index = i;
		video_buffer.memory = V4L2_MEMORY_MMAP;
		if (ioctl(video_fd, VIDIOC_QBUF, &video_buffer)) {
			printf("VIDIOC_QBUF error\n");
			return -6;
		}
	}
	printf("启动摄像头采集\n");
	/*6. 启动摄像头采集*/
	int opt_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	if (ioctl(video_fd, VIDIOC_STREAMON, &opt_type)) {
		printf("VIDIOC_STREAMON error\n");
		return -7;
	}
	return 0;
}
int lcd_init(void)
{
	/*2. 获取可变参数*/
	if (ioctl(lcd_fd, FBIOGET_VSCREENINFO, &vinfo))
		return -2;
	printf("屏幕X:%d   屏幕Y:%d  像素位数:%d\n", vinfo.xres, vinfo.yres,
	       vinfo.bits_per_pixel);
	//分配显存空间,完成图像显示
	lcd_display_buff =
		malloc(vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8);
	/*3. 获取固定参数*/
	if (ioctl(lcd_fd, FBIOGET_FSCREENINFO, &finfo))
		return -3;
	printf("smem_len=%d Byte,line_length=%d Byte\n", finfo.smem_len,
	       finfo.line_length);
	/*4. 映射LCD屏物理地址到进程空间*/
	lcd_mem_p = (unsigned char *)mmap(0, finfo.smem_len,
					  PROT_READ | PROT_WRITE, MAP_SHARED,
					  lcd_fd, 0); //从文件的那个地方开始映射
	memset(lcd_mem_p, 0xFFFFFFFF, finfo.smem_len);
	printf("映射LCD屏物理地址到进程空间\n");
	return 0;
}
static void close_device(void)
{
	if (-1 == close(video_fd))
		errno_exit("close");
	video_fd = -1;
	if (-1 == close(lcd_fd))
		errno_exit("close");
	lcd_fd = -1;
}
static void open_device(void)
{
	video_fd = open(dev_video, O_RDWR /* required */ | O_NONBLOCK, 0);
	if (-1 == video_fd) {
		fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_video, errno,
			strerror(errno));
		exit(EXIT_FAILURE);
	}
	lcd_fd = open(dev_fb0, O_RDWR, 0);
	if (-1 == lcd_fd) {
		fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_fb0, errno,
			strerror(errno));
		exit(EXIT_FAILURE);
	}
}
/*
将YUV格式数据转为RGB
*/
void yuv_to_rgb(unsigned char *yuv_buffer, unsigned char *rgb_buffer,
		int iWidth, int iHeight)
{
	int x;
	int z = 0;
	unsigned char *ptr = rgb_buffer;
	unsigned char *yuyv = yuv_buffer;
	for (x = 0; x < iWidth * iHeight; x++) {
		int r, g, b;
		int y, u, v;
		if (!z)
			y = yuyv[0] << 8;
		else
			y = yuyv[2] << 8;
		u = yuyv[1] - 128;
		v = yuyv[3] - 128;
		r = (y + (359 * v)) >> 8;
		g = (y - (88 * u) - (183 * v)) >> 8;
		b = (y + (454 * u)) >> 8;
		*(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
		*(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
		*(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
		if (z++) {
			z = 0;
			yuyv += 4;
		}
	}
}
void rgb24_to_rgb565(char *rgb24, char *rgb16)
{
	int i = 0, j = 0;
	for (i = 0; i < 320 * 240 * 3; i += 3) {
		rgb16[j] = rgb24[i] >> 3; // B
		rgb16[j] |= ((rgb24[i + 1] & 0x1C) << 3); // G
		rgb16[j + 1] = rgb24[i + 2] & 0xF8; // R
		rgb16[j + 1] |= (rgb24[i + 1] >> 5); // G
		j += 2;
	}
}
int main(int argc, char **argv)
{
	dev_video = argv[1];
	dev_fb0 = "/dev/fb0";
	open_device();
	video_init();
	lcd_init();
	/*3. 读取摄像头的数据*/
	struct pollfd video_fds;
	video_fds.events = POLLIN;
	video_fds.fd = video_fd;
	memset(&video_buffer, 0, sizeof(struct v4l2_buffer));
	rgb_buffer = malloc(CAM_WIDTH * CAM_HEIGHT * 3);
	yuv_buffer = malloc(CAM_WIDTH * CAM_HEIGHT * 3);
	unsigned char *rgb_p;
	int w, h, i, j;
	unsigned char r, g, b;
	unsigned int c;
	while (1) {
		/*等待摄像头采集数据*/
		poll(&video_fds, 1, -1);
		/*得到缓冲区的编号*/
		video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		video_buffer.memory = V4L2_MEMORY_MMAP;
		ioctl(video_fd, VIDIOC_DQBUF, &video_buffer);
		//printf("当前采集OK的缓冲区编号:%d,地址:%#X num:%d\n",
		//       video_buffer.index, video_buff_buff[video_buffer.index],
		 //      strlen(video_buff_buff[video_buffer.index]));
		/*对缓冲区数据进行处理*/
		yuv_to_rgb(video_buff_buff[video_buffer.index], yuv_buffer,
		video_height, video_width);
		rgb24_to_rgb565(yuv_buffer, rgb_buffer);
		//printf("显示屏进行显示\n");
		//显示屏进行显示: 将显存空间的数据拷贝到LCD屏进行显示
		memcpy(lcd_mem_p, rgb_buffer,
		       vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8);
		/*将缓冲区放入采集队列*/
		ioctl(video_fd, VIDIOC_QBUF, &video_buffer);
		//printf("将缓冲区放入采集队列\n");
	}
	/*4. 关闭视频设备*/
	close(video_fd);
	return 0;
}离线
百度语音识别Qt源码
baiduSpeech.zip
离线
时钟源码
clock.zip
#ifndef WIDGET_H
#define WIDGET_H
#include <QMainWindow>
#include<QPainter>
#include <QTimer>
#include <QTime>
#include <QWidget>
#include <QtMath>
namespace Ui {
class Widget;
}
class Widget : public QMainWindow
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    void paintEvent(QPaintEvent *);
    //定义文本区域
    QRectF textRectF(double r,int pointSize,double angle);
private slots:
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));//更新界面
    timer->start(1000);//每秒更新一次界面
}
Widget::~Widget()
{
    delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    //获取系统时间
    QTime time = QTime::currentTime();
    // 时针、分针、秒针位置 - 多边形
    static const QPoint hourHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -30)
    };
    static const QPoint minuteHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -65)
    };
    static const QPoint secondHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -80)
    };
    // 时针、分针、秒针颜色
    QColor hourColor(200, 100, 0, 200);
    QColor minuteColor(0, 127, 127, 150);
    QColor secondColor(0, 160, 230, 150);
    int side = qMin(width(), height());
    //获取窗口信息
    QPainter painter(this);
    //设置抗锯齿,精度越高,效率越低
    painter.setRenderHint(QPainter::Antialiasing);
    // 平移坐标系原点至中心点
    painter.translate(width() / 2, height() / 2);
    // 缩放
    painter.scale(side / 200.0, side / 200.0);
    // 绘制时针
    painter.setPen(Qt::NoPen);
    painter.setBrush(hourColor);
    painter.save();
    // 每圈360° = 12h 即:旋转角度 = 小时数 * 30°
    painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
    painter.drawConvexPolygon(hourHand, 3);
    painter.restore();
    // 绘制小时线 (360度 / 12 = 30度)
    painter.setPen(hourColor);
    for (int i = 0; i < 12; ++i) {
        painter.drawLine(88, 0, 96, 0);
        painter.rotate(30.0);
    }
    int radius = 100;
    QFont font = painter.font();
    font.setBold(true);//字体加粗
    painter.setFont(font);
    int pointSize = font.pointSize();
    // 绘制小时文本
    int nHour = 0;
    for (int i = 0; i < 12; ++i) {
        nHour = i + 3;//原点变了,从3绘制(旋转0°)
        if (nHour > 12) nHour -= 12;//13 14 -> 1 2
        //在中心绘制
        painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));
    }
    painter.setPen(Qt::NoPen);
    // 绘制分针
    painter.setBrush(minuteColor);
        painter.save();
    // 每圈360° = 60m 即:旋转角度 = 分钟数 * 6°
    painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
    painter.drawConvexPolygon(minuteHand, 3);
        painter.restore();
    // 绘制分钟线 (360度 / 60 = 6度)
    painter.setPen(minuteColor);
    for (int j = 0; j < 60; ++j) {
        if ((j % 5) != 0)
            painter.drawLine(92, 0, 96, 0);
        painter.rotate(6.0);
    }
    // 绘制秒针
    painter.setPen(Qt::NoPen);
    painter.setBrush(secondColor);
    painter.save();
    // 每圈360° = 60s 即:旋转角度 = 秒数 * 6°
    painter.rotate(6.0 * time.second());//旋转图像
    painter.drawConvexPolygon(secondHand, 3);
    painter.restore();
}
//绘制文本区域
//输入半径,区域大小,角度
QRectF Widget::textRectF(double r, int pointSize, double angle)
{
    QRectF rectF;
    rectF.setX(r*qCos(angle*M_PI/180.0) - pointSize*2);
    rectF.setY(r*qSin(angle*M_PI/180.0) - pointSize/2.0);
    rectF.setWidth(pointSize*4);
    rectF.setHeight(pointSize);
    return rectF;
}离线
请问这个nes有声音延时的问题吗?
有延时(T_T)
离线
uboot
https://gitee.com/byleefei/uboot-2021.07-v3x
make ARCH=arm  mipi-v3x_defconfig
make ARCH=arm menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12内核 跟v3s通用
https://gitee.com/byleefei/linux-5.10-v3x
最近编辑记录 资本家大善人 (2021-12-18 15:36:34)
离线
扩容问题
软件GParted (apt-get 安装)

扩容,建立swap分区
离线
更新软件包
apt-get update
安装需要的工具
离线
编译usb摄像头代码并运行

最近编辑记录 资本家大善人 (2021-12-18 16:30:00)
离线
弄了桌面系统
浏览器访问坑网,加载只要几秒
50-75%CPU 
65% 内存
v3s上直接爆内存怪不得打不开
远程桌面,还没弄好
离线
弄了桌面系统
浏览器访问坑网,加载只要几秒
50-75%CPU
65% 内存
v3s上直接爆内存怪不得打不开
https://whycan.com/files/members/6250/78b4eb05451268af.jpg
远程桌面,还没弄好https://whycan.com/files/members/6250/-7325f7e9167bae9b.png
求方法,我自己安装的Ledx,感觉一直在重启
最近编辑记录 twzy (2021-12-20 09:23:47)
离线
@twzy 
https://releases.linaro.org/debian/images/alip-armhf/
这里是带桌面的文件系统,换掉原来的文件系统就行
记得启动交换分区,不然很卡
V3X和V3S就uboot有点差异,内核文件系统通用
最近编辑记录 资本家大善人 (2021-12-20 11:39:04)
离线
@twzy
https://releases.linaro.org/debian/images/alip-armhf/这里是带桌面的文件系统,换掉原来的文件系统就行
记得启动交换分区,不然很卡
V3X和V3S就uboot有点差异,内核文件系统通用
其他的已经跑起来了,今天画了个基于v3x的小电脑,已经打样了
另外v3x操作pc4~pc10引脚会报错,估计是使用v3s配置的原因,后续看看怎么修改吧
离线
离线
离线
桌面镜像已上传,链接跟一楼一样,记得建立swap分区
链接:
https://pan.baidu.com/s/1GhGtAKwBWQI940ZrbjnovA
提取码:pjs3
最近编辑记录 资本家大善人 (2022-01-02 00:46:33)
离线
GBA游戏模拟器
apt-get install visualboy*

离线
@资本家大善人 
收藏一下  谢谢!!!!
离线
你这个是支持FLASH启动的吗
离线