Android RK356X TVSettings USB調試開關

Android RK356X TVSettings USB調試開關

    • 平臺
    • 概述
    • 操作-打開USB調試
    • 實現源碼
    • 補充說明

平臺

在這里插入圖片描述

RK3568 + Android 11

概述

RK3568 是瑞芯微(Rockchip)推出的一款高性能處理器,支持 USB OTG(On-The-Go)和 USB Host 功能。USB OTG 和 Host 的切換功能是 RK3568 的一項重要特性,允許設備在不同的 USB 角色之間動態切換,從而實現更靈活的應用場景。

USB OTG 和 Host 的切換功能

  1. USB OTG(On-The-Go)
    USB OTG 是一種允許設備在主機(Host)和設備(Device)之間動態切換的功能。通過 OTG 功能,RK3568 可以在以下兩種模式之間切換:
    ? 主機模式(Host Mode):RK3568 作為主機,連接其他 USB 設備(如 U 盤、鍵盤、鼠標等),并控制數據傳輸。

    ? 設備模式(Device Mode):RK3568 作為從設備,連接到主機(如 PC),被主機控制和數據傳輸。

  2. 動態切換
    RK3568 支持在運行時動態切換 USB OTG 和 Host 模式,無需重新啟動設備或重新插拔 USB 線纜。這種切換功能依賴于硬件設計和軟件驅動的支持。


應用場景
USB OTG 和 Host 的切換功能在以下場景中有廣泛應用:

  1. 移動設備
    ? 在智能手機、平板電腦等設備中,OTG 功能允許用戶通過 USB 連接外部設備(如 U 盤、鍵盤、鼠標等),擴展設備的功能。

    ? 例如,用戶可以將手機作為主機,連接 U 盤進行文件傳輸,或者連接鍵盤和鼠標進行辦公。

  2. 嵌入式設備
    ? 在嵌入式系統中,RK3568 的 OTG 功能可以用于連接各種 USB 設備,如打印機、攝像頭、傳感器等。

    ? 通過動態切換,設備可以在主機和從機模式之間切換,適應不同的應用需求。

  3. 工業控制
    ? 在工業自動化領域,RK3568 可以作為主機連接傳感器、控制器等設備,也可以作為從機連接到上位機(如 PC)進行數據采集和監控。

    ? 動態切換功能使得設備可以根據任務需求靈活調整角色。

  4. 車載系統
    ? 在車載娛樂系統或導航設備中,OTG 功能可以用于連接外部存儲設備(如 U 盤)播放媒體文件,或者連接診斷工具進行系統維護。

    ? 動態切換功能使得設備可以同時支持多種連接方式。

  5. 物聯網設備
    ? 在物聯網設備中,RK3568 可以通過 OTG 功能連接各種傳感器或執行器,實現數據采集和控制。

    ? 通過動態切換,設備可以根據網絡環境或任務需求調整角色。

  6. 調試和開發
    ? 在開發階段,OTG 功能可以用于連接調試工具(如 JTAG 調試器)或燒錄固件。

    ? 動態切換功能使得開發者可以方便地在不同模式之間切換,提高開發效率。


技術實現
RK3568 的 USB OTG 和 Host 切換功能依賴于以下硬件和軟件支持:
? 硬件支持:RK3568 集成了 USB OTG 控制器,支持動態角色切換。

? 軟件驅動:需要操作系統(如 Linux)提供相應的驅動程序和工具,支持 OTG 功能的動態切換。

? 外部電路設計:需要設計合適的 USB 接口電路,支持 OTG 功能(如 ID 引腳檢測)。

操作-打開USB調試

設置 > 設備偏好設置 > 開發者選項 > USB 連接狀態

在這里插入圖片描述

實現源碼

packages/apps/TvSettings/Settings/src/com/android/tv/settings/system/development/DevelopmentFragment.java

import com.android.tv.settings.dialog.UsbModeSettings;
/*** Displays preferences for application developers.*/
public class DevelopmentFragment extends SettingsPreferenceFragmentimplements Preference.OnPreferenceChangeListener,EnableDevelopmentDialog.Callback, OemUnlockDialog.Callback, AdbDialog.Callback {private static final String TAG = "DevelopmentSettings";private static final String ENABLE_DEVELOPER = "development_settings_enable";private static final String ENABLE_ADB = "enable_adb";private static final String ENABLE_USB = "enable_usb";//...省略代碼...@Overridepublic void onCreatePreferences(Bundle savedInstanceState, String rootKey) {mLogdSizeController = new LogdSizePreferenceController(getActivity());mLogpersistController = new LogpersistPreferenceController(getActivity(), getLifecycle());mUsbModeSetting = new UsbModeSettings(getPreferenceManager().getContext());if (!mUm.isAdminUser()|| mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)|| Settings.Global.getInt(mContentResolver,Settings.Global.DEVICE_PROVISIONED, 0) == 0) {// Block access to developer options if the user is not the owner, if user policy// restricts it, or if the device has not been provisionedmUnavailable = true;addPreferencesFromResource(R.xml.development_prefs_not_available);return;}addPreferencesFromResource(R.xml.development_prefs);final PreferenceScreen preferenceScreen = getPreferenceScreen();// Don't add to prefs lists or it'll disable itself when switched offmEnableDeveloper = (SwitchPreference) findPreference(ENABLE_DEVELOPER);final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);mEnableAdb = findAndInitSwitchPref(ENABLE_ADB);mEnableUsb = findAndInitSwitchPref(ENABLE_USB);mEnableInternetAdb = findAndInitSwitchPref(ENABLE_INTERNET_ADB);mEnableAbc = findAndInitSwitchPref(ENABLE_ABC);mEnableUsb.setChecked(mUsbModeSetting.getDefaultValue());if (mEnableUsb.isChecked()){mEnableUsb.setSummary(R.string.usb_connect_to_computer);} else {mEnableUsb.setSummary(R.string.usb_disconnect_to_computer);}//...省略代碼....}

packages/apps/TvSettings/Settings/src/com/android/tv/settings/dialog/UsbModeSettings.java

package com.android.tv.settings.dialog;import com.android.tv.settings.R;import android.content.Context;
import android.os.Handler;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import android.os.storage.StorageManager;
import android.os.storage.StorageEventListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.SystemProperties;
import android.text.TextUtils;import android.util.Log;public class UsbModeSettings {private static final String TAG = "UsbModeSettings";// 0 otg 1 host 2 peripheralpublic static final String HOST_MODE = new String("host");public static final String SLAVE_MODE = new String("otg");public static final String PROP_FAKE_DATA_ROLE = "persist.fake_data_role";private static final String FILE_NAME_RK3399 = "/sys/kernel/debug/usb@fe800000/rk_usb_force_mode";private static final String FILE_NAME_RK3328 = "/sys/devices/platform/ff450000.syscon/ff450000.syscon:usb2-phy@100/otg_mode";private static final String FILE_NAME_RK3229 = "/sys/devices/platform/11000000.syscon/11000000.syscon:usb2-phy@760/otg_mode";private static final String FILE_NAME_RK356X = "/sys/devices/platform/fe8a0000.usb2-phy/otg_mode";private File file = null;private StorageManager mStorageManager = null;private String mMode = "";private String mSocName = "";private Context mContext;private boolean mLock = false;public UsbModeSettings(Context context) {mContext = context;mSocName = SystemProperties.get("sys.rk.soc");if (TextUtils.isEmpty(mSocName)) {mSocName = SystemProperties.get("ro.board.platform");}if(!TextUtils.isEmpty(mSocName) && mSocName.contains("rk3399")){file = new File(FILE_NAME_RK3399);}else{file = new File(FILE_NAME_RK3328);}file = getFile();mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);boolean ret = checkFile();String mode = ReadFromFile(file);if(ret && !TextUtils.isEmpty(mode)) {mMode = mode;}}private File getFile() {String fileName = FILE_NAME_RK3328;if (!TextUtils.isEmpty(mSocName) && mSocName.contains("rk3399")) {fileName = FILE_NAME_RK3399;} else if (!TextUtils.isEmpty(mSocName) && (mSocName.contains("rk322x") || mSocName.contains("rk3128h"))) {fileName = FILE_NAME_RK3229;} else if (!TextUtils.isEmpty(mSocName) && mSocName.contains("rk356x")) {fileName = FILE_NAME_RK356X;} else {fileName = FILE_NAME_RK3328;}return new File(fileName);}public boolean getDefaultValue() {if (isRk3368()) {//通過prop和init來設置otg模式return getFakeDataRole();}if (checkFile()) {Log.d("UsbModeSelect", "/data/otg.cfg not exist,but temp file exist");if (isRk3368()) {return getFakeDataRole();}if (mMode.equals(HOST_MODE)) {return false;} else {return true;}} else {mMode = HOST_MODE;return false;}}private String ReadFromFile(File file) {if (checkFile()) {try {FileInputStream fin = new FileInputStream(file);BufferedReader reader = new BufferedReader(new InputStreamReader(fin));String config = reader.readLine();fin.close();return config;} catch (IOException e) {Log.i(TAG, "ReadFromFile exception:" + e);e.printStackTrace();}}return null;}private void Write2File(File file, String mode) {if (!checkFile() || (mode == null))return;Log.d("UsbModeSelect", "Write2File,write mode = " + mode);try {FileOutputStream fout = new FileOutputStream(file);PrintWriter pWriter = new PrintWriter(fout);pWriter.println(mode);pWriter.flush();pWriter.close();fout.close();} catch (IOException re) {}}public void onUsbModeClick(String mode) {if (isRk3368()) {setPropFakeDataRole(mode);return;}if (mLock)return;mLock = true;mMode = mode;synchronized (this) {Log.d("UsbModeSettings", "synchronized start");new Thread(mUsbSwitch).start();}}private Runnable mUsbSwitch = new Runnable() {public synchronized void run() {Log.d("UsbModeSettings", "mUsbSwitch Runnable() in*******************");if (mStorageManager != null) {if (mMode == HOST_MODE) {mStorageManager.disableUsbMassStorage();Log.d("UsbModeSettings", "mStorageManager.disableUsbMassStorage()*******************");Write2File(file, mMode);} else {Write2File(file, mMode);Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()  in *******************");mStorageManager.enableUsbMassStorage();Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()   out*******************");}}Log.d("UsbModeSettings", "mUsbSwitch Runnable() out*******************");mLock = false;}};private boolean checkFile() {if (file == null) {Log.e(TAG, "file is null pointer");return false;}String fileName = file.getName();if (!file.exists()) {Log.e(TAG, fileName + " not exist!!!");return false;}if (!file.canRead()) {Log.e(TAG, fileName + " can't read!!!");return false;}if (!file.canWrite()) {Log.e(TAG, fileName + " can't write!!!");return false;}return true;}// 判斷是否為3368芯片private boolean isRk3368() {if (!TextUtils.isEmpty(mSocName) && mSocName.contains("rk3368")) {return true;} else {return false;}}private boolean getFakeDataRole() {String fakeDataRole = SystemProperties.get(PROP_FAKE_DATA_ROLE, SLAVE_MODE);Log.d(TAG, "prop fakeDataRole = " + fakeDataRole);if (!TextUtils.isEmpty(fakeDataRole) && fakeDataRole.equals(SLAVE_MODE)) {return true;} else {return false;}}// 將mode轉換為Int值,3368的mode為0,1,2private void setPropFakeDataRole(String mode) {Log.d(TAG, "setprop mode = " + mode);SystemProperties.set(PROP_FAKE_DATA_ROLE, mode);}
}

補充說明

  1. 以上源碼接口需要system及以上權限
  2. StorageManager部分接口可以通過反射獲得.

提取關鍵代碼:

    @Overridepublic void onClick(View v) {StorageManager mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);File file = new File(FILE_NAME_RK356X);//切換為 OTG (USB 調試)if(R.id.btOtg == v.getId()) {Write2File(file, SLAVE_MODE);Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()  in *******************");enableUsbMassStorage(mStorageManager);Log.d("UsbModeSettings", "mStorageManager.enableUsbMassStorage()   out*******************");} else if(R.id.btHost == v.getId()) {//切換為HOSTdisableUsbMassStorage(mStorageManager);Log.d("UsbModeSettings", "mStorageManager.disableUsbMassStorage()*******************");Write2File(file, HOST_MODE);}}//寫入 USB的模式: otg 或 hostprivate void Write2File(File file, String mode) {if (!new File(FILE_NAME_RK356X).exists() || (mode == null))return;Log.d("UsbModeSelect", "Write2File,write mode = " + mode);try {FileOutputStream fout = new FileOutputStream(file);PrintWriter pWriter = new PrintWriter(fout);pWriter.println(mode);pWriter.flush();pWriter.close();fout.close();} catch (IOException re) {}}//反射接口void enableUsbMassStorage(StorageManager sm){try {Method enableUsbMassStorage = sm.getClass().getMethod("enableUsbMassStorage");enableUsbMassStorage.invoke(sm);} catch (Exception e){e.printStackTrace();}}void disableUsbMassStorage(StorageManager sm){try {Method disableUsbMassStorage = sm.getClass().getMethod("disableUsbMassStorage");disableUsbMassStorage.invoke(sm);} catch (Exception e){e.printStackTrace();}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902381.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902381.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902381.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Microsoft Edge for linux debian

下載地址 https://www.microsoft.com/en-us/edge/download?formMA13FJ 安裝 # 下載安裝包 wget https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/microsoft-edge-stable_135.0.3179.85-1_amd64.deb?brandM102 # 安裝 sudo dpkg -i microsoft…

typedef MVS_API CLISTDEF0IDX(ViewScore, IIndex) ViewScoreArr;

查找 MVS_API 定義 我們沒有在 List.h 文件中找到 MVS_API 的定義。MVS_API 很可能在 MVS 庫的其他地方定義。一般來說,MVS_API 是控制 OpenMVS 庫導入導出的宏,通常會出現在 MVS 的頭文件中。為了回答這個問題,我可以提供 MVS 代碼中常見的…

5.4/Q1,GBD數據庫最新文章解讀

文章題目:The global burden of high BMI among adolescents between 1990 and 2021 DOI:10.1038/s43856-025-00838-2 中文標題:1990 年至 2021 年青少年高 BMI 的全球負擔 發表雜志:Commun Med 影響因子:1區&#xff…

【形式化驗證基礎】活躍屬性Liveness Property和安全性質(Safety Property)介紹

文章目錄 一、Liveness Property1、概念介紹2、形式化定義二、Safety Property1. 定義回顧2. 核心概念解析3. 為什么強調“有限前綴”4. 示例說明4.1 示例1:交通信號燈系統4.2 示例2:銀行賬戶管理系統5. 實際應用的意義三. 總結一、Liveness Property 1、概念介紹 在系統的…

Redis面試——常用命令

一、String (1)設置值相關命令 1.1.1 SET 功能:設置一個鍵值對,如果鍵已存在則覆蓋舊值語法: SET key value [EX seconds] [PX milliseconds] [NX|XX]EX seconds:設置鍵的過期時間為 seconds 秒 PX milli…

【Unity】使用Cinemachine+CharacterController實現第三人稱視角下的角色視角、移動和跳躍控制

1.初始配置 安裝Cinemachine插件給角色添加CharacterConroller創建Cinemachine-->Free Look Camera在Free Look Camera中調整參數,Y Axis勾選Inver,X Axis取消勾選InverFree Look Camera要看向角色 跟隨角色(自行設置,我就不…

深入理解 DML 和 DQL:SQL 數據操作與查詢全解析

深入理解 DML 和 DQL:SQL 數據操作與查詢全解析 在數據庫管理中,SQL(結構化查詢語言)是操作和查詢數據的核心工具。其中,DML(Data Manipulation Language,數據操作語言) 和 DQL&…

MongoDB數據庫的安裝到入門使用詳細講解

本篇文章主要講解MongoDB的安裝使用教程及基礎的數據庫管理和操作能力的講解,通過本篇文章您可以快速的掌握對MongDB數據庫的基本認識及,基礎開發能力。 一、MongoDB介紹 MongoDB是一款免費開源的非關系型數據庫,該數據庫適應于復雜關系的存儲和管理,非常適合數據結構復雜…

git提交實現文件或目錄忽略

前言 開發中使用git下載項目代碼開發,存在不需要提交文件或目錄,這里記錄下ideajava項目開發添加以下配置可忽略不需要提交文件,以方便我們提交代碼時,查看及提交文件只涉及項目代碼修改文件。 git提交實現文件或目錄忽略 .gitignore 文件的內容列出了在…

go語言的八股文

1.go語言觸發異常的場景有哪些 運行時錯誤 1.空指針解引用:嘗試訪問一個未初始化的指針指向的內存,會導致程序崩潰并觸發異常。 2.數組越界訪問:試圖訪問數組中不存在的索引,比如數組長度為5,卻嘗試訪問索引為10的元素…

Ubuntu安裝MySQL步驟及注意事項

一、安裝前準備 1. 系統更新:在安裝 MySQL 之前,確保你的 Ubuntu 系統軟件包是最新的,這能避免因軟件包版本問題導致的安裝錯誤,并獲取最新的安全補丁。打開終端,執行以下兩條命令: sudo apt update sudo …

【愚公系列】《Python網絡爬蟲從入門到精通》054-Scrapy 文件下載

🌟【技術大咖愚公搬代碼:全棧專家的成長之路,你關注的寶藏博主在這里!】🌟 📣開發者圈持續輸出高質量干貨的"愚公精神"踐行者——全網百萬開發者都在追更的頂級技術博主! &#x1f…

2025最新︱中國信通院靜態應用程序安全測試(SAST)工具能力評估,懸鏡安全靈脈AI通過評估!

背景 研發運營安全(DevSecOps)從研發運營(DevOps)的概念延伸和演變而來,其核心理念是將安全貫穿從開發到運營的軟件開發生命周期的每一個環節,在每個階段自動實施安全措施,從而實現快速開發交付…

辛格迪客戶案例 | 浙江高跖醫藥委托生產質量管理協同(OWL MAH)項目

一、案例概述 浙江高跖醫藥科技股份有限公司是一家集“研、產、銷”為一體的專業化藥品持證企業。高跖醫藥自成立之初就建立并運行著一套相對完善的質量管理體系,涵蓋了藥品的研發、生產監管及銷售。高跖醫藥于2022年選擇實施了辛格迪的“委托生產質量管理協同解決…

【NLP 65、實踐 ? 基于Agent優化文章】

羈絆由我而起,痛苦也由我承擔 —— 25.4.18 一、?【核心函數】定義大模型調用函數 call_large_model prompt:用戶傳入的提示詞(如 “請分析這篇作文的主題”),指導模型執行任務 client:Zhipu…

【鋰電池SOH估計】BP神經網絡鋰電池健康狀態估計,鋰電池SOH估計(Matlab完整源碼和數據)

目錄 效果一覽程序獲取程序內容研究內容基于BP神經網絡的鋰電池健康狀態估計研究摘要關鍵詞1. 引言1.1 研究背景1.2 研究意義1.3 研究目標2. 文獻綜述2.1 鋰電池SOH估計理論基礎2.2 傳統SOH估計方法2.3 基于BP神經網絡的SOH估計研究進展2.4 研究空白與創新點3. BP神經網絡原理3…

2025第十六屆藍橋杯python B組滿分題解(詳細)

目錄 前言 A: 攻擊次數 解題思路: 代碼: B: 最長字符串 解題思路: 代碼: C: LQ圖形 解題思路: 代碼: D: 最多次數 解題思路: 代碼: E: A * B Problem 解題思路&…

第十二節:原理深挖-React Fiber架構核心思想

鏈表結構、時間切片(Time Slicing) 優先級調度實現(如用戶輸入>網絡請求) React Fiber架構深度解析:從鏈表到優先級調度的革命性升級 一、Fiber架構核心設計思想 React Fiber是React 16的底層協調算法重構&#x…

你學會了些什么211201?--http基礎知識

概念 HTTP–Hyper Text Transfer Protocol,超文本傳輸協議;是一種建立在TCP上的無狀態連接(短連接)。 整個基本的工作流程是:客戶端發送一個HTTP請求(Request ),這個請求說明了客戶端…

MCU開發學習記錄8 - 基本定時器學習與實踐(HAL庫) - 定時器DMA循環模式修改ARR值、定時器中斷方式修改ARR值 - STM32CubeMX

名詞解釋: TRGO:Trigger Out General Purpose Output ARR:Auto-reload PSC:Prescaler CNT:Counter EGR:event generation register 本文將介紹基本定時器的概念、相關函數以及STM32CubeMX生成定時器的配置…