5)像编译内核一样编译了
进内核源代码目录,比如uClinux-dist
make menucinfig
把主菜单选好了,不用说了吧?我的编译内核笔记里有,当然如果不想修改内核就只选上以下这个
Kernel/Library/Defaults Selection --->[*] Customize Kernel Settings (NEW)
意思是修改USER程序
EXIT 保存
然后在Customize Kernel Settings菜单里最后会出现Hello World--->
回车进去以后看见[]demo了吧?
选上
EXIT 保存
6)编译
几大命令~~~
make dep
make clean
make lib_only
make user_only
make romfs
make
之后在生成uClinux-dist/image下有了uclinux_rom.bin
7)烧写到板子里
板子里有UBOOT了吧?
顺序做下面步骤(我在UBOOT编译笔记里写过,再写一次)
A:loadb 0xc500000
B:发送(KERMIT协议)uclinux_rom.bin
C:erase 0x50000 0x1fffff
D:cp 0xc500000 0x50000 文件大小
注意:文件大小就是在传输完uclinux_rom.bin后显示的数字 0X开头=什么的那个0X数字
比如提示是0X0012a7f1=1222641
就0X0012a7f1/4+2=0x4A9FE命令就是:cp 0xc500000 0x50000 0x4A9FE
E:重起板子 就进UCLINUX了
8)板子进到/bin下 看是不是有个helloworld?
执行它就看见“hello world ! I got it!”
注意:因为把文件编写到内核了,所以不是用./helloworld
直接在任何目录下写helloworld就行
最简单的驱动---让LED闪一闪-1
user94/mamajinco/upload/1012942565.rar这几天抽时间做了几个驱动,基本都是字符设备,什么GPS 模块了GPRS模块了LCD了
有很多朋友关心驱动,但更菜的菜鸟居多:)总结了一下 把I/O驱动改成个更简单的LED驱动吧
做的工作非常简单,就是让连在GPC0-GPC2上的LED顺序闪10下
目的就是演示一下驱动过程。
一 先补充一下基础知识 懂的朋友就不用看了
嵌入式驱动的概念
设备驱动程序是操作系统内核和机器硬件之间的接口,设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它主要完成的功能有:对设备进行初始化和释放;把数据从内核传送到硬件和从硬件读取数据;读取应用程序传送给设备文件的数据、回送应用程序请求的数据以及检测和处理设备出现的错误。
Linux将设备分为最基本的两大类:一类是字符设备,另一类是块设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了。字符设备以单个字节为单位进行顺序读写操作,通常不使用缓冲技术;块设备则是以固定大小的数据块进行存储和读写的,如硬盘、软盘等,并利用一块系统内存作为缓冲区。为提高效率,系统对于块设备的读写提供了缓存机制,由于涉及缓冲区管理、调度和同步等问题,实现起来比字符设备复杂得多。LCD是以字符设备方式加以访问和管理的,Linux把显示驱动看做字符设备,把要显示的数据一字节一字节地送往LCD驱动器。
Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。为了管理这些设备,系统为设备编了号,每个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编号,如硬盘的主设备号是3。Linux为所有的设备文件都提供了统一的操作函数接口,方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针,如open()、close()、read()和write()等,但由于外设的种类较多,操作方式各不相同。Struct file_operations结构体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。打开一个文件就是调用这个文件file_operations中的open操作。不同类型的文件有不同的file_operations成员函数,如普通的磁盘数据文件,接口函数完成磁盘数据块读写操作;而对于各种设备文件,则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样,应用程序根本不必考虑操作的是设备还是普通文件,可一律当作文件处理,具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口。
二 开始写了
采用了在代码里加注释的方法,同时把几个文件上传了一下,喜欢的朋友可以下载当作模板。每个文件以==隔开
一共需要写写3个文件,1个驱动头文件,1个驱动文件,一个驱动测试用程序文件
分别是test.h,test.c和ledtest.c
简单说说驱动都做什么,怎么做
1 系统加载驱动
2 应用程序里打开设备(文件)
3 应用程序对设备操作
4 应用程序关闭设备(文件)
5 系统关闭设备
应用程序如何对设备操作?
记得C语言里怎么写文件吗?这里很相象的。对于一般的字符设备(还有块设备,网络设备等等)主要有3个函数(还有很多,可以看)llseek read: write: ioctl: 这里只用ioctl:控制函数,当然也可以使用读写函数操作IO 口,但ioctl:似乎更适合。
具体实现可以看ledtest.c文件了。
test.c中主要有几个函数 分别负责初始化和清除,打开和关闭。以及ioctl对串口寄存器写一些数据。
初始化和清除,打开和关闭函数里都各有一句主要句,已经分别作了注释。只要记住就好了。
对寄存器操作就不单独说了,需要看44B0数据手册了。好了 剩下的看代码吧。
==============================
==========test.h==================
==============================
/****************************************Copyright (c)**************************************************
** FREE
**
**--------------File Info-------------------------------
** File Name: config.h
** Last modified Date: 2006-9-9
** Last Version: 1.0
** Descriptions: User Configurable File
**
**----------------------------------------------------
** Created By: ZLG CHENMINGJI
** Created date: 2006-9-9
** Version: 1.0
** Descriptions: First version
**
**-------------------------------------------------
** Modified by:MAMAJINCO
** Modified date:2006-9-9
** Version:1.0
** Descriptions:在此忠心感谢ZLG的模版 我的高质量编程意识起源于此
**
*****************************************************/
//防止重复包含此文件而设置的宏
#ifndef __CONFIG_H
#define __CONFIG_H
//包含必要的头文件 /********************************/ #define LED_MAJOR_NR 231 //231~239 240~255都可以 #define DEVICE_NAME 'led' /* name for messaging */ #define SET_LED_OFF 0 #endif 最简单的驱动---让LED闪一闪-2 /*************Copyright (c)************************** /************************************************************* /****************************************************************/ static struct file_operations LED_fops = /* 前面基础部分提到的重要结构体了*/ #if 0/*注意:#if 0-#endif里的代码是不编译的,但这里为了驱动模板讲解上的完整性仍然加上了*/ (*(volatile unsigned *)S3C44B0X_PUPC) &= 0xffffffc0;/*GPIO C口0~2 设置为上拉*/ MOD_INC_USE_COUNT; switch(cmd) break; case 1://把ARG传来的IO口编号转换成寄存器数据,把相应IO口置高 default: /************************************************** result = register_chrdev(231,'led', &LED_fops); 最简单的驱动---让LED闪一闪-4 /*********************************************************** ===================================== /*********************Copyright (c)**************************
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
/* 应用程序配置 */
/********************************/
//以下根据需要改动
//定义主设备号 设备名称
#define SET_LED_ON 1
/************************ End Of File
*********************************************************/
=============END===============
==============================
============test.c================
==============================
** FREE
**
**--------------File Info-----------------------------------------
** File Name: test.c
** Last modified Date: 2006-9-9
** Last Version: 1.0
** Descriptions: User Configurable File
**
**----------------------------------------------------
** Created By: ZLG CHENMINGJI
** Created date: 2006-9-9
** Version: 1.0
** Descriptions: First version
**
**--------------------------------------------------------
** Modified by:MAMAJINCO
** Modified date:2006-9-9
** Version:1.0
** Descriptions:在此忠心感谢ZLG的模版 我的高质量编程意识起源于此
**
***********************************************************/
#i nclude 'test.h'//包含驱动头文件
/************************************************************
function announce
******************************************************/
//以下是关键函数的声明
static int led_open(struct inode *inode, struct file *filp);
//打开设备时用的 linux把设备当作文件管理 设备最好在用的时候再打开 尽量不要提前
static int led_release(struct inode *inode, struct file *filp);
static int led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long param);
//控制函数 这里用于控制LED亮与灭
int led_init(void);//注册时用的 注意 模块注册的越早越好
void led_cleanup(void);//卸载时用的
** '全局和静态变量在这里定义'
** global variables and static variables define here
{
owner: THIS_MODULE,
llseek: gpio_llseek,
read: gpio_read,
write: gpio_write,
#endif
ioctl: led_ioctl,//控制函数
open: led_open, //打开函数,打开文件时做初始化的
release: led_release,//释放函数,关闭时调用
};
/**************************************************************
** Function name: led_open
** Descriptions: open device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**-------------------------------------------------------------
** Modified by:mamajinco
** Modified Date: 2006-9-9
**--------------------------------------------------------------
**************************************************************/
static int led_open(struct inode *inode, struct file *filp)
{
/*初始化放在OPEN里*/
(*(volatile unsigned *)S3C44B0X_PCONC) &= 0xffffffc0;
(*(volatile unsigned *)S3C44B0X_PCONC) |= 0xffffffd5; /*GPIO C口0~2 设置为输出*/
return 0;
}
最简单的驱动---让LED闪一闪-3
*********************************************************
** Function name: led_release
** Descriptions: release device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**-----------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**--------------------------------------------------------
****************************************************/
static int led_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return(0);
}
/****************************************************
** Function name: led_ioctl
** Descriptions: IO control function
** Input:inode: information of device
** filp: pointer of file
** cmd: command
** arg: additive parameter
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**-------------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**----------------------------------------------------------
***********************************************************/
static int led_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
if( arg > 2 )//判断IO是否属于0-2
return -1;
{
case 0://把ARG传来的IO口编号转换成寄存器数据,把相应IO口置低
(*(volatile unsigned *)S3C44B0X_PDATC) |= 0x1 << arg;
(*(volatile unsigned *)S3C44B0X_PDATC) &= 0x0 << arg;
break;
return -1;
break;
}
return 0;
}
** Function name: led_init
** Descriptions: init driver
** Input:none
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2006-9-9
**------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**-----------------------------------------------------
*************************************************/
int led_init(void)
{
int result;
/*关键语句 用于注册
** 注意!这是传统的注册方法 在2.4以上的linux版本中 加入了devfs设备文件系统 使注册更容易 但为了与大部分资料相**同 大家看的方便 这里仍然使用老方法*/
if (result < 0) //用于异常检测
{
printk(KERN_ERR DEVICE_NAME ': Unable to get major %dn', LED_MAJOR_NR ); //printk用于向内核输出信息
return(result);
}
printk(KERN_INFO DEVICE_NAME ': init OKn');
return(0);
}
/*************************************************************
** Function name: led_cleanup
** Descriptions: exit driver
** Input:none
** Output none
** Created by: Chenmingji
** Created Date: 2006-9-9
**--------------------------------------------------------
** Modified by: mamajinco
** Modified Date: 2006-9-9
**-----------------------------------------------------
**************************************************/
void led_cleanup(void)
{
unregister_chrdev(231, 'led'); //与register_chrdev配对使用 用于清楚驱动
}
** End Of File
****************************************************/
===============END=============
=============ledtest.c===============
===================================
** FREE
**
**--------------File Info----------------------------
** File Name: led.c
** Last modified Date: 2006-9-9
** Last Version: 1.0
** Descriptions: User Configurable File
**
**-------------------------------------------------------
** Created By: ZLG CHENMINGJI
** Created date: 2006-9-9
** Version: 1.0
** Descriptions: First version
**
**--------------------------------------------------------
** Modified by:MAMAJINCO
** Modified date:2006-9-9
** Version:1.0
** Descriptions:在此忠心感谢ZLG的模版 我的高质量编程意识起源于此
**
********************************************************/
上一篇:学习ARM开发(23)
下一篇:ARM裸机篇--按键中断
设计资源 培训 开发板 精华推荐
- LT1085CT-3.3、3.3V/7.5A LDO稳压器的典型应用电路
- DC1338A,使用 LTC2990 I2C 温度电压和电流监视器的演示板
- AM1D-4809S-RZ 9V 1W DC/DC 转换器的典型应用
- ADP1607-EVALZ,ADP1607 评估板、2MHz、同步升压、DC 到 DC 转换器
- MIKROE-3507,基于 3.5" 320x240 像素 TFT 显示器的 TFT 板 3 电容式显示板
- AM3G-2403SZ 3.3V 3瓦直流转直流转换器的典型应用
- 使用 MaxLinear, Inc 的 SPX385M1-1.2 的参考设计
- LTC4070EDDB 演示板,具有 NTC 热敏电阻输入的简单低 IQ 电池充电器/保护器
- 使用 Analog Devices 的 LTC1315CG 的参考设计
- 用于简单时钟振荡器的 NCP301HSN09T1 0.9V 电压检测器的典型应用
- Allegro MicroSystems 在 2024 年德国慕尼黑电子展上推出先进的磁性和电感式位置感测解决方案
- 左手车钥匙,右手活体检测雷达,UWB上车势在必行!
- 狂飙十年,国产CIS挤上牌桌
- 神盾短刀电池+雷神EM-i超级电混,吉利新能源甩出了两张“王炸”
- 浅谈功能安全之故障(fault),错误(error),失效(failure)
- 智能汽车2.0周期,这几大核心产业链迎来重大机会!
- 美日研发新型电池,宁德时代面临挑战?中国新能源电池产业如何应对?
- Rambus推出业界首款HBM 4控制器IP:背后有哪些技术细节?
- 村田推出高精度汽车用6轴惯性传感器
- 福特获得预充电报警专利 有助于节约成本和应对紧急情况