当前位置: 首页 > news >正文

做跨境电商网站有哪些产品推广文案

做跨境电商网站有哪些,产品推广文案,oa手机版下载,荆州网站建设目录 一、Linux下LED灯驱动原理 1.地址映射 二、硬件原理图分析 三、实验程序编写 1.LED 灯驱动程序编写 2.编写测试APP 四、运行测试 1.编译驱动程序和测试APP (1)编译驱动程序 (2)编译测试APP 2.运行测试 一、Linux下…

目录

一、Linux下LED灯驱动原理

1.地址映射

二、硬件原理图分析

三、实验程序编写

1.LED 灯驱动程序编写

2.编写测试APP

四、运行测试

1.编译驱动程序和测试APP

(1)编译驱动程序

(2)编译测试APP

2.运行测试


一、Linux下LED灯驱动原理

        Linux 下的任何外设驱动,最终都是要配置相应的硬件寄存器。所以本章的LED 灯驱动最终也是对I.MX6ULL 的IO口进行配置,与裸机实验不同的是,在Linux 下编写驱动要符合Linux的驱动框架。I.MX6U-ALPHA 开发板上的LED 连接到I.MX6ULL 的GPIO1_IO03 这个引脚上,因此本章实验的重点就是编写Linux 下I.MX6UL引脚控制驱动。

1.地址映射

        MMU 全称叫做Memory Manage Unit,也就是内存管理单元。在老版本的Linux 中要求处理器必须有MMU,但是现在Linux 内核已经支持无MMU的处理器了。MMU主要完成的功能如下:

(1)完成虚拟空间到物理空间的映射

(2)内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性

        我们重点来看一下第(1)点,也就是虚拟空间到物理空间的映射,也叫做地址映射。首先了解两个地址概念:虚拟地址(VA,Virtual Address)、物理地址(PA,Physcical Address)。对于32 位的处理器来说,虚拟地址范围是2^32=4GB,我们的开发板上有512MB 的DDR3,这512MB 的内存就是物理内存,经过MMU 可以将其映射到整个4GB 的虚拟空间,如下图所示: 

        物理内存只有512MB,虚拟内存有4GB,那么肯定存在多个虚拟地址映射到同一个物理地址上去,虚拟地址范围比物理地址范围大的问题处理器自会处理。

        Linux 内核启动的时候会初始化MMU,设置好内存映射,设置好以后CPU 访问的都是虚拟地址。比如I.MX6ULL 的GPIO1_IO03 引脚的复用寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 的地址为0X020E0068。如果没有开启MMU 的话直接向0X020E0068 这个寄存器地址写入数据就可以配置GPIO1_IO03 的复用功能。现在开启了MMU,并且设置了内存映射,因此就不能直接向0X020E0068 这个地址写入数据了。我们必须得到0X020E0068 这个物理地址在Linux 系统里面对应的虚拟地址,这里就涉及到了物理内存和虚拟内存之间的转换,需要用到两个函数:ioremap 和iounmap

二、硬件原理图分析

        从上图可以看出,LED0 接到了GPIO_3 上,GPIO_3 就是GPIO1_IO03,当GPIO1_IO03输出低电平(0)的时候发光二极管LED0 就会导通点亮,当GPIO1_IO03 输出高电平(1)的时候发光二极管LED0 不会导通,因此LED0也就不会点亮。所以LED0 的亮灭取决于GPIO1_IO03的输出电平,输出0 就亮,输出1 就灭

三、实验程序编写

1.LED 灯驱动程序编写

        新建名为“2_led”文件夹,然后在2_led 文件夹里面创建VSCode 工程,工作区命名为“led”。工程创建好以后新建led.c 文件,此文件就是led 的驱动文件,在led.c 里面输入如下内容:

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/io.h>#define LED_MAJOR 200 //主设备号
#define LED_NAME "led" //设备名字#define LEDOFF 0 //关灯
#define LEDON 1 //开灯//寄存器物理地址
#define CCM_CCGR1_BASE (0X020C406C)
#define SW_MUX_GPIO1_IO03_BASE (0X020E0068)
#define SW_PAD_GPIO1_IO03_BASE (0X020E02F4)
#define GPIO1_DR_BASE (0X0209C000)
#define GPIO1_GDIR_BASE (0X0209C004)//映射后的寄存器虚拟地址指针
static void __iomem *IMX6U_CCM_CCGR1;
static void __iomem *SW_MUX_GPIO1_IO03;
static void __iomem *SW_PAD_GPIO1_IO03;
static void __iomem *GPIO1_DR;
static void __iomem *GPIO1_GDIR;//LED打开/关闭
void led_switch(u8 sta)
{u32 val = 0;if(sta == LEDON){val = readl(GPIO1_DR);val &= ~(1 << 3);writel(val, GPIO1_DR);}else if(sta == LEDOFF){val = readl(GPIO1_DR);val |= (1 << 3);writel(val, GPIO1_DR);}
}
//打开设备
static int led_open(struct inode *inode, struct file *filp)
{return 0;
}
//从设备读取数据
static ssize_t led_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{return 0;
}
//从设备写取数据
static ssize_t led_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{int retvalue;unsigned char databuf[1];unsigned char ledstat;retvalue = copy_from_user(databuf,buf,cnt);if(retvalue < 0){printk("kernel write failed!\r\n");return -EFAULT;}ledstat = databuf[0];//获取状态值if(ledstat == LEDON){led_switch(LEDON); //开灯}else if(ledstat == LEDOFF){led_switch(LEDOFF);//关灯}return 0;
}
//关闭/释放设备
static int led_release(struct inode *inode, struct file *filp)
{return 0;
}
//设备操作函数
static struct file_operations led_fops = {.owner = THIS_MODULE,.open = led_open,.read = led_read,.write = led_write,.release = led_release,
};
//驱动入口函数
static int __init led_init(void)
{int retvalue = 0;u32 val = 0;//初始化LED//1.寄存器地址映射IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE, 4);SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE, 4);SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE, 4);GPIO1_DR = ioremap(GPIO1_DR_BASE, 4);GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE, 4);//2.使能GPIO1时钟val = readl(IMX6U_CCM_CCGR1);val &= ~(3 << 26); //清楚以前的设置bit26, 27val |= (3 << 26); //设置新值bit26,27置1writel(val, IMX6U_CCM_CCGR1);//3.设置GPIO1_IO03的复用功能,将其复用为GPIO1_IO03,最后设置IO属性writel(5, SW_MUX_GPIO1_IO03);//寄存器SW_PAD_GPIO1_IO03 设置电气属性writel(0x10B0, SW_PAD_GPIO1_IO03);//4.设置GPIO_IO03为输出功能,因为用的IO03,所以左移3位val = readl(GPIO1_GDIR);val &= ~(1 << 3); //清楚以前的设置val |= (1 << 3); //bit3置1,设置为输出writel(val, GPIO1_GDIR);//5.默认关闭LED,设置第三位为1就是高点平关闭LEDval = readl(GPIO1_DR);val |= (1 << 3);      writel(val, GPIO1_DR);//6.注册字符设备驱动retvalue = register_chrdev(LED_MAJOR, LED_NAME, &led_fops);if(retvalue < 0){printk("register chrdev failed!\r\n");return -EIO;}return 0;
}
//驱动出口函数
static int __exit led_exit(void)
{//取消映射iounmap(IMX6U_CCM_CCGR1);iounmap(SW_MUX_GPIO1_IO03);iounmap(SW_PAD_GPIO1_IO03);iounmap(GPIO1_DR);iounmap(GPIO1_GDIR);//注销设备驱动unregister_chrdev(LED_MAJOR, LED_NAME);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ssz");

2.编写测试APP

        编写测试APP,led 驱动加载成功以后手动创建/dev/led 节点,应用APP 通过操作/dev/led文件来完成对LED 设备的控制。向/dev/led 文件写0 表示关闭LED 灯,写1 表示打开LED 灯。新建ledApp.c 文件,在里面输入如下内容:

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"#define LEDOFF 0
#define LEDON 1int main(int argc, char *argv[])
{int fd, retvalue;char *filename;unsigned char databuf[1];if(argc != 3){printf("Error Usage!\r\n");return -1;}filename = argv[1];//打开led驱动fd = open(filename, O_RDWR);if(fd < 0){printf("filr %s open failed!\r\n", argv[1]);return -1;}databuf[0] = atoi(argv[2]);//向/dev/led文件写入数据retvalue = write(fd, databuf, sizeof(databuf));if(retvalue < 0){printf("LED Control Failed!\r\n");close(fd);return -1;}retvalue = close(fd); //关闭文件if(retvalue < 0){printf("fail %s close failed!\r\n",argv[1]);return -1;}return 0;
}

四、运行测试

1.编译驱动程序和测试APP

(1)编译驱动程序

编写Makefile 文件如下:

KERNELDIR := /home/ssz/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
CURRENT_PATH := $(shell pwd)
obj-m := led.obuild : kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

输入如下命令编译出驱动模块文件:

(2)编译测试APP
arm-linux-gnueabihf-gcc ledApp.c -o ledApp

2.运行测试

        将上一小节编译出来的led.ko 和ledApp 这两个文件拷贝到rootfs/lib/modules/4.1.15 目录中,重启开发板,进入到目录lib/modules/4.1.15 中,输入如下命令加载led.ko 驱动模块:

        驱动加载成功以后创建“/dev/led”设备节点,命令如下:

        驱动节点创建成功以后就可以使用ledApp 软件来测试驱动是否工作正常,输入如下命令打开LED 灯:

        输入上述命令以后观察I.MX6U-ALPHA 开发板上的红色LED 灯是否点亮,如果点亮的话说明驱动工作正常。在输入如下命令关闭LED 灯:

        如果要卸载驱动的话输入如下命令即可:

http://www.hkea.cn/news/248386/

相关文章:

  • 2017网站开发前景百度网盘资源链接入口
  • 平面广告设计主题seo是怎么优化上去
  • 正规网站制作公司哪家好四年级写一小段新闻
  • 济南网站建设安卓版快手seo
  • java开发兼职网站开发线上推广平台
  • 北京网站建设开发公司网站自动收录
  • wordpress最多多少用户seo基础知识
  • 湘潭做网站 去磐石网络b站推出的短视频app哪个好
  • 宿迁做网站的公司有人看片吗免费观看视频
  • 什么人最需要建设网站淘宝运营一般要学多久
  • 海南网站优化东莞免费建站公司
  • 传播型网站建设优势有哪些推广类软文
  • 如何在百度做网站推广赚钱的软件
  • c# 网站开发教程周口网站seo
  • 湘西网站建设帮人推广注册app的平台
  • 切图做网站web制作网站的模板
  • 网站的做网站公司哪家好网络优化大师app
  • 国内外包网站今日头条(官方版本)
  • 外网建筑设计网站线上渠道推广有哪些方式
  • 厦门做网站公司排名电工培训机构
  • 武汉网站设计制作外包公司的人好跳槽吗
  • 网站建设哪里最好页面关键词优化
  • 清远建设网站制作seo系统培训课程
  • 网站的网页建设知识ppt北大青鸟职业技术学院简介
  • 巫山网站设计aso优化榜单
  • 关于节约化建设网站的表态发言网站制作报价表
  • 建行网站是多少呢故事式的软文广告例子
  • 阳江市住房和城乡规划建设局网站一级消防工程师考试
  • 做课件的网站有哪些用html制作淘宝网页
  • 网站开发前后台整个流程品牌宣传的推广