uClinux设备驱动程序的设计与编写

ObservableList 普通的List是“数据容器”,而是“数据源 + 广播电台”。添加的功能:监听器、精准变更报告、原子替换、实时过滤/排序视图。本质区别普通List是被动的(你问它才给)。是主动的(它变了就立刻告诉你,并且告诉你“哪里变了、怎么变的”)。正是因为它具备了这种“主动广播”的能力,JavaFX 才能实现数据驱动 UI的响应式编程模型。你之前在ComboBox源码中看到的监听器,正是依赖的机制才得以生效的。 阅读详情
uClinux设备驱动程序的设计与编写
1设备驱动程序的一般编写步骤
(1) 确定设备的主设备号
(2) 填充static struct file_operation这样的结构
(3) 定义一个类似__init mydriver_init(void)这样的注册函数,大体如下:
int __init mydriver_init(void)
{
int rc;
rc = register_chrdev(mydevice_Major, "mydev", &mydriver_fops);
if (rc < 0) {
printk(KERN_WARNING "mydevice: can/'t get Major %d//n",
mydevice_Major);
return rc;
}
printk("mydevice Driver Support.//n");

return 0;
}
其中mydev表示的设备文件为/dev/mydev X X,即习惯上起名为mydev mydev01 mydev02……如had hda1 hda2 hda3。不过名字是可以随意的。如果成功就返回0,否则返回-1

2 填充驱动程序子函数集struct file_operation结构
(1)驱动程序子函数集struct file_operation结构
struct file_operation结构共有11个成员,分别表示一函数指针,内容及作用说明如下:
struct file_operations {
/*需要改变文件位置时调用*/
loff_t (*llseek) (struct file *, loff_t, int);
/*执行read(2)系统调用时调用*/
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
/*执行write(2)系统调用时调用*/
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
/*读目录内容时调用*/
int (*readdir) (struct file *, void *, filldir_t);
/*执行poll 系统调用时调用*/
unsigned int (*poll) (struct file *, struct poll_table_struct *);
/*执行ioctl(2) 系统调用时调用*/
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
/*执行mmap(2) 系统调用时调用*/
int (*mmap) (struct file *, struct vm_area_struct *);
/*打开设备时调用*/
int (*open) (struct inode *, struct file *);
/*只在file的使用计数为0时调用,它用来释放file结构*/
int (*release) (struct inode *, struct file *);
/*执行fsync(2)系统调用时调用*/
int (*fsync) (struct file *, struct dentry *);
/*执行fcntl(2)系统调用时调用*/
int (*fasync) (int, struct file *, int);
};
(2)根据需要,按以下方法构造上述函数,如:
static int ReadPower(struct inode * inode, struct file * file, char * buffer, int count)
{
if (!Ready)
return -EAGAIN;
if (count != sizeof(int))
return -EINVAL;
copy_to_user(buffer, &myvar, sizeof(int));
return sizeof(int);
}
这里定义成static是因为该驱动程序子函数在文件外是通过上述的间接方法被调用的,文件外不需要该符号。
(3)把相关操作对应的函数名填入mydevice_operations中
填充static struct file_operations mydevice_operations时,用以上构造的函数名填充相应成员,例如:
struct file_operations TouchPanel_fops = {
read: ReadTouchPanel,
poll: TouchPanelSelect,
ioctl: TouchPanelIoctl,
open: OpenTouchPanel,
release: CloseTouchPanel,
};

3 中断处理
首先,中断不是必须的。如果设备要用中断模式,就要构造中断处理函数,并注册中断处理函数。
Linux中断处理过程由中断子系统完成;而中断处理函数只是处理具体操作,即读写数据等。成功注册该中断处理函数,就挂接到中断子系统上了。
中断处理一般由两个主要部分组成:
(1)构造中断处理函数void MyDriverInterrupt(int irq, void *dev_id, struct pt_regs *regs),
一般说来,Linux中断处理函数完成工作一方面把设备来的数据读出并保存起来,另一方面把内核中的数据写入设备。这样,驱动程序只需从内核读出数据,把用户提交的数据写入内核;这里可以使用一个简单的数组。
中断处理函数时要防止其他中断的干扰,可用"save_flags(flags); cli();"来关闭中断,相关处理完毕,用"restore_flags(flags)"来恢复。
(2) 注册中断可在mydriver_init()中,也 可在 mydriver_open()中,例如:
if (request_irq(
MYDEVICE_IRQ_NUM,
MyDeviceInterrupt,
IRQ_FLG_STD,
"mydevice",
NULL
)
) {
printk("TouchPanel: Cannot register interrupt.//n");
return -EBUSY;
}
其中:
MYDEVICE_IRQ_NUM: 注册中断号码
MyDeviceInterrupt: 中断处理程序
mydevice: 中断说明(可随便写)
如果返回0,表示成功,否则失败。

4 时间处理
在驱动程序中可以使用定时器来调度函数在未来某个特定时间执行。定时器包括它的超时值(timeout, 单位是jiffies)和超时时调用的函数。定时器列表的数据结构如下:
struct timer_list {
struct list_head list;
unsigned long expires; /*timeout超时值,以jiffies值为单位*/
unsigned long data; /*传递给定时器处理程序的参数*/
void (*function)(unsigned long); /*超时调用的定时器处理程序*/
};
定时器的timeout是个"jiffy"值,当jiffies值大于等于timer->expires时,timer->function函数就会执行,timeout值是个绝对数值,它与当前时间无关,不需要更新。
操作定时器有下面几个函数:
void init_timer(struct timer_list *timer);
该函数初始化新分配的定时器队列。
void add_timer(struct timer_list *timer);
该函数将定时器插入挂起的定时器的全局队列。
void del_timer(struct timer_list *timer);
如果需要在定时器超时前将它从列表中删除,应调用del_timer函数。但当定时器超时时,系统会自动地将它从列表中删除。
 
%DUMP LIBRARIES-List Loaded PSL Libraries 阅读详情

相关推荐

树莓派34/100 - Pico读取MPU6050加速度和陀螺仪传感器数据

树莓派Pico连接MPU-6050模块(三轴陀螺仪+三轴加速度),读取运动姿态数据。

申龙斌的程序人生 5043

Linux设备驱动程序-字符设备驱动程序

1.查看主设备号,次设备

Android系统开发-VR OS-系统安全隐私 658

深入探究uCLinux BIOS源码及其启动机制

uCLinux 是专为没有内存管理单元(MMU)的微处理器设计的嵌入式Linux操作系统版本。它的核心设计特点是非抢占式的内核,适用于资源有限的嵌入式设备。传统Linux相比,uCLinux去除了对MMU的依赖,因此在诸多嵌入式应用中大放异彩。引导过程从设备上电开始,经过一系列的初始化阶段直至操作系统内核开始运行。其主要步骤包括:电源开启:设备接通电源,CPU执行复位操作。POST(加电自检):CPU检查自身和系统硬件是否正常。引导加载程序执行。

weixin_33557333的博客 1076

uClinux下可加载设备驱动程序的研究实现

2007-12-25 09:45:09 uCLinux是一种面向嵌入式微处理器的微型操作系统,由于其源代码开放和功能齐备,已经在嵌入式操作系统中占有重要地位。介绍了在uCLinux版本2.4.26上如何实现可加载的设备驱动程序设计步骤及其程序设计要点,以及在S3C4510b上实现LED输出和开关量输入的可加载内核模块驱动程序的实现过程和应用层测试程序。0 引言 随

mybirdsky的专栏 730

基于嵌入式Linux的图形界面显示系统的设计(framebuffer)(DRIFT转)

基于嵌入式Linux的图形界面显示系统的设计(framebuffer)(DRIFT转) 摘要:本文详细描述了基于uClinux嵌入式操作系统的图形界面显示系统的实现方法,并对uClinux下Framebuffer驱动程序编写进行了专门探讨。 关键词:uCli...

weixin_33813128的博客 395

uClinux下的DS1284设备驱动程序开发

2007-12-25 09:47:21 引言 ARM 器件是近年来兴起的一种低功耗、高功效的嵌入式处理器。S3C4510B 是一款针对网络处理而推出的专用处理器。在利用S3C4510B 处理器构成的嵌入式系统中,为了保证系统的可靠稳定,多数都需要看门狗;同时,在某些应用领域还需要时钟和日历服务。Dallas公司的DS1284 集成了上面两个功能。 在嵌入式系

mybirdsky的专栏 436

linux u 驱动程序,在uClinux中增加自己的设备驱动程序

驱动程序的使用可以按照两种方式编译,一种是静态编译进内核,另一种是编译成模块以供动态加载。由于 uClinux不支持模块动态加载,而且嵌入式Linux不能够象桌面Linux那样灵活的使用insmod/rmmod 加载卸载设备驱动程序,因而这里只介绍将设备驱动程序静态编译进uClinux内核的方法。下面以uClinux为例,介绍在一个以模块方式出现的驱动程序test。c基础之上,将其编译进内核的一系...

weixin_39796152的博客 154

如何在嵌入式LINUX中增加自己的设备驱动程序

 驱动程序的使用可以按照两种方式编译,一种是静态编译进内核,另一种是编译成模块以供动态加载。由于uClinux不支持模块动态加载,而且嵌入式LINUX不能够象桌面LINUX那样灵活的使用insmod/rmmod加载卸载设备驱动程序,因而这里只介绍将设备驱动程序静态编译进uClinux内核的方法。  

kring Space 914

linux系统reales,基于uCLinux系统的IEEE1394设备驱动程序的编程研究实现

本文分析了IEEE1394协议驱动层框架,介绍了uCLinux下IEEE1394设备驱动程序架构和编写IEEE1394视频设备驱动程序的步骤和方法。(1)IEEE1394网络架构IEEE1394的网络共有三层,分别是物理层、链接层及传输层。物理层主要的功能是数据的编码、译码总线的判断。链接层主要功能为封包接收、封包传送周期控制。传输层则是定义请求及响应协议,并用以实现读取、写人及锁住三个基本的...

weixin_31715171的博客 407

Java List 接口详解:从基础到实战

List 接口继承自 Collection 接口,位于 java.util 包中。它允许存储重复元素,并且每个元素都有对应的索引位置,可以通过索引精确访问元素。 Set 不同,List 保持了元素的插入顺序。有序性:元素按照插入顺序排列,可通过索引访问。可重复:允许存储相同的元素。允许 null:大多数实现类允许存储 null 值。索引访问:支持通过下标快速定位元素。List 是 Java 集合框架中最重要的接口之一,掌握它的实现原理、常用方法和遍历方式,是写出高质量 Java 代码的基础。

2601_96129122的博客 240

C++ STL 容器深度剖析:vector list 的模拟实现及对比

vectorlist模拟实现

2402_87037360的博客 248

⚡Spring JDBC 完整体系 · 第 9 集 | 封装 list 方法 · 泛型初探

<think>我们只需要从给定内容生成一篇≤150字的摘要。内容是关于Spring JDBC封装list方法、泛型初探的。需要概括核心:项目背景、痛点(每次new RowMapper)、解决方案(BaseDao封装list泛型方法,传入SQL和Class,内部用BeanPropertyRowMapper)。注意字数限制,抓重点。直接输出摘要,不要其他格式。</think>本集针对Spring JDBC中查询需反复手动创建BeanPropertyRowMapper的痛点,设计了一个通用BaseDao并封装泛型

gzz_gzz的博客 445

list(C++)

<think>我们根据要求生成≤150字的摘要。内容是关于std::list的特点、使用和底层实现。注意字数限制,需要精炼。</think>摘要:本文讲解C++ STL中std::list双向链表容器的原理使用。其优势是任意位置O(1)插入删除,迭代器不易失效;缺点是不支持随机访问、内存开销大。介绍了增删改查、迭代器特性及splice、sort等专属操作,并强调不能使用std::sort。最后简要模拟实现迭代器核心接口,指导开发者按场景选择合适的容器。

2401_87882972的博客 497

06-04-排序集合-SortedList-TKey-TValue-双数组实现的有序集合

二分查找是 O(log n),后缀搬移是 O(n),所以中间插入总复杂度是 O(n)。随机生成 Add、setter、Remove、Clear 和查询序列,每步检查 Count、键顺序、键值对应和重复键行为。大 O 不告诉转折点。搬移后,原有最后一个有效槽会留下重复引用,实现应在 TKey/TValue 是引用或含引用时将尾槽置为 default,避免已删对象被后备数组继续保活。二分查找使按键查询为 O(log n),连续布局使枚举和已知索引访问紧凑,中间插入/删除则因双数组搬移为 O(n)。

设计 AI 玩游戏🎮 1116

C++ list 深度解析:从使用原理到模拟实现

list 是带头结点的双向循环链表,插入删除 O(1),无法随机访问。其迭代器通过 Ref/Ptr 模板区分普通 const 版本;注意 typename 语法陷阱。因节点零散,排序比 vector 慢,可拷入 vector 排序再拷回优化。splice/merge 仅改指针,效率极高。适合频繁插入删除、无需随机访问的场景。

xxwxx__的博客 364

06-05-排序集合-综合对比-SortedSet-vs-SortedDictionary-vs-SortedList选型

<think>我们根据要求,生成一篇不超过150字的文章摘要。内容是关于SortedSet、SortedDictionarySortedList的选择指南。需要提取核心要点:根据语义选择类型,树型数组型实现差异,注意比较器、可变键、性能内存,以及实验验证。摘要应精炼。</think>摘要:比较SortedSet、SortedDictionarySortedList,应优先按语义选择:唯一元素用Set,键值映射按更新模式选Dictionary或List,后者支持位置索引。注意比

设计 AI 玩游戏🎮 794

AI古诗生成器,唐诗,五言绝句自动生成(包含预训练模型,数据集,全套代码)

这是一个基于Keras的AI作诗程序,它利用LSTM和RNN算法来学习和预测古诗、唐诗、五言绝句等诗歌形式。该程序不仅提供了多种生成方式,包括藏头诗、随机写诗和给定第一句诗或字进行作诗等,还可以自由控制生成的诗歌形式和长度,让用户可以根据自己的喜好和需求进行创作。在使用该程序时,用户可以自由调控生成诗歌的概率,从而产生更具有多样性的故事,迸发出更多的创意和灵感。除了用于生成诗歌,该程序还可以用于创作灵感的启发、诗歌风格的探索等,具有多种实用价值和趣味性。此外,该程序还支持数据集的替换,用户可以根据自己的需要选择不同的数据集,从而让程序学习到更多的古诗,得到更好的结果。这使得该程序能够不断地迭代和优化,不断提升其生成诗歌的质量和多样性。

上一篇: 已经移植到uCLinux下的主要用户程序简介
下一篇: LCD驱动编写小节
magguang
博客等级 码龄20年 3粉丝 0原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值