当前位置:  编程技术>软件工程/软件设计
本页文章导读:
    ▪linux设备驱动篇之LED驱动(二)      ************************************************************************************ 接        续:linux设备驱动篇之LED驱动(一)http://blog.csdn.net/sonbai/article/details/8760993 PC 平 台:ubuntu12.10 开  .........
    ▪请求发送者与接收者解耦——命令模式(二)      3 完整解决方案       为了降低功能键与功能处理类之间的耦合度,让用户可以自定义每一个功能键的功能,Sunny软件公司开发人员使用命令模式来设计“自定义功能键”.........
    ▪请求发送者与接收者解耦——命令模式(四)      5 撤销操作的实现       在命令模式中,我们可以通过调用一个命令对象的execute()方法来实现对请求的处理,如果需要撤销(Undo)请求,可通过在命令类中增加一个逆向操作.........

[1]linux设备驱动篇之LED驱动(二)
    来源: 互联网  发布时间: 2013-11-19

************************************************************************************

接        续:linux设备驱动篇之LED驱动(一)http://blog.csdn.net/sonbai/article/details/8760993

PC 平 台:ubuntu12.10

开  发  板 :tq2440 fl2440

内核版本:linux-3.0

作        者:fulinux

************************************************************************************

一、内核3.0的LED设备驱动程序:

/*********************************************************************************
 *      Copyright:  (C) 2011 Guo Wenxue<guowenxue@gmail.com> 
 *                  All rights reserved.
 *
 *       Filename:  s3c_led.c
 *    Description:  This is the common LED driver runs on S3C24XX.
 *                
 *        Version:  1.0.0(10/27/2011~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "10/27/2011 11:39:10 AM"
 *                
 ********************************************************************************/
#include "s3c_driver.h"

#define DRV_AUTHOR                "Guo Wenxue <guowenxue@gmail.com>"
#define DRV_DESC                  "S3C24XX LED driver"

/* Driver version*/
#define DRV_MAJOR_VER             1
#define DRV_MINOR_VER             0
#define DRV_REVER_VER             0

#define DEV_NAME                  DEV_LED_NAME

//#define DEV_MAJOR                 DEV_LED_MAJOR
#ifndef DEV_MAJOR
#define DEV_MAJOR                 0 /*  dynamic major by default */
#endif

#define TIMER_TIMEOUT             40

static int debug = DISABLE;
static int dev_major = DEV_MAJOR;
static int dev_minor = 0;


/* ============================ Platform Device part ===============================*/
/*  LED hardware informtation structure*/
struct s3c_led_info
{
    unsigned char           num;              /* The LED number  */
    unsigned int            gpio;             /* Which GPIO the LED used */
    unsigned char           active_level;     /* The GPIO pin level(HIGHLEVEL or LOWLEVEL) to turn on or off  */
    unsigned char           status;           /* Current LED status: OFF/ON */
    unsigned char           blink;            /* Blink or not */
};

/*  The LED platform device private data structure */
struct s3c_led_platform_data
{
    struct s3c_led_info    *leds;
    int                     nleds;
};


/*  LED hardware informtation data*/
static struct s3c_led_info  s3c_leds[] = {
    [0] = {
        .num = 1,
        .gpio = S3C2410_GPB(5),
        .active_level = LOWLEVEL,
        .status = OFF,
        .blink = ENABLE,
    },
    [1] = {
        .num = 2,
        .gpio = S3C2410_GPB(6),
        .active_level = LOWLEVEL,
        .status = OFF,
        .blink = DISABLE,
    },
    [2] = {
        .num = 3,
        .gpio = S3C2410_GPB(8),
        .active_level = LOWLEVEL,
        .status = OFF,
        .blink = DISABLE,
    },
    [3] = {
        .num = 4,
        .gpio = S3C2410_GPB(10),
        .active_level = LOWLEVEL,
        .status = OFF,
        .blink = ENABLE,
    },
};

/*  The LED platform device private data */
static struct s3c_led_platform_data s3c_led_data = {
    .leds = s3c_leds,
    .nleds = ARRAY_SIZE(s3c_leds),
};

struct led_device
{
    struct s3c_led_platform_data    *data;
    struct cdev                     cdev;
    struct class                    *dev_class;
    struct timer_list               blink_timer;
} led_device;

static void platform_led_release(struct device * dev)
{
    int i;
    struct s3c_led_platform_data *pdata = dev->platform_data;

    dbg_print("%s():%d\n", __FUNCTION__,__LINE__);

    /* Turn all LED off */
    for(i=0; i<pdata->nleds; i++)
    {
         s3c2410_gpio_setpin(pdata->leds[i].gpio, ~pdata->leds[i].active_level);
    }
}

static struct platform_device s3c_led_device = {
    .name    = "s3c_led",
    .id      = 1,
    .dev     =
    {
        .platform_data = &s3c_led_data,
        .release = platform_led_release,
    },
};

 

/* ===================== led device driver part ===========================*/

void led_timer_handler(unsigned long data)
{
    int  i;
    struct s3c_led_platform_data *pdata = (struct s3c_led_platform_data *)data;

    for(i=0; i<pdata->nleds; i++)
    {
        if(ON == pdata->leds[i].status)
        {
              s3c2410_gpio_setpin(pdata->leds[i].gpio, pdata->leds[i].active_level);
        }
        else
        {
              s3c2410_gpio_setpin(pdata->leds[i].gpio, ~pdata->leds[i].active_level);
        }

        if(ENABLE == pdata->leds[i].blink )  /* LED should blink */
        {
            /* Switch status between 0 and 1 to turn LED ON or off */
            pdata->leds[i].status = pdata->leds[i].status ^ 0x01;
        }

        mod_timer(&(led_device.blink_timer), jiffies + TIMER_TIMEOUT);

    
[2]请求发送者与接收者解耦——命令模式(二)
    来源: 互联网  发布时间: 2013-11-19

3 完整解决方案

       为了降低功能键与功能处理类之间的耦合度,让用户可以自定义每一个功能键的功能,Sunny软件公司开发人员使用命令模式来设计“自定义功能键”模块,其核心结构如图4所示:

 

图4 自定义功能键核心结构图

       在图4中,FBSettingWindow是“功能键设置”界面类,FunctionButton充当请求调用者,Command充当抽象命令类,MinimizeCommand和HelpCommand充当具体命令类,WindowHanlder和HelpHandler充当请求接收者。完整代码如下所示:

import java.util.*;

//功能键设置窗口类
class FBSettingWindow {
	private String title; //窗口标题
    //定义一个ArrayList来存储所有功能键
	private ArrayList<FunctionButton> functionButtons = new ArrayList<FunctionButton>();
	
	public FBSettingWindow(String title) {
		this.title = title;
	}
	
	public void setTitle(String title) {
		this.title = title;
	}
	
	public String getTitle() {
		return this.title;
	}
	
	public void addFunctionButton(FunctionButton fb) {
		functionButtons.add(fb);
	}
	
	public void removeFunctionButton(FunctionButton fb) {
		functionButtons.remove(fb);
	}
	
    //显示窗口及功能键
	public void display() {
		System.out.println("显示窗口:" + this.title);
		System.out.println("显示功能键:");
		for (Object obj : functionButtons) {
			System.out.println(((FunctionButton)obj).getName());
		}
		System.out.println("------------------------------");
	}	
}

//功能键类:请求发送者
class FunctionButton {
	private String name; //功能键名称
	private Command command; //维持一个抽象命令对象的引用
	
	public FunctionButton(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
	
    //为功能键注入命令
	public void setCommand(Command command) {
		this.command = command;
	}
	
    //发送请求的方法
	public void onClick() {
		System.out.print("点击功能键:");
		command.execute();
	}
}

//抽象命令类
abstract class Command {
	public abstract void execute();
}

//帮助命令类:具体命令类
class HelpCommand extends Command {
	private HelpHandler hhObj; //维持对请求接收者的引用
	
	public HelpCommand() {
		hhObj = new HelpHandler();
	}
	
    //命令执行方法,将调用请求接收者的业务方法
	public void execute() {
		hhObj.display();
	}
}

//最小化命令类:具体命令类
class MinimizeCommand extends Command {
	private WindowHanlder whObj; //维持对请求接收者的引用
	
	public MinimizeCommand() {
		whObj = new WindowHanlder();
	}
	
//命令执行方法,将调用请求接收者的业务方法
	public void execute() {
		whObj.minimize();
	}
}

//窗口处理类:请求接收者
class WindowHanlder {
	public void minimize() {
		System.out.println("将窗口最小化至托盘!");
	}
}

//帮助文档处理类:请求接收者
class HelpHandler {
	public void display() {
		System.out.println("显示帮助文档!");
	}
}

       为了提高系统的灵活性和可扩展性,我们将具体命令类的类名存储在配置文件中,并通过工具类XMLUtil来读取配置文件并反射生成对象,XMLUtil类的代码如下所示:

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;

public class XMLUtil {
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象,可以通过参数的不同返回不同类名节点所对应的实例
	public static Object getBean(int i) {
		try {
			//创建文档对象
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;							
			doc = builder.parse(new File("config.xml")); 
		
			//获取包含类名的文本节点
			NodeList nl = doc.getElementsByTagName("className");
            Node classNode = null;
            if (0 == i) {
            	classNode = nl.item(0).getFirstChild();
            }
            else {
            	classNode = nl.item(1).getFirstChild();
            } 

            String cName = classNode.getNodeValue();
            
            //通过类名生成实例对象并将其返回
            Class c = Class.forName(cName);
	  	    Object obj = c.newInstance();
            return obj;
        }   
        catch(Exception e){
            e.printStackTrace();
           	return null;
        }
	}
}

       配置文件config.xml中存储了具体建造者类的类名,代码如下所示:

<?xml version="1.0"?>
<config>
	<className>HelpCommand</className>
    <className>MinimizeCommand</className>
</config>

       编写如下客户端测试代码:

class Client {
	public static void main(String args[]) {
		FBSettingWindow fbsw = new FBSettingWindow("功能键设置");
			
		FunctionButton fb1,fb2;
		fb1 = new FunctionButton("功能键1");
		fb2 = new FunctionButton("功能键1");
		
		Command command1,command2;
        //通过读取配置文件和反射生成具体命令对象
		command1 = (Command)XMLUtil.getBean(0);
		command2 = (Command)XMLUtil.getBean(1);
	    
        //将命令对象注入功能键
		fb1.setCommand(command1);
		fb2.setCommand(command2);
		
		fbsw.addFunctionButton(fb1);
		fbsw.addFunctionButton(fb2);
		fbsw.display();
		
        //调用功能键的业务方法
		fb1.onClick();
		fb2.onClick();
	}
}

       编译并运行程序,输出结果如下:

显示窗口:功能键设置

显示功能键:

功能键1

功能键1

------------------------------

点击功能键:显示帮助文档!

点击功能键:将窗口最小化至托盘!

       如果需要修改功能键的功能,例如某个功能键可以实现“自动截屏”,只需要对应增加一个新的具体命令类,在该命令类与屏幕处理者(ScreenHandler)之间创建一个关联关系,然后将该具体命令类的对象通过配置文件注入到某个功能键即可,原有代码无须修改,符合“开闭原则”。在此过程中,每一个具体命令类对应一个请求的处理者(接收者),通过向请求发送者注入不同的具体命令对象可以使得相同的发送者对应不同的接收者,从而实现“将一个请求封装为一个对象,用不同的请求对客户进行参数化”,客户端只需要将具体命令对象作为参数注入请求发送者,无须直接操作请求的接收者。

 

【作者:刘伟   http://blog.csdn.net/lovelion】

作者:LoveLion 发表于2013-4-15 21:52:14 原文链接
阅读:0 评论:0 查看评论

    
[3]请求发送者与接收者解耦——命令模式(四)
    来源: 互联网  发布时间: 2013-11-19
5 撤销操作的实现

       在命令模式中,我们可以通过调用一个命令对象的execute()方法来实现对请求的处理,如果需要撤销(Undo)请求,可通过在命令类中增加一个逆向操作来实现。

扩展

除了通过一个逆向操作来实现撤销(Undo)外,还可以通过保存对象的历史状态来实现撤销,后者可通过备忘录模式(Memento Pattern)来实现。

       下面通过一个简单的实例来学习如何使用命令模式实现撤销操作:

       Sunny软件公司欲开发一个简易计算器,该计算器可以实现简单的数学运算,还可以对运算实施撤销操作。

       Sunny软件公司开发人员使用命令模式设计了如图5所示结构图,其中计算器界面类CalculatorForm充当请求发送者,实现了数据求和功能的加法类Adder充当请求接收者,界面类可间接调用加法类中的add()方法实现加法运算,并且提供了可撤销加法运算的undo()方法。

图5  简易计算器结构图

       本实例完整代码如下所示:

//加法类:请求接收者
class Adder {
	private int num=0; //定义初始值为0
	
    //加法操作,每次将传入的值与num作加法运算,再将结果返回
	public int add(int value) {
		num += value;
		return num;
	}
}

//抽象命令类
abstract class AbstractCommand {
	public abstract int execute(int value); //声明命令执行方法execute()
	public abstract int undo(); //声明撤销方法undo()
}

//具体命令类
class ConcreteCommand extends AbstractCommand {
	private Adder adder = new Adder();
	private int value;
		
	//实现抽象命令类中声明的execute()方法,调用加法类的加法操作
public int execute(int value) {
		this.value=value;
		return adder.add(value);
	}
	
    //实现抽象命令类中声明的undo()方法,通过加一个相反数来实现加法的逆向操作
	public int undo() {
		return adder.add(-value);
	}
}

//计算器界面类:请求发送者
class CalculatorForm {
	private AbstractCommand command;
	
	public void setCommand(AbstractCommand command) {
		this.command = command;
	}
	
    //调用命令对象的execute()方法执行运算
	public void compute(int value) {
		int i = command.execute(value);
		System.out.println("执行运算,运算结果为:" + i);
	}
	
    //调用命令对象的undo()方法执行撤销
	public void undo() {
		int i = command.undo();
		System.out.println("执行撤销,运算结果为:" + i);
	}
}

       编写如下客户端测试代码:

class Client {
	public static void main(String args[]) {
		CalculatorForm form = new CalculatorForm();
		AbstractCommand command;
		command = new ConcreteCommand();
		form.setCommand(command); //向发送者注入命令对象
		
		form.compute(10);
		form.compute(5);
		form.compute(10);
		form.undo();
	}
}


        编译并运行程序,输出结果如下:

执行运算,运算结果为:10

执行运算,运算结果为:15

执行运算,运算结果为:25

执行撤销,运算结果为:15

 

思考

如果连续调用“form.undo()”两次,预测客户端代码的输出结果。

       需要注意的是在本实例中只能实现一步撤销操作,因为没有保存命令对象的历史状态,可以通过引入一个命令集合或其他方式来存储每一次操作时命令的状态,从而实现多次撤销操作。除了Undo操作外,还可以采用类似的方式实现恢复(Redo)操作,即恢复所撤销的操作(或称为二次撤销)。

练习

修改简易计算器源代码,使之能够实现多次撤销(Undo)和恢复(Redo)。

 

【作者:刘伟   http://blog.csdn.net/lovelion】

作者:LoveLion 发表于2013-4-15 23:21:29 原文链接
阅读:0 评论:0 查看评论

    
最新技术文章:
▪主-主数据库系统架构    ▪java.lang.UnsupportedClassVersionError: Bad version number i...    ▪eclipse项目出现红色叉叉解决方案
▪Play!framework 项目部署到Tomcat    ▪dedecms如何做中英文网站?    ▪Spring Batch Framework– introduction chapter(上)
▪第三章 AOP 基于@AspectJ的AOP    ▪基于插件的服务集成方式    ▪Online Coding开发模式 (通过在线配置实现一个表...
▪观察者模式(Observer)    ▪工厂模式 - 程序实现(java)    ▪几种web并行化编程实现
▪机器学习理论与实战(二)决策树    ▪Hibernate(四)——全面解析一对多关联映射    ▪我所理解的设计模式(C++实现)——解释器模...
▪利用规则引擎打造轻量级的面向服务编程模式...    ▪google blink的设计计划: Out-of-Progress iframes    ▪FS SIP呼叫的消息线程和状态机线程
▪XML FREESWITCH APPLICATION 实现    ▪Drupal 实战    ▪Blink: Chromium的新渲染引擎
▪(十四)桥接模式详解(都市异能版)    ▪你不知道的Eclipse用法:使用Allocation tracker跟...    ▪Linux内核-进程
▪你不知道的Eclipse用法:使用Metrics 测量复杂度    ▪IT行业为什么没有进度    ▪Exchange Server 2010/2013三种不同的故障转移
▪第二章 IoC Spring自动扫描和管理Bean    ▪CMMI简介    ▪目标检测(Object Detection)原理与实现(六)
▪值班总结(1)——探讨sql语句的执行机制    ▪第二章 IoC Annotation注入    ▪CentOS 6.4下安装Vagrant
▪Java NIO框架Netty1简单发送接受    ▪漫画研发之八:会吃的孩子有奶吃    ▪比较ASP和ASP.NET
▪SPRING中的CONTEXTLOADERLISTENER    ▪在Nginx下对网站进行密码保护    ▪Hibernate从入门到精通(五)一对一单向关联映...
▪.NET领域驱动设计—初尝(三:穿过迷雾走向光...    ▪linux下的块设备驱动(一)    ▪Modem项目工作总结
sqlserver iis7站长之家
▪windows下用putty上传文件到远程Linux方法    ▪iBatis和Hibernate的5点区别    ▪基于学习的Indexing算法
▪设计模式11---设计模式之中介者模式(Mediator...    ▪带你走进EJB--JMS编程模型    ▪从抽象谈起(二):观察者模式与回调
▪设计模式09---设计模式之生成器模式(Builder)也...    ▪svn_resin_持续优化中    ▪Bitmap recycle方法与制作Bitmap的内存缓存
▪Hibernate从入门到精通(四)基本映射    ▪设计模式10---设计模式之原型模式(Prototype)    ▪Dreamer 3.0 支持json、xml、文件上传
▪Eclipse:使用PMD预先检测错误    ▪Jspx.net Framework 5.1 发布    ▪从抽象谈起(一):工厂模式与策略模式
▪Eclipse:使用CheckStyle实施编码标准    ▪【论文阅读】《Chain Replication for Supporting High T...    ▪Struts2 Path_路径问题
▪spring 配置文件详解    ▪Struts2第一个工程helloStruts极其基本配置    ▪Python学习入门基础教程(learning Python)--2 Python简...
▪maven springmvc环境配置    ▪基于SCRUM的金融软件开发项目    ▪software quality assurance 常见问题收录
▪Redis集群明细文档    ▪Dreamer 框架 比Struts2 更加灵活    ▪Maven POM入门
▪git 分支篇-----不断更新中    ▪Oracle非主键自增长    ▪php设计模式——UML类图
▪Matlab,Visio等生成的图片的字体嵌入问题解决...    ▪用Darwin和live555实现的直播框架    ▪学习ORM框架—hibernate(二):由hibernate接口谈...
▪(十)装饰器模式详解(与IO不解的情缘)    ▪无锁编程:最简单例子    ▪【虚拟化实战】网络设计之四Teaming
▪OSGi:生命周期层    ▪Javascript/Jquery——简单定时器    ▪java代码 发送GET、POST请求
▪Entity Framework底层操作封装(3)    ▪HttpClient 发送GET、POST请求    ▪使用spring框架,应用启动时,加载数据
▪Linux下Apache网站目录读写权限的设置    ▪单键模式的C++描述    ▪学习ORM框架—hibernate(一):初识hibernate
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3