当前位置:首页 > 单片机 > 单片机
[导读]嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。共享资源,欢迎转载:http://hbhuanggang.cublog.cn一

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。


共享资源,欢迎转载:http://hbhuanggang.cublog.cn


一、开发环境

主 机:VMWare--Fedora 9

开发板:Mini2440--64MB Nand, Kernel:2.6.30.4

编译器:arm-linux-gcc-4.3.2


二、相关概念

1、平台设备及平台设备驱动:

这个在前面篇幅:S3C2440上RTC时钟驱动开发实例讲解中已经讲过了。这里只需了解一下系统为我们定义的看门狗(Watchdog)平台设备及资源情况,在arch/arm/plat-s3c24xx/devs.c中,如下:


/* Watchdog */


/*定义了Watchdog平台设备使用的资源,这些资源在驱动程序中都会用到*/

static struct resource s3c_wdt_resource[] = {

[0] = { /*Watchdog所使用IO端口资源范围*/

.start = S3C24XX_PA_WATCHDOG,

.end = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,

.flags = IORESOURCE_MEM,

},

[1] = {/*Watchdog中断资源*/

.start = IRQ_WDT,

.end = IRQ_WDT,

.flags = IORESOURCE_IRQ,

}

};


/*定义了Watchdog平台设备*/

struct platform_device s3c_device_wdt = {

.name = "s3c2410-wdt", /*设备名称*/

.id = -1,

.num_resources= ARRAY_SIZE(s3c_wdt_resource), /*资源数量*/

.resource = s3c_wdt_resource, /*引用上面定义的资源*/

};

EXPORT_SYMBOL(s3c_device_wdt);



2、混杂设备(misc设备)

misc设备是Linux定义的主设备号为10的特殊字符设备,因为不符合字符设备的范畴,所以被归纳为misc设备,在Linux中有很多这种设备,例如:LED设备、Watchdog设备等等,系统会根据设备的次设备号来区分具体是哪个设备,通常这些次设备号被定义在include/linux/miscdevice.h中。在Linux中用miscdevice结构体来描述一个misc设备,这就意味着被定义为misc设备的驱动中就要实现该结构体中的接口函数。该结构体也定义在miscdevice.h中,如下:


struct miscdevice {

int minor;

const char *name;

const struct file_operations *fops;

struct list_head list;

struct device *parent;

struct device *this_device;

};



三、实例讲解

1、Watchdog硬件结构图分析:

我们从结构图和数据手册得知,看门狗Watchdog主要是实现系统自动复位的功能,他是利用芯片内部的定时器,定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零(俗称“喂狗”),所以程序在正常工作时,定时器总是不能溢出,也就不能产生复位信号;如果程序出现错误,不在定时周期内复位看门狗,那么定时器就会溢出而产生复位信号使系统复位。

S3C2440的Watchdog模块提供了三个寄存器来对Watchdog进行操作,他们分别是:定时器控制寄存器WTCON、定时器数据寄存器WTDAT和定时器计数寄存器WTCNT。注意:在对定时器数据寄存器WTDAT进行操作时必须在定时器控制寄存器WTCON使能之前写入一个计数目标值,当Watchdog使能开启后,WTDAT中的值会自动被加载到计数寄存器WTCNT中,然后Watchdog从CPU内部的时钟分频和时钟除数因子得到一个工作周期,当每个周期结束时计数寄存器WTCNT中的值会1,直到递减为0时,如果还不重新往WTCNT中写入新的计数目标值(即“喂狗”),则Watchdog就产生复位信号使系统复位。关于这些寄存器的功能和寄存器的各个位的操作值请参考数据手册。

2、Watchdog驱动程序具体实现步骤(建立驱动文件my2440_watchdog.c):

注意:在每步中,为了让代码逻辑更加有条理和容易理解,就没有考虑代码的顺序,比如函数要先定义后调用。如果要编译此代码,请严格按照C语言的规范来调整代码的顺序。

①、依然是驱动程序的最基本结构:Watchdog驱动的初始化和卸载部分及其他,如下:



#include

#include

#include

#include


/*Watchdog平台驱动结构体,平台驱动结构体定义在platform_device.h中,该结构体内的接口函数在第②、④步中实现*/

static struct platform_driver watchdog_driver =

{

.probe= watchdog_probe,/*Watchdog探测函数,在第②步中实现*/

.remove= __devexit_p(watchdog_remove),/*Watchdog移除函数, 在第④步中实现*/

.shutdown= watchdog_shutdown,/*Watchdog关闭函数,在第④步中实现*/

.suspend= watchdog_suspend,/*Watchdog挂起函数,在第④步中实现*/

.resume= watchdog_resume,/*Watchdog恢复函数,在第④步中实现*/

.driver=

{

/*注意这里的名称一定要和系统中定义平台设备的地方一致,这样才能把平台设备与该平台设备的驱动关联起来*/

.name= "s3c2410-wdt",

.owner= THIS_MODULE,

},

};

static int __init watchdog_init(void)

{

/*将Watchdog注册成平台设备驱动*/

return platform_driver_register(&watchdog_driver);

}

static void __exit watchdog_exit(void)

{

/*注销Watchdog平台设备驱动*/

platform_driver_unregister(&watchdog_driver);

}

module_init(watchdog_init);

module_exit(watchdog_exit);

/*驱动程序模块参数,如果在加载驱动模块时没有设定这些参数,则这些参数将采用默认值,

这些参数在接下来的步骤中将被一一用到,参数具体作用也将在各步骤中来说明*/

module_param(tmr_margin, int, 0);

module_param(tmr_atboot, int, 0);

module_param(nowayout, int, 0);

module_param(soft_noboot,int, 0);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Huang Gang");

MODULE_DESCRIPTION("My2440 Watchdog Driver");



②、Watchdog平台驱动结构中探测函数watchdog_probe的实现。探测就意味着在系统总线中去检测设备的存在,然后获取设备有用的相关资源信息,以便我们使用这些信息。代码如下:



#include

#include

#include

#include

#include

#include

/*定义了一个用来保存watchdog的IO端口占用的IO空间和经过虚拟映射后的内存地址*/

static struct resource *wdt_mem;

static void __iomem *wdt_base;

/*保存watchdog中断号,NO_IRQ宏定义在irq.h中*/

static int wdt_irqno = NO_IRQ;

/*保存从平台时钟队列中获取watchdog的时钟*/

static struct clk *wdt_clock;

#define CONFIG_WATCHDOG_ATBOOT(0)

#define CONFIG_WATCHDOG_DEFAULT_TIME(15)

static int tmr_atboot = CONFIG_WATCHDOG_ATBOOT;

static int tmr_margin = CONFIG_WATCHDOG_DEFAULT_TIME;

static int soft_noboot;

static unsigned int wdt_count;/*用于保存经计算后得到的计数寄存器WTCNT的计数值*/

/*申明并初始化一个自旋锁wdt_pie_lock,对Watchdog资源进行互斥访问*/

static DEFINE_SPINLOCK(wdt_pie_lock);

static int __devinit watchdog_probe(struct platform_device *pdev)

{

int ret;

int started = 0;

struct resource *res;/*定义一个资源,用来保存获取的watchdog的IO资源*/

/*在系统定义的watchdog平台设备中获取watchdog中断号

platform_get_irq定义在platform_device.h中*/

wdt_irqno = platform_get_irq(pdev, 0);

if(wdt_irqno < 0)

{

/*获取watchdog中断号不成功错误处理

dev_err定义在device.h中,在platform_device.h中已经引用,所以这里就不需再引用了*/

dev_err(&pdev->dev, "no irq for watchdogn");

return -ENOENT;

}

/*申请Watchdog中断服务,这里使用的是快速中断:IRQF_DISABLED。

中断服务程序为:wdt_irq,将Watchdog平台设备pdev做参数传递过去了*/

ret = request_irq(wdt_irqno, wdt_irq, IRQF_DISABLED, pdev->name, pdev);

if(ret)

{

/*错误处理*/

dev_err(dev, "IRQ%d error %dn", wdt_irqno, ret);

return ret;

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环。程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果。所以...

关键字: 单片机 看门狗 计算机

STC单片机是一款增强型51单片机,完全兼容MCS-51,还增加了新的功能,比如新增两级中断优先级,多一个外中断,内置EEPROM,硬件看门狗,具有掉电模式,512B内存等。还支持ISP下载,不用编程器,只要一个MAX2...

关键字: 单片机 看门狗 中断

今天要学习的是独立看门狗,看门狗电路的应用,使单片机可以在无人状态下实现连续工作,其 工作原理是:看门狗芯片和单片机的一个I/O引脚相连,该I/O引脚通过程序控制它定时地往看门狗的 这个引脚上送入高电平(或低电平),这一...

关键字: 看门狗 中断函数 单片机

看门狗(watch dog)是一个定时器,可以设置一个定时时间,计时到时会把MCU复位,所以MCU必须要在定时时间到之前将计数值重置(这个动作通常称为喂狗)。在嵌入式系统中加入看门狗,可以监测MCU是否还在正常运行,如果...

关键字: 看门狗 定时器

我们是否因系统上出现意外的电压尖峰或电流浪涌而担心系统安全?电流浪涌和电压尖峰可能是由系统上运行的软件引起的。来自软件的意外命令会使系统陷入无限循环,从而导致电源轨上出现电流浪涌或电压尖峰,并可能损坏设备。

关键字: 看门狗 电流浪涌

本文主要介绍AUTOSAR架构下的WdgDriverWdgIfWdgM模块,分析模块之间的依赖关系以及运行原理以帮助快速理解。本文以MPC5746R为主控芯片,以FS6500为SBC,DaVinciConfigurato...

关键字: SAR 看门狗

本文主要介绍AUTOSAR架构下的WdgDriverWdgIfWdgM模块,分析模块之间的依赖关系以及运行原理以帮助快速理解。本文以MPC5746R为主控芯片,以FS6500为SBC,DaVinciConfigurato...

关键字: SAR 看门狗

这是一篇旧文,技术交流群有人在讨论这个问题,今天就来分享一下。 我

关键字: STM32 FreeRTOS 看门狗

当下,一边汽车自动化驾驶的发展势头节节攀高,一边频频出现各类痛心的质量事故。

关键字: 看门狗 自动化驾驶 安全性

  本文根据网络视频采集的需要,将网络传输与视频采集相结合,设计了以S3C2440为核心的USB摄像头视频采集和嵌入式Linux系统下的视频服务器,从而实现了远程网络视频信息采集。   

关键字: s3c2440 视频采集 usb摄像头
关闭
关闭