主要记录正点原子阿尔法开发板使用的一些记录,方便以后查询。
QT开发篇
1、关闭原子出厂界面
vi /etc/rc.local
注释箭头这句话即可。 关闭桌面程序后,可执行下面的指令进行重启桌面程序 /opt/QDesktop > /dev/null 2>&1 &
2、交叉编译环境设置。
3、 如何创建自启动程序 与出厂 Qt 一样,自启动脚本/程序指令可以放到/etc/rc.local 这个文件里,因为/etc/rc.local 是系统启动最后一个执行的。当然也可以放在/etc/init.d/目录下的 rcS 文件里。
linux驱动开发篇
1、编译出厂内核源码
1.1 复制linux内核源码到Ubuntu中
创建新目录
mkdir -p IMX6/linux-imx-4.1.15-2.1.0
解压linux内核源码
tar xf linux-imx-4.1.15-2.1.0-gb78e551-v1.4.tar.xz -C IMX6/linux-imx-4.1.15-2.1.0/
进入解压的目录中
cd IMX6/linux-imx-4.1.15-2.1.0
查看解压后的文件 执行编译
./build.sh
编译完成,及查看 tmp 目录下的编译目标文件,如下图,包含很多 dtb 文件(设备树),及 Linux 内核 zImage,还有 modules.tar.bz2(内核模块)。
2、NFS环境搭建
Windows 主机 IP:192.168.0.104
Ubuntu 虚拟机 IP:192.168.0.105
开发板 IP:192.168.0.106
执行以下指令设置开发板 IP,创建一个 get 目录,将虚拟机(192.168.0.105)NFS 共享目录挂载到到开发板的 get 目录中。
mkdir get
mount -t nfs -o nolock,nfsvers=3 192.168.0.105:/home/alientek/linux/nfs get
查看挂载的 NFS 目录:
df
在完成环境搭建之后,虚拟机把生成的可执行程序辅助到nfs挂载的目录下面。
运行QT程序
下次开启重启无法加载的时候,重启nfs。执行以下指令重启 NFS 服务器。
sudo /etc/init.d/nfs-kernel-server restart
执行以下指令查看 NFS 共享目录。
showmount -e
2022.5.17 P1029字符驱动开发。 驱动加载:insmod drv.ko 驱动卸载:rmmod drv.ko
linux应用开发篇
1、应用编程点灯:
使用交叉编译器
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
2022.5.15 GPIO
linuxc 应用文档p526控制gpio输出
在GPIO中断测试章节中,使用到了 poll() 多路转接。作用:检测文件当前状态是否就绪,是不是需要使用到的状态。 文档交叉P475。
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
int fd;
short events;
short revents;
};
截取中断部分重要代码 P532。 这里用到了access函数,解释说明如下:access函数用法,主要功能是判断进程时候可以对文件进行相应的操作。
sprintf(gpio_path,"/sys/class/gpio%s",argv[1]);
if (access(gpio_path,F_OK)){
int len;
int fd;
if (0 > (fd = open("/sys/class/gpio/export",O_WRONLY))){
perror("open error");
exit(-1);
}
len = strlen(argv[1]);
if (len != write(fd,argv[1],len)){
perror("write error");
exit(-1);
}
close(fd);
}
if (gpio_config("direction","in"))
exit(-1);
if (gpio_config("edge","both"))
exit(-1);
if (gpio_config("active_low","0"))
exit(-1);
sprintf(file_path,"%s/%s",gpio_path,"value");
if (0 > (pfd.fd = open(file_path,O_RDONLY))){
perror("open error");
exit(-1);
}
pfd.events = POLLPRI;
read(pfd.fd,&val,1);
while(1)
{
if (0 > (ret = poll(&pfd,1,-1))){
perror("poll error");
exit(-1);
}
else if (ret == 0){
fprintf(stderr,"poll timeout.\n");
continue;
}
if (pfd.revents & POLLPRI){
if (0 >lseek(pfd.fd,0,SEEK_SET))
{
perror("lseek error");
exit(-1);
}
if (read(pfd.fd,&val,1)<0){
perror("read error");
exit(-1);
}
printf("GPIO 中断触发<value = %c>\n",val);
}
}
2022.5.16 输入设备
linuxc 应用文档p537 输入设备,这章节中判断输入设备的状态和数据解析最重要的是用到了 个 struct input_event 结构体。把握住这个结构体就好啦!!!
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
type :type 用于描述发生了哪一种类型的事件。比如:鼠标事件。
code :code 表示该类事件中的哪一个具体事件。 例如:
value :内核每次上报事件都会向应用层发送一个数据 value,对 value 值的解释随着 code 的变化而变化。 多点触摸:MT 协议之 Type B 协议 P549
获取触摸点信息。
ioctl() 函数P553的原型列出:
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
对于 input 输入设备,对其执行 ioctl()操作需要使用这些宏,不同的宏表示不同请求指令;譬如使用EVIOCGNAME 宏获取设备名称,使用方式如下:
char name[100];
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
获取触摸屏支持的最大触摸点数: 使用ioctl() 函数将触摸屏信息写入info结构体中。
struct input_absinfo info;
int max_slots;
if (0 > ioctl(fd, EVIOCGABS(ABS_MT_SLOT), &info))
perror("ioctl error");
max_slots = info.maximum + 1 - info.minimum;
例程代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
int main(int argc, char *argv[])
{
struct input_event in_event = {0};
int x,y;
int down;
int valid;
int fd = -1;
if (argc<2){
fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);
exit(-1);
}
if (0>open(argv[1],O_RDONLY)){
perror("open error");
exit(-1);
}
x=y=0;
down=-1;
valid=0;
for (;;)
{
if (sizeof(struct input_event)!=read(fd,&in_event,sizeof(struct input_event))){
perror("open error");
exit(EXIT_FAILURE);
}
switch(in_event.type){
case EV_KEY:
if (BTN_TOUCH == in_event.code){
down = in_event.value;
valid = 1;
}
break;
case EV_ABS:
switch(in_event.code){
case ABS_X:
x = in_event.value;
valid = 1;
break;
case ABS_Y:
y = in_event.value;
valid = 1;
break;
}
break;
case EV_SYN:
if (SYN_REPORT == in_event.code){
if(valid){
switch(down){
case 1:
printf("按下(%d %d)\n",x,y);
break;
case 0:
printf("按下(%d %d)\n",x,y);
break;
case -1:
printf("移动(%d %d)\n",x,y);
break;
}
valid = 0;
down = -1;
}
}
break;
}
}
exit(0);
}
2022.5.18 FrameBuffer应用编程
介绍P583。
未完待续。。。。
|