zoukankan      html  css  js  c++  java
  • 实验一 灯程序——OK6410A开发板LINUX3.0.1(嵌入式开发)

    实验一 灯程序

    一、实验目的

    1.熟悉linux系统,学会简单linux指令

    2.熟悉OK6410-A开发板的烧入步骤

    3.熟悉ARM寄存器,地址等。

    4.系统性的了解UBOOT和linux内核,yaffs2系统映像等知识

    二、实验仪器

    开发机环境

          操作系统:ubuntu 20.04
          交叉编译环境:arm-linux-gcc 4.6.4 
          6410板子内核源码:linux-3.0.1 
    

    目标板环境

    	OK6410-A     linux-3.0.1 
    

    环境配置看这里

    三、实验内容(原理)

    1.硬件部分


    从上面的原理图可以得知,LED与CPU引脚的连接方法如下,低电平点亮。
    LED1 -GPM0
    LED2 -GPM1
    LED3 -GPM2
    LED4 -GPM3

    2.寄存器部分

    重点观察下面寄存器的地址,输出方式等信息

    通过上面可以得知,如果要点亮灯1,需要先将GPM0设置为输出方式。将相应的寄存器进行配置。然后将GPMDAT寄存器的第0位置0灯亮,置1灯灭。

    四、实验步骤

    1.编写驱动程序

    driver_led.c

    	#include <linux/module.h>  
    	  
    	#include <linux/kernel.h>  
    	#include <linux/fs.h>  
    	#include <asm/uaccess.h> /* copy_to_user,copy_from_user */  
    	#include <linux/miscdevice.h>    
    	#include <linux/pci.h>    
    	#include <mach/map.h>    
    	#include <mach/regs-gpio.h>    
    	#include <mach/gpio-bank-m.h>    
    	#include <plat/gpio-cfg.h>  
    	 
    	MODULE_LICENSE("GPL" );
    	#define LED_MAJOR 240  
    	  
    	int led_open (struct inode *inode,struct file *filp)  
    	  
    	{  
    	    unsigned tmp;     
    	         tmp = readl(S3C64XX_GPMCON);     
    	    tmp = (tmp & ~(0x7U<<1))|(0x2U);     
    	         writel(tmp, S3C64XX_GPMCON);   
    	    printk("#########open######\n");  
    	    return 0;  
    	}  
    	ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)  
    	{  
    	    printk("#########read######\n");  
    	    return count;  
    	}  
    	  
    	
    	ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  
    	{  
    	    char wbuf[10];  
    	    unsigned tmp;     
    	    printk("#########write######\n");  
    	    copy_from_user(wbuf,buf,count);  
    	    switch(wbuf[0])  
    	    {  
    	        case 0:  //off  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp |= (0x2U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 1:  //on  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp &= ~(0x2U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        default :  
    	            break;  
    	    }  
    	    return count;  
    	}  
    	  
    	int led_release (struct inode *inode, struct file *filp)  
    	{  
    	    printk("#########release######\n");  
    	    return 0;  
    	}  
    	  
    	struct file_operations led_fops ={  
    	    .owner = THIS_MODULE,  
    	    .open = led_open,  
    	    .read = led_read,  
    	    .write = led_write,  
    	    .release = led_release,  
    	};  
    	  
    	int __init led_init (void)  
    	{   int rc;  
    	    printk ("Test led dev\n");  
    	    rc = register_chrdev(LED_MAJOR,"led",&led_fops);  
    	    if (rc <0)  
    	    {  
    	        printk ("register %s char dev error\n","led");  
    	        return -1;  
    	    }  
    	    printk ("ok!\n");  
    	    return 0;  
    	}  
    	  
    	void __exit led_exit (void)  
    	{  
    	    unregister_chrdev(LED_MAJOR,"led");  
    	    printk ("module exit\n");  
    	    return ;  
    	}  
    	  
    	module_init(led_init);  
    	module_exit(led_exit);  
    
    

    2.编写Makefile文件

    ifneq ($(KERNELRELEASE),)
    
    obj-m := driver_led.o
    
    else 
    KDIR := /home/kk/Desktop/forlinx/linux-3.0.1
    all:
    	make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
    clean:
    	rm -f *.ko *.o *.mod.o *.mod.c *.symvers
    
    endif
    

    3.编写test.c

    #include <stdio.h>  
    #include <sys/types.h> 
    #include <sys/stat.h>  
    #include <fcntl.h>  
    int main (void)  
    {  
    	    int fd;  
    	    char buf[10]={0,1};  
    	    fd = open("/dev/my_led",O_RDWR);  
    	    if (fd < 0)  
    	    {  
    	        printf ("Open /dev/my_led file error\n");  
    	        return -1;  
    	    }     
    	    while(1)  
    	    {  
    	        write(fd,&buf[0],1);  
    	        sleep(1);  
    	        write(fd,&buf[1],1);  
    	        sleep(1);  
    	    }  
    	    close (fd);  
    	    return 0;  
    	  
    }  
    

    4.编译驱动程序与测试程序

     #make
    

    将编译生成 driver_led.ko等文件

    #arm-linux-gcc  test.c  -o  test
    

    将生成test可执行文件

    最后呈现以下文件

    5.格式化SD卡,把 SD 卡格式化为 FAT32 格式。

    6.用SD_Writer将 mmc.bin 烧写到 SD 卡中

    1.以管理员身份运行
    2.点击”Scan”,这个步骤是自动搜寻 SD 卡所在盘符。如果"Scan"没有正确设置 SD 卡所在盘符,就需要手动 调整 SD Volume,把盘符号调整为 SD 卡所在盘符(比如说,PC 的 USB 口接了两个或者两个以上的 U 盘或 者 SD 卡,就有可能错误到扫描 SD 卡盘符)。
    3.将”SD Type”更改为 auto。这个步骤是为了让 SD_Writer 自动识别 SD 卡类型。
    4.将”OS Type”更改为 Linux。这个步骤是选择要烧写的系统类型。
    5.点击”Select Boot”, 选择适合自己开发板的 mmc.bin
    mmc_ram128.bin 适用于 128M 内存的开发板
    mmc_ram256.bin 适用于 256M 内存的开发板
    6.点击”Program”,出现”It’s OK”表示操作成功。

    7.拷贝系统文件

    首先,将 u-boot.bin 拷贝到 SD 卡中。
    u-boot_ram128.bin 专门用于 128M 内存开发板。
    u-boot_ram256.bin 专门用于 256M 内存开发板。
    将与开发板对应的 u-boot 拷贝到 SD 卡中。接着在 SD 卡中将文件名改为u-boot.bin 即可。

    然后,将 zImage 拷贝到 SD 卡中。zImage 是 Linux 的内核映像文件。

    最后,将 rootfs.yaffs2 拷贝到 SD 卡中。
    rootfs.yaffs2-nand256m 专门用于 128M 内存,256M NandFlash开发板。
    rootfs.yaffs2-nand2g 专门用于 256M 内存,1G 或 2G 或者 4G Nandflash 的开发板

    8.拷贝驱动程序与测试程序

    将driver_led.ko与test拷贝到SD卡上

    9.烧写Linux到开发板的NandFlash

    步骤 1. 将制作好的 SD 卡插入开发板 SD 的插槽。

    步骤 2. 接好 5V 直流电源(飞凌提供此电源,请使用飞凌提供的电源)。

    步骤 3. 拨码开关设置为 SD 卡启动。

    拨码开关在底板SD 卡启动的拨码开关设置如下:

    引脚号 Pin8 Pin7 Pin6 Pin5 Pin4 Pin3 Pin2 Pin1
    引脚定义 SELNAND OM4 OM3 OM2 OM1 GPN15 GPN14 GPN13
    SD卡启动 1 1 1 1 1 0 0 0

    10. 测试

    1.打开终端
    2.加载驱动
    #insmod /sdcard/driver_led.ko
    3.创建设备文件
    #mknod /dev/my_led c 240 0
    4.测试
    ./test
    5.卸载驱动
    #rmmod driver_led

    看到小灯点亮,实验成功!

    五、实验程序(包括流程图)

    1.点灯

    driver_led.c

    	#include <linux/module.h>  
    	  
    	#include <linux/kernel.h>  
    	#include <linux/fs.h>  
    	#include <asm/uaccess.h> /* copy_to_user,copy_from_user */  
    	#include <linux/miscdevice.h>    
    	#include <linux/pci.h>    
    	#include <mach/map.h>    
    	#include <mach/regs-gpio.h>    
    	#include <mach/gpio-bank-m.h>    
    	#include <plat/gpio-cfg.h>  
    	 
    	MODULE_LICENSE("GPL" );
    	#define LED_MAJOR 240  
    	  
    	int led_open (struct inode *inode,struct file *filp)  
    	  
    	{  
    	    unsigned tmp;     
    	         tmp = readl(S3C64XX_GPMCON);     
    	    tmp = (tmp & ~(0x7U<<1))|(0x2U);     
    	         writel(tmp, S3C64XX_GPMCON);   
    	    printk("#########open######\n");  
    	    return 0;  
    	}  
    	ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)  
    	{  
    	    printk("#########read######\n");  
    	    return count;  
    	}  
    	  
    	  
    	ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  
    	{  
    	    char wbuf[10];  
    	    unsigned tmp;     
    	    printk("#########write######\n");  
    	    copy_from_user(wbuf,buf,count);  
    	    switch(wbuf[0])  
    	    {  
    	        case 0:  //off  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp |= (0x2U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 1:  //on  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp &= ~(0x2U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        default :  
    	            break;  
    	    }  
    	    return count;  
    	}  
    	  
    	int led_release (struct inode *inode, struct file *filp)  
    	{  
    	    printk("#########release######\n");  
    	    return 0;  
    	}  
    	  
    	struct file_operations led_fops ={  
    	    .owner = THIS_MODULE,  
    	    .open = led_open,  
    	    .read = led_read,  
    	    .write = led_write,  
    	    .release = led_release,  
    	};  
    	  
    	int __init led_init (void)  
    	{   int rc;  
    	    printk ("Test led dev\n");  
    	    rc = register_chrdev(LED_MAJOR,"led",&led_fops);  
    	    if (rc <0)  
    	    {  
    	        printk ("register %s char dev error\n","led");  
    	        return -1;  
    	    }  
    	    printk ("ok!\n");  
    	    return 0;  
    	}  
    	  
    	void __exit led_exit (void)  
    	{  
    	    unregister_chrdev(LED_MAJOR,"led");  
    	    printk ("module exit\n");  
    	    return ;  
    	}  
    	  
    	module_init(led_init);  
    	module_exit(led_exit);  
    
    

    Makefile文件

    ifneq ($(KERNELRELEASE),)
    
    obj-m := driver_led.o
    
    else 
    KDIR := /home/kk/Desktop/forlinx/linux-3.0.1
    all:
    	make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
    clean:
    	rm -f *.ko *.o *.mod.o *.mod.c *.symvers
    
    endif
    

    test.c

    #include <stdio.h>  
    #include <sys/types.h> 
    #include <sys/stat.h>  
    #include <fcntl.h>  
    int main (void)  
    {  
    	    int fd;  
    	    char buf[10]={0,1};  
    	    fd = open("/dev/my_led",O_RDWR);  
    	    if (fd < 0)  
    	    {  
    	        printf ("Open /dev/my_led file error\n");  
    	        return -1;  
    	    }     
    	    while(1)  
    	    {  
    	        write(fd,&buf[0],1);  
    	        sleep(1);  
    	        write(fd,&buf[1],1);  
    	        sleep(1);  
    	    }  
    	    close (fd);  
    	    return 0;  
    	  
    }  
    

    2.流水灯

    driver_led.c

    	#include <linux/module.h>  
    	  
    	#include <linux/kernel.h>  
    	#include <linux/fs.h>  
    	#include <asm/uaccess.h> /* copy_to_user,copy_from_user */  
    	#include <linux/miscdevice.h>    
    	#include <linux/pci.h>    
    	#include <mach/map.h>    
    	#include <mach/regs-gpio.h>    
    	#include <mach/gpio-bank-m.h>    
    	#include <plat/gpio-cfg.h>  
    	 
    	MODULE_LICENSE("GPL" );
    	#define LED_MAJOR 240  
    	  
    	int led_open (struct inode *inode,struct file *filp)  
    	  
    	{  
    	    unsigned tmp;     
    	         tmp = readl(S3C64XX_GPMCON);     
    	    tmp = (tmp & ~(0x7U<<1))|(0x1U);     
    	         writel(tmp, S3C64XX_GPMCON);   
    	    printk("#########open######\n");  
    	    return 0;  
    	}  
    	ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)  
    	{  
    	    printk("#########read######\n");  
    	    return count;  
    	}  
    	  
    	  
    	ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  
    	{  
    	    char wbuf[10];  
    	    unsigned tmp;     
    	    printk("#########write######\n");  
    	    copy_from_user(wbuf,buf,count);  
    	    switch(wbuf[0])  
    	    {  
    	        case 7:  //off  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp |= (0x1U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 0:  //on  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp &= ~(0x1U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;
    	        case 6:  //off  
    	            tmp = readl(S3C64XX_GPMDAT);   
    	              
    	                          tmp |= (0x2U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 1:  //on  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp &= ~(0x2U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 5:  //off  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp |= (0x4U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 2:  //on  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp &= ~(0x4U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  	            
    	        case 4:  //off  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp |= (0x8U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  
    	        case 3:  //on  
    	            tmp = readl(S3C64XX_GPMDAT);     
    	                          tmp &= ~(0x8U);     
    	                          writel(tmp, S3C64XX_GPMDAT);  
    	            break;  	            
    	            	       	         
    	        default :  
    	            break;  
    	    }  
    	    return count;  
    	}  
    	  
    	int led_release (struct inode *inode, struct file *filp)  
    	{  
    	    printk("#########release######\n");  
    	    return 0;  
    	}  
    	  
    	struct file_operations led_fops ={  
    	    .owner = THIS_MODULE,  
    	    .open = led_open,  
    	    .read = led_read,  
    	    .write = led_write,  
    	    .release = led_release,  
    	};  
    	  
    	int __init led_init (void)  
    	{   int rc;  
    	    printk ("Test led dev\n");  
    	    rc = register_chrdev(LED_MAJOR,"led",&led_fops);  
    	    if (rc <0)  
    	    {  
    	        printk ("register %s char dev error\n","led");  
    	        return -1;  
    	    }  
    	    printk ("ok!\n");  
    	    return 0;  
    	}  
    	  
    	void __exit led_exit (void)  
    	{  
    	    unregister_chrdev(LED_MAJOR,"led");  
    	    printk ("module exit\n");  
    	    return ;  
    	}  
    	  
    	module_init(led_init);  
    	module_exit(led_exit);  
    

    Makefile

    ifneq ($(KERNELRELEASE),)
    
    obj-m := driver_led.o
    
    else 
    KDIR := /home/kk/Desktop/forlinx/linux-3.0.1
    all:
    	make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
    clean:
    	rm -f *.ko *.o *.mod.o *.mod.c *.symvers
    
    endif
    

    test.c

    #include <stdio.h>  
    #include <sys/types.h> 
    #include <sys/stat.h>  
    #include <fcntl.h>  
    int main (void)  
    {  
    	    int fd;  
    	    char buf[10]={0,1,2,3,4,5,6,7};  
    	    fd = open("/dev/my_led",O_RDWR);  
    	    if (fd < 0)  
    	    {  
    	        printf ("Open /dev/my_led file error\n");  
    	        return -1;  
    	    }     
    	    while(1)  
    	    {  
    	        write(fd,&buf[0],1);  
    	        sleep(1);  
    	        write(fd,&buf[1],1);  
    	        sleep(1);  
    	        write(fd,&buf[2],1);  
    	        sleep(1);  
    	        write(fd,&buf[3],1);  
    	        sleep(1);  
    	        write(fd,&buf[4],1);  
    	        sleep(1);  
    	        write(fd,&buf[5],1);  
    	        sleep(1);  
    	        write(fd,&buf[6],1);  
    	        sleep(1);  
    	        write(fd,&buf[7],1);  
    	        sleep(1);  
    	    }  
    	    close (fd);  
    	    return 0;  
    	  
    }  
    

    3.流程图

    六、运行结果

    1.点灯程序

    2.流水灯程序

    视频就不贴了

    七、心得体会

    第一次接触嵌入式开发,第一次靠自己一步一步做到从配置环境到烧写到点亮第一个小灯,收获点亮小灯的喜悦。这一路并不是一帆风顺的。遇到过ubuntu12.04的源因为年代久远失效,遂更换20.04。遇到过64位操作系统不支持32位交叉编译器的问题,也遇到过各种无读写权限,找不到文件,文件报错,驱动代码报错等大大小小的问题,挣扎了很久,也收获了很多。在硬件领域,很多的第一次,都是从小灯开始,小灯点亮不只是代表着这一个简单的步骤,更是代表第一次走通了这条路,可以第一次说我行了。

    最后,做一个收获的总结,熟悉linux系统,学会简单linux指令,熟悉OK6410-A开发板的烧入步骤,熟悉ARM寄存器,地址等。系统性的了解UBOOT和linux内核,yaffs2系统映像等知识。

  • 相关阅读:
    378. Kth Smallest Element in a Sorted Matrix
    295. Find Median from Data Stream
    857. Minimum Cost to Hire K Workers
    373. Find K Pairs with Smallest Sums
    767. Reorganize String
    无序列表
    有序列表
    缩写
    设计者详细信息
    强调
  • 原文地址:https://www.cnblogs.com/qingjielaojiu/p/15708692.html
Copyright © 2011-2022 走看看