android bluetooth 移植相关注意事项

bluedroid的通用架构框图:




由上图可知,bluedroid包含如下的核心组件:

Bluetooth core stack library

HCI library

Vendor Specific HCI library

UART, RFKILL,TUN/TAP and UHID device drivers


移植过程

基于android上bluedroid上的蓝牙移植涉及到文件有:

bluetooth.apk

bludroid协议栈涉及到的库:

bluetooth.default.so

libbt-hci.so

libbt-utils.so

libbt-vendor.so

audio.a2dp.default.so

android.hardware.bluetooth.xml:该文件用于控制是否显示蓝牙的设置界面,位于/etc/permissions/目录下

bluetooth.default.so依赖于libbt-hci.so、libbt-utils.so、libbt-vendor.so等动态库,该库是蓝牙bluedroid协议栈的核心,该库的核心文件bluetooth.c实现了蓝牙的HAL层。

该硬件抽象层对应的接口定义如下(hardware/include/hardware/bluetooth.h):

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** NOTE: By default, no profiles are initialized at the time of init/enable. 
  2.  *  Whenever the application invokes the 'init' API of a profile, then one of 
  3.  *  the following shall occur: 
  4.  * 
  5.  *    1.) If Bluetooth is not enabled, then the Bluetooth core shall mark the 
  6.  *        profile as enabled. Subsequently, when the application invokes the 
  7.  *        Bluetooth 'enable', as part of the enable sequence the profile that were 
  8.  *        marked shall be enabled by calling appropriate stack APIs. The 
  9.  *        'adapter_properties_cb' shall return the list of UUIDs of the 
  10.  *        enabled profiles. 
  11.  * 
  12.  *    2.) If Bluetooth is enabled, then the Bluetooth core shall invoke the stack 
  13.  *        profile API to initialize the profile and trigger a 
  14.  *        'adapter_properties_cb' with the current list of UUIDs including the 
  15.  *        newly added profile's UUID. 
  16.  * 
  17.  *   The reverse shall occur whenever the profile 'cleanup' APIs are invoked 
  18.  */  
  19.   
  20.   
  21. /** Represents the standard Bluetooth DM interface. */  
  22. typedef struct {  
  23.     /** set to sizeof(bt_interface_t) */  
  24.     size_t size;  
  25.     /** 
  26.      * Opens the interface and provides the callback routines 
  27.      * to the implemenation of this interface. 
  28.      */  
  29.     int (*init)(bt_callbacks_t* callbacks );  
  30.   
  31.   
  32.     /** Enable Bluetooth. */  
  33.     int (*enable)(void);  
  34.   
  35.   
  36.     /** Disable Bluetooth. */  
  37.     int (*disable)(void);  
  38.   
  39.   
  40.     /** This ensures the chip is Powered ON  to support other radios in the combo chip. 
  41.      * If the chip is OFF it set the chip to ON, if it is already ON it just increases the radio ref count 
  42.      * to keep track when to Power OFF */  
  43.     int (*enableRadio)(void);  
  44.   
  45.   
  46.     /** This decreases radio ref count  and ensures that chip is Powered OFF 
  47.      * when the radio ref count becomes zero. */  
  48.     int (*disableRadio)(void);  
  49.   
  50.   
  51.     /** Closes the interface. */  
  52.     void (*cleanup)(void);  
  53.   
  54.   
  55.     /** Get all Bluetooth Adapter properties at init */  
  56.     int (*get_adapter_properties)(void);  
  57.   
  58.   
  59.     /** Get Bluetooth Adapter property of 'type' */  
  60.     int (*get_adapter_property)(bt_property_type_t type);  
  61.   
  62.   
  63.     /** Set Bluetooth Adapter property of 'type' */  
  64.     /* Based on the type, val shall be one of 
  65.      * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc 
  66.      */  
  67.     int (*set_adapter_property)(const bt_property_t *property);  
  68.   
  69.   
  70.     /** Get all Remote Device properties */  
  71.     int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);  
  72.   
  73.   
  74.     /** Get Remote Device property of 'type' */  
  75.     int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,  
  76.                                       bt_property_type_t type);  
  77.   
  78.   
  79.     /** Set Remote Device property of 'type' */  
  80.     int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,  
  81.                                       const bt_property_t *property);  
  82.   
  83.   
  84.     /** Get Remote Device's service record  for the given UUID */  
  85.     int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,  
  86.                                      bt_uuid_t *uuid);  
  87.   
  88.   
  89.     /** Start SDP to get remote services */  
  90.     int (*get_remote_services)(bt_bdaddr_t *remote_addr);  
  91.   
  92.   
  93.     /** Start Discovery */  
  94.     int (*start_discovery)(void);  
  95.   
  96.   
  97.     /** Cancel Discovery */  
  98.     int (*cancel_discovery)(void);  
  99.   
  100.   
  101.     /** Create Bluetooth Bonding */  
  102.     int (*create_bond)(const bt_bdaddr_t *bd_addr);  
  103.   
  104.   
  105.     /** Remove Bond */  
  106.     int (*remove_bond)(const bt_bdaddr_t *bd_addr);  
  107.   
  108.   
  109.     /** Cancel Bond */  
  110.     int (*cancel_bond)(const bt_bdaddr_t *bd_addr);  
  111.   
  112.   
  113.     /** BT Legacy PinKey Reply */  
  114.     /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */  
  115.     int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,  
  116.                      uint8_t pin_len, bt_pin_code_t *pin_code);  
  117.   
  118.   
  119.     /** BT SSP Reply - Just Works, Numeric Comparison and Passkey 
  120.      * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON & 
  121.      * BT_SSP_VARIANT_CONSENT 
  122.      * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey 
  123.      * shall be zero */  
  124.     int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,  
  125.                      uint8_t accept, uint32_t passkey);  
  126.   
  127.   
  128.     /** Get Bluetooth profile interface */  
  129.     const void* (*get_profile_interface) (const char *profile_id);  
  130.   
  131.   
  132.     /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */  
  133.     /* Configure DUT Mode - Use this mode to enter/exit DUT mode */  
  134.     int (*dut_mode_configure)(uint8_t enable);  
  135.   
  136.   
  137.     /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */  
  138.     int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);  
  139.   
  140.   
  141.    /* Send  service level Authorization response */  
  142.    int (*authorize_response)(const bt_bdaddr_t *bd_addr, bt_service_id_t service_id,  
  143.                              uint8_t authorize, uint8_t save_settings);  
  144.   
  145.   
  146.     /** Get FM module interface */  
  147.     const void* (*get_fm_interface) ();  
  148.   
  149.   
  150.     /** BLE Test Mode APIs */  
  151.     /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */  
  152.     int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);  
  153. } bt_interface_t;  
bluetooth.c和bluetooth.h对应到上面图1中的libhardware层。

而bluetooth services和bluetooth JNI编译出来的结果就是bluetooth.apk, bluetooth services透过bluetooth JNI,bluetooth JNI透过硬件抽象层,直接调用到bluedroid的核心协议栈,而核心协议栈通过uart driver,rfkill driver,UHID,TUN等vfs文件接口直接调用到内核空间的驱动。


audio.a2dp.default.so文件是音频模块针对ad2p的硬件抽象层的实现,供音频模块来控制a2dp的通路切换,声音和音量的控制。注意该模块跟BT_PROFILE_ADVANCED_AUDIO_ID模块的关系。


libbt-vendor.so是需要根据特定的蓝牙芯片去客制化实现的。

具体该移植库(libbt-vendor.so),需要实现如下的通用接口(external/bluetooth/bluedroid/hci/include/bt_vendor_lib.h):

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Bluetooth Host/Controller VENDOR Interface 
  3.  */  
  4. typedef struct {  
  5.     /** Set to sizeof(bt_vndor_interface_t) */  
  6.     size_t          size;  
  7.   
  8.     /* 
  9.      * Functions need to be implemented in Vendor libray (libbt-vendor.so). 
  10.      */  
  11.   
  12.     /** 
  13.      * Caller will open the interface and pass in the callback routines 
  14.      * to the implemenation of this interface. 
  15.      */  
  16.     int   (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr);  
  17.   
  18.     /**  Vendor specific operations */  
  19.     int (*op)(bt_vendor_opcode_t opcode, void *param);  
  20.   
  21.     /** Closes the interface */  
  22.     void  (*cleanup)(void);  
  23. } bt_vendor_interface_t;  




在以上结构体中,其中大部份的工作是由int (*op)(bt_vendor_opcode_t opcode, void *param);函数实现,该函数更具OPCODE操作码的不同,一般通过switch语句来实现。

各个OPCODE操作码对应的功能说明如下:(external/bluetooth/bluedroid/hci/include/bt_vendor_lib.h)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** Vendor specific operations OPCODE */  
  2. typedef enum {  
  3. /*  [operation] 
  4.  *      Power on or off the BT Controller. 
  5.  *  [input param] 
  6.  *      A pointer to int type with content of bt_vendor_power_state_t. 
  7.  *      Typecasting conversion: (int *) param. 
  8.  *  [return] 
  9.  *      0 - default, don't care. 
  10.  *  [callback] 
  11.  *      None. 
  12.  */  
  13.     BT_VND_OP_POWER_CTRL,  
  14.   
  15.   
  16. /*  [operation] 
  17.  *      Perform any vendor specific initialization or configuration 
  18.  *      on the BT Controller. This is called before stack initialization. 
  19.  *  [input param] 
  20.  *      None. 
  21.  *  [return] 
  22.  *      0 - default, don't care. 
  23.  *  [callback] 
  24.  *      Must call fwcfg_cb to notify the stack of the completion of vendor 
  25.  *      specific initialization once it has been done. 
  26.  */  
  27.     BT_VND_OP_FW_CFG,  
  28.   
  29.   
  30. /*  [operation] 
  31.  *      Perform any vendor specific SCO/PCM configuration on the BT Controller. 
  32.  *      This is called after stack initialization. 
  33.  *  [input param] 
  34.  *      None. 
  35.  *  [return] 
  36.  *      0 - default, don't care. 
  37.  *  [callback] 
  38.  *      Must call scocfg_cb to notify the stack of the completion of vendor 
  39.  *      specific SCO configuration once it has been done. 
  40.  */  
  41.     BT_VND_OP_SCO_CFG,  
  42.   
  43.   
  44. /*  [operation] 
  45.  *      Open UART port on where the BT Controller is attached. 
  46.  *      This is called before stack initialization. 
  47.  *  [input param] 
  48.  *      A pointer to int array type for open file descriptors. 
  49.  *      The mapping of HCI channel to fd slot in the int array is given in 
  50.  *      bt_vendor_hci_channels_t. 
  51.  *      And, it requires the vendor lib to fill up the content before returning 
  52.  *      the call. 
  53.  *      Typecasting conversion: (int (*)[]) param. 
  54.  *  [return] 
  55.  *      Numbers of opened file descriptors. 
  56.      *      Valid number: 
  57.      *          1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART) 
  58.      *          2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd 
  59.      *          4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd 
  60.  *  [callback] 
  61.  *      None. 
  62.  */  
  63.     BT_VND_OP_USERIAL_OPEN,  
  64.   
  65.   
  66. /*  [operation] 
  67.  *      Close the previously opened UART port. 
  68.  *  [input param] 
  69.  *      None. 
  70.  *  [return] 
  71.  *      0 - default, don't care. 
  72.  *  [callback] 
  73.  *      None. 
  74.  */  
  75.     BT_VND_OP_USERIAL_CLOSE,  
  76.   
  77.   
  78. /*  [operation] 
  79.  *      Get the LPM idle timeout in milliseconds. 
  80.  *      The stack uses this information to launch a timer delay before it 
  81.  *      attempts to de-assert LPM WAKE signal once downstream HCI packet 
  82.  *      has been delivered. 
  83.  *  [input param] 
  84.  *      A pointer to uint32_t type which is passed in by the stack. And, it 
  85.  *      requires the vendor lib to fill up the content before returning 
  86.  *      the call. 
  87.  *      Typecasting conversion: (uint32_t *) param. 
  88.  *  [return] 
  89.  *      0 - default, don't care. 
  90.  *  [callback] 
  91.  *      None. 
  92.  */  
  93.     BT_VND_OP_GET_LPM_IDLE_TIMEOUT,  
  94.   
  95.   
  96. /*  [operation] 
  97.  *      Enable or disable LPM mode on BT Controller. 
  98.  *  [input param] 
  99.  *      A pointer to uint8_t type with content of bt_vendor_lpm_mode_t. 
  100.  *      Typecasting conversion: (uint8_t *) param. 
  101.  *  [return] 
  102.  *      0 - default, don't care. 
  103.  *  [callback] 
  104.  *      Must call lpm_cb to notify the stack of the completion of LPM 
  105.  *      disable/enable process once it has been done. 
  106.  */  
  107.     BT_VND_OP_LPM_SET_MODE,  
  108.   
  109.   
  110. /*  [operation] 
  111.  *      Assert or Deassert LPM WAKE on BT Controller. 
  112.  *  [input param] 
  113.  *      A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t. 
  114.  *      Typecasting conversion: (uint8_t *) param. 
  115.  *  [return] 
  116.  *      0 - default, don't care. 
  117.  *  [callback] 
  118.  *      None. 
  119.  */  
  120.     BT_VND_OP_LPM_WAKE_SET_STATE,  
  121. } bt_vendor_opcode_t;  
以上注释中说明了各个操作码的功能,也就是我们基于bluedroid进行蓝牙移植的最主要的工作量。easy吧?呵呵!简单就是美。


另外还有就是蓝协议栈的配置选项,分为两种:

一种是编译时的配置选项

一种是运行时的配置选项

涉及蓝牙相关的通用配置选项有(具体配置格式的组织是 vendor specific的):

1:uart的端口号,如/dev/ttyS1, /dev/ttS2,/dev/ttyO1等等

2: uart的boadrate,如921600,460800,3000000等

3: 蓝牙固件的名字和路径

4: 是否使能LPM mode(低功耗管理模式)

5: PCM的配置

6: 如果是cob(chip on board)的蓝牙芯片,还需要指定蓝牙mac地址,如果是模块的一般直接可有从模块里读出来,则不需要该项


调试过程

在软件包按上面说的已经准备好的情况,在开发版上实际调试时,应该经历如下的步骤:

硬件方面有如下的check点:

1:蓝牙的power_enable是否正常

2:蓝牙的32Khz是否正常,并且是否足够接近32768HZ

3:蓝牙的26MHZ是否正常

4:蓝牙的硬件流控双方是否支持,如果不支持,需要硬件上进行欺骗:譬如brcm的蓝牙芯片是必须需要硬件流控,而我们uart 主控的硬件流控却有问题,因此我们将brcm的蓝牙端的cts pin硬件拉地(low active),这样就是相当于告诉拨通的蓝牙芯片,我们的uart controller始终都是准备好可以接收数据的。从而实现无硬件流控也可以实现互通讯

5:uart是否需要电平转换,像我们的AP 输出的都是3.3v的电平,而拨通的蓝牙则则只能输出1.8v的电平,这样的话,就需要在拨通的rts和tx pin上接电平转换,将拨通的1.8v提升到3.3v,这样可以让我们AP能够正确检测到高电平。

6:蓝牙芯片的工作电压是否正常


软件方面的调试:

1:通过控制台命令:echo 1/0 > /sys/class/rfkill/rfill0/state再结合示波器来检测power enabe pin和32KHZ的输出/关闭是否正常

2:通过配置文件/etc/bluetooth/bt_stack.conf文件,我们可以来用来控制调试信息的显示,和蓝牙封包的保存,他能够将hci层的cmd,data,event包都保存到btsnoop_hci.log文件中,然后可以通过frontline公司的capture file viewer工具来查看封包的格式和含义。

bt_stack.conf的格式如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /system/etc/bluetooth #   
  2. /system/etc/bluetooth # cat bt_stack.conf   
  3. # Set the phone BT device name  
  4. #Name=Bluetooth Phone  
  5.   
  6. # Set the phone BT device COD (Class of Device)  
  7. #Class={0x5A, 0x02, 0x0C}  
  8.   
  9. # Enable BtSnoop logging function  
  10. # valid value : true, false  
  11. BtSnoopLogOutput=false  
  12.   
  13. # BtSnoop log output file  
  14. BtSnoopFileName=/sdcard/btsnoop_hci.log  
  15.   
  16. # Enable trace level reconfiguration function  
  17. # Must be present before any TRC_ trace level settings  
  18. TraceConf=true  
  19.   
  20. # Trace level configuration  
  21. #   BT_TRACE_LEVEL_NONE    0    ( No trace messages to be generated )  
  22. #   BT_TRACE_LEVEL_ERROR   1    ( Error condition trace messages )  
  23. #   BT_TRACE_LEVEL_WARNING 2    ( Warning condition trace messages )  
  24. #   BT_TRACE_LEVEL_API     3    ( API traces )  
  25. #   BT_TRACE_LEVEL_EVENT   4    ( Debug messages for events )  
  26. #   BT_TRACE_LEVEL_DEBUG   5    ( Full debug messages )  
  27. #   BT_TRACE_LEVEL_VERBOSE 6    ( Verbose messages ) - Currently supported for TRC_BTAPP only.  
  28. TRC_BTM=2  
  29. TRC_HCI=2  
  30. TRC_L2CAP=2  
  31. TRC_RFCOMM=2  
  32. TRC_OBEX=2  
  33. TRC_AVCT=2  
  34. TRC_AVDT=2  
  35. TRC_AVRC=2  
  36. TRC_AVDT_SCB=2  
  37. TRC_AVDT_CCB=2  
  38. TRC_A2D=2  
  39. TRC_SDP=2  
  40. TRC_GATT=2  
  41. TRC_SMP=2  
  42. TRC_BTAPP=2  
  43. TRC_PROTOCOL=0  
3:上一种方法有一个局限性,那就是只能保存完整的hci包,如果hci包不完整,则不能够通过btsnoop_hci.log文件来查看,这个时候可以在hci_h4.c文件中的hci_h4_send_msg函数和userial.c文件中的userial_read_thread函数中添加array2strings()来将串口上发送和接收的数据都打印出来,这样就可以发现那些不完整的hci包。array2strings实现如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int array2strings(char* header, char * array_buf, int array_len)  
  2. {  
  3. #if BT_DEBUG  
  4.     int n,i;  
  5.     uint8_t buf_strings[1600];  
  6.     //IS_DEBUG_ENABLE_CMD_EVENT;  
  7.     memset(buf_strings,0,sizeof(buf_strings));  
  8.     char * tmpbuf = (char * )buf_strings;  
  9.     array_len = (array_len>32)?32:array_len;  
  10.     for(i=0; i<array_len; i++)  
  11.     {  
  12.         n = sprintf(tmpbuf,"0x%x ",array_buf[i]);  
  13.         tmpbuf += n;  
  14.     }  
  15.     ALOGD("%s:len=%d %s", header, array_len, buf_strings);  
  16. #endif  
  17.     return 0;  
  18. }  

4:涉及硬件流控的情况下,需要注意的问题:

有些ap的uart cotroller并不支持硬件流控,这样的话在蓝牙芯片初始化过程中,会碰到如下一些问题:

A: 在切换波特率时会出现错误:

原因就是有些蓝牙芯片,如brcm的6330/6476等芯片在蓝牙芯片和uart controller的波特率切换到较高的波特率时,蓝牙芯片端会忙一段时间,在这段时间里,uart controller就不能够给蓝牙芯片段发送命令或数据。

否则会导致命令或数据超时无响应。如果支持硬件流控则不会存在该问题,因为蓝牙芯片端在切换到高波特率时,在忙的时间段,他会自动将芯片的rts脚拉高,uart controller端在检测到cts变高,认为接收端在忙,

从而不会将数据发送出去,而只是将数据缓存在tty xmit buffer中,待cts变低后,再继续从tty xmit buffer取数据通过dma方式发送出去。

B: 会出现应用层已经将数据写到了/dev/ttyS1设备里,但uart controller并未将数据在tx pin上发送出来。

原因是蓝牙芯片的硬件流控极性跟ap中的uart controller定义的硬件流控的极性不一致,导致蓝牙芯片已经通知ap端,蓝牙芯片已经准备好接受数据,但由于极性不一致,所以导致ap段一直以为蓝牙芯片端没有准备好,所以一直未发送数据。出现这个钟情况时,就是第一条hci reset的命令都不能发送出去。蓝牙芯片的rx pin上也未有任何的波形。这个时候可以通过查看 state->port.tty->hw_stopped位是否为1,如果为1,说明正是由于ap的uart controller检测到硬件流控不允许所以才未发送。

uart驱动的调试


uart drivers的调试方法有:
1: 可以考虑将蓝牙芯片uart口的tx pin在接到AP端的uart口的rx pin的同时也接到pc com口上的rx pin,同理将蓝牙芯片uart口上rx pin同时接到pc com上rx pin,这样可以通过pc上uart debug tool可以看到AP发送给蓝牙芯片的数据和蓝牙芯片送回来的数据。以检查串口收发数据的正确性。局限性是:由于目前pc com上的波特率不能设置太高,所以一般只能在低速的115200上进行调试。

2:在串口驱动添加/proc文件属性来动态的观察uart drivers的工作状况。
譬如在蓝牙串口出错时,我们可以命令:cat /proc/bt_debug来查看串口的如下信息:

a: uart controller的寄存器上下文
b: uart DMA rx buffer中是否还有剩余数据未通过tty_insert_flip_string_fixed_flag函数提交到tty io层
会导致bluedroid层收到一个不完整的数据包,但uart controller其实已经收到了一个完整的数据包
c: uart xmit circ_buf中是否还有剩余数据未能及时发送出去
这会导致蓝牙芯片收到一个不完整的hci包,从而导致蓝牙出错
d: 在proc的文件属性中,还可以添加关键的一些变量的值,这样检测出错时,这些是否正确。
譬如打印port.icount.rx,port.icount.tx,port.icount.overrun,port.icount.parity
port.icount.cts,port.tty->hw_stopped,port.tty->stopped等。

3: 内存数据查看工具:mu命令
该命令可以查看DMA tx buf和DMA rx buf中的数据内容,可以非常的方便检查数据收发是否正确
4: 有时在蓝牙芯片的reset,enable pin,32Khz,26Mhz等都正常的情况下,蓝牙的初始化还是未能正常完成,提示uart发送超时的话。
这个时候,就可以用示波器来测试下ap端的uart的cotroller的tx pin是否有波形发出来,如果有波形发送出来,
但蓝牙芯片段的tx pin没有任何回复波形,则基本可以断定是一下几种问题之一:
a:蓝牙电路上还有问题(请按上面的硬件check点,逐项检测)
b:蓝牙芯片的上电时序还有问题(请严格按芯片的datasheet上电时许规范来配置)

如果ap端的uart的cotroller的tx pin没有波形出来。那基本可以肯定,是如下问题之一:

a:硬件流控的问题(详细的见上面有关流控注意事项)

b:uart驱动的问题(不得不说,这个的调试要比其他驱动更具有挑战性)

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
########################BT FM ########################## Download the image using command: 1 # Flash Image Put the board in Flashing mode. Refer below Appendix - 1 cd <your path>/Nvidia_Demo/android_gb_cardhu_os_image sudo ./nvflash --bct flash.bct --setbct --odmdata 0x40080105 --configfile flash.cfg --create --bl bootloader.bin --go #################################################################################################################################################################################################### Appendix - 1 Nvidia Board in Flashing Mode #################################################################################################################################################################################################### 1. Connect the Debug board to Cardhu board. 2. Connect the power supply and Micro USB to Cardhu 3. On the Debug Board Press S12 (FRC RCV), Keeping this pressed Press and release S7 (RESET), Now Release S12. 4. Now Device is in Flashing mode, We can start nvflash command now. #################################################################################################################################################################################################### Appendix - 2 Nvidia Board Keys (On Debug Board) #################################################################################################################################################################################################### 1. S7 (RESET) --> is the RESET button. 2. S5 (ROW1) --> is the BACK button. 2. S10 (ROW2) --> is the Home button. 4. S6 (ON KEY) --> is Wake up button. #################################################################################################################################################################################################### Appendix - 3 Nvidia Board unavailable Keys workaround #################################################################################################################################################################################################### 1.To execute teh specific keys, provide the key inputs from adb shell. Provide the keyevent for the desired key.Refer teh key list below. Eg: for MENU key run adb shell #input keyevent 82 { "STAR", 17 }, { "POUND", 18 }, { "DPAD_UP", 19 }, { "DPAD_DOWN", 20 }, { "DPAD_LEFT", 21 }, { "DPAD_RIGHT", 22 }, { "DPAD_CENTER", 23 }, { "VOLUME_UP", 24 }, { "VOLUME_DOWN", 25 }, { "POWER", 26 }, { "CAMERA", 27 }, { "CLEAR", 28 }, { "HEADSETHOOK", 79 }, { "FOCUS", 80 }, { "PLUS", 81 }, { "MENU", 82 }, { "NOTIFICATION", 83 }, { "SEARCH", 84 }, { "MEDIA_PLAY_PAUSE", 85 }, { "MEDIA_STOP", 86 }, { "MEDIA_NEXT", 87 },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值