openwrt-安装-驱动-应用-lcd2004a实验

1. 板子f403tech的RT5350的板子和

(1)openWRT系统的定义和特点

OpenWrt是一个高度模块化、高度自动化的嵌入式Linux系统,拥有强大的网络组件,常常被

用于工控设备、电话、小型机器人、智能家居、路由器以及VOIP设备中。

OpenWrt支持各种处理器架构,无论是对ARM,X86,PowerPC或者MIPS都有很好的支持。

其多达3000多种软件包,囊括从工具链(toolchain),到内核(linux kernel),到软件包

(packages),再到根文件系统(rootfs)整个体系,使得用户只需简单的一个make命令即可方便快

速地定制一个具有特定功能的嵌入式系统来制作固件。 其模块化设计也可以方便的移植各类功能

到OpenWrt下,加快开发速度。

2 实验mjpeg-streamer、uvc视频监控

3 openwrt的下载安装

<pre name="code" class="cpp">sudo apt-get install subversion
sudo apt-get install git-core
sudo apt-get install gcc g++ binutils patch bzip2 flex bison make autoconf gettext texinfo unzip sharutils zlib1g-dev libncurses5-dev gawk
mkdir openwrt
cd openwrt/
svn co svn://svn.openwrt.org/openwrt/trunk
cd trunk/
./scripts/feeds update -a
./scripts/feeds install -a
(4) 配置编译openWRT系统
a、选择CPU型号
TargetSystem —> RalinkRT288x/RT3xxx
b、选择CPU子型号
Subtarget —> RT3x5x/RT5350basedboards
c、选择具体路由器型号
Targetprofile—>HAME-MPR-A2
(5) 编译
make V=99

至此,完成内核和文件系统镜像编译

4 驱动开发流程

进入/home/openwrt/trunk/package/kernel驱动目录,仿照参考其他的驱动。

新建example文件夹,进入example文件夹。

创建Makefile:

#

# Copyright (C) 2008-2012 OpenWrt.org

#

# This is free software, licensed under the GNU General Public License v2.

# See /LICENSE for more information.

# modify by 2014-10-23

include $(TOPDIR)/rules.mk

include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=example

PKG_RELEASE:=1

include $(INCLUDE_DIR)/package.mk

define KernelPackage/example

SUBMENU:=Other modules

#  DEPENDS:[email protected]!LINUX_3_3

TITLE:=Simple example driver

FILES:=$(PKG_BUILD_DIR)/example.ko

#  AUTOLOAD:=$(call AutoLoad,30,gpio-button-hotplug,1)

KCONFIG:=

endef

define KernelPackage/example/description

This is a example for the following in-kernel drivers:

1) example one

2) example two

endef

MAKE_OPTS:= \

ARCH="$(LINUX_KARCH)" \

CROSS_COMPILE="$(TARGET_CROSS)" \

SUBDIRS="$(PKG_BUILD_DIR)"

define Build/Prepare

mkdir -p $(PKG_BUILD_DIR)

$(CP) ./src/* $(PKG_BUILD_DIR)/

endef

define Build/Compile

$(MAKE) -C "$(LINUX_DIR)" \

$(MAKE_OPTS) \

modules

endef

$(eval $(call KernelPackage,example))

新建srce文件夹,进入src文件夹。
创建Makefile:
obj-m += example.o
创建example.c源文件
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kmod.h>

static int __init example_init(void)
{
        printk("hello example openwrt\n");
        return 0;
}

static void __exit example_exit(void)
{
        printk("hello example openwrt exit\n");
}

module_init(example_init);
module_exit(example_exit);

MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("example driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);

c.编译驱动的命令
make package/kernel/example/compile V=99
<pre name="code" class="cpp"><pre name="code" class="cpp">在/home/openwrt/trunk/bin/ramips/packages/base目录生成:kmod-example_3.14.18-1_ramips_24kec.ipk

5 应用开发流程

进入/home/openwrt/trunk/package应用目录。参考其他的应用文件。

创建helloworld文件夹,并进入。

创建Makefile:

##############################################

# OpenWrt Makefile for helloworld program

#

#

# Most of the variables used here are defined in

# the include directives below. We just need to

# specify a basic description of the package,

# where to build our program, where to find

# the source files, and where to install the

# compiled program on the router.

#

# Be very careful of spacing in this file.

# Indents should be tabs, not spaces, and

# there should be no trailing whitespace in

# lines that are not commented.

#

##############################################

include $(TOPDIR)/rules.mk

# Name and release number of this package

PKG_NAME:=helloworld

PKG_RELEASE:=1

# This specifies the directory where we‘re going to build the program.

# The root build directory, $(BUILD_DIR), is by default the build_mipsel

# directory in your OpenWrt SDK directory

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

# Specify package information for this program.

# The variables defined here should be self explanatory.

# If you are running Kamikaze, delete the DESCRIPTION

# variable below and uncomment the Kamikaze define

# directive for the description below

define Package/helloworld

SECTION:=utils

CATEGORY:=Utilities

TITLE:=Helloworld -- prints a snarky message

endef

# Uncomment portion below for Kamikaze and delete DESCRIPTION variable above

define Package/helloworld/description

If you can‘t figure out what this program does, you‘re probably

brain-dead and need immediate medical attention.

endef

# Specify what needs to be done to prepare for building the package.

# In our case, we need to copy the source files to the build directory.

# This is NOT the default.  The default uses the PKG_SOURCE_URL and the

# PKG_SOURCE which is not defined here to download the source from the web.

# In order to just build a simple program that we have just written, it is

# much easier to do it this way.

define Build/Prepare

mkdir -p $(PKG_BUILD_DIR)

$(CP) ./src/* $(PKG_BUILD_DIR)/

endef

# We do not need to define Build/Configure or Build/Compile directives

# The defaults are appropriate for compiling a simple program such as this one

# Specify where and how to install the program. Since we only have one file,

# the helloworld executable, install it by copying it to the /bin directory on

# the router. The $(1) variable represents the root directory on the router running

# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install

# directory if it does not already exist.  Likewise $(INSTALL_BIN) contains the

# command to copy the binary file from its current location (in our case the build

# directory) to the install directory.

define Package/helloworld/install

$(INSTALL_DIR) $(1)/bin

$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/

endef

# This line executes the necessary commands to compile our program.

# The above define directives specify all the information needed, but this

# line calls BuildPackage which in turn actually uses this information to

# build a package.

$(eval $(call BuildPackage,helloworld))

创建src文件夹,并进入。

创建Makefile:

# build helloworld executable when user executes "make"

helloworld: helloworld.o

$(CC) $(LDFLAGS) helloworld.o -o helloworld

helloworld.o: helloworld.c

$(CC) $(CFLAGS) -c helloworld.c

# remove object files and executable when user executes "make clean"

clean:

rm *.o helloworld

创建helloworld.c:

#include<stdio.h>

int main(void)

{

printf("helloworld\n");

return 0;

}

make package/helloworld/motor/compile V=99

在/home/openwrt/trunk/bin/ramips/packages/base目录生成:helloworld_1_ramips_24kec.ipk

5 LCD2004实验

lcd_204a_drv.c 驱动源程序:

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <linux/device.h>

#include <asm/uaccess.h>

#include <asm/irq.h>

#include <asm/io.h>

static struct class *lcddrv_class;

static struct device *lcddrv_class_dev;

volatile unsigned long *GPIOMODE;

volatile unsigned long *I2C_CONFIG;

volatile unsigned long *I2C_CLKDIV;

volatile unsigned long *I2C_DEVADDR;

volatile unsigned long *I2C_ADDR;

volatile unsigned long *I2C_DATAOUT;

volatile unsigned long *I2C_STATUS;

volatile unsigned long *I2C_STARTXFR;

volatile unsigned long *I2C_BYTECNT;

static int lcd_204a_open(struct inode *inode, struct file *file)

{

return 0;

}

static ssize_t lcd_204a_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos)

{

unsigned char val;

copy_from_user(&val, buf, 1);

*I2C_CONFIG = (0x6<<2)|(1<<1);                // 设备地址是7bit、不用发地址

*I2C_DEVADDR = 0x20;                        // 设备地址为0x20

*I2C_DATAOUT = val;

*I2C_STARTXFR = 0x0;

while(*I2C_STATUS & 0x1);

return 1;

}

static struct file_operations sencod_drv_fops = {

.owner        = THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open        = lcd_204a_open,

.write        = lcd_204a_write,

};

int major;

static int lcd_204a_init(void)

{

major = register_chrdev(0, "lcd_204a", &sencod_drv_fops);

lcddrv_class = class_create(THIS_MODULE, "lcd");

lcddrv_class_dev = device_create(lcddrv_class, NULL, MKDEV(major, 0), NULL, "lcd"); /* /dev/204a */

/* 映射相应的寄存器的地址 */

GPIOMODE = (volatile unsigned long *)ioremap(0x10000060, 4);

I2C_CONFIG = (volatile unsigned long *)ioremap(0x10000900, 4);

I2C_CLKDIV = (volatile unsigned long *)ioremap(0x10000904, 4);

I2C_DEVADDR = (volatile unsigned long *)ioremap(0x10000908, 4);

I2C_ADDR = (volatile unsigned long *)ioremap(0x1000090C, 4);

I2C_DATAOUT = (volatile unsigned long *)ioremap(0x10000910, 4);

I2C_STATUS = (volatile unsigned long *)ioremap(0x10000918, 4);

I2C_STARTXFR = (volatile unsigned long *)ioremap(0x1000091C, 4);

I2C_BYTECNT = (volatile unsigned long *)ioremap(0x10000920, 4);

/* 开始设置这些寄存器 */

*GPIOMODE &= ~(1<<0);                        // I2C_GPIO_MODE

*I2C_CLKDIV = 0x200;                            // IIC总线时钟 = 40MHz / 512 = 79KHz

return 0;

}

static void lcd_204a_exit(void)

{

unregister_chrdev(major, "lcd_204a");

device_unregister(lcddrv_class_dev);

class_destroy(lcddrv_class);

iounmap(GPIOMODE);

iounmap(I2C_CONFIG);

iounmap(I2C_CLKDIV);

iounmap(I2C_DEVADDR);

iounmap(I2C_ADDR);

iounmap(I2C_DATAOUT);

iounmap(I2C_STATUS);

iounmap(I2C_STARTXFR);

iounmap(I2C_BYTECNT);

}

module_init(lcd_204a_init);

module_exit(lcd_204a_exit);

MODULE_LICENSE("GPL");

lcd2004的应用程序:

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

//根据LCD2004A和PCF8574T的引脚确定

//RS:指令/数据 寄存器选择  RS = 0 : 指令寄存器 RS = 1 : 数据寄存器   根据原理图得:RS 与 PCF8574T的PO链接

//RW:读/写 选择   R/W = 0 : 写     R/W = 1 : 读  根据原理图得:RW 与 PCF8574T的P1链接

//CS:允许信号    表示从高电平到低电平,

#define DATA(rs, rw, cs, data) (data<<4)|(cs<<2)|(rw<<1)|rs

int fd;

static void lcd_write_command(unsigned char command)

{

unsigned char data;

/* 1.发送命令的高4位 */

data = DATA(0, 0, 1, (command>>4));

printf("h data = %d\n", data);

write(fd, &data, 1);

usleep(20);

data = DATA(0, 0, 0, (command>>4));

printf("h data = %d\n", data);

write(fd, &data, 1);

/* 2.发送命令的低4位 */

data = DATA(0, 0, 1, (command&0x0f));

printf("l data = %d\n", data);

write(fd, &data, 1);

usleep(20);

data = DATA(0, 0, 0, (command&0x0f));

printf("l data = %d\n", data);

write(fd, &data, 1);

}

static void lcd_write_data(unsigned char wdata)

{

unsigned char data;

/* 1.发送命令的高4位 */

data = DATA(1, 0, 1, (wdata>>4));

printf("h data = %d\n", data);

write(fd, &data, 1);

usleep(20);

data = DATA(1, 0, 0, (wdata>>4));

printf("h data = %d\n", data);

write(fd, &data, 1);

/* 2.发送命令的低4位 */

data = DATA(1, 0, 1, (wdata&0x0f));

printf("l data = %d\n", data);

write(fd, &data, 1);

usleep(20);

data = DATA(1, 0, 0, (wdata&0x0f));

printf("l data = %d\n", data);

write(fd, &data, 1);

}

static void lcd_set_xy(unsigned char x, unsigned char y)

{

unsigned char address;

if (y == 0)

address = 0x80 + x;

else

address = 0xc0 + x;

lcd_write_command(address);

}

/*

函数名:

lcd_write_char()

功能:

列x=0~15,行y=0,1

用法:

*/

static void lcd_write_char(unsigned char X,unsigned char Y,unsigned char Recdata)

{

lcd_set_xy(X, Y);

lcd_write_data(Recdata);

}

static int lcd_PutStr(unsigned char *DData,int pos)

{

unsigned char i;

if(pos==-1)

{

lcd_write_command(0x01); //清屏

usleep(2);

pos=0;

}

while((*DData)!=‘\0‘)

{

switch(*DData)

{

case ‘\n‘: //如果是\n,则换行

{

if(pos<21)

{

for(i=pos;i<20;i++)

lcd_write_char(i%20, i/20, ‘ ‘);

pos=20;

}

else

{

for(i=pos;i<40;i++)

lcd_write_char(i%20, i/20, ‘ ‘);

pos=40;

}

break;

}

case ‘\b‘: //如果是\b,则退格

{

if(pos>0)

pos--;

lcd_write_char(pos%20, pos/20, ‘ ‘);

break;

}

default:

{

if((*DData)<0x20)

{

*DData=‘ ‘;

}

lcd_write_char(pos%20, pos/20,*DData);

pos++;

break;

}

}

DData++;

}

return(pos);

}

//从右边数,保留几位小数

static int lcd_PutNum(unsigned long num,int XS,int pos)

{

unsigned long tmp=0;

unsigned char numbits=0;

if(pos==-1)

{

lcd_write_command(0x01);

usleep(2);

pos=0;

}

if(num==0)

{

lcd_write_char(pos%20, pos/20, ‘0‘);

pos++;

}

else

{

if(num<0)

{

lcd_write_char(pos%20, pos/20, ‘-‘);

num*=(-1);

pos++;

}

while(num)

{

tmp=tmp*10+(num%10);

num=num/10;

numbits++;

}

while(tmp)

{

lcd_write_char(pos%20, pos/20, (tmp%10)+48);

tmp=tmp/10;

pos++;

numbits--;

if(numbits==XS)

pos=lcd_PutStr(".",pos); //显示小数点

}

while(numbits--)

{

lcd_write_char(pos%20, pos/20, ‘0‘);

pos++;

}

}

return(pos);

}

void lcd_put_char(unsigned char ch, unsigned int pos , int flag)

{

if(flag == 0)

{

lcd_write_command(0x80+pos);

}

if(flag == 1)

{

lcd_write_command(0xc0+pos);

}

lcd_write_data(ch);

}

void lcd_put_str(const char *str, int flag)

{

int cnt=0;

while(*str !=‘\0‘)

{

lcd_put_char(*str, cnt, flag);

cnt++;

str++;

}

}

/* seconddrvtest

*/

int main(int argc, char **argv)

{

int p;

fd = open("/dev/lcd", O_RDWR);

if (fd < 0)

{

printf("can‘t open!\n");

}

lcd_write_command(0x28);

usleep(1000);

lcd_write_command(0x28);

usleep(1000);

lcd_write_command(0x28);

usleep(1000);

lcd_write_command(0x0e);            // 显示开

usleep(1000);

lcd_write_command(0x01);            // 清屏

usleep(1000);

//    lcd_write_char(0, 0, "a");

int i = 0;

for(i=0; i<26; i++)

{

lcd_write_command(0x80+i);

lcd_write_data(‘a‘+i);

}

for(i=0; i<30; i++)

{

lcd_write_command(0xc0+i);

lcd_write_data(‘2‘+i);

}

sleep(10);

lcd_write_command(0x01);                        // 清屏

usleep(1000);

lcd_put_str("Welcome RT5350", 0);

lcd_put_str("        --By Dreeam", 1);

//p = lcd_PutStr("RT5350 By F403tech!\n",0);    // 显示一段文字

//usleep(1000);

//p = lcd_PutStr("f403tech.taobao.com\n",p);    // 显示一段文字

//lcd_PutNum(1234,2,p);                // 显示12.34这个数

return 0;

}

a.软件包管理常用命令

opkg install xxx.ipk                        // 安装指定的软件包

opkg remove xxx.ipk                            // 卸载已经安装过的指定的软件包

opkg list                                                // 获取软件列表

生成的驱动位于 /lib/modules/3.14.18/目录下。

<pre name="code" class="cpp">生成的应用位于 /bin目录下。

opkg help


				
时间: 2024-11-10 08:02:24

openwrt-安装-驱动-应用-lcd2004a实验的相关文章

Window 8.1 安装驱动出现 “文件的哈希值不在指定的目录文件中。。。”

如图: 解决方法: 按下键盘组合键 Win + C,然后点击"设置"-->"更改电脑设置" 进入电脑设置之后,点击"更新和恢复"-->"恢复"-->"立即重启" 等一会,会出现几个选项,点击"疑难解答"--> "高级"-->"重启" 重启之后,会出现一个列表,选择"禁用强制驱动程序签名"(对应那个数

智能路由器-OpenWRT 系列三 (OpenWRT安装LuCI&amp;网络配置)

OpenWRT 安装 LUCI 每次ssh登陆OpenWRT安装新软件时,都必须更新opkg opkg update 安装LUCI opkg install luci 安装luci中文语言包, 不同OpenWRT版本中语言包的名称并不相同,比如15.05.1版本中. 进入 https://downloads.openwrt.org/chaoscalmer/15.05.1/ar71xx/nand/packages/luci/ 查找语言包的ipk 为 'luci-i18n-ahcp-zh-cngit

Arduino在64位WIN7下无法安装驱动的解决办法

1.获取权限 打开C:\Windows\System32\DriverStore\FileRepository,对着FileRepository文件夹,右键 >>属性 >>安全,选中Everyone ,点击编辑,选中完全控制选项框,设置如下: 2.复制文件 将mdmcpq.inf_amd64_neutral_fbc4a14a6a13d0c8文件拷贝至该目录下,下载地址. 3.安装驱动 计算机 >>管理 >>设备管理器 ,选中未知设备,更新驱动

Centos6.5/7.0安装后优化(实验用)

############################################################################## #Centos6.5/7.0安装后优化(实验用)2014.07.18 ############################################################################## # 优化条目: # 1.修改ip地址.网关.主机名.DNS等 # 2.关闭selinux,清空iptables #

[转]Caffe在Linux下的安装,编译,实验

Caffe在Linux下的安装,编译,实验 原文地址:http://www.cnblogs.com/evansyang/p/6150118.html 第一部分:Caffe 简介 caffe是有伯克利视觉和学习中心(BVLC)开发.作者是伯克利博士贾杨清.caffe是一个深度学习(deep learning)框架.其具有易读.快速和模块化思想. 第二部分:Caffe安装与配置 2.1 配置环境:ubuntu 14.04LTS, 使用Homebrew进行安装.暂不使用GPU,所以使用CPU-ONLY

2016031901 - ubuntu15.1安装驱动

个人使用u盘安装的ubuntu15.1,安装后找不到无线,主要是驱动没有安装的问题. 解决方案如下: 01.wife无法找到 02.pool文件夹内都是驱动,我们需要的网络驱动也在内 03.网络驱动包 此时你点击安装,缺少必要的依赖包.如果无法通过其他方式联网的话. 04.必要的安装包 笨方法安装驱动依赖包,那就打开main包,将见到的软件包安装一遍.最后安装网络包,就会出现周围的wife可以连接

Beaglebone Black开发板安装驱动

Beaglebone Black开发板安装驱动 Beaglebone Black开发板安装驱动,在使用Beaglebone Black开发板子做任何事情之前首先需要安装驱动.下面的内容就了展示在Windows.Mac OS X以及Linux操作系统下Beaglebone Black开发板驱动的安装方式.使用USB连接的Beaglebone Black在电脑中显示为一个存储设备,如图1.2所示.   图1.2  Beaglebone Black作为可移动存储设备 这其中包括了你要开始使用Beagl

Centos6.5安装后优化(实验用)

############################################################################## #Centos6.5安装后优化(实验用) ############################################################################## # 优化条目: # 1.修改ip地址.网关.主机名.DNS等 # 2.关闭selinux,清空iptables # 3.更新yum源及必要软件

电脑安装驱动报错解决办法,个人实践证明可以解决

1. 安装串口类型的驱动时,有可能会出现驱动安装不了的情况,报错:找不到相应文件或者找到文件,安装出错,如下图: 2.遇到此类问题,解决方法如下: 1>检查C盘路径下是否有“mdmcpq.inf”   "usbser.sys"文件,如果没有下载相应系统的文件, mdmcpq.inf 文件放在 c:\window\inf 下 usbser.sys 放在 c:\window\system32\dirver\下 重新安装驱动,如果不成功,请参考下面的方法. 2> 把usbser.