TQ2440在linux下控制AD实验总结
myadc.c:
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
volatile unsigned long *adccon = NULL; //adc控制寄存器
volatile unsigned long *adctsc = NULL; //adc 触摸屏控制寄存器
volatile unsigned long *adcdly = NULL; //adc 起始延迟寄存器
volatile unsigned long *adcdat0 = NULL; //adc 转换数据寄存器
volatile unsigned long *adcdat1 = NULL; //adc 转换数据寄存器
volatile unsigned long *intmsk = NULL;
#define MYADC_MAJOR 150 /*预设的globalmem的主设备号*/
static int myadc_major = MYADC_MAJOR;
struct cdev* adc_cdev;
ssize_t drive_read(struct file *file, char *buf, size_t count, loff_t *f_ops)
{
int val;
printk("-----------------drive read ok----------------\n");
*adccon |= (1 << 14) | (0xff << 6) | (2 << 3);//设置分频倍数0xff,设置输入通道为2
//CLKDIV = pclk(50M) /(255+1),即转换时钟为0.195MHz
*adccon |= 0x1;//使能ADC 转换
while(*adccon & 0x1); //判断是否使能ADC转换
while(!(*adccon & 0x8000));//等待转换结束
val = (*adcdat0 & 0x3ff); //取出ADC转换值
*adccon &= ~1;//关ADC 转换
printk("----------------drive -----val=%d\n", val);
copy_to_user(buf, &val, sizeof(val));
printk("---------------drive-close-ok-------------\n", val);
return val;
}
static struct file_operations drive_ops =
{
.owner = THIS_MODULE,
.read = drive_read,
};
static int __init init_drive(void)
{
dev_t dev;
adc_cdev = cdev_alloc();
alloc_chrdev_region(&dev, 0, 1, "myadc");
myadc_major = MAJOR(dev);
adc_cdev->ops = &drive_ops;
cdev_init(&adc_cdev, &drive_ops);
cdev_add(&adc_cdev, dev, 1);
adccon = (volatile unsigned long *)ioremap(0x58000000, 16);
adctsc = (volatile unsigned long *)ioremap(0x58000004, 8);
adcdly = (volatile unsigned long *)ioremap(0x58000008, 16);
adcdat0 = (volatile unsigned long *)ioremap(0x5800000c, 16);
adcdat1 = (volatile unsigned long *)ioremap(0x58000010, 16);
intmsk = (volatile unsigned long *)ioremap(0x4a000008, 32);
printk("-----------------drive button init ok----------------\n");
return 0;
}
static void __exit exit_drive(void)
{
dev_t dev;
dev = MKDEV(myadc_major, 0);
cdev_del(&adc_cdev);
unregister_chrdev_region(dev, 1);
printk("-----------------drive button exit ok----------------\n");
}
module_init(init_drive);
module_exit(exit_drive);
MODULE_LICENSE("GPL");
Makefile:
ifneq ($(KERNELRELEASE),)
obj-m :=myadc.o
else
KERNELDIR ?= /home/book/opt/EmbedSky/linux-2.6.30.4/
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
endif
test.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fd, ret;
int val;
fd = open("/dev/myadc", O_RDWR);
if(fd == -1)
{
printf("can't open device mknod %s c zhu ci \n", "/dev/myadc");
return 0;
}
while(1)
{
read(fd,&val,sizeof(val));
printf("------------------app--------------------\n");
printf("val=%d\n",val);
sleep(3);
}
ret = close(fd);
if (ret == -1)
{
printf("app close error!!!!!!!!!!\n");
return 0;
}
return 0;
}
实验现象:拨动可调电阻改变电压,发现数值会随之发生变化。
[root@EmbedSky /]# insmod myadc.ko
-----------------drive button init ok----------------
[root@EmbedSky /]# ls -l /dev/myadc
crw-rw---- 1 root root 10, 55 Feb 24 11:38 /dev/myadc
[root@EmbedSky /]# cat /proc/devices
Character devices:
…
7 vcs
10 misc
13 input
…
[root@EmbedSky /]# ./test
-----------------drive read ok----------------
----------------drive -----val=518
---------------drive-close-ok-------------
------------------app--------------------
val=518
-----------------drive read ok----------------
----------------drive -----val=520
---------------drive-close-ok-------------
------------------app--------------------
val=520
[root@EmbedSky /]# rmmod myadc.ko
-----------------drive button exit ok----------------
第二篇:实验2 Linux进程控制
实验2 Linux进程控制
一. 实验目的
1.学会查看和杀死进程。
2.加深对进程概念的理解,明确进程与程序的区别。
3.熟悉linux下vi的使用。
二. 实验指导
1. 查看系统中的进程
格式:ps [选项]
例如:ps //显示当前用户在shell下所运行的进程。
ps -u osmond //显示用户osmond的进程。
ps -aux //显示系统中正在运行的所有进程的详细信息。
2. 杀死系统中的进程
格式:kill [signal] PID
PID是进程的识别号;signal是向进程发出的进程信号。
3. vi文本编辑工具
进入Linux的字符界面,输入vi file,进入vi编辑程序。
vi提供了输入模式(insert mode)和命令模式(command mode)。使用者进入vi后,即处在命令模式下,此刻键入i转换到输入模式。
在输入模式下,按ESC可切换到命令模式。命令模式下,常用的指令有:
4. 有关进程控制系统调用
三.实验内容
1. 请在字符界面下完成下列作业控制操作:
? 显示当前运行的进程
? 运行cat命令
cat > example
输入若干字符如this is a example.
? 新建一个终端窗口,显示当前运行的进程
? 杀死cat进程
2. vi工具的使用
(1) 进入Linux的字符界面,输入vi,进入vi。
例:$vi hello.c
(2) 利用实验指导中的相关内容完成在屏幕上显示“Hello world”的C语言源程序hello.c的创建。保存上述程序,并退出vi。
3 用gcc编译上述C程序,并运行之。
编译:gcc –o hello hello.c
运行:./hello
4 进程控制之一:
(1) 先在vi窗口中编写下列程序:
使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a“;子进程分别显示字符”b“和字符“c”。
(2) 保存上述程序,并退出vi。
(3) 编译并多次运行上述程序,分析运行结果。
参考程序
}
5. 进程控制之二:分析下列程序的运行结果,getpid()函数为取当前进程号。
6.进程控制之三:分析下列程序的运行结果
进程控制之四:
创建一个子进程输出pid,并给它加载新程序hello,hello即上述显示“Hello world”程序和pid。
提示:创建程序parent.c,在该程序中创建子进程,在子进程分支中用execl加载hello。
四.实验报告
(1)需给出实验课题、目的与主要内容要求。
(2)实际进行的实验详细记录:完整的命令串或程序、执行结果、结果分析。