Android 串口通信開發(fā)筆記3:CMake 方式實現(xiàn)和 多對多的實現(xiàn)邏輯

上一篇:Android 串口通信筆記2 調(diào)試工具分析 工具類實現(xiàn)分析犀盟、項目實現(xiàn)
Android串口開發(fā) 延伸和擴展蛙粘,
1.使用JNI Cmake 自己編譯串口通信 的so庫:Android Studio 3.0 實現(xiàn)方式。
2.CRC校驗 以及擴展設(shè)計:

a.一(串口)對多(硬件通信);
b.多(串口)對多(硬件)的實現(xiàn)赠橙。

1.以串口調(diào)試工具為例婶希,使用其原本的源代碼使用JNI Cmake Android Studio 3.0 實現(xiàn)方式孔轴。

creat project

勾選 include C++ support 沒有下載ndk 的要下載。

①.延續(xù)使用jni 的方式


image.png

把相關(guān)的 been 和實現(xiàn)方法 都復(fù)制過來如圖唇礁。

創(chuàng)建.h 文件 注:一定要現(xiàn)進(jìn)入到app/main/java/ 目錄下

然后 javah -classpath -jni +完整路徑到類名

image.png

在main目錄下創(chuàng)建jni 文件夾勾栗,把生成的.h 文件復(fù)制進(jìn)去 ,新建同名的.c文件盏筐,把實現(xiàn)代碼拷進(jìn)去--注意需要修改 open 和close方法的名字 和.h 文件里改為一致围俘。

.c.png

這是.h 文件的

image.png

修改 cmakelist.txt 中 add_library 的so文件名 和路徑

add_library( # Sets the name of the library.
  # 設(shè)置so文件名稱.
   serial_port

   # Sets the library as a shared library.
   SHARED
   # 設(shè)置這個so文件為共享.

   # Provides a relative path to your source file(s).
   # 設(shè)置這個so文件為共享.
   src/main/jni/com_silencefun_comtest_serialport_SerialPort.c)
// .......省略注釋部分
  target_link_libraries( # Specifies the target library.
        # 制定目標(biāo)庫.
        serial_port

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib} )

注: “serial_port” 這個 so庫名稱要和你要加載的要保持一致
在SerialPortJava類中,

image.png

在app的build.gradle中 defaultConfig中配置生成平臺so包

  defaultConfig {
    applicationId "com.silencefun.comtest"
    minSdkVersion 19
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags ""
            //生成多個版本的so文件
            abiFilters 'arm64-v8a','armeabi-v7a','x86','x86_64'
        }
    }
}

然后 同步琢融,build-make project 執(zhí)行完畢之后切換視圖

如圖已經(jīng)生成了so:

image.png

②直接使用cmake方式 不得不說新支持方式的簡單了好多楷拳。

創(chuàng)建完支持C的項目后,

在需要調(diào)用java 的Native 類中聲明方法吏奸,其實還是直接復(fù)制SerialPort把加載的so 文件名字改一下:


image.png

直接在自動生成的Native-lib.c中完善實現(xiàn) (其他都不用改欢揖,方便快捷)

把 原來.c文件中的實現(xiàn)方法 直接拷過去然后修改方法名:
注意 要對應(yīng)好路徑


image.png
出現(xiàn)問題反思:采

用jni方式在Android 5.1的板子沒有問題 換到4.4結(jié)果就不行 總是 LOGE("tcgetattr() failed");

后來 更新ndk 、cmake奋蔚、 LLDB到最新她混,完全解決問題。

github 地址歡迎 star?

https://github.com/silencefun/ComTest/tree/master/AndroidStuido_3.0_COMTEST

2.擴展設(shè)計:一(串口)對多(硬件通信)泊碑、多(串口)對多(硬件)的實現(xiàn)坤按。

因為 有些智能終端硬件限制有些可能只開放一個通信口來接多個硬件模塊數(shù)據(jù),當(dāng)然前提是 掛在這一個通信口上的 硬件模塊 是在同一波特率馒过,因為打開初始化的時候已經(jīng)設(shè)定好了波特率(嘗試動態(tài)更改臭脓,不太理解底層實現(xiàn)過程代碼,屢敗屢試腹忽,最終放棄)来累。

相似的某些硬件模塊要采集的數(shù)據(jù)可能是多條數(shù)據(jù)(多個命令下返回多條數(shù)據(jù) 最后在封裝)所以設(shè)定一個【命令組】的概念:把硬件模塊對應(yīng)的命令放進(jìn)一個數(shù)組或者list中砚作。

命令組,即 該硬件所需要的數(shù)據(jù)是需要連續(xù)發(fā)送一組 若干個命令嘹锁,根據(jù)接收到的多條數(shù)據(jù)來解析--- 此處只是解析方式不同葫录,可以根據(jù)每次傳遞標(biāo)志位來區(qū)分,待所有所需所有數(shù)值都有领猾,即執(zhí)行一輪次之后 完全解析再更新數(shù)據(jù)米同。

同理多串口情況下就是多個通信串口,每一個口上邊都掛了N(N>=1)個硬件模塊(當(dāng)然這么殘暴的情形是有的:比如波特率不同必須多個串口)摔竿。

在之前一篇筆記中 Android 串口通信筆記2 的SerialHelper面粮,即控制類---每個硬件串口對象的管理控制實例 中添加 相應(yīng)的 成員變量 來區(qū)分 目前 具體是哪一個 硬件模塊 的哪一個命令 響應(yīng)的 值。

所以對應(yīng)的 封裝 讀取到的 信息 也要添加上 當(dāng)前 對應(yīng)的 命令 和硬件 模塊標(biāo)志继低。

Combean 添加字段

private String scmd = "";
private String sflag = "";

對應(yīng)的 硬件模塊 數(shù)據(jù)結(jié)構(gòu)大概可以:

MeterInfo 
private String name;//名稱
private String modenname;//型號
private String modertype;//類型
private List<String>  cmdlist;//發(fā)送命令
private String cleandatacmd;//清除命令
private String decimal;//小數(shù)位置 (可能解析能用到)
private String portname;//port路徑 類似 /dev/ttys1
private String sFlag;//flag 可取 模塊name

SerialHelper 類要在原有基礎(chǔ)之上 添加 部分字段

....
private String scmd = "";
private String sflag = "";
private List<MeterInfo> meterlist = new ArrayList<>(); //一個串口肯能要和多個 硬件通信
.....

所以初始化串口控制類SerialHelper的實例時候但金,要先set List<MeterInfo> ,
 在send 命令線程中郁季,兩層循環(huán):

for (int i = 0; i < meterlist .size(); i++) {
        List<String> cmdlist = meterlist .get(i).getGetdatacmdlist();

         for (int j = 0; j < cmdlist.size(); j++) {
                 setHexLoopData(cmdlist.get(j));
                  setSflag(meterlist .get(i).getsFlag());
                   setScmd(cmdlist.get(j));
                        //設(shè)定兩次的時間間隔
                   setTimespace(meterlist .get(i));
                    send(getbLoopData());//發(fā)送命令
                  try {
                    Thread.sleep(iDelay);
                   } catch (InterruptedException e) {
                     e.printStackTrace();
                   }
           }
  }

對應(yīng)的在 發(fā)送線程發(fā)送后 發(fā)送線程sleep 的時候 冷溃,讀的線程一直在跑,讀取到數(shù)據(jù) 封裝Combean 對象:

int size = mInputStream.read(buffer);
       if (size > 0) {
         ComBean ComRecData = new ComBean(sPort, buffer, size);
         ComRecData.setScmd(scmd);
         ComRecData.setSflag(sflag);
         onDataReceived(ComRecData); //調(diào)用抽象方法傳遞
       }

這樣在業(yè)務(wù)處理部分實現(xiàn) onDataReceived 方法時候就能判斷是哪個模塊哪個命令對應(yīng)的值梦裂。

關(guān)于CRC校驗:

   /**
 * 獲取 crc校驗碼
 *
 * @param hextext 16進(jìn)制
 * @return 低位高位順序
 */
public static String getCrc16(String hextext) {
    byte[] arr_buff = SerialFunc.HexToByteArr(hextext);

    int len = arr_buff.length;

    // 預(yù)置 1 個 16 位的寄存器為十六進(jìn)制FFFF, 稱此寄存器為 CRC寄存器似枕。
    int crc = 0xFFFF;
    int i, j;
    for (i = 0; i < len; i++) {
        // 把第一個 8 位二進(jìn)制數(shù)據(jù) 與 16 位的 CRC寄存器的低 8 位相異或, 把結(jié)果放于 CRC寄存器
        crc = ((crc & 0xFF00) | (crc & 0x00FF) ^ (arr_buff[i] & 0xFF));
        for (j = 0; j < 8; j++) {
            // 把 CRC 寄存器的內(nèi)容右移一位( 朝低位)用 0 填補最高位, 并檢查右移后的移出位
            if ((crc & 0x0001) > 0) {
                // 如果移出位為 1, CRC寄存器與多項式A001進(jìn)行異或
                crc = crc >> 1;
                crc = crc ^ 0xA001;
            } else
                // 如果移出位為 0,再次右移一位
                crc = crc >> 1;
        }
    }
    String c = Integer.toHexString(crc);
    if (c.length() == 4) {
        c = c.substring(2, 4) + c.substring(0, 2);
    } else if (c.length() == 3) {
        c = "0" + c;
        c = c.substring(2, 4) + c.substring(0, 2);
    } else if (c.length() == 2) {
        c = "0" + c.substring(1, 2) + "0" + c.substring(0, 1);
    }
    return c.toUpperCase();
}

Android 串口通信開發(fā)筆記01

Android 串口通信筆記2 調(diào)試工具分析 工具類實現(xiàn)分析、項目實現(xiàn)
Android 串口通信開發(fā)筆記3:CMake 方式實現(xiàn)和 多對多的實現(xiàn)邏輯
Android 串口開發(fā) 支持N-8-1(數(shù)據(jù)位停止位校驗方式) 設(shè)定

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末年柠,一起剝皮案震驚了整個濱河市凿歼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冗恨,老刑警劉巖答憔,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掀抹,居然都是意外死亡虐拓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門傲武,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓉驹,“玉大人,你說我怎么就攤上這事揪利√耍” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵疟位,是天一觀的道長瞻润。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么绍撞? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任正勒,我火速辦了婚禮,結(jié)果婚禮上楚午,老公的妹妹穿的比我還像新娘昭齐。我一直安慰自己尿招,他們只是感情好矾柜,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著就谜,像睡著了一般怪蔑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丧荐,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天缆瓣,我揣著相機與錄音,去河邊找鬼虹统。 笑死弓坞,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的车荔。 我是一名探鬼主播渡冻,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忧便!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤浩嫌,失蹤者是張志新(化名)和其女友劉穎葬馋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒂教,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡巍举,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了凝垛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片禀综。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖苔严,靈堂內(nèi)的尸體忽然破棺而出定枷,到底是詐尸還是另有隱情,我是刑警寧澤届氢,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布欠窒,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏岖妄。R本人自食惡果不足惜型将,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荐虐。 院中可真熱鬧七兜,春花似錦、人聲如沸福扬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铛碑。三九已至狠裹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汽烦,已是汗流浹背涛菠。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撇吞,地道東北人俗冻。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像牍颈,于是被迫代替她去往敵國和親迄薄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,841評論 25 707
  • 前言: 最近在總是看見有人在群里面問一些串口通信相關(guān)的問題颂砸,特別是對于我們這些做APP出生的程序員來說噪奄,初次接觸串...
    Roy88閱讀 37,497評論 30 37
  • 大學(xué)的時候,幫朋友寫的操作系統(tǒng)調(diào)研的作業(yè)人乓,最近整理過去的文檔時候偶然發(fā)現(xiàn)勤篮,遂作為博客發(fā)出來。 從串口驅(qū)動到Linu...
    free_will閱讀 7,375評論 7 59
  • 原創(chuàng)/氧氣是個地鐵(大夢) 需要嗎?不需要嗎戳护? 需要金抡,同時也不需要。這并不是兩個對立的結(jié)論腌且,而是一個過程的兩種形式...
    氧氣是個地鐵閱讀 1,469評論 0 0
  • 好想好想感謝司徒梗肝。那天和司徒聊完後,更體會到佛法的精妙铺董,也愈發(fā)渴望親近佛法巫击。自那天起,每天把大部分時間放在思維觀察...
    Tsangce閱讀 188評論 0 0