1. 程式人生 > >第31章 OpenWrt 4G撥號上網(Ubuntu12.04+Openwrt15.05)

第31章 OpenWrt 4G撥號上網(Ubuntu12.04+Openwrt15.05)

開發環境:
開發板:RT5350
4G 模組:QUECTEL EC25
OpenWrt 原始碼版本:Chaos_Calmer
參考文件:Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.7.pdf

31.1 USB Serial驅動

首先修改核心,核心檔案在chaos_calmer/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_rt305x/linux-3.18.109目錄下,需要事先編譯過系統。當模組連線到USB序列驅動時,驅動程式將在目錄/dev中建立裝置檔案,
ttyUSB0/ttyUSB1/ttyUSB2…
接下來就是講解如何移植USB Serial。

31.1.1增加PID&VID

要想識別模組,客戶應該在下面新增模組維和PID資訊
File: [KERNEL]/drivers/usb/serial/option.c

static const struct usb_device_id option_ids[] = {
#if 1 //Added by Quectel
{ USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
{ USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */
{ USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */ { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */ { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */ { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */ { USB_DEVICE(0x2C7C, 0x0435
) }, /* Quectel AG35 */ #endif

31.1.2新增零包處理

根據USB協議的要求,客戶需要新增處理零資料包的機制。
For Linux Kernel Version newer than 2.6.34:
File: [KERNEL]/drivers/usb/serial/usb_wwan.c

static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,
int dir, void *ctx, char *buf, int len,void (*callback) (struct urb *))
{
……
usb_fill_bulk_urb(urb, serial->dev,
usb_sndbulkpipe(serial->dev, endpoint) | dir,
buf, len, callback, ctx);
#if 1 //Added by Quectel for zero packet
if (dir == USB_DIR_OUT) {
struct usb_device_descriptor *desc = &serial->dev->descriptor;
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
urb->transfer_flags |= URB_ZERO_PACKET;
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
urb->transfer_flags |= URB_ZERO_PACKET;
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
urb->transfer_flags |= URB_ZERO_PACKET;
if (desc->idVendor == cpu_to_le16(0x2C7C))
urb->transfer_flags |= URB_ZERO_PACKET;
}
#endif
return urb;
}

31.1.3增加休眠後喚醒介面

當MCU進入暫停/休眠模式時,一些USB主機控制器/USB集線器將失去電源或重新設定,並且在MCU退出暫停/休眠模式後,它們不能恢復USB裝置。請新增以下語句以啟用重新設定恢復過程。
For Linux kernel version higher than 3.4:
File: [KERNEL]/drivers/usb/serial/option.c

static struct usb_serial_driver option_1port_device = {
……
#ifdef CONFIG_PM
.suspend = usb_wwan_suspend,
.resume = usb_wwan_resume,
#if 1 //Added by Quectel
.reset_resume = usb_wwan_resume,
#endif
#endif
};

31.1.4使用 GobiNet or QMI WWAN

如果客戶使用ucxx/ec2x/egxx/EP06/EM06/BG96/AG35,並要求GobiNet或QMI WWAN,請新增以下語句,以防止這些模組介面4被用作USB序列裝置。
For Linux Kernel Version newer than 2.6.30:
File: [KERNEL]/drivers/usb/serial/option.c

static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) {
struct usb_wwan_intf_private *data;
……
#if 1 //Added by Quectel
//Quectel UC20's interface 4 can be used as USB network device
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
//Quectel EC20's interface 4 can be used as USB network device
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&
serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
//Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as USB network device
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)
&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
return -ENODEV;
#endif
/* Store device id so we can use it during attach. */
usb_set_serial_data(serial, (void *)id);
return 0;
}

31.2 QMI WWAN驅動

31.2.1. Add VID and PID

QMI WWAN driver source file is [KERNEL]/drivers/net/usb/qmi_wwan.c.
File: [KERNEL]/drivers/net/usb/qmi_wwan.c

static const struct usb_device_id products[] = {
#if 1 //Added by Quectel
#ifndef QMI_FIXED_INTF
/* map QMI/wwan function by a fixed interface number */
#define QMI_FIXED_INTF(vend, prod, num) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_INFO, \
.idVendor = vend, \
.idProduct = prod, \
.bInterfaceClass = 0xff, \
.bInterfaceSubClass = 0xff, \
.bInterfaceProtocol = 0xff, \
.driver_info = (unsigned long)&qmi_wwan_force_int##num,
#endif
{ QMI_FIXED_INTF(0x05C6, 0x9003, 4) }, /* Quectel UC20 */
{ QMI_FIXED_INTF(0x2C7C, 0x0125, 4) }, /* Quectel EC25 */
{ QMI_FIXED_INTF(0x2C7C, 0x0121, 4) }, /* Quectel EC21 */
{ QMI_FIXED_INTF(0x05C6, 0x9215, 4) }, /* Quectel EC20 */
{ QMI_FIXED_INTF(0x2C7C, 0x0191, 4) }, /* Quectel EG91 */
{ QMI_FIXED_INTF(0x2C7C, 0x0195, 4) }, /* Quectel EG95 */
{ QMI_FIXED_INTF(0x2C7C, 0x0306, 4) }, /* Quectel EG06/EP06/EM06 */
{ QMI_FIXED_INTF(0x2C7C, 0x0296, 4) }, /* Quectel BG96 */
{ QMI_FIXED_INTF(0x2C7C, 0x0435, 4) }, /* Quectel AG35 */
#endif

31.2.2 Add Support for Raw IP Mode

File: [KERNEL]/drivers/net/usb/qmi_wwan.c

#include <linux/usb/usbnet.h>
#include <linux/usb/cdc-wdm.h>
#if 1 //Added by Quectel
#include <linux/etherdevice.h>
struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))
return skb;
// Skip Ethernet header from message
if (skb_pull(skb, ETH_HLEN)) {
return skb;
} else {
dev_err(&dev->intf->dev, "Packet Dropped ");
}
// Filter the packet out, release it
dev_kfree_skb_any(skb);
return NULL;
}
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 ))
static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
__be16 proto;
if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))
return 1;
/* This check is no longer done by usbnet */
if (skb->len < dev->net->hard_header_len)
return 0;
switch (skb->data[0] & 0xf0) {
case 0x40:
proto = htons(ETH_P_IP);
break;
case 0x60:
proto = htons(ETH_P_IPV6);
break;
case 0x00:
if (is_multicast_ether_addr(skb->data))
return 1;
/* possibly bogus destination - rewrite just in case */
skb_reset_mac_header(skb);
goto fix_dest;
default:
/* pass along other packets without modifications */
return 1;
}
if (skb_headroom(skb) < ETH_HLEN)
return 0;
skb_push(skb, ETH_HLEN);
skb_reset_mac_header(skb);
eth_hdr(skb)->h_proto = proto;
memset(eth_hdr(skb)->h_source, 0, ETH_ALEN);
fix_dest:
memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
return 1;
}
/* very simplistic detection of IPv4 or IPv6 headers */
static bool possibly_iphdr(const char *data)
{
return (data[0] & 0xd0) == 0x40;
}
#endif
#endif
……
/* if follow function exist, modify it as below */
static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
{
……
#if 1 //Added by Quectel
if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
dev_info(&intf->dev, "Quectel
EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96&AG35 work on RawIP mode\n");
dev->net->flags |= IFF_NOARP;
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 ))
/* make MAC addr easily distinguishable from an IP header */
if (possibly_iphdr(dev->net->dev_addr)) {
dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */
dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */
}
#endif
usb_control_msg(
interface_to_usbdev(intf),
usb_sndctrlpipe(interface_to_usbdev(intf), 0),
0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE
0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
1, //active CDC DTR
intf->cur_altsetting->desc.bInterfaceNumber,
NULL, 0, 100);
}
#endif
err:
return status;
}
……
/* if follow function exist, modify it as below */
static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf)
{
……
#if 1 //Added by Quectel
if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
dev_info(&intf->dev, "Quectel EC25&EC21&
EG91&EG95&EG06&EP06&EM06&BG96&AG35 work on RawIP mode\n");
dev->net->flags |= IFF_NOARP;
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 ))
/* make MAC addr easily distinguishable from an IP header */
if (possibly_iphdr(dev->net->dev_addr)) {
dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */
dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */
}
#endif
usb_control_msg(
interface_to_usbdev(intf),
usb_sndctrlpipe(interface_to_usbdev(intf), 0),
0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE
0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
1, //active CDC DTR
intf->cur_altsetting->desc.bInterfaceNumber,
NULL, 0, 100);
}
#endif
err:
return status;
}
……
/* if follow struct exist, modify it as below */
static const struct driver_info qmi_wwan_info =
{
……
#if 1 //Added by Quectel
.tx_fixup = qmi_wwan_tx_fixup,
.rx_fixup = qmi_wwan_rx_fixup,
#endif
}

……
/* if follow struct exist, modify it as below */
static const struct driver_info qmi_wwan_force_int4 = {
……
#if 1 //Added by Quectel
.tx_fixup = qmi_wwan_tx_fixup,
.rx_fixup = qmi_wwan_rx_fixup,
#endif
};
/* if follow struct exist, modify it as below */
static const struct driver_info qmi_wwan_shared = {
……
#if 1 //Added by Quectel
.tx_fixup = qmi_wwan_tx_fixup,
.rx_fixup = qmi_wwan_rx_fixup,
#endif
};

31.3修改配置

第一步:進入配置環境
$make menuconfig
第二步:配置

Kernel modules >>
    USB Support >>
        <*> Kmod -usb-core
        -*-Kmod -usb-net
        -*- kmod-usb-net-cdc-ether
        <*> kmod-usb-net-cdc-mbim
        -*- kmod-usb-net-cdc-ncm
        <*> kmod-usb-net-cdc-subset
        <*>kmod-usb-net-qmi-wwan
        <*>Kmod-usb-ohci     //這個選項一定要勾選,否則可能無法在系統中檢視裝置
        <*>Kmod-usb-serial
        <*>Kmod-usb-serial-option
        <*>Kmod-usb-serial-wwan
        <*>kmod-usb-uhci
        <*>Kmod-usb2
NetWork   >>
    <*> wwan
    <*>chat
    <*>ppp
    <*>uqmi
Utilities
    -*- comgt
    <*> comgt-ncm 
    <*>usb-modeswitch

Luci以下為可選:

Luci
1. Collections
        <*> luci
3. Applications
        <*> luci-app-multiwan (optional to support multiple 3g dongles)
        <*> luci-app-qos (optional to provide QOS support)
6. Protocols
        <*> luci-proto-3g
        -*- luci-proto-ppp

31.4編譯測試

以上操作完成後就是編譯原始碼了。
$ make V=99
將韌體燒寫進入板子中,插入4G模組,啟動板子會看到以下資訊。
這裡寫圖片描述
這裡寫圖片描述
也可以在dev目錄下檢視
這裡寫圖片描述
有以上資訊表示驅動配置成功,接下來就撥號了。

31.5撥號上網

撥號程式仍然使用移遠提供的quectel-CM,這是一個4G連線管理程式,這裡沒什麼說的,交叉編譯後得到可執行bin“quectel-CM”,
$mipsel-openwrt-linux-gcc *.c -o quectel-CM -lpthread –ldl
【注】將quectel-CM下的Makefile檔案修改成如下,然後 make
CROSS-COMPILE:=mipsel-openwrt-linux-
這裡寫圖片描述
把這個bin放到板卡上啟動後上述一、二驅動沒有問題的情況下直接執行該bin就可以。將quectel-CM可執行程式拷貝到板子中。
後臺執行:./quectel-CM &
[email protected]:~# ./quectel-CM &
[email protected]:~# [09-05_02:21:55:872] Quectel_Linux_ConnectManager_SR01A01V30
[09-05_02:21:55:872] ./quectel-CM profile[1] = (null)/(null)/(null)/0, pincode = (null)
[09-05_02:21:55:874] Find /sys/bus/usb/devices/1-1 idVendor=2c7c idProduct=0125
[09-05_02:21:55:875] Find /sys/bus/usb/devices/1-1:1.4/net/wwan0
[09-05_02:21:55:875] Find usbnet_adapter = wwan0
[09-05_02:21:55:876] Find /sys/bus/usb/devices/1-1:1.4/usbmisc/cdc-wdm0
[09-05_02:21:55:877] Find qmichannel = /dev/cdc-wdm0
[09-05_02:21:55:896] cdc_wdm_fd = 7
[09-05_02:21:55:996] Get clientWDS = 20
[09-05_02:21:56:027] Get clientDMS = 1
[09-05_02:21:56:061] Get clientNAS = 4
[09-05_02:21:56:091] Get clientUIM = 1
[09-05_02:21:56:124] Get clientWDA = 1
[09-05_02:21:56:156] requestBaseBandVersion EC20CEFAGR06A08M4G
[09-05_02:21:56:221] requestGetSIMStatus SIMStatus: SIM_READY
[09-05_02:21:56:253] requestGetProfile[1] ///0
[09-05_02:21:56:285] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
[09-05_02:21:56:316] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
[09-05_02:21:56:382] requestRegistrationState2 MCC: 460, MNC: 0, PS: Attached, DataCap: LTE
[09-05_02:21:57:084] requestSetupDataCall WdsConnectionIPv4Handle: 0x8722b410
[09-05_02:21:57:148] requestQueryDataCall IPv4ConnectionStatus: CONNECTED
[09-05_02:21:57:180] ifconfig wwan0 up
[09-05_02:21:57:207] busybox udhcpc -f -n -q -t 5 -i wwan0
[09-05_02:21:57:229] udhcpc (v1.23.2) started
[09-05_02:21:57:255] Sending discover…
[09-05_02:21:57:261] Sending select for 10.28.26.75…
[09-05_02:21:57:264] Lease of 10.28.26.75 obtained, lease time 7200
[09-05_02:21:57:276] udhcpc: ifconfig wwan0 10.28.26.75 netmask 255.255.255.248 broadcast +
[09-05_02:21:57:296] udhcpc: setting default routers: 10.28.26.76

這就是撥號成功了,接下來就是ping一下看是否可以聯網。
$ping 47.106.72.113
這裡寫圖片描述
【注意】這裡需要UDHCPC ,檢測你的busybox是否有這個東西,如果不存在,你需要重新移植busybox,啟用CONFIG_UDHCPC選項。還需要配置一個配置檔案,注意檢查。可以在開發板中輸入busybox中檢視,筆者的檔案系統有,所以就不需要配置了。
這裡寫圖片描述

相關推薦

31 OpenWrt 4G撥號上網Ubuntu12.04+Openwrt15.05

開發環境: 開發板:RT5350 4G 模組:QUECTEL EC25 OpenWrt 原始碼版本:Chaos_Calmer 參考文件:Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.7.pdf

5設定開發板的IP地址Ubuntu12.04+Openwrt15.05

【注】本文是基於Ubuntu12.04+Openwrt15.05開發的教程。 5.1在開發板上設定IP 由於我們在開發過程中,可能會用到其他路由器,而它們的IP一般都是192.168.1.1,為了讓開發板上的IP不與這些路由器的IP衝突,我們需要修改開發板上

31 新的設計模式2

31.2 物件池模式 31.2.1 定義和類圖 (1)定義:物件池是一種設計模式,它通過管理有限物件複用來共享某些稀少或必須付出昂貴代價的資源。 (2)類圖: 31.2.2 物件池的擴充套件介面 (1)兩級物件池方式:空閒物件池和已用物件池 (2)利用Wrap

Thinking in Java 18 Java I/O 系統18.9-18.14

//宣告:部分內容引自《Java程式設計思想(第四版)》機械工業出版社 【程序控制】 – 你經常會需要在 Java 內部執行其他作業系統的程式,並且要控制這些程式的輸入和輸出。Java 類庫提供了執行這些操作的類。 【新 I/O】 – 轉換資料。

C++復習與總結思維導圖分享

自己的 使用 適用於 img 情況下 它的 space ali 默認 在完成了第三章的學習後,為了便於日後的復習整理,我制作了一張思維導圖,有需要的可以自取。 函數的定義與使用 帶默認值的函數 在C++中我們可以為函數添加默認的參數值,在調用時可不傳入或部分傳入參數,為傳

《Linux作業系統-系統移植》8 USB-4G/LTE移植 -4節 USB-4G移植移遠EC20開發-Gobi撥號

開發環境 主機:ubuntu12.04 開發板核心版本:linux-2.6.35 【注】EC20支援PPP撥號,Gobi撥號和QMI撥號,筆者使用的是Gobi撥號,關於另外兩種撥號請參考官方文件,後文的附件連結中已經給出了參考文件。 3.1 USB Serial

《Linux作業系統-系統移植》8 USB-4G/LTE移植 -2節 USB-4G移植中興ME3760移植

ME3760 是一款Mini PCI-E介面的LTE 模組,支援LTE TDD band38(2.6GHz),band39(1.9GHz),band40(2.3GHz); LTE FDD band7(2.6GHz),向下相容TD-SCDMA A頻段(2.1GHz

《Linux作業系統-系統移植》8 USB-4G/LTE移植 -1節 USB-4G移植C華為E392u­924G移植

1.3 PPP編譯 1.獲取原始碼 PPP官網下載:https://download.samba.org/pub/ppp/ 下載解壓ppp-2.4.7.tar.gz原始碼,存放在/home/farsig

GZIP壓縮原理分析31—— Deflate演算法詳解五22 動態哈夫曼編碼分析11構建哈夫曼樹03

*構建distance樹 現在已經知道壓縮會在壓縮結果中儲存葉子節點深度資訊(即碼字長度)從而讓解壓方間接得到碼錶,但是問題來了,構造樹的資訊只包括碼字長度,可解壓方怎麼知道這個碼字長度是哪個原碼的(注意,“原碼”與“原始碼”的差別,前者是指原始資料,後者是指程式碼)?有什

《Linux作業系統-系統移植》8 USB-4G/LTE移植 -3節 USB-4G移植移遠AG35開發-GPS解析及程式設計

檢視參考手冊,移遠帶有GPS的晶片的USB Serial如下。 2.1應用簡介 1、若不使用 AT+QGPSCFG 指令對AG35進行配置,則會以預設引數開啟GPS引數,NMEA埠開始上報,"gpsnmeatype"預設值為31,上報間隔為1s,每次上報所有種

《Linux作業系統-系統移植》8 USB-4G/LTE移植 -1節 USB-4G移植 F華為E392u­924G移植

1.6啟動撥號指令碼 $mkdir shell_script $cd /shell_script $ vi usb.sh 輸入以下內容,然後儲存退出。 usb_modeswitch -W -c /etc

Java Script 06 瀏覽器對象模型BOM

block alt display play java pla .cn img script Java Script 第06章 瀏覽器對象模型(BOM)

MOOC清華《面向對象程序設計》8:棧的實現采用模板實例化

com mooc html 程序 ndt wot 面向 tar dmz 3lztmo1xf豪已4茲6http://www.zcool.com.cn/collection/ZMTkxNTY1OTI=.html 6桓50勞爻拍62誹喜0栽2http://www.zcool.c

:循環結構

結構 不執行 三種 表達式 成了 不改變 條件 運算符 步驟 第六章:循環結構(二) 一. for 循環 1.循環結構的四個組成部分 (1). 初始部分:設置循環的初始狀態,比如我們設置記錄循環次數的變量 i 為 0 . (2). 循環體:重復執行的代碼 .

:循環結構

如何 如何使用 滿足 為什麽 發現 每日 生活 打印機 結構 第五章:循環結構(一) 1.什麽是循環結構 在日常生活中,會有很多需要反復執行的事情,比如:每一年的 4個季節,每一周的7天,每日的3餐,打印機每份文檔打印50 份,一圈跑道400米跑3圈,都是在反復執行的。 2

13 linux系統管理技巧日常運維管理技巧

linux第13章 linux系統管理技巧(日常運維管理技巧)這一章的內容是核心,以後會用的幾率也是很大的,只要掌握必備的基礎知識,做初級系統管理員是不成問題的。13.1監控系統的狀態作為一個運維工程師、系統管理員,如果對自己的系統不了解的話,那怎麽排查問題呢?如果出現問題的話,肯定要查一下是什麽問題,哪裏的

Python培訓知識總結系列- Python3文件操作

readline new socket 總結 排序 tin strip() list 是否 open 123456789f = open(‘filename‘,‘r‘) # 讀模式f = open(‘filename‘,‘w‘) # 寫模式f = open(‘filenam

Python入門+進階 1 Python入門導學無論何時,只要開始就不晚

編寫程序 開放 per python入門 範圍 工作 win 器) 客戶 1、 Python入門導學 1.1 Python概念 Python(英國發音:/?pa?θ?n/ 美國發音:/?pa?θɑ?n/) 是一個高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言。 P

Learning Spark中文版----使用鍵值對2

最小 定制 單個 locate 最大限度 ces 之一 定期 情況 Actions Available on Pair RDDs (鍵值對RDD可用的action) ??和transformation(轉換)一樣,鍵值對RDD也可以使用基礎RDD上的action(開工),並

MNIST數字識別問題

AR dom post mod 變量名 elements 之前 spl with 4.1. ckpt文件保存方法 在對模型進行加載時候,需要定義出與原來的計算圖結構完全相同的計算圖,然後才能進行加載,並且不需要對定義出來的計算圖進行初始化操作。 這樣保存下來的模型,會在其文