linux学习的步骤

linux学习的步骤,第1张

嵌入式 Linux学习步骤

1、Linux 基础

安装Linux *** 作系统 Linux文件系统 Linux常用命令 Linux启动过程详解 熟悉Linux服务能

够独立安装Linux *** 作系统 能够熟练使用Linux系统的基本命令 认识Linux系统的常用服务

安装Linux *** 作系统 Linux基本命令实践 设置Linux环境变量 定制Linux的服务 Shell 编程

基础使用vi编辑文件 使用Emacs编辑文件 使用其他编辑器

2、Shell 编程基础

Shell简介 认识后台程序Bash编程熟悉Linux系统下的编辑环境 熟悉Linux下的各种Shell

熟练进行shell编程熟悉vi基本 *** 作 熟悉Emacs的基本 *** 作 比较不同shell的区别 编写一个

测试服务器是否连通的shell脚本程序 编写一个查看进程是否存在的shell脚本程序 编写一

个带有循环语句的shell脚本程序

3、Linux 下的 C 编程基础

linux C语言环境概述 Gcc使用方法 Gdb调试技术 Autoconf Automake Makefile 代码优化

熟悉Linux系统下的开发环境 熟悉Gcc编译器 熟悉Makefile规则编写Hello,World程序 使用

make命令编译程序 编写带有一个循环的程序 调试一个有问题的程序

4、嵌入式系统开发基础

嵌入式系统概述 交叉编译 配置TFTP服务 配置NFS服务 下载Bootloader和内核 嵌入式

Linux应用软件开发流程熟悉嵌入式系统概念以及开发流程 建立嵌入式系统开发环境制作

cross_gcc工具链 编译并下载U-boot 编译并下载Linux内核 编译并下载Linux应用程序

5、嵌入式系统移植

Linux内核代码 平台相关代码分析 ARM平台介绍 平台移植的关键技术 移植Linux内核到

ARM平台 了解移植的概念 能够移植Linux内核移植Linux26内核到 ARM9开发板

6、嵌入式 Linux 下串口通信

串行I/O的基本概念 嵌入式Linux应用软件开发流程 Linux系统的文件和设备 与文件相关的

系统调用 配置超级终端和MiniCOM 能够熟悉进行串口通信 熟悉文件I/O 编写串口通信程序

编写多串口通信程序

7、嵌入式系统中多进程程序设计

Linux系统进程概述 嵌入式系统的进程特点 进程 *** 作 守护进程 相关的系统调用了解Linux

系统中进程的概念 能够编写多进程程序编写多进程程序 编写一个守护进程程序 sleep系统

调用任务管理、同步与通信 Linux任务概述任务调度 管道 信号 共享内存 任务管理 API

了解Linux系统任务管理机制 熟悉进程间通信的几种方式 熟悉嵌入式Linux中的任务间同步

与通信编写一个简单的管道程序实现文件传输 编写一个使用共享内存的程序

线程的基础知识 多线程编程方法 线程应用中的同步问题了解线程的概念 能够编写简单的

多线程程序编写一个多线程程序

8、嵌入式 Linux 网络编程

网络基础知识 嵌入式Linux中TCP/IP网络结构 socket 编程 常用 API函数 分析Ping命令的

实现 基本UDP套接口编程 许可证管理 PPP协议 GPRS 了解嵌入式Linux网络体系结构 能够

进行嵌入式Linux环境下的socket 编程 熟悉UDP协议、PPP协议 熟悉GPRS 使用socket 编写

代理服务器 使用socket 编写路由器 编写许可证服务器 指出TCP和UDP的优缺点 编写一个

web服务器 编写一个运行在 ARM平台的网络播放器

9、GUI 程序开发

GUI基础 嵌入式系统GUI类型 编译QT 进行QT开发熟悉嵌入式系统常用的GUI 能够进行QT编

程使用QT编写“Hello,World”程序 调试一个加入信号/槽的实例 通过重载QWidget 类方

法处理事件

10、Linux 字符设备驱动程序

设备驱动程序基础知识 Linux系统的模块 字符设备驱动分析 fs_operation结构 加载驱动

程序了解设备驱动程序的概念 了解Linux字符设备驱动程序结构 能够编写字符设备驱动程

序编写Skull驱动 编写键盘驱动 编写I/O驱动 分析一个看门狗驱动程序 对比Linux26内核

与24内核中字符设备驱动的不同Linux 块设备驱动程序块设备驱动程序工作原理 典型的块

设备驱动程序分析 块设备的读写请求队列了解Linux块设备驱动程序结构 能够编写简单的

块设备驱动程序比较字符设备与块设备的异同 编写MMC卡驱动程序 分析一个文件系统 对比

Linux26内核与24内核中块设备驱动的不同

11、文件系统

虚拟文件系统 文件系统的建立 ramfs内存文件系统 proc文件系统 devfs 文件系统 MTD技

术简介 MTD块设备初始化 MTD块设备的读写 *** 作了解Linux系统的文件系统 了解嵌入式

Linux的文件系统 了解MTD技术 能够编写简单的文件系统为 ARM9开发板添加 MTD支持 移植

JFFS2文件系统 通过proc文件系统修改 *** 作系统参数 分析romfs 文件系统源代码 创建一个

cramfs 文件系统

应用层默认open函数定义:int open( const char pathname,int flags);

驱程序般open函数定义:int(open)(struct inode inode, struct file filp)

LED点亮应用层主函数

[code=C/C++][/code]void main(void)

{

int testdev;

int i;

char buf[10];

testdev = open ("/dev/test",O_RDWR); //应该用应用层默认Open函数吧

if(testdev == -1)

{

printf("Cann't open file/n");

exit(0);

}

printf("buf = 0x%x/n",buf);

read(testdev,buf,10); //功opentestdev值0能够file文件描述符呢

write(testdev,buf,1);

led_ctlport='G';

led_ctlbit=5;

led_ctlvalue=0;

ioctl(testdev,GPIO_IO_SET_GPG,&led_ctl);

printf("%s",buf);

pause();

close(testdev);

}

我疑问:

1驱程序open函数:int(open)(struct inode inode, struct file filp)

哪使用啊

2驱open函数般用做啊

3文代码功opentestdev值0能够file文件描述符呢

才始习Linux设备驱发借本书代码没注释面驱意思懂希望各位神指点指点万谢

面都我编写字符设备驱代码请问static int read_test()函数始static void release_test()函数参数内部代码意义

万谢

采纳前加100谢谢

#include <stdioh>

#include <stringh>

#include <stdlibh>

#include <linux/typesh>

#include <linux/fsh>

#include <linux/mmh>

#include <linux/errnoh>

#include <asm/segmenth>

#include <asm/uaccessh>

#include <linux/moduleh>

unsigned int test_major = 0;

static int read_test(struct inode node,struct file fle,char buf,int count)

{

int left;

if (access_ok(VERIFY_WRITE, buf, count))

{

for (left = count; left > 0; left--)

{

_put_user('a',buf);

buf ++;

}

}

return count;

}

static int write_test(struct inode node, struct file fle, char buf, int count)

{

return count;

}

static int open_test(struct inode inode,struct file file)

{

try_module_get(THIS_MODULE);

return 0;

}

static void release_test(struct inode inode, struct file file)

{

module_put(THIS_MODULE);

}

struct file_operations test_fops =

{

owner = THIS_MODULE,

read = read_test,

write = write_test,

open = open_test,

release = release_test,

};

int init_module()

{

int result;

result = register_chrdev(0,"test,&test_fops");

if (result < 0)

{

printk(KERN_INFO "dddddddddddddddd");

return result;

}

return 0;

}

/这是一个简单的用户程序与驱动交互的例程/

void main(void)

{

int testdev;

int i;

char buf[10];

/ 这里是用的open系统调用,是linux内核接口函数,不是库函数,返回fd,详细请google ,这个open最终会调用驱动中的open函数(代码流程是这样的open()->sys_open()->filp_open()->dentry_open()->驱动open)/

testdev = open ("/dev/test",O_RDWR);

if(testdev == -1)

{

printf("Cann't open file/n");

exit(0);

}

printf("buf = 0x%x/n",buf);

/ 下面的read write 和ioctl是用户程序和内核驱动的最直接的交互方式 /

read(testdev,buf,10);

write(testdev,buf,1);

led_ctlport='G';

led_ctlbit=5;

led_ctlvalue=0;

ioctl(testdev,GPIO_IO_SET_GPG,led_ctl);

printf("%s",buf);

pause();

close(testdev);

}

你基础有点弱,慢慢学习就知道了,参考下《linux设备驱动程序》

Linux下生成驱动设备节点文件的方法有3个:1、手动mknod;2、利用devfs;3、利用udev

在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点。

在2617以前,在/dev目录下生成设备文件很容易,

devfs_mk_bdev

devfs_mk_cdev

devfs_mk_symlink

devfs_mk_dir

devfs_remove

这几个是纯devfs的api,2617以前可用,但后来devfs被sysfs+udev的形式取代,同时期sysfs文件系统可以用的api:

class_device_create_file,在2626以后也不行了,现在,使用的是device_create ,从2618开始可用

struct device device_create(struct class class, struct device parent,

dev_t devt, const char fmt, )

从2626起又多了一个参数drvdata: the data to be added to the device for callbacks

不会用可以给此参数赋NULL

struct device device_create(struct class class, struct device parent,

dev_t devt, void drvdata, const char fmt, )

下面着重讲解第三种方法udev

在驱动用加入对udev的支持主要做的就是:在驱动初始化的代码里调用class_create()为该设备创建一个class,再为每个设备调用device_create()( 在26较早的内核中用class_device_create)创建对应的设备。

内核中定义的struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。

struct class和class_create(…) 以及device_create(…)都包含在在/include/linux/deviceh中,使用的时候一定要包含这个头文件,否则编译器会报错。

struct class定义在头文件include/linux/deviceh中

class_create(…)在/drivers/base/classc中实现

device_create(…)函数在/drivers/base/corec中实现

class_destroy(),device_destroy()也在/drivers/base/corec中实现调用过程类似如下:

static struct class spidev_class;

/-------------------------------------------------------------------------/

static int __devinit spidev_probe(struct spi_device spi)

{

dev =device_create(spidev_class, &spi->dev, spidev->devt,

spidev, "spidev%d%d",

spi->master->bus_num, spi->chip_select);

}

static int __devexit spidev_remove(struct spi_device spi)

{

device_destroy(spidev_class, spidev->devt);

return 0;

}

static struct spi_driver spidev_spi = {

driver = {

name = "spidev",

owner = THIS_MODULE,

},

probe = spidev_probe,

remove = __devexit_p(spidev_remove),

};

/-------------------------------------------------------------------------/

static int __init spidev_init(void)

{

spidev_class =class_create(THIS_MODULE, "spidev");

if (IS_ERR(spidev_class)) {

unregister_chrdev(SPIDEV_MAJOR, spidev_spidrivername);

return PTR_ERR(spidev_class);

}

}

module_init(spidev_init);

static void __exit spidev_exit(void)

{

class_destroy(spidev_class);

}

module_exit(spidev_exit);

MODULE_DESCRIPTION("User mode SPI device interface");

MODULE_LICENSE("GPL");

下面以一个简单字符设备驱动来展示如何使用这几个函数

#include <linux/moduleh>

#include <linux/kernelh>

#include <linux/inith>

#include <linux/fsh>

#include <linux/cdevh>

#include <linux/deviceh>

int HELLO_MAJOR = 0;

int HELLO_MINOR = 0;

int NUMBER_OF_DEVICES = 2;

struct class my_class;

//struct cdev cdev;

//dev_t devno;

struct hello_dev {

struct device dev;

dev_t chrdev;

struct cdev cdev;

};

static struct hello_dev my_hello_dev = NULL;

struct file_operations hello_fops = {

owner = THIS_MODULE

};

static int __init hello_init (void)

{

int err = 0;

struct device dev;

my_hello_dev = kzalloc(sizeof(struct hello_dev), GFP_KERNEL);

if (NULL == my_hello_dev) {

printk("%s kzalloc failed!\n",__func__);

return -ENOMEM;

}

devno = MKDEV(HELLO_MAJOR, HELLO_MINOR);

if (HELLO_MAJOR)

err= register_chrdev_region(my_hello_dev->chrdev, 2, "memdev");

else

{

err = alloc_chrdev_region(&my_hello_dev->chrdev, 0, 2, "memdev");

HELLO_MAJOR = MAJOR(devno);

}

if (err) {

printk("%s alloc_chrdev_region failed!\n",__func__);

goto alloc_chrdev_err;

}

printk("MAJOR IS %d\n",HELLO_MAJOR);

cdev_init(&(my_hello_dev->cdev), &hello_fops);

my_hello_dev->cdevowner = THIS_MODULE;

err = cdev_add(&(my_hello_dev->cdev), my_hello_dev->chrdev, 1);

if (err) {

printk("%s cdev_add failed!\n",__func__);

goto cdev_add_err;

}

printk (KERN_INFO "Character driver Registered\n");

my_class =class_create(THIS_MODULE,"hello_char_class"); //类名为hello_char_class

if(IS_ERR(my_class))

{

err = PTR_ERR(my_class);

printk("%s class_create failed!\n",__func__);

goto class_err;

}

dev = device_create(my_class,NULL,my_hello_dev->chrdev,NULL,"memdev%d",0); //设备名为memdev

if (IS_ERR(dev)) {

err = PTR_ERR(dev);

gyro_err("%s device_create failed!\n",__func__);

goto device_err;

}

printk("hello module initialization\n");

return 0;

device_err:

device_destroy(my_class, my_hello_dev->chrdev);

class_err:

cdev_del(my_hello_dev->chrdev);

cdev_add_err:

unregister_chrdev_region(my_hello_dev->chrdev, 1);

alloc_chrdev_err:

kfree(my_hello_dev);

return err;

}

static void __exit hello_exit (void)

{

cdev_del (&(my_hello_dev->cdev));

unregister_chrdev_region (my_hello_dev->chrdev,1);

device_destroy(my_class, devno); //delete device node under /dev//必须先删除设备,再删除class类

class_destroy(my_class); //delete class created by us

printk (KERN_INFO "char driver cleaned up\n");

}

module_init (hello_init);

module_exit (hello_exit);

MODULE_LICENSE ("GPL");

这样,模块加载后,就能在/dev目录下找到memdev这个设备节点了。

例2:内核中的drivers/i2c/i2c-devc

在i2cdev_attach_adapter中调用device_create(i2c_dev_class, &adap->dev,

MKDEV(I2C_MAJOR, adap->nr), NULL,

"i2c-%d", adap->nr);

这样在dev目录就产生i2c-0 或i2c-1节点

接下来就是udev应用,udev是应用层的东西,udev需要内核sysfs和tmpfs的支持,sysfs为udev提供设备入口和uevent通道,tmpfs为udev设备文件提供存放空间

udev的源码可以在去相关网站下载,然后就是对其在运行环境下的移植,指定交叉编译环境,修改Makefile下的CROSS_COMPILE,如为mipsel-linux-,DESTDIR=xxx,或直接make CROSS_COMPILE=mipsel-linux-,DESTDIR=xxx 并install

把主要生成的udevd、udevstart拷贝rootfs下的/sbin/目录内,udev的配置文件udevconf和rulesd下的rules文件拷贝到rootfs下的/etc/目录内

并在rootfs/etc/initd/rcS中添加以下几行:

echo “Starting udevd”

/sbin/udevd --daemon

/sbin/udevstart

(原rcS内容如下:

# mount filesystems

/bin/mount -t proc /proc /proc

/bin/mount -t sysfs sysfs /sys

/bin/mount -t tmpfs tmpfs /dev

# create necessary devices

/bin/mknod /dev/null c 1 3

/bin/mkdir /dev/pts

/bin/mount -t devpts devpts /dev/pts

/bin/mknod /dev/audio c 14 4

/bin/mknod /dev/ts c 10 16

这样当系统启动后,udevd和udevstart就会解析配置文件,并自动在/dev下创建设备节点文件

可以讲字符设备和字符设备驱动归为一类,它们都是可以顺序/随机地进行读取和存储的单元,二者驱动主要在于块设备需要具体的burst实现,对访问也有一定的边界要求。其他的没有什么不同。

网络设备是特殊设备的驱动,它负责接收和发送帧数据,可能是物理帧,也可能是ip数据包,这些特性都有网络驱动决定。它并不存在于/dev下面,所以与一般的设备不同。网络设备是一个net_device结构,并通过register_netdev注册到系统里,最后通过ifconfig -a的命令就能看到。

不论是什么设备,设备级的数据传输都是基本类似的,内核里的数据表示只是一部分,更重要的是总线的访问,例如串行spi,i2c,并行dma等。

以上就是关于linux学习的步骤全部的内容,包括:linux学习的步骤、编写字符驱动时出了问题: linux驱动测试程序打不开驱动设备文件 。求指导!谢谢了!、cat一个字符设备的时候i,没有调用该字符设备驱动的open函数吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9349547.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存