android cdc 设备,x86 android 設備與外部硬體溝通研究 - cdc-acm.c (28/30)

本文对比分析了CDCserialdriver与Linux CDC-ACM模块在设置串口参数时的不同实现方式,包括波特率、数据位、停止位及校验位等配置细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天從 CDC serial driver 的 setParameters 部分下手,

private static final int SET_LINE_CODING = 0x20; // USB CDC 1.1 section 6.2

private static final int USB_RECIP_INTERFACE = 0x01;

private static final int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;

// UsbConstants.USB_TYPE_CLASS = 0x20

@Override

public void setParameters(int baudRate, int dataBits, int stopBits, int parity) {

byte stopBitsByte;

switch (stopBits) {

case STOPBITS_1: stopBitsByte = 0; break;

case STOPBITS_1_5: stopBitsByte = 1; break;

case STOPBITS_2: stopBitsByte = 2; break;

default: throw new IllegalArgumentException("Bad value for stopBits: " + stopBits);

}

byte parityBitesByte;

switch (parity) {

case PARITY_NONE: parityBitesByte = 0; break;

case PARITY_ODD: parityBitesByte = 1; break;

case PARITY_EVEN: parityBitesByte = 2; break;

case PARITY_MARK: parityBitesByte = 3; break;

case PARITY_SPACE: parityBitesByte = 4; break;

default: throw new IllegalArgumentException("Bad value for parity: " + parity);

}

byte[] msg = {

(byte) ( baudRate & 0xff),

(byte) ((baudRate >> 8 ) & 0xff),

(byte) ((baudRate >> 16) & 0xff),

(byte) ((baudRate >> 24) & 0xff),

stopBitsByte,

parityBitesByte,

(byte) dataBits}; // 共計 7 byte 的msg資料

sendAcmControlMessage(SET_LINE_CODING, 0, msg);

}

private int sendAcmControlMessage(int request, int value, byte[] buf) {

return mConnection.controlTransfer(

USB_RT_ACM, request, value, 0, buf, buf != null ? buf.length : 0, 5000);

}

上面是 CDC serial driver 的控制方式

下面是 Linux/drivers/usb/class/cdc-acm.c 針對 CDC 通訊控制中設定 serial port 參數的部分,我們先來看看有什麼不一樣 :

static void acm_tty_set_termios(struct tty_struct *tty,

struct ktermios *termios_old)

{

struct acm *acm = tty->driver_data;

struct ktermios *termios = &tty->termios;

struct usb_cdc_line_coding newline;

int newctrl = acm->ctrlout;

newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty)); // 轉換成 little endian binary (32bit)

newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;

newline.bParityType = termios->c_cflag & PARENB ?

(termios->c_cflag & PARODD ? 1 : 2) +

(termios->c_cflag & CMSPAR ? 2 : 0) : 0;

switch (termios->c_cflag & CSIZE) {

case CS5:

newline.bDataBits = 5;

break;

case CS6:

newline.bDataBits = 6;

break;

case CS7:

newline.bDataBits = 7;

break;

case CS8:

default:

newline.bDataBits = 8;

break;

}

/* FIXME: Needs to clear unsupported bits in the termios */

acm->clocal = ((termios->c_cflag & CLOCAL) != 0);

//這邊用到的 #define ACM_CTRL_DTR 0x01

if (!newline.dwDTERate) {

newline.dwDTERate = acm->line.dwDTERate;

newctrl &= ~ACM_CTRL_DTR; // ACM_CTRL_DTR 變成 0xFE 跟 newctrl 做 AND 運算

} else

newctrl |= ACM_CTRL_DTR; // 跟 newctrl 做 OR 運算

if (newctrl != acm->ctrlout)

acm_set_control(acm, acm->ctrlout = newctrl);

if (memcmp(&acm->line, &newline, sizeof newline)) {

memcpy(&acm->line, &newline, sizeof newline);

dev_dbg(&acm->control->dev, "%s - set line: %d %d %d %d\n",

__func__,

le32_to_cpu(newline.dwDTERate),

newline.bCharFormat, newline.bParityType,

newline.bDataBits);

acm_set_line(acm, &acm->line);

}

}

由上面可以看到他最後是交由

acm_set_control acm_set_line

送出控制指令,而上述這兩的 method 又全部把資料交到 acm_ctrl_msg( ) 這個 method 做分配。

而上述兩者 跟 acm_ctrl_msg 之間又做了那些動作呢? 我們留著明天在作進一步說明

我們明天見 :P

Ref :

結語:

有沒有發現

(byte) ( baudRate & 0xff),

(byte) ((baudRate >> 8 ) & 0xff),

(byte) ((baudRate >> 16) & 0xff),

(byte) ((baudRate >> 24) & 0xff),

newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty)); // 轉換成 little endian binary (32bit)

兩個好像結果不太一樣? 似乎可以從這邊下手研究兩者異同之處 :P

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值