分类: usb

  • Creating udev rule for USB DAC

    Target:

    Create a new udev rule which will:

    Stop the Jack Daemon if DAC power off

    Start the Jack Daemon if DAC power on

    Identify USB DAC Card:

    Power on USB DAC

    Check the name of USB DAC

    ls -l /proc/asound/
    lrwxrwxrwx 1 root root 5 11月 22 17:55 AUDIO -> card2
    dr-xr-xr-x 3 root root 0 11月 16 18:43 card0
    dr-xr-xr-x 4 root root 0 11月 16 18:43 card1
    dr-xr-xr-x 4 root root 0 11月 22 17:55 card2
    -r–r–r– 1 root root 0 11月 16 16:36 cards
    -r–r–r– 1 root root 0 11月 16 18:43 devices
    lrwxrwxrwx 1 root root 5 11月 16 18:43 Generic -> card0
    -r–r–r– 1 root root 0 11月 16 18:43 hwdep
    -r–r–r– 1 root root 0 11月 16 18:43 modules
    dr-xr-xr-x 2 root root 0 11月 16 18:43 oss
    -r–r–r– 1 root root 0 11月 16 18:43 pcm

    card2 is the name of DAC Card

    ls  /sys/class/sound
    card0  card2      controlC1  hwC0D0  pcmC0D3p  pcmC1D0p  pcmC2D0p
    card1  controlC0  controlC2  hwC1D0  pcmC1D0c  pcmC2D0c  timer
    
    
    

    Get the Attr List of card2

    udevadm info /sys/class/sound/card2
    P: /devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0/sound/card2
    L: 0
    E: DEVPATH=/devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0/sound/card2
    E: SUBSYSTEM=sound
    E: USEC_INITIALIZED=523137960408
    E: ID_PATH=pci-0000:00:12.0-usb-0:4:1.0
    E: ID_PATH_TAG=pci-0000_00_12_0-usb-0_4_1_0
    E: ID_FOR_SEAT=sound-pci-0000_00_12_0-usb-0_4_1_0
    E: SOUND_INITIALIZED=1
    E: ID_VENDOR_FROM_DATABASE=Actions Semiconductor Co., Ltd
    E: ID_VENDOR=ACTIONS
    E: ID_VENDOR_ENC=ACTIONS
    E: ID_VENDOR_ID=10d6
    E: ID_MODEL=USB_AUDIO
    E: ID_MODEL_ENC=USB\x20AUDIO
    E: ID_MODEL_ID=dd01
    E: ID_REVISION=0100
    E: ID_SERIAL=ACTIONS_USB_AUDIO_4512482ADF0FEEEE
    E: ID_SERIAL_SHORT=4512482ADF0FEEEE
    E: ID_TYPE=audio
    E: ID_BUS=usb
    E: ID_USB_INTERFACES=:010100:010200:030000:
    E: ID_USB_INTERFACE_NUM=00
    E: ID_USB_DRIVER=snd-usb-audio
    E: ID_ID=usb-ACTIONS_USB_AUDIO_4512482ADF0FEEEE-00
    E: SYSTEMD_WANTS=sound.target
    E: TAGS=:systemd:seat:
    
    udevadm info --path=/sys/class/sound/card2 --attribute-walk
    
    looking at device '/devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0/sound/card2':
        KERNEL=="card2"
        SUBSYSTEM=="sound"
        DRIVER==""
        ATTR{number}=="2"
        ATTR{id}=="AUDIO"
    
      looking at parent device '/devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0':
        KERNELS=="2-4:1.0"
        SUBSYSTEMS=="usb"
        DRIVERS=="snd-usb-audio"
        ATTRS{supports_autosuspend}=="1"
        ATTRS{bInterfaceProtocol}=="00"
        ATTRS{authorized}=="1"
        ATTRS{bNumEndpoints}=="00"
        ATTRS{bInterfaceClass}=="01"
        ATTRS{bInterfaceNumber}=="00"
        ATTRS{bInterfaceSubClass}=="01"
        ATTRS{bAlternateSetting}==" 0"
    
      looking at parent device '/devices/pci0000:00/0000:00:12.0/usb2/2-4':
        KERNELS=="2-4"
        SUBSYSTEMS=="usb"
        DRIVERS=="usb"
        ATTRS{devpath}=="4"
        ATTRS{bDeviceProtocol}=="00"
        ATTRS{bmAttributes}=="c0"
        ATTRS{quirks}=="0x0"
        ATTRS{tx_lanes}=="1"
        ATTRS{product}=="USB AUDIO"
        ATTRS{busnum}=="2"
        ATTRS{bcdDevice}=="0100"
        ATTRS{bNumConfigurations}=="1"
        ATTRS{manufacturer}=="ACTIONS"
        ATTRS{bNumInterfaces}==" 4"
        ATTRS{bDeviceClass}=="00"
        ATTRS{configuration}==""
        ATTRS{maxchild}=="0"
        ATTRS{devnum}=="20"
        ATTRS{serial}=="4512482ADF0FEEEE"
        ATTRS{bMaxPower}=="300mA"
        ATTRS{idVendor}=="10d6"
        ATTRS{bDeviceSubClass}=="00"
        ATTRS{urbnum}=="25748"
        ATTRS{idProduct}=="dd01"
        ATTRS{version}==" 1.00"
        ATTRS{removable}=="unknown"
        ATTRS{authorized}=="1"
        ATTRS{bMaxPacketSize0}=="64"
        ATTRS{speed}=="12"
        ATTRS{rx_lanes}=="1"
        ATTRS{lATTRS{avoid_reset_quirk}=="0"
        ATTRS{bConfigurationValue}=="1"
    
      looking at parent device '/devices/pci0000:00/0000:00:12.0/usb2':
        KERNELS=="usb2"
        SUBSYSTEMS=="usb"DRIVERS=="usb"
        ATTRS{configuration}==""
        ATTRS{idProduct}=="0001"
        ATTRS{version}==" 1.10"
        ATTRS{tx_lanes}=="1"
        ATTRS{bNumInterfaces}==" 1"
        ATTRS{bDeviceClass}=="09"
        ATTRS{removable}=="unknown"
        ATTRS{authorized_default}=="1"
        ATTRS{bDeviceSubClass}=="00"
        ATTRS{interface_authorized_default}=="1"
        ATTRS{busnum}=="2"
        ATTRS{bDeviceProtocol}=="00"
        ATTRS{bMaxPower}=="0mA"
        ATTRS{quirks}=="0x0"
        ATTRS{speed}=="12"
        ATTRS{bcdDevice}=="0419"
        ATTRS{maxchild}=="5"
        ATTRS{idVendor}=="1d6b"
        ATTRS{devpath}=="0"
        ATTRS{manufacturer}=="Linux 4.19.0-9-amd64 ohci_hcd"
        ATTRS{avoid_reset_quirk}=="0"
        ATTRS{bMaxPacketSize0}=="64"
        ATTRS{rx_lanes}=="1"
        ATTRS{bmAttributes}=="e0"
        ATTRS{urbnum}=="511"
        ATTRS{bNumConfigurations}=="1"
        ATTRS{product}=="OHCI PCI host controller"
        ATTRS{serial}=="0000:00:12.0"
        ATTRS{bConfigurationValue}=="1"
        ATTRS{ltm_capable}=="no"
        ATTRS{devnum}=="1"
        ATTRS{authorized}=="1"
    
        
    
    # Get kernel prop
    udevadm monitor --kernel --property --subsystem-match=usb
    monitor will print the received events for:
    KERNEL - the kernel uevent
    
    KERNEL[1083.319560] add      /devices/pci0000:00/0000:00:12.0/usb2/2-4 (usb)
    ACTION=add
    DEVPATH=/devices/pci0000:00/0000:00:12.0/usb2/2-4
    SUBSYSTEM=usb
    DEVNAME=/dev/bus/usb/002/002
    DEVTYPE=usb_device
    PRODUCT=10d6/dd01/100
    TYPE=0/0/0
    BUSNUM=002
    DEVNUM=002
    SEQNUM=2112
    MAJOR=189
    MINOR=129

    Write your udev rule based on selected attrs

    cat /opt/local/libexec/udev/rules.d/99-AD-86d.rules

    ACTION=="add",SUBSYSTEM=="sound",ATTR{id}=="AUDIO",RUN+="/opt/local/bin/add_ad_86d.sh"
    ACTION=="remove",SUBSYSTEM=="usb",ATTRS{idVendor}=="10d6",ATTRS{idProduct}=="dd01",RUN+="/opt/local/bin/remove_ad_86d.sh"
  • Config NUT for CyberPower VAL600 UPS with TrueNAS Core 12.0-U6

         Master NAS,   PC/TrueNAS Core attached with UPS USB Cable

    • Step 1:   Power on the Cyberpower VAL600 & plug the USB cable into TrueNas system

    • Step 2:   Find out UPS port information, say ugen3.0

    TrueNAS Web Gui / System/Advance/Show Console Message

    • Step 3:   Config with the UPS

    TrueNAS Web Gui / Services/UPS

    UPS Mode:  Master

    Remote Monitor:    Enable

    Monitor User:      upsmon

    Monitor Password:   Your Passwrod

    Driver:  Cyber Power System ups2 Value 600E USB

    Port or Hostname:   /dev/ugen0.3auto

    Shutdown Command:  shutdown -h now

    • Step 4:  Check with command upsc ups@localhost

    TrueNAS Web Gui / Shell

    • Step 5:   Verify shutdown command is working by turn off the AC power supplier of UPS

         Slave NAS:    PC/TrueNAS Core not  attached with UPS USB Cable

    • Step 6:Config TrueNAS PC as NUT Salve

    UPS Mode:     Slave

    Remote Host:   IP of Master NAS

    Remote Port:    3493

    Port or Hostname:  auto

    Monitor User:     upsmon

    Monitor Password:    Same as Master UPS

    Shutdown command:     shutdown -h now

         Slave Linux:    PC/Linux not  attached with UPS USB Cable

    • Step 7: Config Linux PC as NUT slave

    Install NUT

    Config upsmon as following

    POWERDOWNFLAG /etc/nut/killpower
                   MONITOR ups@MASTER_UPS_IP 1  upsmon YOUR_PASSWORD  slave
                   MINSUPPLIES 1
                   SHUTDOWNCMD “/sbin/shutdown -h +0”

                   POLLFREQ 5
                   POLLFREQALERT 5
                   HOSTSYNC 15
                   DEADTIME 15
                   RBWARNTIME 43200
                   NOCOMMWARNTIME 300
                   FINALDELAY 5

    Launch upsmon service

    Note:

    TrueNAS Core only support  UPS On Battery Action

  • Understanding Flash: Unpredictable Write Performance

    https://flashdba.com/2014/12/10/understanding-flash-unpredictable-write-performance/

    fast-page-slow-page

    I’ve spent a lot of time in this blog series talking about the challenges involved in using flash, such as the way that pages have to be erased before they are written and the restriction that erase operations take place on a whole block. I also described the problem of erase operations being slow in comparison to reads and writes – and the resulting processes we have to put in place to manage that problem (i.e. garbage collection) . And most recently I covered the way that garbage collection can result in unpredictable performance.

    But so far we’ve always worked under the assumption that reads and writes to NAND flash have the same predictably low latency. This post is all about bursting that particular bubble…

    Programming NAND Flash: A Quick Recap

    You might remember from my post on the subject of SLC, MLC and TLC that I used the analogy of electrons in a bucket to explain the programming of NAND flash cells:

    slc-mlc-tlc-buckets

    I’d now like to change that analogy slightly, so I’m asking you to consider that you have an empty bucket and a powerful hose pipe. You can turn the hose on and off whenever you want to fill the bucket up, but you cannot empty water out of the bucket unless you completely empty it. Ok, now we’re ready.

    For SLC we simply say that an empty bucket denotes a binary value of 1 and a full bucket denotes binary 0. Thus when you want to program an SLC bucket you simply let rip with your hose pipe until it’s full. No need to measure whether the water line is above or below the halfway point (the threshold), just go crazy. Blam! That was quick, wasn’t it?

    For MLC however, we have three thresholds – and again we start with the bucket empty (denoting binary 11). Now, if I want to program the binary values of 01 or 10 in the above diagram I need to be careful, because if I overfill I cannot go backwards. bucketI therefore have to fill a little, test, fill some more, test and so on. It’s actually kind of tricky – and it’s one of the reasons that MLC is both slower than SLC and has a lower wear limit. But here’s the thing… if I want to program my MLC to have a value of binary 00 in the above diagram, I have no such problems because (as with SLC) I can just open the hose up on full power and hit it.

    What we’ve demonstrated here is that programming a full charge value to an MLC cell is faster than programming any of the other available values. With a little more thought you can probably see that TLC has this problem to an even worse degree – imagine how accurate you need to be with that hose when you have seven thresholds to consider!

    One final thought. We read and write (program) to NAND flash at the page level, which means we are accessing a large collection of cells as if they are one single unit. What are the chances that when we write a page we will want every cell to be programmed to full charge? I’d say extremely low. So even if some cells are programmed “the fast way”, just one “slow” program operation to a non-full-charge threshold will slow the whole program operation down. In other words, I can hardly ever take advantage of the faster latency experienced by full charge operations.

    Fast Pages and Slow Pages

    The majority of flash seen in the data centre today is MLC, which contains two bits per cell. Is there a way to program MLC in order that, at least sometimes, I can program at the faster speeds of a full-charge operation?

    mlc-bucket-msb-lsbLet’s take my MLC bucket diagram from above and remap the binary values like the diagram on the left. What have I changed? Well most importantly I’ve reordered the binary values that correspond to each voltage level; empty charge still represents 11 but now full charge represents 10. Why did I do that?

    The clue is the dotted line separating the most significant bit (MSB) and the least significant bit (LSB) of each value. Let’s consider two NAND flash pages, each comprising many cells. Now, instead of having both bits from each MLC cell used for a single page, I will put all of the MSB values into one page and call that the slow page. Then I’ll take all of the LSB values and put that into the other page and call that the fast page.

    Why did I do this? Well, consider what happens when I want to program my fast page: in the diagram you can see that it’s possible to turn the LSB value from one to zero by programming it to either of the two higher thresholds… including the full charge threshold. In fact, if you forget about the MSB side for a second, the LSB side very similar to an SLC cell – and therefore performs like one.

    The slow page, meanwhile, has to be programmed just like we discussed previously and therefore sees no benefit from this configuration. What’s more, if I want to program the fast page in this way I can’t store data in the corresponding slow page (the one with the matching MSBs) because every time I program a full charge to this cell the MSB ends up with a value of one. Also, when I want to program the slow page I have to erase the whole block first and then program both pages together (slowly!).

    It’s kind of complicated… but potentially we now have the option to program certain MLC pages using a faster operation, with the trade-off that other pages will be affected as a result.

    Getting To The Point

    I should point out here that this is pretty low-level stuff which requires direct access to NAND flash (rather than via an SSD for example). It may also require a working relationship with the flash manufacturer. So why am I mentioning it here?

    Well first of all I want to show you that NAND flash is actually a difficult and unpredictable medium on which to store data – unless you truly understand how it works and make allowances for its behaviour. NAND-flashThis is one of the reasons why so many flash products exist on the market with completely differing performance characteristics.

    When you look at the datasheet for an MLC flash product and you see write / program times shown as, for example, 1.4 milliseconds it’s important to realise that this is the average of its bi-modal behaviour. Fast (LSB) pages may well have program times of 300 microseconds, while slow (MSB) pages might take up to 2.5 milliseconds.

    Secondly, I want to point out that direct access to the flash (instead of via an SSD) brings certain benefits. What if, in my all flash array, I send all inbound user writes to fast pages but then, later on during garbage collection, I move data to be stored in slow pages? If I could do that, I’d effectively be hiding much of the slower performance of MLC writes from my users. And that would be a wonderful thing…

    …which is why, at Violin, we’ve been doing it for years

  • Total Phase, Inc & Aardvark

    Total Phase:   http://www.totalphase.com

    Founded in 2001, Total Phase is dedicated to creating simple, affordable, and powerful development tools for the embedded systems engineer.

     

    Aardvark:

    Aardvark I2C/SPI主机适配器是一个通过USB界面的快速,强大的I2C及SPI总线主机适配器

  • Install dd-wrt onto wndr3700 v4

    Hardware:                       2.4G/5G Wifi,  USB,  128MB RAM/128B NAND

    Version Installed:             DD-WRT v24-sp2 (01/04/15) std – build 25760

    Feature Integrated:

    FreeRadius,                   PPPoE Server / Relay
    PPTP Server / Client,     OpenVPN Server / Client
    USB:                               Printer,  Storage,     USB Over IP
    FTP Server,                    DLNA Server,          Samba Server
    SIP Proxy,                       Http Server (Lighttpd)
    Mikrotik MAC Telnet,      IP over DNS Tunneling (nstx)
    SNMP,                            VNC Repeat,          Zabbix client

     

    Add 32G USB key with following partition setting:

    Part1 LABEL=”EXEC”   SIZE=2G   TYPE=”ext4″ With Journal

    Part2  LABEL=”DATA”   SIZE=30G  TYPE=”ext4″ Without Journal

     

    SSH into the route and execute:

    umount /dev/sda1
    umount /dev/sda2
    mkdir /mnt/exec
    mkdir /mnt/data
    mount /dev/sda1 /mnt/exec
    mount /dev/sda2 /mnt/data
    cp -r -p  /opt /mnt/exec/
    cp -r -p  /etc /mnt/exec/
    cp -r -p /www /mnt/exec/
    cp -r -p /jffs /mnt/exec/

    Startup Script:
    umount /dev/sda1
    umount /dev/sda2
    cp -r -p /tmp /tmp/mnt
    mkdir /mnt/exec
    mkdir /mnt/data
    mount /dev/sda1 /mnt/exec
    mount /dev/sda2 /mnt/data
    mount –bind /mnt/exec/www /www
    mount –bind /mnt/exec/opt /opt
    mount –bind /mnt/exec/etc /etc
    mount –bind /mnt/exec/jffs /jffs
    mv /tmp/mnt/tmp /mnt/exec/
    mount –bind /mnt/exec/tmp /tmp