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:=@!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("zhaochuang8888@126.com");
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

openwrt-安装-驱动-应用-lcd2004a实验相关推荐

  1. openwrt系统安装到云服务器,openwrt安装到云服务器

    openwrt安装到云服务器 内容精选 换一换 本节定义了云耀云服务器上报云监控的监控指标的命名空间,监控指标列表,各项监控指标的具体含义与使用说明,用户可以通过云监控检索云耀云服务器服务产生的监控指 ...

  2. openwrt系统安装到云服务器异常,openwrt安装到云服务器

    openwrt安装到云服务器 内容精选 换一换 Linux云服务器一般采用SSH连接方式,使用密钥对进行安全地无密码访问.但是SSH连接一般都是字符界面,有时我们需要使用图形界面进行一些复杂操作.本文 ...

  3. 怎样删除usb计算机连接网络打印机驱动,惠普激光打印机安装驱动时报“跟这台计算机连接的一个 USB 设备运行不正...

    1. 确保打印机驱动的安装方法是采用软件优先安装的方法.即,先将打印机和计算机断开连接,直接运行驱动光盘,当计算机提示"请确保打印机已连接到计算机,并打开打印机电源"时,再将打印机 ...

  4. Beaglebone Black开发板安装驱动

    Beaglebone Black开发板安装驱动 Beaglebone Black开发板安装驱动,在使用Beaglebone Black开发板子做任何事情之前首先需要安装驱动.下面的内容就了展示在Win ...

  5. Windows7自动安装驱动功能关闭与开启教程

    解决方法有两种: 方法一:更改设备安全设置 1. 按一下开始按钮,在开始搜索框中键入"设备和打印机",然后单击打开. 2. 这个窗口中包含了所有连接到当前计算机上的设备.包括显示器 ...

  6. openwrt安装oracle,Openwrt安装软件的方法-tomcat 随笔小记-install ubuntu 12.04 in virtualbox_169IT.COM...

    Openwrt安装软件 简介 Openwrt是个很自由的开源路由器系统,软件包支持几千个,功能很强大! 安装的方法主要有两种,telnet或者ssh连接后台安装和 页面安装. 下面的所有步骤的前提是当 ...

  7. stm32官方例程在哪找_正点原子Linux第十一章模仿STM32驱动开发格式实验

    1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第十一章模仿STM32驱动开发格式实验 在上一章使用C语 ...

  8. Nvidia: Mx150 CUDA10安装驱动

    参考这个:GeForce MX150显卡+Ubuntu16.04安装NVIDIA驱动+CUDA9.0+cuDNN7.0.5 1.下载合适版本的最合适的驱动 我的是430的驱动 CUDA支持版本的对应列 ...

  9. python病毒usb文件自动安装_win7禁USB自动安装驱动功能避免木马病毒入侵

    用户在限制USB设备使用方面,首先考虑的就是禁止其自动播放,以避免木马病毒入侵,但很多时候,这样的方法并不是很有效.如果你是Win7用户,那就可以通过它独有的"权限控制"技术,从源 ...

最新文章

  1. 2016年CCPC/ICPC比赛总结
  2. GET和POST有什么区别?及为什么网上的多数答案都是错的
  3. 【python图像处理】】python绘制散点图
  4. rust实战入门到进阶(3)
  5. 【Elasticsearch】action_request_validation_exception alidation Failed: 1: mapping type is missing
  6. 微型计算机的主要,微型计算机组成,微型计算机主要由什么组成
  7. VAD实现(一) 读取语音数据
  8. Python3.4 枚举类型的使用
  9. MySQL5 使用概要
  10. php 检查txt中全角大写字母的个数
  11. 对C语言指针的学习与理解
  12. HTML的字体10种酷炫效果
  13. 室内设计——住宅空间室内设计(包含预览图jpg和.psd文件)
  14. Windows故障恢复控制台使用方法
  15. 苏州VS上海:城市化的二个阶段
  16. Matlab入门(隐藏图片)
  17. linux虚拟网桥 docker,Docker 使用自定义网桥
  18. mysql 5.7.14 winx64_mysql-5.7.14-winx64解压版配置
  19. 计算机编写代码简介,Vcomputer简介
  20. 那么手机网站关键词优化排名该怎样做?

热门文章

  1. 百度开源的Warp-CTC人工智能技术,到底是什么鬼?
  2. 【编译原理】正则文法与正则式的等价性
  3. 安卓系统查看分区挂载信息
  4. 使用Python自动连接校网
  5. MAC抹盘重装详细教程
  6. 央视爆光微信打飞机流量门事件的思考
  7. 世界时钟 软件_Windows自带日历不好用?这款神仙软件用过就不想卸载!
  8. Python多线程篇一,theanding库、queue队列、生产者消费者模式爬虫实战代码超详细的注释、自动分配线程对应多任务,GIF演示【傻瓜式教程】
  9. python 实现读取excel中的所有sheet后,增加新的sheet,生成新的excel文件
  10. python电路仿真软件_电路仿真软件multisim