linux 添加misc 字符设备

来源:互联网 发布:手机淘宝退款退货流程 编辑:程序博客网 时间:2024/04/28 10:49

linux 每个设备分为主设备号和次设备号,主设备号用于区分设备的种类,此设备号用于区分该种设备有多少个。linux中的字符设备的主设备号是10。如下:

crw------- 1 root root     10, 234 Apr  9 11:44 btrfs-controlcrw------- 1 root root     10,  60 Apr  9 11:44 cpu_dma_latencycrw------- 1 root root     10, 203 Apr  9 11:44 cusecrw------- 1 root root     10,  61 Apr  9 11:44 ecryptfs


次设备号 范围 0- 255:

#define MAJOR(dev)((dev)>>8)10#define MINOR(dev)((dev) & 0xff)11#define MKDEV(ma,mi)((ma)<<8 | (mi))

次设备号说明:

 10 charNon-serial mice, misc features  0 = /dev/logibmLogitech bus mouse  1 = /dev/psauxPS/2-style mouse port  2 = /dev/inportbmMicrosoft Inport bus mouse  3 = /dev/atibmATI XL bus mouse  4 = /dev/jbmJ-mouse  4 = /dev/amigamouseAmiga mouse (68k/Amiga)  5 = /dev/atarimouseAtari mouse  6 = /dev/sunmouseSun mouse  7 = /dev/amigamouse1Second Amiga mouse  8 = /dev/smouseSimple serial mouse driver  9 = /dev/pc110padIBM PC-110 digitizer pad 10 = /dev/adbmouseApple Desktop Bus mouse 11 = /dev/vrtpanelVr41xx embedded touch panel 13 = /dev/vpcmouseConnectix Virtual PC Mouse 14 = /dev/touchscreen/ucb1x00  UCB 1x00 touchscreen 15 = /dev/touchscreen/mk712MK712 touchscreen128 = /dev/beepFancy beep device129 =130 = /dev/watchdogWatchdog timer port131 = /dev/temperatureMachine internal temperature132 = /dev/hwtrapHardware fault trap133 = /dev/exttrpExternal device trap134 = /dev/apm_biosAdvanced Power Management BIOS135 = /dev/rtcReal Time Clock137 = /dev/vhciBluetooth virtual HCI driver139 = /dev/openpromSPARC OpenBoot PROM140 = /dev/relay8Berkshire Products Octal relay card141 = /dev/relay16Berkshire Products ISO-16 relay card142 =143 = /dev/pciconfPCI configuration space144 = /dev/nvramNon-volatile configuration RAM145 = /dev/hfmodemSoundcard shortwave modem control146 = /dev/graphicsLinux/SGI graphics device147 = /dev/openglLinux/SGI OpenGL pipe148 = /dev/gfxLinux/SGI graphics effects device149 = /dev/input/mouseLinux/SGI Irix emulation mouse150 = /dev/input/keyboard Linux/SGI Irix emulation keyboard151 = /dev/ledFront panel LEDs152 = /dev/kpollKernel Poll Driver153 = /dev/mergememMemory merge device154 = /dev/pmuMacintosh PowerBook power manager155 = /dev/isictlMultiTech ISICom serial control156 = /dev/lcdFront panel LCD display157 = /dev/acApplicom Intl Profibus card158 = /dev/nwbuttonNetwinder external button159 = /dev/nwdebugNetwinder debug interface160 = /dev/nwflashNetwinder flash memory161 = /dev/userdmaUser-space DMA access162 = /dev/smbusSystem Management Bus163 = /dev/likLogitech Internet Keyboard164 = /dev/ipmoIntel Intelligent Platform Management165 = /dev/vmmonVMware virtual machine monitor166 = /dev/i2o/ctlI2O configuration manager167 = /dev/specialix_sxctl Specialix serial control168 = /dev/tcldrvTechnology Concepts serial control169 = /dev/specialix_rioctl Specialix RIO serial control170 = /dev/thinkpad/thinkpadIBM Thinkpad devices171 = /dev/srripcQNX4 API IPC manager172 = /dev/usemacloneSemaphore clone device173 = /dev/ipmikcsIntelligent Platform Management174 = /dev/uctrlSPARCbook 3 microcontroller175 = /dev/agpgartAGP Graphics Address Remapping Table176 = /dev/gtrscGorgy Timing radio clock177 = /dev/cbmSerial CBM bus178 = /dev/jsflashJavaStation OS flash SIMM179 = /dev/xsvcHigh-speed shared-mem/semaphore service180 = /dev/vrbuttonsVr41xx button input device181 = /dev/toshibaToshiba laptop SMM support182 = /dev/perfctrPerformance-monitoring counters183 = /dev/hwrngGeneric random number generator184 = /dev/cpu/microcode CPU microcode update interface186 = /dev/atomicpsAtomic shapshot of process state data187 = /dev/irnetIrNET device188 = /dev/smbusbiosSMBus BIOS189 = /dev/ussp_ctlUser space serial port control190 = /dev/crashMission Critical Linux crash dump facility191 = /dev/pcl181<information missing>192 = /dev/nas_xbusNAS xbus LCD/buttons access193 = /dev/d7sSPARC 7-segment display194 = /dev/zkshimZero-Knowledge network shim control195 = /dev/elographics/e2201Elographics touchscreen E271-2201196 = /dev/vfio/vfioVFIO userspace driver interface197 = /dev/pxa3xx-gcuPXA3xx graphics controller unit driver198 = /dev/sexecSigned executable interface199 = /dev/scanners/cuecat :CueCat barcode scanner200 = /dev/net/tunTAP/TUN network device201 = /dev/button/gulpbTransmeta GULP-B buttons202 = /dev/emd/ctlEnhanced Metadisk RAID (EMD) control203 = /dev/cuseCuse (character device in user-space)204 = /dev/video/em8300EM8300 DVD decoder control205 = /dev/video/em8300_mvEM8300 DVD decoder video206 = /dev/video/em8300_maEM8300 DVD decoder audio207 = /dev/video/em8300_spEM8300 DVD decoder subpicture208 = /dev/compaq/cpqphpcCompaq PCI Hot Plug Controller209 = /dev/compaq/cpqridCompaq Remote Insight Driver210 = /dev/impi/btIMPI coprocessor block transfer211 = /dev/impi/smicIMPI coprocessor stream interface212 = /dev/watchdogs/0First watchdog device213 = /dev/watchdogs/1Second watchdog device214 = /dev/watchdogs/2Third watchdog device215 = /dev/watchdogs/3Fourth watchdog device216 = /dev/fujitsu/apanelFujitsu/Siemens application panel217 = /dev/ni/natmotnNational Instruments Motion218 = /dev/kchuidInter-process chuid control219 = /dev/modems/mwaveMWave modem firmware upload220 = /dev/mptctlMessage passing technology (MPT) control221 = /dev/mvista/hssdsiMontavista PICMG hot swap system driver222 = /dev/mvista/hasiMontavista PICMG high availability223 = /dev/input/uinputUser level driver support for input224 = /dev/tpmTCPA TPM driver225 = /dev/ppsPulse Per Second driver226 = /dev/systraceSystrace device227 = /dev/mcelogX86_64 Machine Check Exception driver228 = /dev/hpetHPET driver229 = /dev/fuseFuse (virtual filesystem in user-space)230 = /dev/midishareMidiShare driver231 = /dev/snapshotSystem memory snapshot device232 = /dev/kvmKernel-based virtual machine (hardware virtualization extensions)233 = /dev/kmviewView-OS A process with a view234 = /dev/btrfs-controlBtrfs control device235 = /dev/autofsAutofs control device236 = /dev/mapper/controlDevice-Mapper control device237 = /dev/loop-control Loopback control device238 = /dev/vhost-netHost kernel accelerator for virtio net239 = /dev/uhidUser-space I/O driver support for HID subsystem240-254Reserved for local use255Reserved for MISC_DYNAMIC_MINOR


注册misc字符设备有方便的接口可用:

/** *      misc_register   -       register a miscellaneous device *      @misc: device structure *       *      Register a miscellaneous device with the kernel. If the minor *      number is set to %MISC_DYNAMIC_MINOR a minor number is assigned *      and placed in the minor field of the structure. For other cases *      the minor number requested is used. * *      The structure passed is linked into the kernel and may not be *      destroyed until it has been unregistered. * *      A zero is returned on success and a negative errno code for *      failure. */int misc_register(struct miscdevice * misc)


内核空间:

#include "xyf.h"#include <linux/miscdevice.h>#include <linux/fs.h>#include <linux/list.h>#include <linux/module.h>#include <linux/uaccess.h>static long xyf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){    int ret;    void __user *ubuf = (void __user *)arg;    struct buffer_read buff;        printk("xyf_ioctl: %d %lx\n", cmd, arg);    if (copy_from_user(&buff, ubuf, sizeof(buff))) {         printk("xyf_ioctl error copy_from_user\n");    }else{        printk("xyf_ioctl buff: %d %d\n", buff.buffer_size, buff.read_size);    }    switch (cmd) {        case 11:            ret = 12;            break;        default:            ret = 0;            break;    }    return ret;}static int xyf_open(struct inode *nodp, struct file *filp){    printk("xyf_open\n");    return 0;}static ssize_t xyf_read(struct file *filep, char __user *buf, size_t len, loff_t *pos){    int value;    value = 66;    if(copy_to_user(buf,&value,sizeof(value))){        printk("xyf_read error copy_to_user\n");    }    printk("xyf_read %d\n", value);    return 0;}static ssize_t xyf_write(struct file *filep, const char __user *buf, size_t len, loff_t *pos){    int value;    value = 0;    if (copy_from_user(&value, buf, len)) {        printk("xyf_write error copy_from_user\n");    }        printk("xyf_write %d\n", value);    return len;}static const struct file_operations xyf_fops = {.owner = THIS_MODULE,.unlocked_ioctl = xyf_ioctl,.compat_ioctl = xyf_ioctl,.open = xyf_open,    .read = xyf_read,    .write = xyf_write,};static struct miscdevice xyf_miscdev = {.minor = MISC_DYNAMIC_MINOR,.name = "xyf",.fops = &xyf_fops};static int __init xyf_init(void){    int ret = misc_register(&xyf_miscdev);;        return ret;}device_initcall(xyf_init);MODULE_LICENSE("GPL v2");



用户空间访问字符设备:

#include <unistd.h>#include <stdio.h>#include <binder/ProcessState.h>#include <binder/IPCThreadState.h>#include <utils/RefBase.h>#include <sys/ioctl.h>#include <errno.h>#include <fcntl.h>static int open_driver(){    int fd = open("/dev/xyf", O_RDWR | O_CLOEXEC);      printf("open_driver fd=%d \n", fd);      if(fd >= 0){        buffer_read buff;          buff.buffer_size = 55;          buff.read_size = 121;          int result = ioctl(fd, 11, &buff);          printf("ioctl result=%d \n", result);        if (result == -1) {              close(fd);            fd = -1;              return fd;        }          int value_w  = 45;        write(fd, &value_w, sizeof(value_w));        int value_r = 0;        read(fd, &value_r,sizeof(value_r));        printf("read %d \n", value_r);        close(fd);    }else{        printf("Opening '/dev/xyf' failed: %s\n", strerror(errno));    }    return fd;}int main() {    open_driver();    return 0;}

硬件抽象层:

#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <hardware/hardware.h>#define XYF_HARDWARE_MODULE_ID "xyf"char const*const XYF_FILE = "/dev/xyf";        struct xyf_device_t {    struct hw_device_t common;    /**     * Set the provided lights to the provided values.     *     * Returns: 0 on succes, error code on failure.     */    int (*xyf_read)(struct xyf_device_t* dev, int* value);    int (*xyf_write)(struct xyf_device_t* dev, int value);};static int write_int(char const* path, int value){    int fd;    fd = open(path, O_RDWR);    if (fd >= 0) {        ssize_t amt = write(fd, &value, sizeof(value));        close(fd);        return amt == -1 ? -errno : 0;    } else {        return -errno;    }}static int read_int(char const* path, int* value){    int fd;    fd = open(path, O_RDWR);    if (fd >= 0) {        read(fd, value, sizeof(*value));          close(fd);        return 0;    } else {        return -errno;    }}static int xyf_read(struct xyf_device_t* dev, int* value){    read_int(XYF_FILE, value);    return 0;}static int xyf_write(struct xyf_device_t* dev, int value){    write_int(XYF_FILE, value);    return 0;}static int xyf_close(struct xyf_device_t *dev){    if (dev) {        free(dev);    }    return 0;}static int xyf_open(const struct hw_module_t* module, char const* name,        struct hw_device_t** device){    struct xyf_device_t *dev = malloc(sizeof(struct xyf_device_t));    if(!dev){        return -ENOMEM;    }    memset(dev, 0, sizeof(*dev));    dev->common.tag = HARDWARE_DEVICE_TAG;    dev->common.version = 0;    dev->common.module = (struct hw_module_t*)module;    dev->common.close = (int (*)(struct hw_device_t*))xyf_close;    dev->xyf_read = xyf_read;    dev->xyf_write = xyf_write;        *device = (struct hw_device_t*)dev;    return 0;}static struct hw_module_methods_t xyf_module_methods = {    .open = xyf_open,};struct hw_module_t HAL_MODULE_INFO_SYM = {    .tag = HARDWARE_MODULE_TAG,    .version_major = 1,    .version_minor = 0,    .id = XYF_HARDWARE_MODULE_ID,    .name = "xyf Module",    .author = "The Android Open Source Project",    .methods = &xyf_module_methods,};

通过HAL层访问:

#include <unistd.h>#include <stdio.h>#include <utils/RefBase.h>#include <utils/Log.h>#include <hardware/hardware.h>#define XYF_HARDWARE_MODULE_ID "xyf"struct xyf_device_t {    struct hw_device_t common;    /**     * Set the provided lights to the provided values.     *     * Returns: 0 on succes, error code on failure.     */    int (*xyf_read)(struct xyf_device_t* dev, int* value);    int (*xyf_write)(struct xyf_device_t* dev, int value);};static xyf_device_t* get_device(hw_module_t* module, char const* name){    int err;    hw_device_t* device;    err = module->methods->open(module, name, &device);    if (err == 0) {        return (xyf_device_t*)device;    } else {        return NULL;    }}int main() {    int err;    hw_module_t* module;    err = hw_get_module(XYF_HARDWARE_MODULE_ID, (hw_module_t const**)&module);    xyf_device_t* device = get_device(module, XYF_HARDWARE_MODULE_ID);    if(!device){        return 0;    }    int val = 89;    device->xyf_write(device, val);        int value = 0;    device->xyf_read(device, &value);    printf("hal client read %d\n", value);        return 0;}

HAL层只是封装了一下,最终还是通过read,write访问的kernel。原理都是相通的。


原创粉丝点击