USB Audio Class (UAC) 分析_snd_usb_audio_create-程序员宅基地

技术标签: usb  Linux设备驱动  audio  Android  

一个UAC设备插入到Ubuntu 14.04电脑上dmesg中打印的信息如下:

[ 2367.490491] usb 3-3.2: new full-speed USB device number 9 using xhci_hcd
[ 2367.580010] usb 3-3.2: New USB device found, idVendor=0d8c, idProduct=0132
[ 2367.580018] usb 3-3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2367.580023] usb 3-3.2: Product: USB PnP Audio Device
[ 2367.580027] usb 3-3.2: Manufacturer: C-Media Electronics Inc.
[ 2367.581679] input: C-Media Electronics Inc. USB PnP Audio Device as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.2/3-3.2:1.2/0003:0D8C:0132.0004/input/input18
[ 2367.581999] hid-generic 0003:0D8C:0132.0004: input,hidraw3: USB HID v1.11 Device [C-Media Electronics Inc. USB PnP Audio Device] on usb-0000:00:14.0-3.2/input2
[ 2367.913280] usbcore: registered new interface driver snd-usb-audio

这里可以看到其驱动程序为snd-usb-audio,依据这个关键词在内核中查找到如下内容:

tony@tony-E431:~/linux-3.4.y$ grep "registered new interface driver" ./ -rn
Binary file ./vmlinux.o matches
Binary file ./.tmp_vmlinux1 matches
Binary file ./.tmp_vmlinux2 matches
Binary file ./drivers/built-in.o matches
Binary file ./drivers/usb/built-in.o matches
Binary file ./drivers/usb/core/built-in.o matches
./drivers/usb/core/driver.c:865:    pr_info("%s: registered new interface driver %s\n",
Binary file ./drivers/usb/core/driver.o matches
Binary file ./drivers/usb/core/usbcore.o matches
Binary file ./arch/arm/boot/Image matches
Binary file ./vmlinux matches
tony@tony-E431:~/linux-3.4.y$ 

以及

// file: linux-3.4.y/sound/usb/card.c
/*
 * entry point for linux usb interface
 */

static struct usb_driver usb_audio_driver = {
    .name =     "snd-usb-audio",
    .probe =    usb_audio_probe,
    .disconnect =   usb_audio_disconnect,
    .suspend =  usb_audio_suspend,
    .resume =   usb_audio_resume,
    .id_table = usb_audio_ids,
    .supports_autosuspend = 1,
};

根据probe方法snd_usb_audio_probe调用了snd_usb_apply_boot_quirksnd_card_register,查到了

// linux-3.4.y/sound/usb/card.c
/*
 * new 2.5 USB kernel API
 */
static int usb_audio_probe(struct usb_interface *intf,
               const struct usb_device_id *id)
{
    struct snd_usb_audio *chip;
    chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
    if (chip) {
        usb_set_intfdata(intf, chip);
        return 0;
    } else
        return -EIO;
}


// linux-3.4.y/sound/usb/quirks.c
int snd_usb_apply_boot_quirk(struct usb_device *dev,
                 struct usb_interface *intf,
                 const struct snd_usb_audio_quirk *quirk)
{
    u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
            le16_to_cpu(dev->descriptor.idProduct));

    switch (id) {
    case USB_ID(0x041e, 0x3000):
        /* SB Extigy needs special boot-up sequence */
        /* if more models come, this will go to the quirk list. */
        return snd_usb_extigy_boot_quirk(dev, intf);

    case USB_ID(0x041e, 0x3020):
        /* SB Audigy 2 NX needs its own boot-up magic, too */
        return snd_usb_audigy2nx_boot_quirk(dev);

    case USB_ID(0x10f5, 0x0200):
        /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
        return snd_usb_cm106_boot_quirk(dev);

    case USB_ID(0x0d8c, 0x0102):
        /* C-Media CM6206 / CM106-Like Sound Device */
    case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
        return snd_usb_cm6206_boot_quirk(dev);

    case USB_ID(0x133e, 0x0815):
        /* Access Music VirusTI Desktop */
        return snd_usb_accessmusic_boot_quirk(dev);

    case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
    case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
    case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
        return snd_usb_nativeinstruments_boot_quirk(dev);
    case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
        return snd_usb_fasttrackpro_boot_quirk(dev);
    }

    return 0;
}

snd_usb_audio_probe

/*
 * probe the active usb device
 *
 * note that this can be called multiple times per a device, when it
 * includes multiple audio control interfaces.
 *
 * thus we check the usb device pointer and creates the card instance
 * only at the first time.  the successive calls of this function will
 * append the pcm interface to the corresponding card.
 */
static struct snd_usb_audio *
snd_usb_audio_probe(struct usb_device *dev,
            struct usb_interface *intf,
            const struct usb_device_id *usb_id)
{
    const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
    int i, err;
    struct snd_usb_audio *chip;
    struct usb_host_interface *alts;
    int ifnum;
    u32 id;

    alts = &intf->altsetting[0];
    ifnum = get_iface_desc(alts)->bInterfaceNumber;
    id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
            le16_to_cpu(dev->descriptor.idProduct));
    if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
        goto __err_val;

    if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
        goto __err_val;

    /*
     * found a config.  now register to ALSA
     */

    /* check whether it's already registered */
    chip = NULL;
    mutex_lock(&register_mutex);
    for (i = 0; i < SNDRV_CARDS; i++) {
        if (usb_chip[i] && usb_chip[i]->dev == dev) {
            if (usb_chip[i]->shutdown) {
                snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
                goto __error;
            }
            chip = usb_chip[i];
            chip->probing = 1;
            break;
        }
    }
    if (! chip) {
        /* it's a fresh one.
         * now look for an empty slot and create a new card instance
         */
        for (i = 0; i < SNDRV_CARDS; i++)
            if (enable[i] && ! usb_chip[i] &&
                (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
                (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
                if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
                    goto __error;
                }
                snd_card_set_dev(chip->card, &intf->dev);
                chip->pm_intf = intf;
                break;
            }
        if (!chip) {
            printk(KERN_ERR "no available usb audio device\n");
            goto __error;
        }
    }

    /*
     * For devices with more than one control interface, we assume the
     * first contains the audio controls. We might need a more specific
     * check here in the future.
     */
    if (!chip->ctrl_intf)
        chip->ctrl_intf = alts;

    chip->txfr_quirk = 0;
    err = 1; /* continue */
    if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
        /* need some special handlings */
        if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
            goto __error;
    }

    if (err > 0) {
        /* create normal USB audio interfaces */
        if (snd_usb_create_streams(chip, ifnum) < 0 ||
            snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
            goto __error;
        }
    }

    /* we are allowed to call snd_card_register() many times */
    if (snd_card_register(chip->card) < 0) {
        goto __error;
    }

    usb_chip[chip->index] = chip;
    chip->num_interfaces++;
    chip->probing = 0;
    mutex_unlock(&register_mutex);
    return chip;

 __error:
    if (chip) {
        if (!chip->num_interfaces)
            snd_card_free(chip->card);
        chip->probing = 0;
    }
    mutex_unlock(&register_mutex);
 __err_val:
    return NULL;
}

probe依次调用了:

snd_usb_apply_boot_quirk
snd_usb_audio_create
snd_usb_create_quirk
snd_usb_create_streams
 snd_usb_create_stream
  snd_usb_parse_audio_interface 这里根据usb的信息解析成pcm参数(如声道数量,采样率等等)

snd_usb_create_mixer
snd_card_register
// linux-3.4.y/sound/core/init.c
snd_card_register调用了init_info_for_card以及snd_device_register_all。

打开DEBUG后

<6>[   58.704000] usb 1-1.1: new full-speed USB device number 5 using nxp-ehci
<6>[   58.804000] usb 1-1.1: New USB device found, idVendor=0d8c, idProduct=0132
<6>[   58.812000] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
<6>[   58.820000] usb 1-1.1: Product: USB PnP Audio Device
<6>[   58.824000] usb 1-1.1: Manufacturer: C-Media Electronics Inc.
<6>[   58.832000] ALSA sound/usb/stream.c:438 5:1:1: add audio endpoint 0x82
<6>[   58.840000] ALSA sound/usb/stream.c:438 5:1:2: add audio endpoint 0x82
<6>[   58.848000] ALSA sound/usb/mixer.c:1214 [10] FU [Mic Capture Switch] ch = 1, val = 0/1/1
<3>[   58.856000] ALSA sound/usb/mixer.c:868 10:0: cannot get min/max values for control 2 (id 10)
<6>[   58.864000] ALSA sound/usb/mixer.c:1214 [10] FU [Mic Capture Volume] ch = 2, val = 0/1/1
<3>[   58.876000] ALSA sound/usb/mixer.c:868 10:0: cannot get min/max values for control 2 (id 10)
<6>[   58.884000] input: C-Media Electronics Inc. USB PnP Audio Device as /devices/platform/nxp-ehci/usb1/1-1/1-1.1/1-1.1:1.2/input/input6
<6>[   58.896000] generic-usb 0003:0D8C:0132.0003: input,hidraw0: USB HID v1.11 Device [C-Media Electronics Inc. USB PnP Audio Device] on usb-nxp-ehci-1.1/input2
Bus 003 Device 019: ID 0d8c:0132 C-Media Electronics, Inc. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        16
  idVendor           0x0d8c C-Media Electronics, Inc.
  idProduct          0x0132 
  bcdDevice            1.00
  iManufacturer           1 C-Media Electronics Inc.
  iProduct                2 USB PnP Audio Device
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          221
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol      0 
      iInterface              0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength           47
        bInCollection           1
        baInterfaceNr( 0)       1
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             2
        wTerminalType      0x0201 Microphone
        bAssocTerminal          0
        bNrChannels             2
        wChannelConfig     0x0003
          Left Front (L)
          Right Front (R)
        iChannelNames           0 
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             7
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               8
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      5 (SELECTOR_UNIT)
        bUnitID                 8
        bNrInPins               1
        baSource( 0)           10
        iSelector               0 
      AudioControl Interface Descriptor:
        bLength                10
        bDescriptorType        36
        bDescriptorSubtype      6 (FEATURE_UNIT)
        bUnitID                10
        bSourceID               2
        bControlSize            1
        bmaControls( 0)      0x01
          Mute Control
        bmaControls( 1)      0x02
          Volume Control
        bmaControls( 2)      0x02
          Volume Control
        iFeature                0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol      0 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           7
        bDelay                  1 frames
        wFormatTag              1 PCM
      AudioStreaming Interface Descriptor:
        bLength                29
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bNrChannels             1
        bSubframeSize           2
        bBitResolution         16
        bSamFreqType            7 Discrete
        tSamFreq[ 0]         8000
        tSamFreq[ 1]        11025
        tSamFreq[ 2]        16000
        tSamFreq[ 3]        22050
        tSamFreq[ 4]        32000
        tSamFreq[ 5]        44100
        tSamFreq[ 6]        48000
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0064  1x 100 bytes
        bInterval               1
        bRefresh                0
        bSynchAddress           0
        AudioControl Endpoint Descriptor:
          bLength                 7
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x01
            Sampling Frequency
          bLockDelayUnits         0 Undefined
          wLockDelay              0 Undefined
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           7
        bDelay                  1 frames
        wFormatTag              1 PCM
      AudioStreaming Interface Descriptor:
        bLength                29
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bNrChannels             2
        bSubframeSize           2
        bBitResolution         16
        bSamFreqType            7 Discrete
        tSamFreq[ 0]         8000
        tSamFreq[ 1]        11025
        tSamFreq[ 2]        16000
        tSamFreq[ 3]        22050
        tSamFreq[ 4]        32000
        tSamFreq[ 5]        44100
        tSamFreq[ 6]        48000
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x00c8  1x 200 bytes
        bInterval               1
        bRefresh                0
        bSynchAddress           0
        AudioControl Endpoint Descriptor:
          bLength                 7
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x01
            Sampling Frequency
          bLockDelayUnits         0 Undefined
          wLockDelay              0 Undefined
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      26
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)

总结:

UAC设备的参数是通过USB描述符确定的。比如声道bNrChannels位深bBitResolution采样率bSamFreqType。截取其中一段说明:

bNrChannels             1
bSubframeSize           2
bBitResolution         16
bSamFreqType            7 Discrete
tSamFreq[ 0]         8000
tSamFreq[ 1]        11025
tSamFreq[ 2]        16000
tSamFreq[ 3]        22050
tSamFreq[ 4]        32000
tSamFreq[ 5]        44100
tSamFreq[ 6]        48000

声道1,位深16,波特率8000~48000。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kangear/article/details/78485994

智能推荐

Cocos2d-x 窗口大小调整_cocos2dx设置窗口大小-程序员宅基地

文章浏览阅读4.2k次。打开src目录下的AppDelegate.cpp文件,若无修改则在第45行处找到全局声明的Size变量,修改`designResolutionSize`中的大小即可。_cocos2dx设置窗口大小

springboot接收枚举值的默认方式_springboot get请求怎么接收前端传递的枚举数字-程序员宅基地

文章浏览阅读1.6k次。测试代码:@PostMapping() public void test(@RequestBody Student student){ System.out.println(student.getLover().name()); }class Student{ private Lover lover; public Lover getLover() { return lover; } public void setLover_springboot get请求怎么接收前端传递的枚举数字

【数学建模笔记】【第七讲】多元线性回归分析(二):虚拟变量的设置以及交互项的解释,以及基于Stata的普通回归与标准化回归分析实例_stata两个虚拟变量的交互项-程序员宅基地

文章浏览阅读1.5w次,点赞24次,收藏120次。简单来说就是去量纲后的回归(因为你要比较不同变量之间的显著性的大小,那么带着量纲怎么比,所以先把量纲去掉,然后再比较)官话:为了更为精准的研究影响评价量的重要因素(去除量纲的影响),我们可考虑使用标准化回归系数。_stata两个虚拟变量的交互项

mysql-程序员宅基地

文章浏览阅读203次。有时候安装mysql后使用mysql命令时报错 Can't connect to MySQL server on localhost (10061),或者用net start mysql 时报服务名无效,一般是因为mysql服务没有启动。这时候可以用管理身份运行cmd.exe(注意必须是管理..._c:\program files\mysql\mysql server 5.6\bin>mysqld --install install/remove

亚信科技java笔试题答案_亚信笔试题卷以及答案.docx-程序员宅基地

文章浏览阅读6.2k次,点赞3次,收藏44次。亚信联创科技校园招聘B 卷考试时间60_分钟 _考试方式(闭)卷(本试卷满分 100 分,答案请写在答题卡上)请不要在问卷上答题或涂改,笔试结束后请务必交回试卷部分内容分值备注一、计算机基础40分C/C++语言基础40分技能部分二、二选一JAVA 语言基础40分三、数据库20分总分100 分第一部分——计算机基础一、选择题(每题 2 分,总分 40分)1.CPU 状态分为目态和管态两种..._亚信科技java实习笔试题

三线城市程序员的薪资待遇怎么样?我分享提高java技术水平的几个方法_三线城市学java-程序员宅基地

文章浏览阅读1.3k次。3年对一个程序员来说是非常重要的。像我自己本身就是做程序员的,目前的薪资待遇是13K左右,虽然在我所在的公司不是最高的,但在所在的这个城市的消费水平来说,除了日常的开支,包括房租、水电、伙食、人际交往等费用之外,还能留下一部分闲钱自己存起来。不同城市的薪资待遇是不一样的,这主要是由于当地的消费水平和经济发展水平不同,所以如果你想要更高的薪资待遇,就要考虑在一线城市或者经济发达的城市工作。一个有着丰富工作经验的程序员,他的技能水平、经验和能力都比没有经验的程序员更加出色,所以他们的薪资待遇也会更高一些。_三线城市学java

随便推点

恭迎万亿级营销(圈人)潇洒的迈入毫秒时代 - 万亿user_tags级实时推荐系统数据库设计...-程序员宅基地

文章浏览阅读418次。标签PostgreSQL , 标签 , 推荐系统 , 实时圈人 , 数组 , gin , gist , 索引 , rum , tsvector , tsquery , 万亿 , user , tag , 淘宝背景我们仅用了PostgreSQL的两个小特性,却解决了业务困扰已久的大问题。推荐系统是广告营销平台的奶牛,其核心是精准、实时、..._实时圈人

软件测试风险追踪表_软件测试风险管理表格-程序员宅基地

文章浏览阅读430次。软件测试风险追踪表风险追踪表 项目名称: 填制人: 编号 风险描述 影响 风险等级 发生的可能性 应对策略 状态 责任人 备注 ..._软件测试风险管理表格

AAC ADTS封装实现-程序员宅基地

文章浏览阅读1.2k次。一、AAC音频格式种类有哪些AAC音频格式是一种由MPEG-4标准定义的有损音频压缩格式。AAC包含两种格式 ADIF(Audio Data Interchange Format音频数据交换格式)和ADTS(Audio Data transport Stream音频数据传输流)。ADIF特点:可以确定的找到音视频数据的开始,不需要进行在音视频数据流中间开始的解码,它的解码必须在明确的定义开始。应用场景:常用在磁盘文件中。ADTS特点:具有同步字的比特流,解码可以在这个流中任何位置开始。类似于mp_aac adts

Unity基础概念_unity基本概念-程序员宅基地

文章浏览阅读213次。像要使用Resouce类,必须创建一个 Resouce 文件夹,然后把需要的资源放进去,才可以在代码中设置路径进行访问_unity基本概念

在gitlab中指定自定义 CI/CD 配置文件_gitlab配置cicd-程序员宅基地

文章浏览阅读2.4k次。指定自定义 CI/CD 配置文件,顾名思义就是在项目中指定文件来代替默认的.gitlab-ci.yml文件的方式来运行流水线。以往我们在使用流水线的时候,都是默认将.gitlab-ci.yml文件存在在项目的跟路径下,但是我们也可以指定备用文件名路径,或者不想在每个项目中来维护这个yml文件,那么通过自定义 CI/CD 配置文件便可以实现。_gitlab配置cicd

mysql出现#1063 - Incorrect column specifier for column 'id'的解决方法_sql 错误 [1063] [42000]: incorrect column specifier -程序员宅基地

文章浏览阅读1w次。出现这个表示如果设置了自动增长,字段类型应该设置为int整型。_sql 错误 [1063] [42000]: incorrect column specifier for column 'id' incorrec