2016/3/24

Android Studio 1.5.1 and JNI

https://codelabs.developers.google.com/codelabs/android-studio-jni/index.html?index=..%2F..%2Findex#0
照這一篇,step by step

重點大概是..
  • 要用 gradle-experimental:0.4.0
  • 所以配合的 gradle 是 2.8 (雖然最新的是 2.12)
  • build.gradle (Module: app) 內容要 follow experimanetal 的格式來寫。* 注意 "=" 號
  • build.gradle (Module: app) 新增 jni module
這樣改完,sync project 後,就可以寫 code 了。

寫 code 有很方便的 code-gen.只要在java code 宣告 native, 之後在宣告處出現的紅色燈泡按下...Create Function....
就會幫你寫好 c source 的 function 外框。

2016/3/22

PQI Air, A500 的 adaptor Mode

就是到 access page . advance.-- internet setting -- Operation Mode, 選 Bridge Mode
確認後等一陣子,再連上去後就 OK 了。

連上的 client 會向LAN request IP.

--- 在 user manual 上可以看到說明。

OpenGL texture compression support , android

http://developer.android.com/intl/zh-tw/guide/topics/graphics/opengl.html#textures
The Android framework provides support for the ETC1 compression format as a standard feature,
..
Beyond the ETC formats, Android devices have varied support for texture compression based on their GPU chipsets and OpenGL implementations.


如果真的要使用特定的 TC 功能,記得宣告在 manifest 中:
Note: Once you decide which texture compression formats your application will support, make sure you declare them in your manifest using <supports-gl-texture> . Using this declaration enables filtering by external services such as Google Play, so that your app is installed only on devices that support the formats your app requires. For details, see OpenGL manifest declarations.

google playstore 會依照 manifest 內容,決定用戶的手機能不能安裝該程式:
Each time you upload an application to the Google Play Developer Console, Google Play scans the application's manifest file and looks for any elements. It extracts the format descriptors from the elements and stores them internally as metadata associated with the application .apk and the application version.

When a user searches or browses for applications on Google Play, the service compares the texture compression formats supported by the application with those supported by the user's device. The comparison is based on the format descriptor strings and a match must be exact.

If any of an application's supported texture compression formats is also supported by the device, Google Play allows the user to see the application and potentially download it. Otherwise, if none of the application's formats is supported by the device, Google Play filters the application so that it is not available for download.
http://developer.android.com/intl/zh-tw/guide/topics/manifest/supports-gl-texture-element.html#market-texture-filtering

2016/3/8

tinyalsa : tinyplay

root@sabreauto_6q:/ # tinyplay                                                 
Usage: tinyplay file.wav [-D card] [-d device] [-p period_size] [-n n_periods] 

看一下source:
pcm.c : pcm_open( )
    snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
             flags & PCM_IN ? 'c' : 'p');

    pcm->flags = flags;
    pcm->fd = open(fn, O_RDWR);
看一下系統 /dev/snd/..
1|root@sabreauto_6q:/ # ls /dev/snd/
controlC0
controlC1
pcmC0D0c
pcmC0D0p
pcmC1D0c
timer
所以play 就是...
# tinyplay 1ch48k.wav -D 0 -d 0

bookmark : wandboard

2016/3/7

idmapping -- nfs with user permission

from http://serverfault.com/questions/514118/mapping-uid-and-gid-of-local-user-to-the-mounted-nfs-share


This is what idmapping is suppose to do. First of all, enable is on the client and server:
# echo N > /sys/module/nfs/parameters/nfs4_disable_idmapping
clean idmap cache and restart idmap daemon:
# nfsidmap -c
# service rpcidmapd restart
Now on server and the client will send instead of numeric IDs string principals like bob@YOURDOMAIN.COM. You need to have bob account on the both hosts - client and server. Nevertheless, the numeric ID's can be different.

shareimprove this answer
answered Sep 30 '14 at 5:32

kofemann
1,163717

Ftr, on nfs server the path is /sys/module/nfsd/parameters/nfs4_disable_idmapping (nfsd, not nfs) – Mike Purcell Dec 21 '15 at 19:42

原來 idmapd 要而外啟動,
ref: http://jamyy.us.to/blog/2014/03/6166.html

環境:
Server: CentOS / Fedora
Client: Debian / Ubuntu
Server
# yum install nfs-utils
# vi /etc/idmapd.conf
Domain = localdomain
# vi /etc/exports
/path *(rw,sync,no_root_squash,no_subtree_check)
# exportfs -rv
# service rpcbind start
# service nfs start
# chkconfig nfs on
# chkconfig rpcbind on
Client
$ sudo apt-get install nfs-common
$ sudo vi /etc/idmapd.conf
Domain = localdomain
$ sudo service nfs-common restart (Debian)
或
$ sudo service idmapd restart (Ubuntu 12.04)
Ubuntu 13.10 只要改好 /etc/idmapd.conf 立即生效, 無需其他操作
$ mount -t nfs4 remote:/path /local/mount/point

其他:

2016/3/4

android 6.0 : fingerprint cannot exceed 91 bytes..

出現了
error: ro.build.fingerprint cannot exceed 91 bytes:
然後網路上說,改一些 PROP_VALUE_MAX 的值:
http://stackoverflow.com/questions/28776970/android-build-error-ro-build-fingerprint-cannot-exceed-91-bytes
Edit build/tools/post_process_props.py. Change lines as follows:

PROP_NAME_MAX = 31
# PROP_VALUE_MAX = 91
PROP_VALUE_MAX = 128
Edit bionic/libc/include/sys/system_properties.h. Change lines as follows:

#define PROP_NAME_MAX   32
// #define PROP_VALUE_MAX  92
#define PROP_VALUE_MAX  128
Do

make clean
make
所以照著改...
然後就出現...
In file included from hardware/qcom/camera/QCamera/HAL/core/src/QCameraHWI_Record.cpp:27:0:
In function 'int property_get(const char*, char*, const char*)',
    inlined from 'virtual android::status_t android::QCameraStream_record::getBuf(mm_camera_frame_len_offset*, uint8_t, uint8_t*, mm_camera_buf_def_t*)' 
at 
hardware/qcom/camera/QCamera/HAL/core/src/QCameraHWI_Record.cpp:220:60:
system/core/include/cutils/properties.h:122:41: 
error: call to '__property_get_too_small_error' declared with attribute error: 
property_get() called with too small of a buffer
         __property_get_too_small_error();
因為一開始出現了 ...所以改 PROPERTY_VALUE_MAX 從 92 改 128.
結果出現上面的錯誤。

因為google 很好心的寫了一個 check, 在 system/core/include/properties.h:
int property_get(const char *key, char *value, const char *default_value) {
   size_t bos = __bos(value);
   if (bos < PROPERTY_VALUE_MAX) {
      __property_get_too_small_error();
      ...

所以問題應該是在call property_get( ) function 的 code, 傳入的 array size 太小。
所以打開 QCameraHWI_Record.cpp : 220 : 60:
char value[100];
...
property_get("persist.camera.mem.usecache",value,"1");
...
把 value[100] 改 value[PROPERTY_VALUE_MAX]

2016/3/2

imx6 CLK.

struct clk 宣告在:include/linux/clk-private.h

裡面除了 struck clk 外,還定義了:
DEFINE_CLK
DEFINE_CLK_FIXED_RATE
DEFINE_CLK_GATE
DEFINE_CLK_DIVIDER
DEFINE_CLK_DIVIDER_TABLE
DEFINE_CLK_MUX
DEFINE_CLK_FIXED_FACTOR
但是這些imx 都沒用...

是在arch/arm/mach-imx/clk-imx6q.c 中宣告,生成。
CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
device tree 宣告在: imx6qdl.dtsi:
                        clks: ccm@020c4000 {
                                compatible = "fsl,imx6q-ccm";
                                reg = <0x020c4000 0x4000>;
                                interrupts = <0 87 0x04 0 88 0x04>;
                                #clock-cells = <1>;
                        };

在 Documentation/devicetree/bindings/clock/imx6q-clock.txt 有清楚的說明:

每個使用clk 的裝置(consumer) 都要在 device tree 中指名使用到的 clk id
imx bsp 把所有的 clk 排列在一起,並且給每個clk 一個index

        Clock                   ID
        ---------------------------
        dummy                   0
        ckil                    1
        ckih                    2
        osc                     3
        pll2_pfd0_352m          4
        pll2_pfd1_594m          5
        pll2_pfd2_396m          6
        pll3_pfd0_720m          7
        pll3_pfd1_540m          8
        pll3_pfd2_508m          9
        pll3_pfd3_454m          10
        pll2_198m               11
        pll3_120m               12
        pll3_80m                13
        pll3_60m                14
        twd                     15
        step                    16
        pll1_sw                 17
        periph_pre              18
        periph2_pre             19
        periph_clk2_sel         20
        periph2_clk2_sel        21
        axi_sel                 22
        esai_sel                23
        spdif1_sel              24
        spdif_sel               25
        ...

這個表其實宣告在 clk-imx6q.c 的 enum mx6q_clks {}

系統clock 的 device node:
Examples:

clks: ccm@020c4000 {
        compatible = "fsl,imx6q-ccm";
        reg = <0x020c4000 0x4000>;
        interrupts = <0 87 0x04 0 88 0x04>;
        #clock-cells = <1>;
};

以 serial port (UART) 為例,他使用兩種clk, ipg, serial, 所以 device node 是:
uart1: serial@02020000 {
        compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
        reg = <0x02020000 0x4000>;
        interrupts = <0 26 0x04>;
        clocks = <&clks 160>, <&clks 161>;
        clock-names = "ipg", "per";
        status = "disabled";
};
idex 分別是 160, 161


clock 的 hierachy 是寫在 clk-imx6q.c:
imx6q_clocks_init( ):
約略是由上而下...
        clk[dummy] = imx_clk_fixed("dummy", 0);
        clk[ckil] = imx_obtain_fixed_clock("ckil", 0);
        clk[ckih] = imx_obtain_fixed_clock("ckih1", 0);
        clk[osc] = imx_obtain_fixed_clock("osc", 0);
        /* Clock source from external clock via ANACLK1/2 PADs */
        clk[anaclk1] = imx_obtain_fixed_clock("anaclk1", 0);
        clk[anaclk2] = imx_obtain_fixed_clock("anaclk2", 0);
ckil : external low freq
ckih : external high freq clock and internal oscillator
osc : the 24MHz
anaclk1, anaclk2 : another external osc in

這幾個 最源頭的 clk 都定義在 dts 中。

最後系統的 clk hierachy, 在 debugfs 中可以看到: wondboard:
root@wandboard:/sys/kernel/debug/clk # busybox find . -name 'esai*'
./osc/pll2_bus/pll2_pfd2_396m/periph_pre/periph/ahb/esai_ipg
./osc/pll2_bus/pll2_pfd2_396m/periph_pre/periph/ahb/esai_mem
./osc/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel
./osc/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel/esai_pred
./osc/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel/esai_pred/esai_podf
./osc/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel/esai_pred/esai_podf/esai_extal
sabreauto:
root@sabreauto_6q:/sys/kernel/debug/clk # busybox find . -name 'esai*'
./osc/pll2_bus/pll2_pfd2_396m/periph_pre/periph/ahb/esai_ipg
./osc/pll2_bus/pll2_pfd2_396m/periph_pre/periph/ahb/esai_mem
./anaclk2/lvds2_in/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel
./anaclk2/lvds2_in/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel/esai_pred
./anaclk2/lvds2_in/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel/esai_pred/esai_podf
./anaclk2/lvds2_in/pll4_sel/pll4_audio/pll4_post_div/pll4_audio_div/esai_sel/esai_pred/esai_podf/esai_extal
因為 mach-imx6q.c 的 ..
static void __init imx6q_audio_lvds2_init(void)
{
        struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai_extal;

        printk("%s\n",__func__);

        pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
        pll4_sel = clk_get_sys(NULL, "pll4_sel");
        lvds2_in = clk_get_sys(NULL, "lvds2_in");
        esai_extal = clk_get_sys(NULL, "esai_extal");
        if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
            IS_ERR(lvds2_in) || IS_ERR(esai_extal))
                return;

        if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
                return;

        clk_set_parent(pll4_sel, lvds2_in);
        clk_set_rate(pll4_audio_div, 786432000);
        clk_set_rate(esai_extal, ESAI_AUDIO_MCLK);
}
把 pll4_sel 的 parent 改到 lvds2_in
pll4_sel 的 parent 可以是:
{ "osc", "lvds1_in", "lvds2_in", "dummy", }