FL2440驱动入门——helloworld


该文主要内容:1.驱动的编写
                            2.ARM以及PC的Makefile编写
                            3.开发板tftp无法下载文件的问题
                            4.开发板无法使用rmmod命令的问题




在编程的世界里, 一种编程语言一般从Hello World开始。 按照惯例,驱动开发的世界也从Hello模块开始入门。


1.驱动hello.c的编写.

[lwn@localhost hello]$vim hello.c  
    /********************************************************************************* 
     *      Copyright:  (C) 2017 SCUEC 
     *                  All rights reserved. 
     * 
     *       Filename:  hello.c 
     *    Description:  This file is hello driver 
     *                  
     *        Version:  1.0.0(03/17/2017) 
     *         Author:  Li Wanneng  
     *      ChangeLog:  1, Release initial version on "03/17/2017 08:52:37 PM" 
     *                  
     ********************************************************************************/  
      
    #include //定义了经常用到的函数原型及宏定义  
    #include //定义了内核模块相关的函数、变量及宏  
    #include  //定义了驱动的初始化和退出相关函数  
  
static int __init hello_init(void)//  
{  
    printk("Hello World!\n");  
    printk("Hello li wanneng!([email protected])\n");  
    return 0;  
}  
  
static void __exit hello_exit(void)  
{  
    printk("Wow! it's very good and I have Learned much from it .\n");  
    printk("Bye\n ");  
    return;  
}  
  
module_init(hello_init);  
module_exit(hello_exit);  
  
MODULE_AUTHOR("li wanneng ([email protected])");  
MODULE_DESCRIPTION("It's just a Linux kernel module sample!");  
MODULE_LICENSE("GPL");  



代码分析:
   1._init 属性:linux内核中很大一部分是驱动函数,这些函数只需要执行一次。linux对于只需要执行一次的函数前都会加上 _init属性。
                          目的是将驱动模块的初始化函数放入名叫.init.text的输入段。当内核启动完毕后,这个段中的内存会被释放掉供其他使用。
  2._exit属性:如果驱动被编译进内核,则__exit宏会忽略清理函数,因为编译进内核的模块不需要做清理工作。
  3.module_init宏:几乎每个linux驱动都有个module_init,其定义在linux/Init.h  中。驱动的加载就靠它。module_init(hello_init)表示将                                        hello_init()函数加载到内核映像的".initcall"区,内核加载的时候,会按优先级搜索".initcall"中所有的函数并依次执行。
 4.module_exit宏:同样定义在 /linux/init.h 中,在使用rmmod命令卸载驱动的时候会调用该函数。
 5.printk()函数:在驱动里面打印信息用printk()函数。

2.驱动的Makefile.

针对不同的CPU架构体系,编译器的编译是不一样 ,所以需要两个不同的Makefile编译使其在不同的CPU体系上运行。


 2-1.PC版本的Makefile

[lwn@localhost hello]vim Makefile
obj-m := hello.o
modules:
make -C /lib/modules/`uname -r`/build/ M=`pwd` modules
make clean
clean:
rm -f *.ko.* *.o *mod.c *.order *.symvers


2-2.ARM版本的Makefile

[lwn@localhost hello]vim Makefile
LINUX_SRC ?= ../kernel/linux-3.0
CROSS_COMPILE=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linuxobj-m := hello.o
modules:
@make -C $(LINUX_SRC) M=`pwd` modules
@make clean
clean:
rm -f *.ko.* *.o *mod.c *.order *.symvers

3.驱动编译和使用.


3-1.编译PC版本的驱动

先用PC版本的makefile编译运行,确认驱动源程序无误之后我们再交叉编译然后下载到开发板上运行。Make命令编译生成的hello.ko就是我们要安装在PC的helloworld驱动。

FL2440驱动入门——helloworld_第1张图片


3-2.使用insmod命令在PC上安装helloworld驱动

FL2440驱动入门——helloworld_第2张图片

安装之后使用 lsmod命令可以查看到hello驱动已经安装在PC上了,接下来使用dmesg命令可以看到我们在hello.c源文件中配置的打印信息已经显示了。说明hello.c驱动源程序没有问题。



接下来我们使用rmmod命令卸载该驱。然后使用lsmod可以看到已经没有hello驱动了。

FL2440驱动入门——helloworld_第3张图片


3-3.编译ARM版本的驱动

按照上面同样的方法使用ARM版本的makefile编译生成hello.ko,然后使用tftp命令下载到开发板上运行。(注意此时的Makefile文件一定是ARM版本带)


使用make命令编译后生成了hello.ko镜像文件。

FL2440驱动入门——helloworld_第4张图片


我们使用tftp命令下载到开发板,并且使用insmod命令安装hello驱动,打印出在hello.c源文件编辑好的信息,说明驱动安装成功。

FL2440驱动入门——helloworld_第5张图片

同样使用rmmod命令卸载驱动。卸载之后我们使用lsmod命令已经看不到hello驱动了。

FL2440驱动入门——helloworld_第6张图片


4.遇到的问题及解决办法.


4-1.问题描述:在开发板上无法使用tftp命令下载



问题分析:无法下载tftp无外乎3种情况

1.    没有tftp命令

2.    开发板没有网卡驱动导致无法与tftp主机通信

3.    开发板没有配置IP导致无法与tftp主机通信


解决思路:根据提示排除第一种情况,问题出在后面两种情况。  使用ifconfig -a查看,可以看到eth0存在,说明网卡驱动良好,但是ifconfig 命令并没有打印任何信息。问题显而易见了:网卡没有使能,即网卡没有配置IP导致无法与tftp主机通信。

FL2440驱动入门——helloworld_第7张图片


解决办法:使用ifconfig命令配置IP,配置完成之后使用ifconfig命令可以看到已经使能网卡了。

FL2440驱动入门——helloworld_第8张图片

现在已经可以使用tftp命令下载了 。



4-2.问题描述:在开发板上无法使用rmmod命令



问题分析&解决思路:

根据提示找不到目录3.0.1,联想到我使用的的内核版本是linux-3.0.1。

查看/lib/modules目录发现该目录下只有3.0.0文件夹而没有3.0.1


解决办法:把3.0.0文件夹名字重命名为3.0.1。便可以使用rmmod命令成功卸载驱动了。

FL2440驱动入门——helloworld_第9张图片






你可能感兴趣的:(学习心得,FL2440驱动)