Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Android

ปลดล็อกการประหยัดพลังงานของ Android:บทบาทของการตั้งค่าซ็อกเก็ต Bluetooth ใน Low Power Island ของ AOSP

ปลดล็อกการประหยัดพลังงานของ Android:บทบาทของการตั้งค่าซ็อกเก็ต Bluetooth ใน Low Power Island ของ AOSP

ลองนึกภาพสิ่งนี้:คุณกำลังนั่งอยู่ในร้านกาแฟโดยเปิดแล็ปท็อปไว้ โทรศัพท์บนโต๊ะ นาฬิกาอัจฉริยะส่งเสียงพึมพำทุกๆ สองสามนาที และหูฟังบลูทูธที่เล่นเพลง จากมุมมองของคุณ ชีวิตก็สงบสุข จากมุมมองของโทรศัพท์ของคุณ มันมีแพ็กเก็ต Bluetooth ขนาดเล็กจำนวนไร้สาระอยู่ตลอดเวลา

ทุกครั้งที่นาฬิกาซิงค์ขั้นตอนของคุณ ทุกครั้งที่หูฟังของคุณได้รับเสียงอีกก้อนหนึ่ง ทุกครั้งที่อุปกรณ์พื้นหลังเช็คอิน โปรเซสเซอร์แอปพลิเคชันหลักในโทรศัพท์ของคุณจะถูกบังคับให้ตื่น ดูข้อมูล ตัดสินใจว่าจะทำอย่างไรกับข้อมูลนั้น จากนั้นจึงกลับไปนอนต่อ ทำแบบนั้นสักสองสามพันครั้ง และทันใดนั้นแบตเตอรี่ขนาด 5000 mAh ที่ดีก็เริ่มรู้สึกว่าเล็กลงอย่างน่าสงสัย

วิศวกรของ Android มองรูปแบบนี้แล้วพูดว่า จะเกิดอะไรขึ้นถ้าเราไม่ปลุก CPU ขนาดใหญ่สำหรับบลูทูธเล็กๆ ทุกชิ้นล่ะ จะเกิดอะไรขึ้นถ้าเรามีสมองผู้ช่วยที่มีขนาดเล็กกว่าซึ่งมีหน้าที่ทั้งหมดในการจัดการการรับส่งข้อมูล Bluetooth ที่ซ้ำซากจำเจในขณะที่ CPU หลักผ่อนคลาย นั่นคือที่มาของแนวคิดเรื่อง Low Power Island ซึ่งมักจะเรียกสั้น ๆ ว่า LPI เข้ามา

ในสถาปัตยกรรมบลูทูธ Android สมัยใหม่ โดยเฉพาะอย่างยิ่งตั้งแต่ AOSP รุ่นที่ 16 เป็นต้นไป งานบลูทูธส่วนใหญ่สามารถถ่ายโอนไปยังโปรเซสเซอร์พลังงานต่ำโดยเฉพาะซึ่งอยู่ใกล้กับวิทยุ Bluetooth มากขึ้น โปรเซสเซอร์ขนาดเล็กนี้ฝังอยู่ในตัวควบคุม Bluetooth หรือ SoC และได้รับการออกแบบมาให้ทำงานได้อย่างมีประสิทธิภาพมาก ใช้พลังงานน้อยกว่า CPU หลักมาก และสามารถตื่นตัวได้โดยไม่เปลืองแบตเตอรี่เหมือนที่ตัวประมวลผลแอปพลิเคชันเต็มรูปแบบทำ หน้าที่ของ Android คือตัดสินใจว่าการรับส่งข้อมูลใดที่สามารถอาศัยอยู่บนเกาะนี้ได้ และการรับส่งข้อมูลใดที่ยังต้องการ CPU หลัก

แต่ Android ตัดสินใจในทางปฏิบัติได้อย่างไร? นี่คือจุดที่ซ็อกเก็ต Bluetooth และสิ่งที่เรียกว่า BluetoothSocketSettings เข้ามามีบทบาท

ในแอปทั่วไป เมื่อคุณเปิด BluetoothSocket คุณจะรู้สึกเหมือนกำลังเปิดไปป์เพื่อให้คุณสามารถส่งและรับไบต์ได้ ภายใต้ฝากระโปรง กรอบงานกำลังถามคำถามที่ลึกซึ้งกว่านั้น:ท่อนี้ควรผ่านทางหลวงขนาดใหญ่ที่ปลุก CPU หลัก หรือท่อนี้สามารถเชื่อมต่อโดยตรงกับเครือข่ายถนนส่วนตัวของเกาะพลังงานต่ำได้หรือไม่

ในสแต็ก AOSP Bluetooth ล่าสุด คำตอบสำหรับคำถามดังกล่าวจะแสดงผ่านออบเจ็กต์การกำหนดค่าเล็กๆ:BluetoothSocketSettings คลาสนี้ช่วยให้โค้ดระดับระบบอธิบายว่าซ็อกเก็ตควรทำงานอย่างไร สามารถระบุได้ว่าข้อมูลควรถูกเก็บไว้บนเส้นทางโฮสต์ปกติหรือออฟโหลดลงในเส้นทางข้อมูลฮาร์ดแวร์ที่สิ้นสุดบนโปรเซสเซอร์พลังงานต่ำ

ข้างในมีช่องต่างๆ เช่น 05 และ 10 พร้อมข้อมูลเพิ่มเติม เช่น 22 , 35 และ 41 ที่ช่วยให้คอนโทรลเลอร์เข้าใจวิธีกำหนดเส้นทางแพ็กเก็ตในโลก LPI

จากภายนอก ดูเหมือนว่าคุณกำลังติดต่อกับ BluetoothSocket ปกติ ภายในกรอบงาน Bluetooth ซ็อกเก็ตนั้นถูกแท็กด้วยข้อมูลเมตาพิเศษที่บอกสแต็ก Bluetooth อย่างเงียบๆ ว่าอันนี้พิเศษ ส่งไปที่เกาะ

จากนั้นโฮสต์สแต็กจะพูดคุยกับโค้ดเลเยอร์ใหม่ในระบบ Bluetooth ที่เรียกว่า LPP offload manager และ HAL เฉพาะซ็อกเก็ต (Hardware Abstraction Layer) เพื่อให้สามารถแจ้งโปรเซสเซอร์พลังงานต่ำทุกครั้งที่เปิดหรือปิดซ็อกเก็ต และสามารถอ้างสิทธิ์ความรับผิดชอบในการจัดการข้อมูลได้

ดังนั้นหากเรารักษาความคล้ายคลึงของร้านกาแฟ ก่อนหน้านี้ลูกค้าที่ใช้ Bluetooth ทุกคนจะตะโกนสั่งอาหารไปที่บาริสต้าหลักโดยตรง ด้วย Low Power Island และ BluetoothSocketSettings ทำให้ Android สามารถพูดได้ว่า “การสั่งเอสเปรสโซปกติเหล่านี้สามารถสั่งผ่านบาริสต้ารุ่นเยาว์ที่เคาน์เตอร์ด้านข้างได้ มีเพียงเครื่องดื่มสั่งทำพิเศษแปลกๆ เท่านั้นที่ส่งไปยังบาริสต้าหลัก” ผู้ใช้จะได้รับประสบการณ์ Bluetooth แบบเดียวกัน แต่ความวุ่นวายน้อยกว่าและสิ้นเปลืองพลังงานหลังเคาน์เตอร์น้อยกว่ามาก

ในบทความนี้ เราจะขยายจากเรื่องราวระดับสูงนี้ไปสู่ Android API จริง เราจะดูว่า BluetoothSocketSettings ถูกกำหนดไว้อย่างไรในเฟรมเวิร์ก วิธีที่คุณร้องขอการถ่ายโอนฮาร์ดแวร์ และฟิลด์ที่ดูน่ากลัวเหล่านั้น เช่น hubId และ endpointId จริงๆ แล้วมีความหมายอย่างไรในภาษาอังกฤษธรรมดา

สารบัญ

  1. กายวิภาคของ BluetoothSocketSettings

  2. เจาะลึก HAL:วิธีการทำงานของ Bluetooth Offload จริงๆ

  3. เมื่อ CPU หลับแต่บลูทูธไม่:การจัดการพลังงานกำลังทำงาน

  4. วิธีที่นักพัฒนาสามารถควบคุมการตั้งค่า BluetoothSocket

  5. The Grand Finale:ความสง่างามของการหลับอย่างชาญฉลาด

กายวิภาคของการตั้งค่า BluetoothSocket

จนถึงตอนนี้ เราได้พูดถึง BluetoothSocketSettings เหมือนกับว่าเป็นตั๋ววิเศษที่จะส่งแพ็กเก็ตของคุณไปยังเกาะที่ใช้พลังงานต่ำที่มีแสงแดดสดใสที่ไหนสักแห่งในโทรศัพท์ของคุณ ตอนนี้เรามาดูกันว่าตั๋วนั้นมีลักษณะอย่างไรในโค้ด

หากคุณเปิดแผนผังโครงการ Android Open Source และไปที่เลเยอร์เฟรมเวิร์ก คุณจะพบคำจำกัดความของคลาสซ่อนอยู่ใต้ 54 . เมื่อมองแวบแรกมันดูเล็ก เกือบจะง่ายเกินไปสำหรับบางอย่างที่ช่วยประหยัดแบตเตอรี่ได้มาก แต่คลาสเล็กๆ นี้มีคำสั่งลับที่บอกสแต็ก Bluetooth ว่าข้อมูลซ็อกเก็ตของคุณควรไหลไปที่ใด

เวอร์ชันแบบแยกส่วนจะมีลักษณะดังนี้:

public final class BluetoothSocketSettings implements Parcelable {
 public static final int DATA_PATH_NO_OFFLOAD = 0;
 public static final int DATA_PATH_HARDWARE_OFFLOAD = 1;
 private int mDataPath;
 private int mHubId;
 private int mEndpointId;
 private int mRequestedMaxPacketSize;
 public BluetoothSocketSettings(int dataPath, int hubId, int endpointId,
 int requestedMaxPacketSize) {
 mDataPath = dataPath;
 mHubId = hubId;
 mEndpointId = endpointId;
 mRequestedMaxPacketSize = requestedMaxPacketSize;
 }
 public int getDataPath() { return mDataPath; }
 public int getHubId() { return mHubId; }
 public int getEndpointId() { return mEndpointId; }
 public int getRequestedMaxPacketSize() { return mRequestedMaxPacketSize; }
}

เมื่อมีการสร้างซ็อกเก็ตใหม่ใน Android Bluetooth ระบบหรือบริการที่มีสิทธิ์สามารถส่งหนึ่งในออบเจ็กต์การตั้งค่าเหล่านี้ลงไปที่สแต็ก บรรทัดสำคัญคือ 62 . นั่นคือสวิตช์ที่บอกระบบบลูทูธ เฮ้ พยายามเก็บการรับส่งข้อมูลนี้ไว้บนไมโครโปรเซสเซอร์ของคอนโทรลเลอร์ แทนที่จะปลุก CPU หลัก

73 และ 88 ก็เหมือนที่อยู่บนเกาะ พวกเขาบอกเฟิร์มแวร์ว่าพอร์ตลอจิคัลหรือคิวใดที่จะใช้สำหรับซ็อกเก็ตนั้น 95 ช่วยปรับแต่งการจัดสรรบัฟเฟอร์ ดังนั้นจึงสามารถปรับปริมาณการรับส่งข้อมูลและประสิทธิภาพการใช้พลังงานได้อย่างสมดุล

ณ จุดนี้คุณอาจสงสัยว่าวัตถุ Java จิ๋วนี้ลงมาถึงฮาร์ดแวร์ได้อย่างไร คำตอบอยู่ใน HAL (Hardware Abstraction Layer) เมื่อคุณเรียกบางอย่างเช่น 105 ในที่สุดมันก็ส่งผ่านโค้ดเนทิฟในไฟล์เช่น 114 และ 127 . ที่นั่นคุณจะเห็นร่องรอยดังนี้:

bt_status_t status = BTA_SockConnect(type, addr, channel, flags);
if (settings.data_path == DATA_PATH_HARDWARE_OFFLOAD) {
 BTIF_TRACE_DEBUG("Configuring socket for hardware offload path");
 BTA_SockSetOffloadParams(settings.hub_id, settings.endpoint_id);
}

ตัวอย่างนี้อาจดูเรียบง่าย แต่แสดงถึงการเปลี่ยนแปลงครั้งสำคัญในความรับผิดชอบ แทนที่จะส่งทุกแพ็กเก็ตไปยังโฮสต์สแต็ก คอนโทรลเลอร์ Bluetooth สามารถอ้างสิทธิ์ความเป็นเจ้าของเส้นทางข้อมูลได้แล้ว จากนั้นเฟิร์มแวร์ Bluetooth ภายใน SoC จะเข้ามาแทนที่ โดยจัดการการส่งข้อมูลแพ็กเก็ตใหม่ การรับทราบ และการควบคุมโฟลว์โดยไม่ต้องปลุก CPU หลักอย่างต่อเนื่อง

หากคุณตรวจสอบบันทึกเคอร์เนลของอุปกรณ์ระหว่างการเชื่อมต่อ คุณอาจพบบางสิ่งเช่น:

bt_vendor: enabling LPI offload for handle 0x0041
bt_controller: lpi path active, cpu wakelocks released

บรรทัดบันทึกนั้นเป็นการยืนยันอย่างเงียบๆ ของคุณว่าเส้นทางข้อมูลได้ย้ายไปยังเกาะพลังงานต่ำสำเร็จแล้ว

ในแง่มนุษย์ โทรศัพท์เพิ่งตัดสินใจว่าการสนทนาผ่านบลูทูธนี้คาดเดาได้เพียงพอที่จะจัดการโดยโปรเซสเซอร์ขนาดเล็ก จึงบอกกับ CPU ตัวใหญ่อย่างสุภาพว่า "คุณงีบหลับได้แล้ว ฉันเข้าใจแล้ว"

ในส่วนถัดไป เราจะติดตามการเดินทางนี้ให้ลึกลงไปอีกระดับหนึ่ง ตรงเข้าไปในขอบเขต HAL และเฟิร์มแวร์ เพื่อดูว่าการตั้งค่าซ็อกเก็ตเหล่านี้กลายเป็นการกำหนดเส้นทางข้อมูลพลังงานต่ำจริงภายในชิปตัวควบคุมได้อย่างไร นี่คือจุดที่ความมหัศจรรย์ของฮาร์ดแวร์ที่แท้จริงเกิดขึ้น และจุดที่การประหยัดเริ่มเพิ่มขึ้นทุกๆ มิลลิวัตต์ในแต่ละครั้ง

เจาะลึก HAL:วิธีการทำงานของ Bluetooth Offload จริงๆ

จนถึงตอนนี้ เราส่วนใหญ่อยู่ใน Java และเลเยอร์ดั้งเดิมของ Android ซึ่งเป็นอพาร์ทเมนต์ที่สะดวกสบายซึ่งมีเฟรมเวิร์กและบริการระบบอยู่ แต่ข้างใต้นั้นมีห้องใต้ดินที่เต็มไปด้วยเครื่องจักรอันชาญฉลาด:Hardware Abstraction Layer หรือฮาล นี่คือจุดที่ Android หยุดพูดใน "วัตถุ" และเริ่มพูดใน opcode และบัฟเฟอร์ และเป็นสะพานเชื่อมระหว่างซอฟต์แวร์และซิลิคอน

เมื่อแฟล็ก BluetoothSocketSettings แจ้งระบบว่า "โปรดใช้ออฟโหลดฮาร์ดแวร์" คำขอนั้นจะไม่เทเลพอร์ตไปยังชิปอย่างน่าอัศจรรย์ มันเดินไปทีละขั้นจากสแต็ก Bluetooth ข้ามผ่าน JNI (Java Native Interface) ไปยัง C++ จากนั้นเข้าสู่ HAL ซึ่งกำหนดไว้ภายใน 137 .

เริ่มตั้งแต่ Android 14 และโดยเฉพาะอย่างยิ่งใน AOSP 16 HAL ได้เติบโตขึ้นอย่างชาญฉลาดมากขึ้น โดยตอนนี้เข้าใจความสามารถของ LPI และกำหนดเส้นทางการรับส่งข้อมูลซ็อกเก็ตบางอย่างไปยังความสามารถเหล่านั้นได้

มาดูฟังก์ชัน HAL แบบง่ายกันดีกว่า นี่ไม่ใช่ตัวอย่างที่สมมติขึ้น ใกล้เคียงกับสิ่งที่คุณอาจพบใน 141 หรือ 155 :

Return<void> BluetoothHci::createSocketChannel(
 const hidl_string& device, const BluetoothSocketSettings& settings,
 createSocketChannel_cb _hidl_cb) {
 int fd = -1;
 if (settings.data_path == DATA_PATH_HARDWARE_OFFLOAD) {
 ALOGI("LPI offload requested for socket on hub %d endpoint %d",
 settings.hub_id, settings.endpoint_id);
 fd = controller->allocateLpiChannel(settings.hub_id, settings.endpoint_id);
 } else {
 fd = controller->allocateHostChannel();
 }
 _hidl_cb(Status::SUCCESS, fd);
 return void();
}

ในภาษาอังกฤษธรรมดา วิธีการนี้เหมือนกับเจ้าหน้าที่จราจรที่ทางแยกบลูทูธ ระบบจะดูการตั้งค่าซ็อกเก็ตของคุณและตัดสินใจว่าจะส่งข้อมูลไปที่ถนนใด ถ้า 160 ได้รับการตั้งค่า เส้นทางข้อมูลจะต่อเข้ากับ MCU ภายในของคอนโทรลเลอร์ แทนที่จะเป็นบัฟเฟอร์ฝั่งโฮสต์ปกติ

โทรไปที่ 171 เป็นที่ที่ HAL พูดว่า "เอาล่ะ ชิป โปรดสร้างคิวที่อยู่ภายในโปรเซสเซอร์ที่ใช้พลังงานต่ำทั้งหมดของคุณ" ไมโครคอนโทรลเลอร์นี้อยู่ใกล้กับวิทยุ Bluetooth มากขึ้น มันสามารถจัดการการตอบรับ การระเบิดของข้อมูลจำนวนเล็กน้อย และแม้แต่การกำหนดเวลาของโปรโตคอลบางอย่างด้วยตัวเอง ซึ่งโดยปกติแล้วจะต้องปลุกการทำงานของ CPU หลัก

เมื่อสร้างช่องนี้แล้ว เฟรมเวิร์กและแอปของ Android จะยังคงเห็นตัวอธิบายไฟล์ปกติ ราวกับว่าซ็อกเก็ตอยู่ในเครื่องทั้งหมด ความมหัศจรรย์อยู่ที่ข้อเท็จจริงที่ว่าตัวอธิบายนี้ได้รับการสนับสนุนโดยหน่วยความจำที่จัดการโดยเฟิร์มแวร์และเส้นทาง DMA แทนที่จะเป็นบัฟเฟอร์เคอร์เนลของ Linux

หากคุณแนบไฟล์ดีบักเกอร์หรือบันทึกดัมพ์จากคอนโทรลเลอร์ คุณอาจเห็นข้อความดังนี้:

bt_lpi_mcu: channel 0x03 opened for handle 0x0041
bt_hci: diverting ACL packets to LPI path
bt_lpi_mcu: sleeping host processor

บรรทัดที่สาม 180 คือความฝันที่เป็นจริงสำหรับวิศวกรด้านพลังงานทุกคน โทรศัพท์จะปิดระบบย่อย CPU ส่วนใหญ่ในขณะที่ยังคงรักษา Bluetooth ไว้

นี่คือจุดที่ผู้ขายอย่าง Qualcomm หรือ Broadcom เพิ่มซอสพิเศษของพวกเขา HAL ของพวกเขามักจะมี hooks พิเศษสำหรับตัวจับเวลา "keep-alive", "ช่วงเวลาการรวมตัวกัน" และ "การส่งสัญญาณซ้ำที่ขับเคลื่อนด้วยเฟิร์มแวร์" สิ่งเหล่านี้ทำให้มั่นใจได้ว่าการเชื่อมต่อจะราบรื่นแม้ว่าโปรเซสเซอร์หลักจะไม่ทำงานก็ตาม

จากมุมมองระดับสูง ตอนนี้ไปป์ไลน์จะมีลักษณะดังนี้:

App -> Bluetooth Framework -> JNI -> btif_sock -> HAL -> Controller MCU (LPI)

ทุกชั้นเข้าใจเพียงพอที่จะส่งกระบองไปยังชั้นถัดไปได้อย่างหมดจด HAL ทำหน้าที่เป็นผู้แปล โดยรับการตั้งค่าระดับสูงและเปลี่ยนให้เป็นคำสั่งระดับต่ำที่เฟิร์มแวร์ชิปสามารถทำงานได้

เมื่อนาฬิกาอัจฉริยะของคุณส่งแพ็กเก็ตหรือหูฟังของคุณขอเสียง CPU หลักจะไม่กระพริบด้วยซ้ำ ธุรกรรมทั้งหมดมีชีวิตอยู่และตายไปภายในโดเมนเล็กๆ ของตัวควบคุม Bluetooth โดยสูบพลังงานแทนที่จะกลืนลงไป

ในส่วนถัดไป เราจะสำรวจว่าสถาปัตยกรรมออฟโหลดนี้ผสานรวมกับระบบจัดการพลังงานของ Android ได้อย่างไร รวมถึง Wakelock โหมด Doze และการประสานงานของเคอร์เนล และวิธีที่ทำให้แน่ใจได้ว่าแม้ว่า CPU หลักจะอยู่ในโหมดสลีป แต่การเชื่อมต่อจะไม่พลาดทุกจังหวะ

เมื่อ CPU เข้าสู่โหมดสลีปแต่บลูทูธไม่ทำงาน:การจัดการพลังงานกำลังทำงาน

เอาล่ะ เราได้เห็นแล้วว่าซ็อกเก็ตออฟโหลดเดินทางจากเลเยอร์แอปลงไปยัง HAL และในที่สุดก็ตกลงบน MCU เล็กๆ ที่อยู่ภายในชิป Bluetooth แต่จะเกิดอะไรขึ้นต่อไป? จะเกิดอะไรขึ้นหาก CPU หลักของโทรศัพท์ของคุณตัดสินใจที่จะงีบหลับในขณะที่การถ่ายโอนไฟล์หรือสตรีมเสียงยังคงดำเนินต่อไป นั่นไม่เสี่ยงที่จะทำลายการเชื่อมต่อ Bluetooth ใช่ไหม

นี่คือการออกแบบท่าเต้นการจัดการพลังงานของ Android ก้าวเข้ามา เป็นการเต้นรำระหว่างนักแสดง 3 คน ได้แก่ Power HAL สแต็คบลูทูธ และระบบเคอร์เนล wakelock .

เมื่อกำหนดค่าซ็อกเก็ต Bluetooth สำหรับ Low Power Island สแต็ก Bluetooth ของ Android จะส่งสัญญาณเคอร์เนลว่าสามารถรักษาการเชื่อมต่อนี้ได้โดยไม่ต้องใช้ CPU หลัก ภายใน ระบบจะล้างหรือลดสเกลตัวจับเวลา Wakelock ซึ่งปกติจะทำให้โปรเซสเซอร์ตื่นตัวระหว่างการรับส่งข้อมูล Bluetooth ในบันทึกเคอร์เนล คุณอาจเห็นสิ่งนี้:

wakelock: release "bt_wake" (LPI mode active)
bt_controller: firmware handling link supervision locally

ข้อความนี้ถือเป็นข้อความทองสำหรับวิศวกรระบบ มันบอกคุณว่าคอนโทรลเลอร์ได้เป็นเจ้าของการเชื่อมต่อโดยสมบูรณ์แล้ว ขณะนี้เฟิร์มแวร์บลูทูธกำลังตรวจสอบการหมดเวลาการควบคุมดูแล จัดการการส่งสัญญาณซ้ำ และดูแลรักษาตัวนับการเข้ารหัส

จากมุมมองของผู้จัดการพลังงาน อุปกรณ์ Bluetooth จะดูเหมือน "ไม่ได้ใช้งาน" เนื่องจากไม่มีการขัดจังหวะต่อ CPU หลัก ในขณะเดียวกัน MCU ตัวควบคุมจะแลกเปลี่ยนแพ็กเก็ตกับหูฟังเอียร์บัดหรือสมาร์ทวอทช์ของคุณอย่างเงียบๆ โดยใช้โดเมนนาฬิกาที่ใช้พลังงานต่ำของตัวเอง

เพื่อประสานสิ่งนี้ Bluetooth HAL จะแสดงการโทรกลับเล็กน้อยเพื่อแจ้ง Power HAL ทุกครั้งที่ระดับการรับส่งข้อมูลเปลี่ยนแปลง คุณอาจพบตัวอย่างเช่นนี้ใน 192 :

void bt_lpi_activity_update(bool active) {
 if (active)
 power_hint(POWER_HINT_LPI_ACTIVITY, 1);
 else
 power_hint(POWER_HINT_LPI_ACTIVITY, 0);
}

เมื่อ 203 ไปที่ศูนย์ Power HAL รู้ว่าสามารถอนุญาตให้ระบบเข้าสู่สถานะสลีปได้ลึกขึ้น (เช่น Suspend-to-RAM) เนื่องจาก Bluetooth จะทำให้สิ่งต่าง ๆ คงอยู่ได้ด้วยตัวเอง

ความมหัศจรรย์ที่แท้จริงก็คือผู้ใช้ไม่เคยสังเกตเห็นสิ่งนี้เลย โทรศัพท์อาจแสดงสถานะ "หลับ" ปิดหน้าจอ CPU cores gated แต่เสียง Bluetooth ของคุณยังคงเล่น สมาร์ทวอทช์ของคุณยังคงซิงค์ และโทรศัพท์ของคุณยังคงค้นพบได้

มันเกือบจะเป็นบทกวี โปรเซสเซอร์หลักกำลังฝัน ตัวควบคุมส่งเสียงฮัมเบาๆ และเพลย์ลิสต์ของคุณเล่นต่อไปเหมือนไม่มีอะไรเกิดขึ้น

หากคุณต้องการยืนยันสิ่งนี้บนอุปกรณ์ Android จริง คุณสามารถใช้คำสั่ง:

adb shell cat /sys/kernel/debug/wakeup_sources | grep bt

เมื่อคุณเห็น 216 เคาน์เตอร์ยังคงต่ำแม้ในระหว่างการสตรีม ยินดีด้วย! การถ่ายออฟโหลดของ Low Power Island ทำงานได้อย่างสวยงาม

ในส่วนถัดไป เราจะไต่กลับขึ้นมาจากระดับความลึกของเฟิร์มแวร์เพื่อดูว่าทั้งหมดนี้เข้ากับโลกของนักพัฒนาในแต่ละวันได้อย่างไร ในฐานะนักพัฒนาแอปหรือระบบ คุณสามารถควบคุมหรือรับประโยชน์จากการตั้งค่าซ็อกเก็ตเหล่านี้ได้โดยตรงหรือไม่ และการทำความเข้าใจสิ่งเหล่านี้จะช่วยคุณสร้างแอปบลูทูธที่จิบแทนพลังได้อย่างไร

นักพัฒนาซอฟต์แวร์สามารถควบคุมการตั้งค่า BluetoothSocket ได้อย่างไร

ตอนนี้เราได้เจาะลึกลงไปในใจกลางของ Bluetooth Stack แล้ว เรามาย้อนกลับไปที่จุดที่คุณและฉันอาศัยอยู่จริง ๆ กัน นั่นก็คือ เลเยอร์นักพัฒนา คุณอาจสงสัยว่า “เอาล่ะ เวทมนตร์ด้านฮาร์ดแวร์ทั้งหมดนั้นเจ๋ง แต่ฉันทำอะไรได้จริงๆ ด้วย?”

ส่วนที่สนุก:แม้ว่า Low Power Island ส่วนใหญ่เป็นคุณสมบัติระดับระบบ แต่การทำความเข้าใจวิธีการทำงานยังคงช่วยให้คุณออกแบบแอป Bluetooth ที่เป็นมิตรต่อพลังงานและคาดเดาได้มากขึ้น

ที่ระดับเฟรมเวิร์ก คุณจะไม่สามารถเปิดหรือปิด LPI จากแอปของคุณได้โดยตรง สวิตช์เหล่านั้นอาศัยอยู่ลึกลงไปในส่วนประกอบของระบบ เช่น BluetoothService และ BluetoothSocketManagerService แต่ทุกครั้งที่คุณใช้ 220 หรือ 230 ข้อมูลของคุณจะไหลผ่านเลเยอร์เหล่านั้นอย่างเงียบๆ เพื่อตรวจสอบว่าออฟโหลด LPI พร้อมใช้งานหรือไม่

นั่นหมายความว่าแอปของคุณจะได้รับประโยชน์โดยอัตโนมัติ ตราบใดที่คุณไม่ทำอะไรก็ตามที่บังคับให้ CPU ตื่นตัวโดยไม่จำเป็น . ตัวอย่างเช่น การใช้เธรดสลีปที่เหมาะสม การหลีกเลี่ยงการวนซ้ำที่ไม่ว่าง และการปล่อยให้สตรีม Bluetooth I/O ของ Android จัดการการบัฟเฟอร์จะช่วยให้คุณได้รับข้อดีของตรรกะออฟโหลด

หากคุณเจาะลึกบันทึกเซิร์ฟเวอร์ระบบของ AOSP ขณะเชื่อมต่อซ็อกเก็ต Bluetooth คุณอาจสังเกตเห็นสิ่งนี้:

BluetoothSocketManager: Offload eligible socket detected, enabling LPI mode
Bluetooth HAL: LPI channel activated for fd=42

เส้นเล็กๆ นั้นบอกคุณว่าซ็อกเก็ตของคุณถูกกำหนดเส้นทางใหม่อย่างเงียบๆ ทั่วทั้งเกาะ โดยที่คุณไม่ต้องยกนิ้วเลย

ด้านล่างกรอบงานสร้าง 242 วัตถุแล้วส่งต่อไปตามโซ่เมื่อเปิดเบ้า ใน pseudo-Java ดูเหมือนว่านี้:

BluetoothSocketSettings settings =
 new BluetoothSocketSettings(
 BluetoothSocketSettings.DATA_PATH_HARDWARE_OFFLOAD,
 /* hubId */ 1,
 /* endpointId */ 2,
 /* maxPacketSize */ 512);
BluetoothSocket socket = adapter.createSocket(device, settings);
socket.connect();

แน่นอนว่านี่ไม่ใช่ส่วนหนึ่งของ SDK สาธารณะ แต่แอประบบหรือเฟรมเวิร์กที่ได้รับสิทธิพิเศษใช้การเรียกที่คล้ายกันเพื่ออธิบายวิธีจัดการการรับส่งข้อมูล

แล้วเหตุใดคุณซึ่งเป็นผู้พัฒนาจึงต้องใส่ใจ? เนื่องจากการรู้ว่ามีเส้นทางดังกล่าวอยู่ หมายความว่าคุณสามารถ ออกแบบโดยคำนึงถึงเส้นทางนั้น ได้ . ตัวอย่างเช่น คุณสามารถ:

  • รวบรวมการเขียน BLE ขนาดเล็กเป็นชุดแทนที่จะส่งทีละรายการ ช่วยให้คอนโทรลเลอร์ประมวลผลได้อย่างมีประสิทธิภาพภายในบัฟเฟอร์ออฟโหลด

  • หลีกเลี่ยงวงจรการเชื่อมต่อ/ยกเลิกการเชื่อมต่อบ่อยครั้ง ซึ่งจะบังคับให้สแต็กปลุก CPU หลักซ้ำๆ

  • จัดโครงสร้างการถ่ายโอนพื้นหลังของคุณให้พอดีภายในขีดจำกัดของบัฟเฟอร์พลังงานต่ำ (ลองนึกถึงส่วนที่เล็กลงและช่วงเวลาที่นานขึ้น)

โดยพื้นฐานแล้ว ยิ่งรูปแบบข้อมูลของคุณคาดเดาได้มากเท่าไร โอกาสที่จะอยู่ในเกาะโดยไม่ปลุกโฮสต์ก็จะยิ่งมากขึ้นเท่านั้น

หากคุณกำลังสร้างซอฟต์แวร์ระบบ เช่น อุปกรณ์ Android แบบกำหนดเองหรือผลิตภัณฑ์แบบฝังตัว คุณก็สามารถพัฒนาไปไกลกว่านี้ได้อีก คุณสามารถปรับแต่งลักษณะการทำงานของ HAL กำหนด ID ฮับหรือปลายทางแบบกำหนดเอง และแม้กระทั่งปรับขนาดแพ็กเก็ตสูงสุดที่เฟิร์มแวร์ใช้สำหรับการถ่ายโอน DMA วิธีนี้ช่วยให้คุณสร้างฟีเจอร์บลูทูธได้ เช่น การสตรีมการวัดและส่งข้อมูลทางไกลที่ใช้พลังงานต่ำ หรือการซิงค์เซ็นเซอร์แบบสวมใส่ได้ ซึ่งทำงานโดยลดภาระเกือบทั้งหมด

เมื่อถึงจุดนั้น ชิปบลูทูธของคุณจะกลายเป็นเซิร์ฟเวอร์ขนาดเล็กที่ทำงานต่อไปในขณะที่ระบบปฏิบัติการหลักอยู่ในโหมดสลีป ทำให้มีอายุการใช้งานแบตเตอรี่ที่น่าทึ่งและการเชื่อมต่อที่รวดเร็ว

ในส่วนสุดท้าย เราจะสรุปสิ่งต่างๆ และมองย้อนกลับไปที่ภาพรวม เหตุใด BluetoothSocketSettings และ Low Power Island จึงรวมกันเป็นหนึ่งในตัวอย่างที่หรูหราที่สุดของ "วิศวกรรมที่มองไม่เห็น" ของ Android นี่เป็นหนึ่งในชัยชนะอันเงียบสงบที่คุณแทบจะไม่ได้เห็นในประเด็นสำคัญ แต่รู้สึกได้ทุกวันเมื่อโทรศัพท์ของคุณยังมีพลังอยู่ตอนเที่ยงคืน

ตอนจบที่ยิ่งใหญ่:ความสง่างามของการหลับอย่างชาญฉลาด

ลองย้อนกลับไปสักครู่ เราเริ่มต้นจากร้านกาแฟที่มีบาริสต้าทำงานหนักเกินไป จากนั้นเราก็ค้นพบผู้ช่วยที่ซ่อนอยู่ นั่นคือ Low Power Island ที่ทำให้คาเฟ่ทำงานอย่างเงียบๆ แม้ว่าบาริสต้าหลักจะก้าวออกไป

เราเดินตามเส้นทางของซ็อกเก็ต Bluetooth ที่เรียบง่าย และเฝ้าดูซ็อกเก็ตนั้นถูกห่อหุ้มด้วย 254 เดินทางผ่าน HAL และในที่สุดก็ตกลงบนโปรเซสเซอร์ขนาดเล็กภายในตัวควบคุมที่ส่งเสียงฮัมไปในขณะที่ CPU ตัวใหญ่ฝัน

และนั่นคือความสวยงามของมัน:กลไกการถ่ายโอน Bluetooth ของ Android เป็นหนึ่งในตัวอย่างที่สวยงามที่สุดของวิศวกรรมที่มองไม่เห็น มันไม่ได้ประกาศตัวเองด้วย API ใหม่หรือแอนิเมชั่นแฟนซี มันเพียงแค่ทำให้แบตเตอรี่ใช้งานได้นานขึ้นโดยไร้เสียง บลูทูธของคุณเชื่อถือได้มากขึ้น และโทรศัพท์ของคุณก็รู้สึกนุ่มนวลขึ้น โดยที่คุณไม่รู้ตัวเลยว่ามีอยู่

จากมุมมองทางเทคนิค ความฉลาดนั้นอยู่ที่ความสมดุล ระบบยังคงอนุญาตให้ใช้ซ็อกเก็ตที่มีคุณสมบัติครบถ้วนและการจัดการโปรโตคอลที่หลากหลายเมื่อคุณต้องการ แต่สำหรับกระแสข้อมูลทั่วไป เสียง การวัดและส่งข้อมูลทางไกล การแจ้งเตือน หรือการสตรีมอัตราการเต้นของหัวใจ ระบบจะปล่อยให้ตัวควบคุมที่ใช้พลังงานต่ำควบคุมวงล้อ เหมือนกับว่า Android เรียนรู้ที่จะมอบหมาย

ทุกครั้งที่นาฬิกาอัจฉริยะของคุณซิงค์ในขณะที่หน้าจอโทรศัพท์ปิดอยู่ หรือหูฟังของคุณยังคงเชื่อมต่อระหว่างเที่ยวบินที่ยาวนานโดยไม่ทำให้แบตเตอรี่หมด คุณจะเห็น 263 และกรอบการทำงานของเกาะพลังงานต่ำ สิ่งเหล่านี้เป็นส่วนหนึ่งของปรัชญาที่ใหญ่กว่าในการออกแบบ Android สมัยใหม่ โดยนำความอัจฉริยะมาใกล้กับฮาร์ดแวร์มากขึ้น ยิ่งเราสอนชิปของเราให้จัดการกับงานอัตโนมัติมากเท่าไร เราก็จะปล่อยให้โปรเซสเซอร์หลักได้พักผ่อนมากขึ้นเท่านั้น

หากคุณเป็นนักพัฒนาหรือวิศวกรระบบ การทำความเข้าใจสถาปัตยกรรมนี้ไม่ใช่แค่เชิงวิชาการเท่านั้น มันสามารถสร้างแรงบันดาลใจให้กับวิธีที่คุณออกแบบคุณสมบัติของคุณเอง ไม่ว่าคุณจะสร้าง Android ROM แบบกำหนดเอง เพิ่มประสิทธิภาพเฟิร์มแวร์สำหรับอุปกรณ์สวมใส่ หรือสร้างอุปกรณ์ IoT ด้วยชิป Bluetooth บทเรียนก็มีความชัดเจน:อย่าให้ CPU หลักดูแลทุกแพ็กเก็ต ถ่ายเมื่อทำได้ นอนเมื่อควร และอุปกรณ์ของคุณจะขอบคุณคุณด้วยชั่วโมงการทำงานที่เพิ่มขึ้น

ดังนั้น ครั้งถัดไปที่คุณเสียบหูฟังเอียร์บัดและสังเกตเห็นว่าโทรศัพท์ยังคงเย็นอยู่และเปอร์เซ็นต์แบตเตอรี่แทบจะไม่เคลื่อนไหว โปรดจำไว้ว่า:ลึกเข้าไปข้างใน MCU บลูทูธตัวเล็กๆ ทำหน้าที่ยกของหนักทั้งหมด ในขณะที่ CPU หลักสนุกกับการงีบหลับในเปลญวนที่ใช้พลังงานต่ำ

นั่นคืออัจฉริยะอันเงียบสงบของ Low Power Island และ BluetoothSocketSettings ของ Android ไม่ใช่แค่เกี่ยวกับบลูทูธเท่านั้น เป็นการสอนอุปกรณ์ของเราให้ฉลาดขึ้น ไม่ยุ่งมากขึ้น และบางที บางที นั่นอาจเป็นบทเรียนที่ควรค่าแก่การจดจำด้วยตัวเราเองเช่นกัน

เรียนรู้การเขียนโค้ดฟรี หลักสูตรโอเพ่นซอร์สของ freeCodeCamp ช่วยให้ผู้คนมากกว่า 40,000 คนได้งานในตำแหน่งนักพัฒนา เริ่มต้น