自从选择了物联网这个专业,智能XX的字样牵动着每一个学习这个专业的孩子。
  大家兴致勃勃的来到了学校,结果一切想象和自己的设想并不一样。想象中的各种智能般梦幻的场景变成了真实的高数/电路/模电等等诸如此类!不知道这个世界什么时候变得如此的浮躁,当大家的一段时间的努力看不到结果的时候往往会不太感兴趣,模电大家都没听懂,于是大家自我安慰tmd学这玩意到底干什么?本人当初也是这样,可是到了后来接触了单片机,接触了应用电路的设计才知道那些课程那个没用啊!当初还是too young,too simple呀!
  这个学期也将要过去了,明年开始去实习啦!趁着现在实现自己的物联网梦想吧!没错,是比较恶俗的智能家具系统。
  考虑到单片机局限比较大,遂向同学借了一块友善之臂的板子,本人第一次接触arm,单片机系自学,文中又搞笑的地方大家笑笑行了,如果能给予指正,那更好了。先来实现一个比较简单的功能,即通过web远程控制灯光的亮灭。要实现这个功能,我们需要在嵌入式linux的平台上写led的驱动,要学习驱动我们直接写led的驱动可能难度比较大,而且不易成功,所以我们先用的helloworld来熟悉环境。
  现在,越来越觉得和计算机打交道,要有两条准则:1 思路要清晰  2 实现过程要一步一步。因为计算机是机器,0和1的世界,程序过程中稍不注意会错误百出。所以写程序过程中一定要步步为营,一点一点测试,一点一点推进,这样看似很慢,却非常有效也容易成功。好了,不为我写hellow辩护了。其实我在写helloworld的时候也是做准备了,那是在pc端上已经成功的测试过了。
  在补充一点,我们写的驱动程序终都是要加载进内核的,我们有两种方法添加到内核中。第一种是直接编进内核里,第二种是动态编进内核里。动态加入内核是我们把自己的驱动程序看成一个模块,然后把这个模块加载到内核内。直接编译进内核是这个模块和内核一起编译,如果有什么这个驱动有什么问题的话,我们还需要调试编译整个内核,因此刚开始学习的时候我采用了模块化的动态加载内核。
  下面开发过程中的一些地方做一些记录:
  1 在pc机上为目标机编写驱动程序的.c文件应该放在哪里比较好?
  这个应该放在目标机内核的目录。比如我的是友善之臂的板子,因为helloworld是字符设备,因此hello.c建在了/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char的目录内。为什么要建在这里,因为这样我们可以借助与char内的makefile来编译出模块,也是说我们不必自己单独写makefile,有点抱大腿的赶脚。
  2 简单的helloworld模块是什么样的?

 

1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 static int __init mini2440_hello_module_init(void)
4 {
5 printk("Hello, world ! ");
6 return 0;
7 }
8 static void __exit mini2440_hello_module_cleanup(void)
9 {
10 printk("Good-bye! ");
11 }
12 module_init(mini2440_hello_module_init);
13 module_exit(mini2440_hello_module_cleanup);
14 MODULE_LICENSE("GPL");

  第一行和第二行不说了,因为我们用到了内核的相关函数以及模块的一些东西,因此必须要声明。
  后一行是内核2.6以上版本建议大家把模块的lincense带上。
  在我们动态加载和卸载模块的时候,我们需要init_module和exit_module这两个函数来加载,而上面的代码中并没有。原因在哪里呢?
  原来是module_init和module_exit在作怪。以module_init为例,这个函数有两个功能,一个是验证传入的参数是否为正确的模块格式,另一个是将参数改名字为init_module。这样模块能被成功的加载了。
  虽然上面的module是个空架子,但是也可以让我们对模块有个感官的认识。