Linux 字符设备驱动开发基础(二)—— 编写简单 PWM 设备驱动

编写驱动的第一步仍是看原理图:


       可以看到,该蜂鸣器由 GPD0_0 来控制 ,查手册可知该I/O口由Time0 来控制,找到相应的寄存器:

a -- I/O口寄存器及地址

      GPD0CON  0x114000a0

b -- Time0 寄存器及地址

      基地址为:TIMER_BASE 0x139D0000 

      这些物理寄存器地址都是相邻的,我们这里用偏移量来表示:

      寄存器名      地址偏移量            所需配置

        TCFG0          0x0000              [7-0]     0XFF

        TCFG1          0x0004              [3-0]     0X2              

        TCON            0x0008              [3-0]     0X2       0X9   0X0

        TCNTB0        0x000C             500

        TCMPB0       0x0010              250


       前面已经知道,驱动是无法直接操纵物理地址的,所以这里仍需物理地址向虚拟地址的转换,用到 ioremap() 函数、writel()函数、readl()函数:

1、地址映射操作

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. unsigned int   *gpd0con;  
  2. void *timer_base;<span style="white-space:pre">   </span>//之所以是void类型,偏移量为4时,只是移动4个字节,方便理解  
  3.   
  4. gpd0con = ioremap(GPD0CON,4);  
  5. timer_base = ioremap(TIMER_BASE , 0x14);  

2、Time0初始化操作(这里使用的已经是虚拟地址)

       这里现将数据从寄存器中读出,修改后再写回寄存器,具体寄存器操作可以移步Exynos4412裸机开发——PWM定时器:   

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. writel((readl(gpd0con)&~(0xf<<0)) | (0x2<<0),gpd0con);  
  2. writel ((readl(timer_base +TCFG0  )&~(0xff<<0)) | (0xff <<0),timer_base +TCFG0);   
  3. writel ((readl(timer_base +TCFG1 )&~(0xf<<0)) | (0x2 <<0),timer_base +TCFG1 );   

3、装载数据,配置占空比

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. writel(500, timer_base +TCNTB0  );  
  2. writel(250, timer_base +TCMPB0 );  
  3. writel ((readl(timer_base +TCON )&~(0xf<<0)) | (0x2 <<0),timer_base +TCON );   

4、相关控制函数

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. void beep_on(void)  
  2. {  
  3.     writel ((readl(timer_base +TCON )&~(0xf<<0)) | (0x9 <<0),timer_base +TCON );  
  4. }  
  5.    
  6. void beep_off(void)  
  7. {  
  8.     writel ((readl(timer_base +TCON )&~(0xf<<0)) | (0x0 <<0),timer_base +TCON );  
  9. }   

下面是驱动程序,这里我们用到了 write() read() ioctl() 函数,具体解析移步:

驱动程序:beep.c

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. #include <linux/module.h>  
  2. #include <linux/fs.h>  
  3. #include <linux/cdev.h>  
  4. #include <linux/device.h>  
  5. #include <asm/io.h>  
  6. #include <asm/uaccess.h>  
  7.   
  8. static int major = 250;  
  9. static int minor=0;  
  10. static dev_t devno;  
  11. static struct class *cls;  
  12. static struct device *test_device;  
  13.   
  14. #define GPD0CON       0x114000a0  
  15. #define TIMER_BASE    0x139D0000             
  16. #define TCFG0         0x0000                 
  17. #define TCFG1         0x0004                              
  18. #define TCON          0x0008               
  19. #define TCNTB0        0x000C            
  20. #define TCMPB0        0x0010             
  21.   
  22. static unsigned int *gpd0con;  
  23. static void *timer_base;  
  24. #define  MAGIC_NUMBER    'k'  
  25. #define  BEEP_ON    _IO(MAGIC_NUMBER    ,0)  
  26. #define  BEEP_OFF   _IO(MAGIC_NUMBER    ,1)  
  27. #define  BEEP_FREQ   _IO(MAGIC_NUMBER   ,2)  
  28.   
  29. static void fs4412_beep_init(void)  
  30. {  
  31.     gpd0con = ioremap(GPD0CON,4);  
  32.     timer_base = ioremap(TIMER_BASE,0x14);  
  33.       
  34.     writel ((readl(gpd0con)&~(0xf<<0)) | (0x2<<0),gpd0con);  
  35.     writel ((readl(timer_base +TCFG0  )&~(0xff<<0)) | (0xff <<0),timer_base +TCFG0);   
  36.     writel ((readl(timer_base +TCFG1 )&~(0xf<<0)) | (0x2 <<0),timer_base +TCFG1 );   
  37.   
  38.     writel (500, timer_base +TCNTB0  );  
  39.     writel (250, timer_base +TCMPB0 );  
  40.     writel ((readl(timer_base +TCON )&~(0xf<<0)) | (0x2 <<0),timer_base +TCON );   
  41. }  
  42.   
  43. void fs4412_beep_on(void)  
  44. {  
  45.     writel ((readl(timer_base +TCON )&~(0xf<<0)) | (0x9 <<0),timer_base +TCON );  
  46. }  
  47.   
  48. void fs4412_beep_off(void)  
  49. {  
  50.     writel ((readl(timer_base +TCON )&~(0xf<<0)) | (0x0 <<0),timer_base +TCON );  
  51. }  
  52.   
  53.   
  54. static int beep_open (struct inode *inode, struct file *filep)  
  55. {  
  56.  // fs4412_beep_on();  
  57.     return 0;  
  58. }  
  59.   
  60. static int beep_release(struct inode *inode, struct file *filep)  
  61. {  
  62.      fs4412_beep_off();  
  63.      return 0;  
  64. }  
  65.   
  66. #define BEPP_IN_FREQ 100000  
  67. static void beep_freq(unsigned long arg)  
  68. {  
  69.     writel(BEPP_IN_FREQ/arg, timer_base +TCNTB0  );  
  70.     writel(BEPP_IN_FREQ/(2*arg), timer_base +TCMPB0 );  
  71.   
  72. }  
  73.   
  74. static long beep_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)  
  75. {  
  76.     switch(cmd)  
  77.     {  
  78.         case BEEP_ON:  
  79.             fs4412_beep_on();  
  80.             break;  
  81.         case BEEP_OFF:  
  82.             fs4412_beep_off();  
  83.             break;  
  84.         case BEEP_FREQ:  
  85.             beep_freq( arg );  
  86.             break;  
  87.         default :  
  88.             return -EINVAL;  
  89.     }  
  90. }  
  91.   
  92. static struct file_operations beep_ops=  
  93. {  
  94.     .open     = beep_open,  
  95.     .release = beep_release,  
  96.     .unlocked_ioctl      = beep_ioctl,  
  97. };  
  98.   
  99. static int beep_init(void)  
  100. {  
  101.     int ret;      
  102.     devno = MKDEV(major,minor);  
  103.     ret = register_chrdev(major,"beep",&beep_ops);  
  104.   
  105.     cls = class_create(THIS_MODULE, "myclass");  
  106.     if(IS_ERR(cls))  
  107.     {  
  108.         unregister_chrdev(major,"beep");  
  109.         return -EBUSY;  
  110.     }  
  111.     test_device = device_create(cls,NULL,devno,NULL,"beep");//mknod /dev/hello  
  112.     if(IS_ERR(test_device))  
  113.     {  
  114.         class_destroy(cls);  
  115.         unregister_chrdev(major,"beep");  
  116.         return -EBUSY;  
  117.     }     
  118.     fs4412_beep_init();  
  119.     return 0;  
  120. }  
  121.   
  122. void fs4412_beep_unmap(void)  
  123. {  
  124.     iounmap(gpd0con);  
  125.     iounmap(timer_base);  
  126. }  
  127.   
  128. static void beep_exit(void)  
  129. {  
  130.     fs4412_beep_unmap();  
  131.   
  132.     device_destroy(cls,devno);  
  133.     class_destroy(cls);   
  134.     unregister_chrdev(major,"beep");  
  135.     printk("beep_exit \n");  
  136. }  
  137.   
  138. MODULE_LICENSE("GPL");  
  139. module_init(beep_init);  
  140. module_exit(beep_exit);  

makefile:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. ifneq  ($(KERNELRELEASE),)  
  2. obj-m:=beep.o  
  3. $(info "2nd")  
  4. else  
  5. #KDIR := /lib/modules/$(shell uname -r)/build  
  6. KDIR := /home/fs/linux/linux-3.14-fs4412  
  7. PWD:=$(shell pwd)  
  8. all:  
  9.     $(info "1st")  
  10.     make -C $(KDIR) M=$(PWD) modules  
  11.     arm-none-linux-gnueabi-gcc test.c -o beeptest  
  12.     sudo cp beep.ko beeptest /tftpboot  
  13. clean:  
  14.     rm -f *.ko *.o *.symvers *.mod.c *.mod.o *.order  
  15. endif  

下面是是个简单的测试程序test.c,仅实现蜂鸣器响6秒的功能:
[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. #include <sys/types.h>  
  2. #include <sys/stat.h>  
  3. #include <fcntl.h>  
  4. #include <stdio.h>  
  5. #include <sys/ioctl.h>  
  6.   
  7. #define  MAGIC_NUMBER    'k'  
  8. #define   BEEP_ON    _IO(MAGIC_NUMBER    ,0)  
  9. #define   BEEP_OFF   _IO(MAGIC_NUMBER    ,1)  
  10. #define   BEEP_FREQ   _IO(MAGIC_NUMBER    ,2)  
  11.   
  12. main()  
  13. {  
  14.     int fd;  
  15.   
  16.     fd = open("/dev/beep",O_RDWR);  
  17.     if(fd<0)  
  18.     {  
  19.         perror("open fail \n");  
  20.         return ;  
  21.     }  
  22.   
  23.     ioctl(fd,BEEP_ON);  
  24.   
  25.     sleep(6);  
  26.     ioctl(fd,BEEP_OFF);   
  27.   
  28.     close(fd);  
  29. }  

这是个音乐播放测试程序,慎听!!分别为《大长今》、《世上只有妈妈好》、《渔船》,这个单独编译一下

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. /* 
  2.  * main.c : test demo driver 
  3.  */  
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. #include <unistd.h>  
  7. #include <fcntl.h>  
  8. #include <string.h>  
  9. #include <sys/types.h>  
  10. #include <sys/stat.h>  
  11. #include <sys/ioctl.h>  
  12. #include "pwm_music.h"  
  13.   
  14. /*ioctl 鍛戒护*/  
  15. #define magic_number 'k'  
  16. #define BEEP_ON _IO(magic_number,0)  
  17. #define BEEP_OFF _IO(magic_number,1)  
  18. #define SET_FRE _IO(magic_number,2)  
  19.   
  20.   
  21.   
  22. int main(void)  
  23. {  
  24.     int i = 0;  
  25.     int n = 2;  
  26.     int dev_fd;  
  27.     int div;  
  28.     dev_fd = open("/dev/beep",O_RDWR | O_NONBLOCK);  
  29.     if ( dev_fd == -1 ) {  
  30.         perror("open");  
  31.         exit(1);  
  32.     }  
  33.   
  34.     for(i = 0;i<sizeof(GreatlyLongNow)/sizeof(Note);i++ )  
  35.     {  
  36.         div = (GreatlyLongNow[i].pitch);  
  37.       
  38.         ioctl(dev_fd, SET_FRE, div);  
  39.         ioctl(dev_fd, BEEP_ON);  
  40.         usleep(GreatlyLongNow[i].dimation * 100);   
  41.         ioctl(dev_fd, BEEP_OFF);  
  42.     }  
  43.       
  44.     for(i = 0;i<sizeof(MumIsTheBestInTheWorld)/sizeof(Note);i++ )  
  45.     {  
  46.         div = (MumIsTheBestInTheWorld[i].pitch);  
  47.         ioctl(dev_fd, SET_FRE, div);  
  48.         ioctl(dev_fd, BEEP_ON);  
  49.           
  50.         usleep(MumIsTheBestInTheWorld[i].dimation * 100);   
  51.         ioctl(dev_fd, BEEP_OFF);  
  52.     }  
  53.   
  54.   
  55.   
  56.     for(i = 0;i<sizeof(FishBoat)/sizeof(Note);i++ )  
  57.     {  
  58.         div = (FishBoat[i].pitch);  
  59.         ioctl(dev_fd, SET_FRE, div);  
  60.         ioctl(dev_fd, BEEP_ON);  
  61.         usleep(FishBoat[i].dimation * 100);   
  62.         ioctl(dev_fd, BEEP_OFF);  
  63.     }  
  64.     return 0;  
  65. }  
附所用头文件:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. #ifndef __PWM_MUSIC_H  
  2. #define __PWM_MUSIC_H  
  3.   
  4. #define BIG_D  
  5.   
  6. #define PCLK (202800000/4)  
  7.   
  8. typedef struct  
  9. {  
  10.     int pitch;   
  11.     int dimation;  
  12. }Note;  
  13. // 1            2       3        4          5           6       7  
  14. // C            D       E        F          G           A       B  
  15. //261.6256  293.6648   329.6276 349.2282   391.9954     440     493.8833  
  16.   
  17. //C澶ц皟  
  18. #ifdef BIG_C  
  19. #define DO 262  
  20. #define RE 294  
  21. #define MI 330  
  22. #define FA 349  
  23. #define SOL 392  
  24. #define LA  440  
  25. #define SI  494  
  26. #define TIME 6000  
  27. #endif  
  28.    
  29.  //D澶ц皟  
  30. #ifdef BIG_D  
  31. #define DO 293  
  32. #define RE 330  
  33. #define MI 370  
  34. #define FA 349  
  35. #define SOL 440  
  36. #define LA  494  
  37. #define SI  554  
  38. #define TIME 6000  
  39. #endif  
  40.   
  41.   
  42.   
  43. Note MumIsTheBestInTheWorld[]={  
  44.     //6.              //_5       //3         //5      
  45.     {LA,TIME+TIME/2}, {SOL,TIME/2},{MI,TIME},{SOL,TIME},  
  46.   
  47.     //1^           //6_       //_5      //6-  
  48.     {DO*2,TIME},{LA,TIME/2},{SOL,TIME/2} ,{LA,2*TIME},  
  49.     // 3      //5_      //_6           //5  
  50.     {MI,TIME},{SOL,TIME/2},{LA,TIME/2},{SOL,TIME},  
  51.     // 3        //1_        //_6,  
  52.     {MI,TIME},{DO,TIME/2},{LA/2,TIME/2},  
  53.     //5_        //_3        //2-           //2.  
  54.     {SOL,TIME/2},{MI,TIME/2},{RE,TIME*2},{RE,TIME+TIME/2},  
  55.     //_3    //5         //5_            //_6  
  56.     {MI,TIME/2},{SOL,TIME},{SOL,TIME/2},{LA,TIME/2},  
  57.     // 3        //2         //1-            //5.  
  58.     {MI,TIME},{RE,TIME},{DO,TIME*2},{SOL,TIME+TIME/2},  
  59.     //_3        //2_        //_1        //6,_  
  60.     {MI,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME/2},  
  61.     //_1        //5,--  
  62.     {DO,TIME/2},{SOL/2,TIME*3}  
  63.   
  64. };  
  65.   
  66.   
  67. Note GreatlyLongNow[]={       
  68.     // 2        3           3       3.              _2              1  
  69.     {RE,TIME}, {MI,TIME},{MI,TIME},{MI,TIME+TIME/2},{RE,TIME/2},{DO,TIME},  
  70.     //6,        1           2       1--             2           3           3  
  71.     {LA/2,TIME},{DO,TIME},{RE,TIME},{DO,TIME*3},{RE,TIME},{MI,TIME},{MI,TIME},  
  72.     //3.                _5          3           3           2           3  
  73.     {MI,TIME+TIME/2},{SOL,TIME/2},{MI,TIME},{MI,TIME},{RE,TIME},{MI,TIME},  
  74.     //3--       5           6           6         6.                _5  
  75.     {MI,TIME*3},{SOL,TIME},{LA,TIME},{LA,TIME},{LA,TIME+TIME/2},{SOL,TIME/2},  
  76.     // 3        3       5               6       5---            2           3  
  77.     {MI,TIME},{MI,TIME},{SOL,TIME},{LA,TIME},{SOL,TIME*3},{RE,TIME},{MI,TIME},  
  78.     // 3        2.              _3              3         2         3  
  79.     {MI,TIME},{RE,TIME+TIME/2},{MI,TIME/2},{MI,TIME},{RE,TIME},{MI,TIME},  
  80.     //6,        1_            _6,             6,-  
  81.     {LA/2,TIME},{DO,TIME/2},{LA/2,TIME/2},{LA/2,TIME*2},  
  82.     //2_        _2          2_              _1          6,  
  83.     {RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},  
  84.     //2_        _2          2_              _1          6,  
  85.     {RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},  
  86.     // 2        3       1           2.                  _3          5  
  87.     {RE,TIME},{MI,TIME},{DO,TIME},{RE,TIME+TIME/2},{MI,TIME/2},{SOL,TIME},  
  88.     //6_        _6              6_          _5          3  
  89.     {LA,TIME/2},{LA,TIME/2},{LA,TIME/2},{SOL,TIME/2},{MI,TIME},  
  90.     //2_        _2          2_              _1          6,  
  91.     {RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},  
  92.     //6,        5,.                   _6,            6,--  
  93.     {LA/2,TIME},{SOL/2,TIME+TIME/2},{LA/2,TIME/2},{LA/2,TIME*3},  
  94.     //2_        _2          2_              _1          6,  
  95.     {RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},  
  96.     //2_        _2          2_              _1          6,  
  97.     {RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},  
  98.     // 2        3       1           2.                  _3          5  
  99.     {RE,TIME},{MI,TIME},{DO,TIME},{RE,TIME+TIME/2},{MI,TIME/2},{SOL,TIME},  
  100.     //6_        _6              6_          _5          3  
  101.     {LA,TIME/2},{LA,TIME/2},{LA,TIME/2},{SOL,TIME/2},{MI,TIME},  
  102.     //2_        _2          2_              _1          6,  
  103.     {RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},  
  104.     //6,        5,.                   _6,            6,--  
  105.     {LA/2,TIME},{SOL/2,TIME+TIME/2},{LA/2,TIME/2},{LA/2,TIME*3}  
  106.   
  107. };  
  108. Note FishBoat[]={ //3.              _5          6._                 =1^          6_  
  109.     {MI,TIME+TIME/2},{SOL,TIME/2},{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},  
  110.     //_5            3 -.        2         1.             _3          2._  
  111.     {SOL,TIME/2},{MI,TIME*3},{RE,TIME},{DO,TIME+TIME/2},{MI,TIME/2},{RE,TIME/2+TIME/4},  
  112.     //=3            2_          _1       2--            3.              _5  
  113.     {MI,TIME/4},{RE,TIME/2},{DO,TIME/2},{RE,TIME*4},{MI,TIME+TIME/2},{SOL,TIME/2},  
  114.     // 2        1       6._                 =1^             6_          _5  
  115.     {RE,TIME},{DO,TIME},{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},{SOL,TIME/2},  
  116.     //6-         5,.                    _6,         1._                 =3  
  117.     {LA,TIME*2},{SOL/2,TIME+TIME/2},{LA/2,TIME/2},{DO,TIME/2+TIME/4},{MI,TIME/4},  
  118.     //2_            _1       5,--  
  119.     {RE,TIME/2},{DO,TIME/2},{SOL/2,TIME*4},  
  120.     //3.                _5          6._                 =1^         6_  
  121.     {MI,TIME+TIME/2},{SOL,TIME/2},{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},  
  122.     //_5            3-.         5_          _6          1^_                _6  
  123.     {SOL,TIME/2},{MI,TIME*3},{SOL,TIME/2},{LA,TIME/2},{DO*2,TIME+TIME/2},{LA,TIME/2},  
  124.     //5._                   =6          5_        _3            2--  
  125.     {SOL,TIME/2+TIME/4},{LA,TIME/4},{SOL,TIME/2},{MI,TIME/2},{RE,TIME*4},  
  126.     //3.                _5          2._                 =3          2_          _1  
  127.     {MI,TIME+TIME/2},{SOL,TIME/2},{RE,TIME/2+TIME/4},{MI,TIME/4},{RE,TIME/2},{DO,TIME/2},  
  128.     //6._               =1^             6_          _5          6-          1.  
  129.     {LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},{SOL,TIME/2},{LA,TIME*2},{DO,TIME+TIME/2},  
  130.     //_2         3_         _5              2_          _3          1--  
  131.     {RE,TIME/2},{MI,TIME/2},{SOL,TIME/2},{RE,TIME/2},{MI,TIME/2},{DO,TIME*4}  
  132. };  
  133. #endif  


编译好程序后

# insmod beep.ko

#mknod /dev/beep c 250 0

#./music

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

专访:混合云的发展趋势

近日&#xff0c;业界享有盛誉的vForum2013大会在京召开&#xff0c;此次大会云集了近百家国内外知名的云计算、数据存储、大数据及信息安全厂商&#xff0c;共同讨论了虚拟化、云计算及未来IT模式的发展趋势。笔者也有幸在大会期间采访到了VMware 大中华区技术总监张振伦先生&…

Tomcat7性能优化

用了很久的Tomcat&#xff0c;没怎么看过它的优化&#xff0c;今天抽出时间研究了下&#xff0c;将内容记录下。 首先&#xff0c;是客户端访问tomcat的一个过程&#xff0c;如图所示&#xff1a; 图中间虚线框部分是 Apache基金下的服务器来做静态资源处理的&#xff0c;而这部…

Fast Image Cache – iOS 应用程序高性能图片缓存

Fast Image Cache 是一种在 iOS 应用程序中高效、持续、超快速的存储和检索图像的解决方案。任何良好的 iOS 应用程序的用户体验都应该是快速&#xff0c;平滑滚动的&#xff0c;Fast Image Cache 提供图像高速缓存有助于使这更容易实现。 对于图片丰富的应用程序&#xff0c;图…

Linux 字符设备驱动开发基础(四)—— ioctl() 函数解析

解析完 open、close、read、write 四个函数后&#xff0c;终于到我们的 ioctl() 函数了 一、 什么是ioctl ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理&#xff0c;就是对设备的一些特性进行控制&#xff0c;例如串口的传输波特率、马达的转速…

android自动化框架简要剖析(一):运行原理+基本框架

android自动化测试原理&#xff1a; 1、将测试apk和被测试apk&#xff0c;运行在一个进程中&#xff1b;通过instrumentation进行线程间的通信 2、通过android.test.AndroidTestCase及其子类&#xff0c;控制android系统对象 3、通过android.test.InstrumentationTestCase 及其…

Linux 字符设备驱动开发基础(一)—— 编写简单 LED 设备驱动

现在&#xff0c;我们来编写自己第一个字符设备驱动 —— 点亮LED。&#xff08;不完善&#xff0c;后面再完善&#xff09; 硬件平台&#xff1a;Exynos4412&#xff08;FS4412&#xff09; 编写驱动分下面几步&#xff1a; a -- 查看原理图、数据手册&#xff0c;了解设备的操…

Linux 字符设备驱动结构(四)—— file_operations 结构体知识解析

前面在 Linux 字符设备驱动开发基础 &#xff08;三&#xff09;—— 字符设备驱动结构&#xff08;中&#xff09; &#xff0c;我们已经介绍了两种重要的数据结构 struct inode{...}与 struct file{...} &#xff0c;下面来介绍另一个比较重要数据结构 struct _file_operatio…

Android开发群

为什么80%的码农都做不了架构师&#xff1f;>>> 我的自建Android应用开发群&#xff0c;欢迎大家来聊聊呀&#xff01;201427584 转载于:https://my.oschina.net/catia/blog/176384

Linux 字符设备驱动结构(三)—— file、inode结构体及chardevs数组等相关知识解析

前面我们学习了字符设备结构体cdev Linux 字符设备驱动开发 &#xff08;一&#xff09;—— 字符设备驱动结构&#xff08;上&#xff09; 下面继续学习字符设备另外几个重要的数据结构。 先看下面这张图&#xff0c;这是Linux 中虚拟文件系统、一般的设备文件与设备驱动程序…

技术人生:三亚之行

人生收获 此次是公司组团去的三亚&#xff0c;地接的导游非常热情&#xff0c;如同大多数人一样&#xff0c;导游也会在这短短的几天内&#xff0c;尽可能的表现自己&#xff0c;此文聊聊导游说的三句话。 旅游三不“较”&#xff1a; 不比较不计较不睡觉人生何尝不是如此&…

Linux 字符设备驱动结构(二)—— 自动创建设备节点

上一篇我们介绍到创建设备文件的方法&#xff0c;利用cat /proc/devices查看申请到的设备名&#xff0c;设备号。 第一种是使用mknod手工创建&#xff1a;mknod filename type major minor 第二种是自动创建设备节点&#xff1a;利用udev&#xff08;mdev&#xff09;来实现设备…

Linux 字符设备驱动结构(一)—— cdev 结构体、设备号相关知识解析

一、字符设备基础知识 1、设备驱动分类 linux系统将设备分为3类&#xff1a;字符设备、块设备、网络设备。使用驱动程序&#xff1a; 字符设备&#xff1a;是指只能一个字节一个字节读写的设备&#xff0c;不能随机读取设备内存中的某一数据&#xff0c;读取数据需要按照先后数…

Linux 驱动开发之内核模块开发(四)—— 符号表的导出

Linux内核头文件提供了一个方便的方法用来管理符号的对模块外部的可见性,因此减少了命名空间的污染(命名空间的名称可能会与内核其他地方定义的名称冲突),并且适当信息隐藏。 如果你的模块需要输出符号给其他模块使用,应当使用下面的宏定义: EXPORT_SYMBOL(name); EXPORT_SYMBO…

Linux 驱动开发之内核模块开发 (三)—— 模块传参

一、module_param() 定义 通常在用户态下编程&#xff0c;即应用程序&#xff0c;可以通过main()的来传递命令行参数&#xff0c;而编写一个内核模块&#xff0c;则通过module_param() 来传参。 module_param()宏是Linux 2.6内核中新增的&#xff0c;该宏被定义在include/linux…

Exynos4412 文件系统制作(二)—— 文件系统简介

一、Linux磁盘分区和目录 Linux发行版本之间的差别很少&#xff0c;差别主要表现在系统管理的特色工具以及软件包管理方式的不同。目录结构基本上都是一样的。 Windows的文件结构是多个并列的树状结构&#xff0c;最顶部的是不同的磁盘&#xff08;分区&#xff09;&#xff0c…

MM引擎新应用——爱车加油记

基于MM应用引擎开发的EXTJS应用&#xff0c;车主每次加完汽油后&#xff0c;记录加油时的里程数以及加油金额和汽油价格&#xff0c;就可计算出上次加油后行驶的里程数、上次加油的平均油耗。点击刷新按钮&#xff0c;即可计算有记录以来的行驶公里数和再次期间加油金额和平均油…

### 阅读之痕-2013/11

2019独角兽企业重金招聘Python工程师标准>>> 阅读之痕-2013/11 Andy erpingwugmail.com 2013/11/01-2013/11/30 2013/11/01-2013/11/30 The story of rocksdb - Embedded key-value store for Flash and RAM http://rocksdb.org/intro.pdf High Performance Network…

Exynos4412 内核移植(六)—— 设备树解析

一、描述ARM Device Tree起源于OpenFirmware (OF)&#xff0c;在过去的Linux中&#xff0c;arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码&#xff0c;相当多数的代码只是在描述板级细节&#xff0c;而这些板级细节对于内核来讲&#xff0c;不过是垃圾&#xff…

Github Page创建个人主页以及绑定域名

2019独角兽企业重金招聘Python工程师标准>>> 在github中 我们可以通过github page创建个人主页 以及绑定域名 据说有300m空间 以及无限流量 不过只能支持静态html 以及一些脚本语言 顺便吐槽一下 阿里云最低配那个云空间服务器 512m内存 启动web服务器后 mys…