1、通过GPIO库函数控制LED
   open("/dev/myleds",...)       close(fd)
   ---------------------------------------------
   sys_open                      sys_close
       led_open(...)                led_release(...)
       {                            {
           亮灯                        灭灯
       }                            }
   
   电路原理图:
       控制LED1 实则控制CPU上的管脚GPIOC12输出低/高电平
   如何控制GPIOC12输出低/高电平:cpu datasheet
       GPIOCALTFN0  0xc001c020
       GPIOCOUTENB  0xc001c004
       GPIOCOUT     0xc001c000
   linux系统中如何控制GPIO管脚输出:本质上就是操作以上特殊功能寄存器
       1)将物理地址映射为虚拟地址
          然后通过虚拟地址访问特殊功能寄存器
       2)内核中提供了一套控制GPIO的库函数   
   
   GPIO库函数控制GPIO管脚有固定的步骤:
       1)申请GPIO管脚 (可选的)
          int gpio_request(unsigned gpio, const char *name)
              gpio,要申请的管脚编号
                   arch/arm/plat-s5p6818/common/cfg_type.h
              name,名称
              返回值,0 申请成功
                      非0 失败
                      
                      
       2)使用GPIO管脚
          //将参数指定的管脚设置为输入模式
          int gpio_direction_input(unsigned gpio)
          //获取指定管脚的电平状态
          // 0/1, 低/高
          int gpio_get_value(unsigned gpio)
          
          
          //将参数指定的管脚设置为输出模式
          //value 为0 默认输出低电平
                  非0 默认输出高电平
          int gpio_direction_output(unsigned gpio, int value)
          //设置指定管脚输出高/低电平
          void gpio_set_value(unsigned gpio, int value)   
       3)释放GPIO管脚 (可选的)
          //释放管脚
          void gpio_free(unsigned gpio)          
    
   安装模块前将内核中自带的LED驱动裁剪掉
      cd kernel/
      make menuconfig
         Device Drivers  --->
           -*- LED Support  --->
              < >   LED Support for GPIO connected LEDs
              < >   PWM driven LED Support
              [ ]   LED Trigger support
      make uImage
      
      让开发板使用新内核        
         cp arch/arm/boot/uImage /tftpboot/
         setenv bootcmd ping 192.168.1.8\;ping 192.168.1.8 \; tftp 48000000 uImage \; bootm 48000000
         saveenv
         
      insmod led_drv.ko           
      mknod /dev/myleds c 244 5
      ./test
      观察LED1的变化     
   练习:LED1/2/3/4

2、内核空间和用户空间的数据交换
   用户空间代码不能(直接)访问内核空间
   内核空间代码访问用户空间时也加了限制
       
   long copy_to_user(void __user *to,
        const void *from, unsigned long n)
    to, 目标地址
        该地址应该介于0~3G
    from, 源数据地址
         该地址应该介于3G~4G
    n, 希望连续拷贝的字节数
    返回值,拷贝失败的字节数        
        
        
   long copy_from_user(void *to,
        const void __user * from, unsigned long n)    
        to, 目标地址 (3G~4G)
        from,源数据地址(0~3G)
        n, 连续拷贝的字节数
        返回值,操作失败的字节数
练习:
     用户空间向led1设备写入1时灭灯
                           0  亮
                       读取 1 灯是灭            
 
3、ioctl
   对LED写操作实现LED亮灭控制不合理?
   
   如果需要去实现uart驱动程序
       应用程序通过uart发数据 应该实现write
                       收             read
       如何在用户空间改变通信时的波特率?
           用户空间使用ioctl----->unlocked_ioctl
 
   ioctl,用于设置或者获取设备工作属性信息
        例如uart 通信时 设置使用8n1 115200
            查询当前uart通信时使用的波特率        
   
   函数原型:int ioctl(int d, int request, ...)
   通常使用
            1)ioctl(fd, cmd)
            2)ioctl(fd, cmd, &arg)
            
   练习:./test on/off   1/2/3/4

4、设备文件的自动创建  
   1) 根文件系统中有mdev
   
   2) 挂载了proc sys 文件系统
      rootfs/etc/init.d/rcS
         mount -a
      rootfs/etc/fstab
         proc    /proc   proc    defaults    0   0
         sysfs   /sys    sysfs   defaults    0   0
   3)配置热插拔事件产生后要执行的动作
      echo /sbin/mdev > /proc/sys/kernel/hotplug
                   产生热插拔事件后,自动到proc/sys/kernel/hotplug执行/sbin/mdev产生相应的设备文件。
      热插拔事件:
          狭义: U盘的插入和拔出
          广义: 也包括/sys目录的文件变化
      
   4)编程产生热插拔事件
      
      class_create
      struct device *device_create(struct class *class, struct device *parent,
                       dev_t devt, void *drvdata, const char *fmt, ...)
             class, 该device属于那种类型的设备
                    该果实挂在哪个树枝上
             parent, 该device的父设备
             devt, 设备号
             drvdata,创建设备时传递给设备的附加信息
                     通常给NULL                       
             fmt, ...:决定了将来/dev目录下产生的设备文件的名称
                     例如:  "ttySAC%d",i
                     
                     for(i=0; i<4; i++)
                     {
                         device_create(...., "ttySAC%d",i);
                     }
                     
                     
      device_destroy
      class_destroy

4) 设备的文件自动创建
      真正创建设备文件的软件:mdev
      
      挂载proc sys文件系统 /proc /sys
      
      procfs
      sysyfs都是基于内存的文件系统
            其中的内容都是linux在执行过程中动态创建的
      
      procfs, 用来向用户空间导出内核态的执行信息
             常用的一些系统软件 例如ps基于该文件系统实现的
             
             每个进程都会在proc目录对应一个其进程ID命名的文件夹
             
             cat /proc/cmdline
             cat /proc/partitions
             cat /proc/cpuinfo
             cat /proc/meminfo
             cat /proc/devices
             ....  
             cat /proc/sys/kernel/printk
             echo 7 >/proc/sys/kernel/printk
             echo /sbin/mdev >/proc/sys/kernel/hotplug
       sysfs, 它是从procfs分家出来的  
              专门用来展示硬件驱动模型 层次关系  
              
             安装xxx.ko模块
             会自动产生 /sys/module/xxx/    
             
       触发热插拔事件
           class_create  device_create
           class_destroy device_destroy

  1. #include "../../global.h"
  2. #include <linux/fs.h>
  3. #include <linux/cdev.h>
  4. #include <linux/gpio.h>
  5. #include <mach/platform.h>
  6.  
  7. unsigned int major = ;
  8. unsigned int minor = ;
  9. dev_t dev ; //设备号
  10.  
  11. /*1 定义一个struct cdev变量*/
  12. struct cdev led_cdev;
  13.  
  14. static int led_open(struct inode *inode,
  15. struct file *filp)
  16. {
  17. /*输出低电平*/
  18. gpio_set_value(PAD_GPIO_C+, );
  19. return ;
  20. }
  21. static int led_close(struct inode *inode,
  22. struct file *filp)
  23. {
  24. gpio_set_value(PAD_GPIO_C+, );
  25. return ;
  26. }
  27.  
  28. struct file_operations led_fops =
  29. {
  30. .owner = THIS_MODULE,
  31. .open = led_open,
  32. .release = led_close,
  33. };
  34. int __init led_drv_init(void)
  35. {
  36. if(major) //静态
  37. {
  38. //dev = major<<20|minor;
  39. dev = MKDEV(major, minor);
  40.  
  41. register_chrdev_region(dev, , "myleds");
  42. }
  43. else //动态注册
  44. {
  45. alloc_chrdev_region(&dev, minor, , "myleds");
  46. printk("<1>" "major=%d minor=%d\n",
  47. MAJOR(dev), MINOR(dev));
  48. }
  49. /*2 初始化cdev变量*/
  50. cdev_init(&led_cdev, &led_fops);
  51. /*3 注册cdev变量*/
  52. cdev_add(&led_cdev, dev, );
  53. /*申请GPIO管脚*/
  54. gpio_request(PAD_GPIO_C+, "led1");
  55. /*使用GPIO管脚*/
  56. gpio_direction_output(PAD_GPIO_C+, );
  57.  
  58. return ;
  59. }
  60. void __exit led_drv_exit(void)
  61. {
  62. /*释放GPIO管脚*/
  63. gpio_free(PAD_GPIO_C+);
  64. /*4 注销cdev*/
  65. cdev_del(&led_cdev);
  66.  
  67. unregister_chrdev_region(dev, );
  68. }
  69. module_init(led_drv_init);
  70. module_exit(led_drv_exit);
  1. #include "../../global.h"
  2. #include <linux/fs.h>
  3. #include <linux/cdev.h>
  4. #include <linux/gpio.h>
  5. #include <mach/platform.h>
  6. #include <linux/uaccess.h>
  7.  
  8. unsigned int major = ;
  9. unsigned int minor = ;
  10. dev_t dev ; //设备号
  11.  
  12. /*1 定义一个struct cdev变量*/
  13. struct cdev led_cdev;
  14.  
  15. static int led_open(struct inode *inode,
  16. struct file *filp)
  17. {
  18. return ;
  19. }
  20. static int led_close(struct inode *inode,
  21. struct file *filp)
  22. {
  23. return ;
  24. }
  25. int k_stat = ; //记录灯的当前状态
  26. ssize_t led_write(struct file *filp,
  27. const char __user *buf,
  28. size_t len, loff_t *offset)
  29. {
  30. int ret = ;
  31. int k_cmd = ;
  32. //buf中保存的是用户空间地址
  33. //*buf在直接读取用户空间内存 没有权限检查 不安全
  34. //*buf
  35. ret = copy_from_user(&k_cmd, buf, len);
  36. /*
  37. *cmd=0 亮灯
  38. * =1 灭灯
  39. * */
  40. gpio_set_value(PAD_GPIO_C+, k_cmd);
  41. /*
  42. * 1,灭的状态
  43. * 0,亮的状态
  44. * */
  45. k_stat = k_cmd;
  46. return len;
  47.  
  48. }
  49. ssize_t led_read(struct file *filp,
  50. char __user *buf,
  51. size_t len, loff_t *offset)
  52. {
  53. int ret = ;
  54. /*
  55. *buf 保存的是用户空间stat变量的地址
  56. *内核需要向其中写入数据应该先检查是否有写权限
  57. *以下做法不安全
  58. * */
  59. //*buf = k_stat;
  60.  
  61. ret = copy_to_user(buf, &k_stat, len);
  62.  
  63. return len;
  64.  
  65. }
  66. struct file_operations led_fops =
  67. {
  68. .owner = THIS_MODULE,
  69. .open = led_open,
  70. .release = led_close,
  71. .write = led_write,
  72. .read = led_read,
  73. };
  74. int __init led_drv_init(void)
  75. {
  76. if(major) //静态
  77. {
  78. //dev = major<<20|minor;
  79. dev = MKDEV(major, minor);
  80.  
  81. register_chrdev_region(dev, , "myleds");
  82. }
  83. else //动态注册
  84. {
  85. alloc_chrdev_region(&dev, minor, , "myleds");
  86. printk("<1>" "major=%d minor=%d\n",
  87. MAJOR(dev), MINOR(dev));
  88. }
  89. /*2 初始化cdev变量*/
  90. cdev_init(&led_cdev, &led_fops);
  91. /*3 注册cdev变量*/
  92. cdev_add(&led_cdev, dev, );
  93. /*申请GPIO管脚*/
  94. gpio_request(PAD_GPIO_C+, "led1");
  95. /*使用GPIO管脚*/
  96. gpio_direction_output(PAD_GPIO_C+, );
  97.  
  98. return ;
  99. }
  100. void __exit led_drv_exit(void)
  101. {
  102. /*释放GPIO管脚*/
  103. gpio_free(PAD_GPIO_C+);
  104. /*4 注销cdev*/
  105. cdev_del(&led_cdev);
  106.  
  107. unregister_chrdev_region(dev, );
  108. }
  109. module_init(led_drv_init);
  110. module_exit(led_drv_exit);
  1. #include "../../global.h"
  2. #include <linux/fs.h>
  3. #include <linux/cdev.h>
  4. #include <linux/gpio.h>
  5. #include <mach/platform.h>
  6. #include <linux/uaccess.h>
  7.  
  8. #define CMD_LED_ON (0x10001)
  9. #define CMD_LED_OFF (0x10002)
  10.  
  11. unsigned int major = ;
  12. unsigned int minor = ;
  13. dev_t dev ; //设备号
  14.  
  15. /*1 定义一个struct cdev变量*/
  16. struct cdev led_cdev;
  17.  
  18. typedef struct led_desc
  19. {
  20. int gpio;//管脚编号
  21. char *name;//名称
  22. }led_desc_t;
  23.  
  24. led_desc_t leds[]=
  25. {
  26. {PAD_GPIO_C+, "led1"},
  27. {PAD_GPIO_C+ , "led2"},
  28. {PAD_GPIO_C+, "led3"},
  29. {PAD_GPIO_B+, "led4"},
  30. };
  31.  
  32. static int led_open(struct inode *inode,
  33. struct file *filp)
  34. {
  35. return ;
  36. }
  37. static int led_close(struct inode *inode,
  38. struct file *filp)
  39. {
  40. return ;
  41. }
  42. ssize_t led_write(struct file *filp,
  43. const char __user *buf,
  44. size_t len, loff_t *offset)
  45. {
  46. return len;
  47. }
  48. ssize_t led_read(struct file *filp,
  49. char __user *buf,
  50. size_t len, loff_t *offset)
  51. {
  52. return len;
  53. }
  54.  
  55. long led_ioctl(struct file *filp,
  56. unsigned int cmd,
  57. unsigned long arg)
  58. {
  59. int ret = ;
  60. int k_index = ;
  61.  
  62. ret = copy_from_user(&k_index,
  63. (const void *)arg, );
  64.  
  65. if(k_index> || k_index<)
  66. {
  67. return -EINVAL;
  68. }
  69.  
  70. switch(cmd)
  71. {
  72. case CMD_LED_ON:
  73. gpio_set_value(leds[k_index-].gpio, );
  74. break;
  75. case CMD_LED_OFF:
  76. gpio_set_value(leds[k_index-].gpio, );
  77. break;
  78. default:
  79. return -EINVAL;
  80. }
  81.  
  82. return ;
  83. }
  84.  
  85. struct file_operations led_fops =
  86. {
  87. .owner = THIS_MODULE,
  88. .open = led_open,
  89. .release = led_close,
  90. .write = led_write,
  91. .read = led_read,
  92. .unlocked_ioctl = led_ioctl,
  93. };
  94. int __init led_drv_init(void)
  95. {
  96. int i = ;
  97. if(major) //静态
  98. {
  99. //dev = major<<20|minor;
  100. dev = MKDEV(major, minor);
  101.  
  102. register_chrdev_region(dev, , "myleds");
  103. }
  104. else //动态注册
  105. {
  106. alloc_chrdev_region(&dev, minor, , "myleds");
  107. printk("<1>" "major=%d minor=%d\n",
  108. MAJOR(dev), MINOR(dev));
  109. }
  110. /*2 初始化cdev变量*/
  111. cdev_init(&led_cdev, &led_fops);
  112. /*3 注册cdev变量*/
  113. cdev_add(&led_cdev, dev, );
  114.  
  115. for(i=; i<ARRAY_SIZE(leds); i++)
  116. {
  117. /*申请GPIO管脚*/
  118. gpio_request(leds[i].gpio, leds[i].name);
  119. /*使用GPIO管脚*/
  120. gpio_direction_output(leds[i].gpio, );
  121. }
  122. return ;
  123. }
  124. void __exit led_drv_exit(void)
  125. {
  126. int i = ;
  127. for(i=; i<ARRAY_SIZE(leds); i++)
  128. {
  129. /*释放GPIO管脚*/
  130. gpio_free(leds[i].gpio);
  131. }
  132. /*4 注销cdev*/
  133. cdev_del(&led_cdev);
  134.  
  135. unregister_chrdev_region(dev, );
  136. }
  137. module_init(led_drv_init);
  138. module_exit(led_drv_exit);
  1. #include "../../global.h"
  2. #include <linux/fs.h>
  3. #include <linux/cdev.h>
  4. #include <linux/gpio.h>
  5. #include <mach/platform.h>
  6. #include <linux/uaccess.h>
  7. #include <linux/device.h>
  8.  
  9. #define CMD_LED_ON (0x10001)
  10. #define CMD_LED_OFF (0x10002)
  11.  
  12. struct class *cls = NULL;
  13.  
  14. unsigned int major = ;
  15. unsigned int minor = ;
  16. dev_t dev ; //设备号
  17.  
  18. /*1 定义一个struct cdev变量*/
  19. struct cdev led_cdev;
  20.  
  21. typedef struct led_desc
  22. {
  23. int gpio;//管脚编号
  24. char *name;//名称
  25. }led_desc_t;
  26.  
  27. led_desc_t leds[]=
  28. {
  29. {PAD_GPIO_C+, "led1"},
  30. {PAD_GPIO_C+ , "led2"},
  31. {PAD_GPIO_C+, "led3"},
  32. {PAD_GPIO_B+, "led4"},
  33. };
  34.  
  35. static int led_open(struct inode *inode,
  36. struct file *filp)
  37. {
  38. return ;
  39. }
  40. static int led_close(struct inode *inode,
  41. struct file *filp)
  42. {
  43. return ;
  44. }
  45. ssize_t led_write(struct file *filp,
  46. const char __user *buf,
  47. size_t len, loff_t *offset)
  48. {
  49. return len;
  50. }
  51. ssize_t led_read(struct file *filp,
  52. char __user *buf,
  53. size_t len, loff_t *offset)
  54. {
  55. return len;
  56. }
  57.  
  58. long led_ioctl(struct file *filp,
  59. unsigned int cmd,
  60. unsigned long arg)
  61. {
  62. int ret = ;
  63. int k_index = ;
  64.  
  65. ret = copy_from_user(&k_index,
  66. (const void *)arg, );
  67.  
  68. if(k_index> || k_index<)
  69. {
  70. return -EINVAL;
  71. }
  72.  
  73. switch(cmd)
  74. {
  75. case CMD_LED_ON:
  76. gpio_set_value(leds[k_index-].gpio, );
  77. break;
  78. case CMD_LED_OFF:
  79. gpio_set_value(leds[k_index-].gpio, );
  80. break;
  81. default:
  82. return -EINVAL;
  83. }
  84.  
  85. return ;
  86. }
  87.  
  88. struct file_operations led_fops =
  89. {
  90. .owner = THIS_MODULE,
  91. .open = led_open,
  92. .release = led_close,
  93. .write = led_write,
  94. .read = led_read,
  95. .unlocked_ioctl = led_ioctl,
  96. };
  97. int __init led_drv_init(void)
  98. {
  99. int i = ;
  100. if(major) //静态
  101. {
  102. //dev = major<<20|minor;
  103. dev = MKDEV(major, minor);
  104.  
  105. register_chrdev_region(dev, , "myleds");
  106. }
  107. else //动态注册
  108. {
  109. alloc_chrdev_region(&dev, minor, , "myleds");
  110. printk("<1>" "major=%d minor=%d\n",
  111. MAJOR(dev), MINOR(dev));
  112. }
  113. /*2 初始化cdev变量*/
  114. cdev_init(&led_cdev, &led_fops);
  115. /*3 注册cdev变量*/
  116. cdev_add(&led_cdev, dev, );
  117. /*自动产生设备文件*/
  118. /*会产生 /sys/class/LEDS/*/
  119. cls = class_create(THIS_MODULE, "LEDS");
  120. /*会产生 /sys/class/LEDS/myleds/ */
  121. device_create(cls,NULL,dev, NULL,"myleds");
  122.  
  123. for(i=; i<ARRAY_SIZE(leds); i++)
  124. {
  125. /*申请GPIO管脚*/
  126. gpio_request(leds[i].gpio, leds[i].name);
  127. /*使用GPIO管脚*/
  128. gpio_direction_output(leds[i].gpio, );
  129. }
  130. return ;
  131. }
  132. void __exit led_drv_exit(void)
  133. {
  134. int i = ;
  135. for(i=; i<ARRAY_SIZE(leds); i++)
  136. {
  137. /*释放GPIO管脚*/
  138. gpio_free(leds[i].gpio);
  139. }
  140. /*自动销毁设备文件*/
  141. device_destroy(cls, dev);
  142. class_destroy(cls);
  143.  
  144. /*4 注销cdev*/
  145. cdev_del(&led_cdev);
  146.  
  147. unregister_chrdev_region(dev, );
  148. }
  149. module_init(led_drv_init);
  150. module_exit(led_drv_exit);

GPIO硬件资源的申请,内核空间和用户空间的数据交换,ioctl(.....),设备文件的自动创建的更多相关文章

  1. Linux 内核空间与用户空间

    本文以 32 位系统为例介绍内核空间(kernel space)和用户空间(user space). 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为 4 ...

  2. linux内存(一) 内核空间与用户空间

    来自如下网站 https://www.cnblogs.com/sparkdev/p/8410350.html 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间 ...

  3. Linux操作系统,为什么需要内核空间和用户空间?

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 本文以 32 位系统为例介绍内核空间(kernel sp ...

  4. 内核空间和用户空间的分界 PAGE_OFFSET

      PAGE_OFFSET 首先看看PAGE_OFFSET的功能   内存映射 |            用户空间                  |   内核空间   | |——————+———— ...

  5. linux内核空间和用户空间详解

    linux驱动程序一般工作在内核空间,但也可以工作在用户空间.下面我们将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们.Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Li ...

  6. Linux内核中断引入用户空间(异步通知机制)【转】

    转自:http://blog.csdn.net/kingdragonfly120/article/details/10858647 版权声明:本文为博主原创文章,未经博主允许不得转载. 当Linux内 ...

  7. windbg 如何再内核模式调试用户空间的程序

    1:使用!process 0 0 获取用户空间的所有的进程的信息 !process 0 0 **** NT ACTIVE PROCESS DUMP ****    PROCESS 80a02a60   ...

  8. Oracle小技巧_不同表空间不同用户导入导出数据dmp

    [博主注:数据库方面 ITPUB网站及博客内容非常丰富]   转载来源ITPUB 博客 经常有人会问:原来的数据在USERS表空间里面,我想把它IMP进APP表空间,我已经修改了目的用户的默认表空间, ...

  9. 【mark】OS是否使用svc方式分开系统空间和用户空间的优劣

    对于Cortex-M单片机,用户程序调用RTOS系统函数有两种思路: 假设创建任务的RTOS函数是xxx_task_create() 第一类:FreeRTOS.RT-Thread中采用的方法,和调用普 ...

随机推荐

  1. html5视频常用API接口

    一.虽然有的属性是boolean类型,但仍旧建议按照XHTML书写(属性名=”属性值”)格式,避免出现错误 (下面加粗的属性为常用属性) 属性 值 功能描述 controls controls 是否显 ...

  2. 直线扫描转换-DDA算法

    直线扫描转换-DDA算法 直线段的扫描转换算法 已知两个点,求直线. 为了在光栅显示器上用这些离散的像素点逼近这条直线,需要知道这些像素点的x,y坐标. 求出过P0,P1的直线段方程: y=kx+b ...

  3. 微信小程序中事件

    微信小程序中事件 一.常见的事件有 类型 触发条件 最低版本 touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒,弹窗 ...

  4. 白话系列之实现自己简单的mvc式webapi框架

    前言:此文为极简mvc式的api框架,只当做入门api的解析方式,并且这里也不算是mvc框架,因为没有view层,毕竟现在大部分都属于前后端分离,当然也可以提供view层,因为只是将view当做文本返 ...

  5. Luogu1119灾后重建

    题目背景 BBB 地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公 ...

  6. 初识AutoIt

    1.定义 AutoIt 目前最新是v3版本,这是一个使用类似BASIC脚本语言的免费软件,它设计用于Windows GUI(图形用户界面)中进行自动化操作.它利用模拟键盘按键,鼠标移动和窗口/控件的组 ...

  7. MFC中如何分割CString类型的数据

    [才疏学浅,难免有纰漏,若有不正确的地方,欢迎指教] MFC中有一个库函数 Tokenize(); 函数原型:CStringT Tokenize( PCXSTR pszTokens , int& ...

  8. 图论-最小生成树<Kruskal>

    昨天: 图论-最小生成树<Dijkstra,Floyd> 以上是昨天的Blog,有需要者请先阅读完以上再阅读今天的Blog. 可能今天的有点乱,好好理理,认真看完相信你会懂得 然而,文中提 ...

  9. Java 中的 final、finally、finalize 有什么不同?

    Java 中 final.finally.finalize 有什么不同?这是在 Java 面试中经常问到的问题,他们究竟有什么不同呢? 这三个看起来很相似,其实他们的关系就像卡巴斯基和巴基斯坦一样有基 ...

  10. netty源码解析(4.0)-26 ByteBuf内存池:PoolArena-PoolSubpage

    PoolChunk用来分配大于或等于一个page的内存,如果需要小于一个page的内存,需要先从PoolChunk中分配一个page,然后再把一个page切割成多个子页-subpage,最后把内存以s ...