Upload
national-science-and-technology-development-agency-nstda-thailand
View
588
Download
2
Embed Size (px)
Citation preview
วรฬห ศรบรรกษวศวกรรมระบบสมองกลฝงตว
ภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา
สนบสนนโดย สำนกงานพฒนาวทยาศาสตรและเทคโนโลยแหงชาต สำนกงานคณะกรรมการสงเสรมการลงทน และ สมาคมสมองกลฝงตวไทย
EMBEDDED ANDROID DEVELOPMENT
ส เ ส น ท า ง น ก พ ฒ น า
EMBEDDED ANDROID DEVELOPMENT
จดทำโดย ผศ. วรฬห ศรบรรกษ
ตดตอ :
169 ภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา
ถนนลงหาดบางแสน ตำบลแสนสข อำเภอเมองชลบร จงหวดชลบร 20131
โทรศพท 0-3810-2222 ตอ 3380-82 ตอ 203 โทรสาร 0-3874-5806 อเมล [email protected]
ขอมลทางบรรณานกรมของสำนกหอสมดแหงชาต :วรฬห ศรบรรกษ. Embedded Android Development.-- : วรฬห ศรบรรกษ, 2557. 397 หนา. 1. ระบบสมองกลฝงตว 2. ระบบปฏบตการลนกซ 3. แอนดรอยดI. ชอเรอง.
ISBN (e-book) : 978-616-361-117-8
จดจำหนายโดย :
อาคารทซไอเอฟ ทาวเวอร ชน 19 เลขท 1858/87-90 ถนนบางนา-ตราด แขวงบางนาเขตบางนา กรงเทพฯ 10260 โทรศพท 0-2739-8000
หนงสอ eBook เลมนอนญาตใหใชไดตามสญญาอนญาตครเอทฟคอมมอนส # # # # # # # # แสดงทมา-ไมดดแปลง-ไมใชเพอการคา (เผยแพรฟร) 3.0 ประเทศไทย
คำนยม
หนงสอเกยวกบความรทางดานระบบสมองกลฝงตว (Embedded Systems) ทเราพบโดยทวไปมกจะเปนหนงสอเกยวกบไมโครคอนโทรเลอร ทเนนใหเขาใจฮารดแวรและการเขยนโปรแกรมแบบงายๆ ซงปญหาหนงทตามมาคอผสนใจหรอผทอยากจะเปนนกพฒนาไมสามารถจะทำระบบทซบซอนได (เพอใหใชงานไดจรง) หรอการทำ User Interface กทำไดยากมากตองใชเวลามากเปนตน
ปจจบนแนวทางการพฒนาระบบสมองกลฝงตวเรมเปลยนเปนทำงานตอยอดจากแพลตฟอรมเพอชวยลดเวลาการทำฮารดแวรลง เชน ไมตองซอชนสวนมาประกอบเองแตซอบอรดมาใชเลย นอกจากนนการพฒนาโปรแกรมกไมจำเปนตองเรมใหมทงหมด แตเรมจากระบบปฏบตการขนาดเลกและโปรแกรมฟงชนสนบสนนตางๆ ทำใหการพฒนาในลกษณะนสามารถเนนความคดสรางสรรคใหมๆโดยมการทำงาน ทซบซอนไดอยางรวดเรว นอกจากนน อปกรณเชน Smart Phone หรอ Tablet มการกระจายตวอยางรวดเรว มขดความสามารถสงรวมถงมเซนเซอรและความสามารถสอสารตางๆครบถวน จงสงเสรมใหเกดการเขยนโปรแกรมประยกตทดๆอยางมากมาย หรอถกนำเปนอปกรณรวมกบระบบฮารดแวรอนๆไดอยางด
Smart Phone หรอ Tablet ทสดสวนการครอบครองตลาดมากทสดคอระบบปฏบตการแอน ดรอยด ซงมสดสวนประมาณ 56% ตามดวยระบบปฏบตการ iOS ซงมสดสวนประมาณ 22% ดงนนการเขาใจและสามารถพฒนาบนระบบแอนดรอยดใหเกงและชำนาญเปนเรองทจำเปนมาก
หนงสอ “Embedded Android Development สเสนทางนกพฒนา" ทเขยนโดย อ.วรฬห ศรบรรกษ นนบวามความโดดเดนมากทงในแงวชาการ ประวตศาสตร และการนำไปปฏบตจรง สำหรบระบบปฏบตการแอนดรอยดมรากเงาการพฒนาจากระบบปฏบตการลนกซและมาจากระบบปฏบตการ ยนกซ หนงสอเลมนกบรรยายทมาทไปใหผสนใจโดยเฉพาะนกพฒนาไดซาบซง กบประวตความเปนมาละเอยดชวยกระตนความอยากเปนนกพฒนาระบบสมองกลฝงตวไดอยางด
หนงสอเลมนมงสรางนกพฒนารนใหมใหเรมเดนดวยตนเองไดหรอเพอเปนพเลยงทจดเรมเทานน ซงจำเปนมาก นกพฒนาเปรยบเหมอนนกนอยทเรมหดบนซงจรงๆแลว นกทกตวมวญญาณทจะบนเองไดอยแลว ขอใหมโอกาสใหเรมไดบน
ผมเหนวาหนงสอเลมนจะมอบโอกาสใหผทสนใจ เปนนกพฒนาระบบสมองกลฝงตว แอนดรอยด สามารถเรมบนในโลกแอนดรอยดไดอยางมอสระและสรางสรรคสงใหมๆไดครบ
ดร. พนธศกด ศรรชตพงษผอำนวยการศนยเทคโนโลยอเลกทรอนกสและคอมพวเตอรแหงชาต (NECTEC)
FOREWORD
I am honoured to be writing the forward for Ajarn Wiroon Sriborrirux’s new book. I have admired Ajarn Wiroon for a long time as one of the leaders and mentors in the embedded systems community in Thailand. He is well known and widely respected in terms of his generousity in sharing his deep technical knowledge, as a teacher, a profes-sional consultant, an advisor to startup companies and as a colleague. It is very fitting for him to be writing this book as a way to continue to share his knowledge with our community in order to keep advancing Thailand forward in the technology field.
The topic of this book, “Embedded Android Development”, is incredibly timely, given the newest developments in terms of the Internet of Things (IOT), cyberphysical trend and the move to a “post-PC era”, or what we can call the “embedded systems era” or “device era”.
Stage 1 of the “embedded systems era” (2000-2015) was about connectivity. We saw the rise of Ubiquitous Computing or Universal Communicator led by mobile phone and smart phones. By putting a very powerful personal computing and communication device into the hands of a major part of the world’s population, this stage built up an important infrastructure for the IOT.
From 2010-2020, we are seeing Stage 2 of this era, with IOT being the keyword of this decade. We will see a rising need to make things “smart”. The challenge is not just in the technology, but rather in creating innovation or value creation that utilises infor-mation or knowledge gathered from connected devices. CISCO predicted that the value created by the use of IOT is expected to reach $14 trillion by 2020 which is only a few years from now. This means tremendous opportunity for the development community.
Within this context, Embedded Android has become very popular in all types of devices requiring user interface such as measurement instruments, kiosk, access control, payment, health monitor, wearable devices, and cars. We are now currently only at the beginning of IOT innovation race, and I believe that we’ll be seeing a lot of exciting in-novations utilising Embedded Android in the next few years.
I am confident that this book should be very useful for key courses such as Unix Systems Programming or Embedded Systems Development. This book should also serve as a very good reference for students working on senior project related to advance em-bedded systems and device development. These days, students learn a lot of theory but have little practical skills, which makes it difficult for them to meet workforce re-quirements. It is refreshing to see a book with a practical knowledge focus that en-hances development skills. It fills a key gap in this field, and particularly in Thailand.
Assistant Professor Apinetr UnakulPresident of Thai Embedded Systems Association (TESA)
คำนำ
หนงสอ Embedded Android Development เลมนไดรบการสนบสนนเงนทนจากศนยเทคโนโลยอเลกทรอนกสและคอมพวเตอรแหงชาต (NECTEC) สำนกงานพฒนาวทยาศาสตรและเทคโนโลยแหงชาต (สวทช.) สำนกงานคณะกรรมการสงเสรมการลงทน (BOI) และสมาคมสมองกลฝงตวไทย (TESA) เพอนำไปใชประโยชนภายใตโครงการสรางเสรมศกยภาพวชาชพ Embedded System เพอสงเสรมการเรยนการสอนทงทกษะดานการเขยนโปรแกรมและหลกการเขาใจการทำงานฮารดแวรทางดานเทคโนโลยสมองกลฝงตวใหนาสนใจและสามารถดงดดนกศกษาใหศกษาตอในสาขา Embed-ded System รวมทงนำไปเผยแพรยงมหาวทยาลยทวประเทศเพอใชประกอบในการเรยนการสอนหรอการฝกอบรมทางดานระบบสมองกลฝงตว
หนงสอเลมนผเขยนตงใจเขยนขนมาจากใจทมงมนและศรทธาเพอตองการสงเสรมและกระตนใหเกดนกพฒนารนใหมภายในเมองไทย โดยผเขยนตงใจนำประสบการณทสงสมอยในวงการเทคโนโลยคอมพวเตอร ระบบปฏบตการลนกซ ระบบสมองกลฝงตว และระบบปฏบตการแอนดรอยด ตลอดระยะเวลาไมนอยกวา 18 ป ซงไดรวบรวมพนฐานความรสำคญทหาอานไดยากแลวนำมาเรยบเรยงใหเหมาะสมกบนสตทเรยนในวชาทเกยวของกบระบบสมองกลฝงตว ตวอยางเชน วชาระบบปฏบตการยนกซ/ลนกซ วชาการเขยนโปรแกรม วชาระบบสอสารและเครอขาย วชาระบบฏบตการคอมพวเตอร และวชาระบบสมองกลฝงตว เปนตน ซงจะเปนพนฐานสำคญในการออกแบบและพฒนาทางดานระบบสมองกลฝงตวโดยเฉพาะสำหรบนสตนกศกษาทางดานวศวกรรมคอมพวเตอร วศวกรรมไฟฟาอเลกทรอนกส วศวกรรมไฟฟาสอสาร วศวกรรมไฟฟาควบคม วทยาการคอมพวเตอร และสาขาทใกลเคยง
นอกจากนนยงเหมาะสำหรบนกพฒนาและผทสนใจการทำงานภายในระบบสมองกลฝงตว ซงเนอหาในหนงสอเลมนจะรวบรวมศาสตรความรทเกยวของในการออกแบบและพฒนาทางดานระบบสมองกลฝงตวเพอนำไปใชในการปรบปรงหรอสรางสรรคผลตภณฑใหมในอนาคตได วตถประสงคหลกของหนงสอเลมนตองการปพนความรตงแตการใชงานระบบปฏบตการลนกซเพอใหคนเคยกบคำสงทเกยวของตงแตระดบพนฐานจนถงระดบกลางใหผอานเขาใจระบบลนกซเคอรเนล การพฒนาโปรแกรมระดบลาง การเตรยมสภาพแวดลอมใหพรอมสำหรบการปรบแตงระบบปฏบตการลนกซ เครองมอทเกยวของทงหมดสำหรบการพฒนาโปรแกรมบนระบบสมองกลฝงตว ทำความเขาใจโครงสรางระบบปฏบตการแอนดรอยด การพฒนาโปรแกรมดวยโปรแกรมภาษา C/C++/JAVA/Python และการประยกตบนบอรดสมองกลฝงตว โดยในบทสดทายเปนการยกตวอยางกรณศกษาและแนวคดสำคญในการออกแบบและพฒนาเพอใหผอานสามารถเขาใจและสามารถเชอมโยงความรทไดเพอนำไปสการเรมตนการออกแบบและพฒนาทางดานระบบสมองกลฝงตวในอนาคต
กตตกรรมประกาศ
หนงสอ Embedded Android Development เลมนจะสมบรณไมไดถาขาดการชวยเตรยมขอมลประกอบสำหรบแตละบทจากลกศษยทรกและนกวจยประจำหองปฏบตการวจยและพฒนาดานสมองกลฝงตวของขาพเจา ซงไดแก นายสรไกร ไกรปย นายธตพงษ สอนจนทร นายภานวฒน พรหมศร นายวธ-วช บญแยม นายวระเดช ขมทอง นายวสนต วยะรนดร นายปรวฒน เลยมสำราญ นายนพนธ สมหมาย นายจเร ปยฉตรพนม นายนฐพงษ แสงสงาศร และนายกตตศกด พรมศร รวมทงเพอนรวมงานทคอยเปนกำลงใจ ซงไดแก ดร.ภาณวฒน ดานกลาง รศ.ดร.ณกร อนทรพยง และ ดร.อภรฐ ลมมณ
ขอขอบคณภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา ทสนบสนนใหมการเปดสาขาวชาทางดานวศวกรรมอเลกทรอนกสและระบบสมองกลฝงตว และหลกสตร Embedded Systems Engineering (English Program) ซงทำใหขาพเจาไดมโอกาสสอนและทำการวจยและพฒนาองคความรทางดานวศวกรรมระบบสมองกลฝงตว รวมทงขอขอบคณนายกสมาคมสมองกลฝงตวไทย ผชวยศาสตราจารยอภเนตร อนากล และ ผจดการสมาคมฯ พขนษฐา ประสารสข ทไดใหขาพเจาไดมโอกาสเขามารวมทำงานและสรางกจกรรมดๆตงแตป พ.ศ. 2548 เปนตนมา
ทสำคญดวยกำลงใจทเปยมลนจากครอบครวทรกของขาพเจาเอง (นางณฐณชา หนคง และ ด.ญ. ปวรนนทน ศรบรรกษ) ทคอยเปนกำลงใจตลอดระยะเวลาหลายเดอนของการเขยนหนงสอเลมน ขอบพระคณบดา (นายสามารถ ศรบรรกษ) มารดา (นางแดง ศรบรรกษ) ทใหชวตทมคานแกขาพเจาไดมโอกาสสรางสรรผลงาน และสรางคนสำหรบวงการระบบสมองกลฝงตว เพอสกวนหนงเมองไทยจะไดเหนความสำคญทแทจรงของเทคโนโลยเหลาน
สารบญ
บทท 1 พนฐาน Unix/Linux สำหรบนกพฒนา 13
ประวตระบบปฏบตการ Unix/Linux 13
ประเภทของ Licenses 18
ปรญชา และความรพนฐานของระบบปฏบตการลนกซ 19
กระบวนการทำงานของเชลล และชดคำสงทเกยวของ 20
ตวแปรสภาพแวดลอมของระบบ 28
การเรยกใชงานคำสงภายในเชลล และภายนอกเชลล 32
คำสงพนฐานสำหรบนกพฒนาดานบนระบบสมองกลฝงตว 33
คำสงตรวจสอบทรพยากรระบบ 33
คำสงตรวจสอบการใชหนวยความจำระบบ 36
คำสงตรวจสอบการใชพนทสำหรบเกบขอมล 37
คำสงสำหรบการบรหารจดการโปรเซส 38
การอานสถานะของทรพยากรระบบจากไดเรกทอร /proc 43
คำสงเกยวกบการเปดอานขอมลภายในไฟล 45
คำสงคนหาขอความและไฟลดวยชด Regular Expressions 48
คำสงจดการดานระบบเครอขาย 60
บทท 2 พนฐานลนกซคอรเนลสำหรบนกพฒนา 67
Linux Kernel 68
Linux Versioning 69
โครงสรางไดเรกทอร และขนาดพนทของ Linux Kernel 3.2 70
พนฐานการปรบแตงและสราง Custom Kernel 73
5 ขนตอนพนฐานการคอมไพล Linux Kernel 74
คอมไพล Linux Kernel 3.x สำหรบ Ubuntu ทใชอย 81
การพฒนา Linux Kernel Module 84
พนฐานการเขยน Linux Module 88
พนฐานการเขยนโปรแกรมไดรเวอรสำหรบ character device 92
การเพม Linux Module ใหมเขาไปยง Linux Source Tree 97
บทท 3 Embedded Linux Development 100
ความเปนมาของระบบสมองกลฝงตว 100
สถาปตยกรรมในระบบสมองกลฝงตว 104
สถาปตยกรรมไมโครโปรเซสเซอรและอปกรณฮารดแวรสำคญสำหรบระบบสมองกลฝงตว 104
กอนจะเปนบอรดสมองกลฝงตว 106
เรมตนสการพฒนาบนระบบปฏบตการ Embedded Linux 109
องคประกอบการเตรยมสภาพแวดลอมสำหรบ Embedded Linux 109
การเชอมตอระหวางเครอง Host และ บอรด Target 112
เครองมอ Cross Toolchains 116
ประเภทของ Cross Toolchains 117
องคประกอบหลกภายใน Cross Toolchains 118
ขนตอนการเตรยมระบบสำหรบพฒนาบน Embedded Linux 120
การเตรยมสภาพแวดลอมใหกบเครอง Host 121
Toolchain Options ทสำคญ 123
Bootloaders 124
รายละเอยดภายใน Kernel Image ทใชในบอรดสมองกลฝงตว 126
Linux File Systems 127
Virtual Filesystems 127
การปองกนขอมลภายในระบบไฟล 134
Embedded Linux File System 137
ระบบไฟลในระบบสมองกลฝงตว 139
Memory Technology Devices (MTD) 140
ขนตอนการเขาโหลดระบบไฟลเพอเขาสระบบฏบตการ Embedded Linux 142
BusyBox มดพกพาสารพดประโยชน 147
การพฒนาระบบสมองกลฝงตวภายใตระบบจำลองเสมอนจรง 152
ขนตอนการทดสอบการรนโปรแกรมภาษา C บน QEMU 155
ขนตอนการทดสอบ BusyBox ภายใน Root Filesystem บน QEMU 157
การสรางระบบจำลองสถาปตยกรรม ARM ดวยชดเครองมอ Buildroot บน QEMU 161
ตวอยางการสรางระบบจำลองเสมอนของบอรด Raspberry Pi บน QEMU 168
ตวอยางการสรางระบบจำลองเสมอนของบอรด Friendly ARM บน QEMU 171
บทท 4 พนฐานการเขยนโปรแกรมภาษา C/C++ และ Qt สำหรบนกพฒนา 178
พนฐานเขยนโปรแกรมภาษา C/C++ สำหรบการพฒนาระบบสมองกลฝงตว 178
พนฐานการสราง Makefile 179
การสรางและอางองไลบราร 181
การพฒนาโปรแกรมเพอเขาถงระบบไฟล 184
การพฒนาโปรแกรมตดตอพอรตอนกรม 185
การพฒนาโปรแกรมสอสารระหวางโปรเซส 198
การพฒนาโปรแกรมสอสารบนระบบเครอขาย 210
การพฒนาโปรแกรมเกบขอมลดวย SQLite 218
การดบกโปรแกรมภาษา C/C++ 220
การเขยนโปรแกรมภาษา C++ ดวย Qt 227
การตดตง Qt สำหรบแตละระบบปฏบตการ 227
กลไกการทำงานของ Signal และ Slot 232
การพฒนาโปรแกรมตดตอพอรตอนกรม 236
การพฒนาโปรแกรมแบบ Multi-threading 240
บทท 5 พนฐานระบบปฏบตการแอนดรอยดสำหรบนกพฒนา 244
ระบบปฏบตการแอนดรอยด 244
สถาปตยกรรมของระบบปฏบตการแอนดรอยด 247
แนวทางการพฒนา Embedded Android 250
เตรยมสภาพแวดลอมสำหรบการพฒนา Embedded Android 252
เตรยมสภาพแวดลอมบนเครอง Host 252
Android Open Source Project (AOSP) 254
ดาวนโหลดซอรส AOSP 254
โครงสรางภายใน AOSP 256
Android Kernel 258
ขนตอนการคอมไพล AOSP มาเปนระบบปฏบตการแอนดรอยด 259
ระบบปฏบตการแอนดรอยดบน Android Emulator 265
พนฐานการใช Android Debug Bridge (ADB) 267
ขนตอนการปรบแตง Android Kernel สำหรบ Emulator 271
ขนตอนการตดตง Android Kernel สำหรบ Android Emulator (Goldfish) 271
การพฒนา Kernel Module สำหรบระบบปฏบตการแอนดรอยด 276
การสรางโปรแกรมประยกตเพอฝงลงระบบปฏบตการแอนดรอยด 280
ชดเครองมอและคำสงภายใน Android Emulator 288
บทท 6 พนฐานการเขยนโปรแกรมภาษาจาวาบนแอนดรอยดสำหรบนกพฒนา 302
เครองมอพฒนา Android Studio IDE 303
วธการตดตง Android Studio IDE 304
การตดตงและเรยกใชโปรแกรมบนอปกรณแอนดรอยด 309
การยายโคดโปรแกรมเดม Eclipse IDE มาส Android Studio 311
Apache Ant สำหรบการนกพฒนาแอนดรอยด 312
Android Activity 313
User Interface 320
Android Adapter 329
Android Intent 332
Broadcast Receiver 333
การพฒนาโปรแกรมดวย Android Native Development Kit 337
พนฐาน Android NDK 337
เรมตนการพฒนาโปรแกรม Android NDK 340
ตวอยางโปรแกรม Hello World ดวย Android NDK 342
พนฐานการพฒนา JAVA Native Interface (JNI) 348
ตวอยางการสรางและเรยกใช JNI Methods 352
ตวอยางการพฒนา Android NDK Multi-Threading 359
บทท 7 การพฒนาโปรแกรมประยกตบนระบบสมองกลฝงตว 366
ตวอยางการพฒนาโปรแกรมบนบอรด Raspberry Pi 366
เครองมอพฒนาพนฐานสำหรบ Android และ Arduino 382
ตวอยางการเชอมตอระหวาง Android กบ Arduino ผาน ADK 386
ตวอยางการพฒนาการแสดงสญญาณไฟฟากลามเนอ (EMG) 389
บทสรปและกาวตอไป... 395
ประวตผเขยน 396
บทท 1 พนฐาน UNIX/LINUX สำหรบนกพฒนา
ประวตระบบปฏบตการ Unix/Linux
เปนระยะเวลาไมนอยกวา 55 ป เมอยอนกลบไปตงแตกอนทนกพฒนาจากหองปฏบตการ Bell จะพฒนาระบบปฏบตการแบบใหมชอระบบปฏบตการ UNIX โดยใชภาษาซ (C Language) เปนภาษาโปรแกรมหลกในการเขยนระบบปฏบตการตวนขนมา จนกลายเปนภาษาทไดรบความนยมในหมนกเขยนโปรแกรมมากทสด จดเรมตนของเรองนทงหมดเกดขนในป ค.ศ. 1960 ซงไดเรมมการพฒนาระบบปฏบตการแบบแบงเวลา (timesharing) โดย Dartmouth College และ Massachusetts Institute of Technology (M.I.T.) ซงมจดเดนคอ ผใชหลายคนสามารถใชเครองในเวลาเดยวกนได โดยอาศยการแบงเวลาของหนวยประมวลผลกลางใหแกผใชเวยนกนไป ถกพฒนาขนโดยภาษาโปรแกรมเบสค (BASIC Language) แตประสบความสำเรจในการใชงานทางธรกจแคชวงระยะหนง ในขณะทระบบปฏบตการอกตวชอ CTSS (MIT's Compatible Time-Sharing System) จาก M.I.T. ซงเปนระบบฏบตการทไดถกออกแบบเพอใหเปนระบบปฏบตการอเนกประสงค กไดรบความนยมในกลมนกวทยาศาสตรเปนพเศษ หลงจากนนไมนาน ทาง M.I.T. หองปฏบตการ Bell และบรษท GE (General Electric) ซงเปนบรษทผผลตคอมพวเตอร ไดรวมกลมกนเพอทำการวจยและออกแบบระบบปฏบตการแบบแบงเวลาตวใหม ใหมความสามารถมากขนและกำหนดชอระบบปฏบตใหมนชอวา MULTICS (MULTiplexed Information and Computing Service)
แมวาตวระบบปฏบตการ MULTICS จะสามารถรองรบผใชไดหลายรอยคน แตโครงการกยงเกดปญหาขนหลายอยาง โดยเฉพาะอยางยงตวภาษา PL/I ทใชในการเขยนโปรแกรมนนยงอยในระหวางการพฒนาและมการพฒนาลาชากวากำหนดการทกำหนดไวมากและมขอบกพรองมากมาย รวมทงปจจยอนทเทคโนโลยในขณะนนเองกยงไมพรอม หองปฏบตการ Bell จงไดถอนตวออกจากโครงการหลงจากสนสดโครงการระยะแรก
หนงในนกวจยของโครงการชอ Ken Thompson จงเรมหาแนวทางในการทำวจยตอไป โดยยงคงนำระบบปฏบตการ MULTICS มาทำการพฒนาตอ ซงไดทำการยอสวนโคดโปรแกรมโดยใชภาษาแอสเซมบล (Assembly Language) ในการพฒนาระบบปฏบตการตวใหมนบนเครองมนคอมพวเตอรรน PDP-7 จนกลายเปนระบบปฏบตการทสามารถทำงานไดเปนอยางด และในทสดกไดถกตงชอใหมโดยหนงในนกวจยของหองปฏบตการ Bell ชอ Brian Kernighan วา UNICS (Uniplexed Information and Computing Service) เพอเปนการลอเลยนโครงการ MULTICS และตอมากไดรบการเปลยนชอเปน UNIX ในทสด
ตอมากไดมนกวจยคนอนๆในหองปฏบตการ Bell เรมสนใจทจะขอเขารวมโครงการเพอพฒนาระบบปฏบตการ UNIX ของ Ken Thompson มากขน และคนแรกทไดเขารวมกคอ Dennis Ritchie เพอพฒนาระบบปฏบตการ UNIX อยบนเครองมนคอมพวเตอรรน PDP-11 ซงมขดความสามารถสงกวา
13
Embedded Android Development สเสนทางนกพฒนา
เครองรน PDP-7 เดม ตอมานกวจยทเหลอกไดเขารวมโครงการทงหมด จนทำใหระบบปฏบตการ UNIX ทอยบนเครองรน PDP-11/45 และ PDP-11/70 ไดรบความนยมในตลาดสงในชวงทศวรรษท 1970 เพราะไดเพมขนาดของหนวยความจำใหขนาดใหญ และมกลไกการปองกนหนวยความจำ ทำใหเปนเครองคอมพวเตอรท สามารถรองรบการใชงานผ ใชหลายคนในเวลาเดยวกนไดพรอมกน
นอกจากนนหองปฏบตการ Bell ยงไดวางแผนพฒนาภาษาโปรแกรมตวใหม เพอใชในการเขยนระบบปฏบตการเนองจากคอมพวเตอรแตละรนจะมโครงสรางทางฮารดแวรแตกตางกน ทำใหตองใชเวลาในการพฒนาดวยภาษาโปรแกรมแอสเซมบลมากพอสมควร จงเปนเหตผลสำคญทจะตองเรงสรางภาษาโปรแกรมตวใหมทยดหยนสำหรบระบบปฏบตการในอนาคต โดยในระยะแรกของการพฒนาภาษาโปรแกรมนนทาง Ken Thompson ไดเลอกใชภาษาบ (B Language) ซงเปนภาษาโปรแกรมทพฒนาตอมาจากภาษา BCPL (Basic Conbined Programming Lanaguge) พฒนาโดย M.I.T. ดงววฒนาการภาษาโปรแกรมดงรปขางลาง
รปท 1.2 ววฒนาการภาษาโปรแกรม
14
Embedded Android Development สเสนทางนกพฒนา
รปท 1.1 Ken Thompson และ Dennis Ritchie
ตวอยางโปรแกรมแสดงคา 5 Factorials โดยเปรยบเทยบรปแบบการเขยนโปรแกรมดวยภาษา BCPL และภาษาบ
โปรแกรมดวยภาษา BCPL:
GET "LIBHDR"LET START() = VALOF $( FOR I = 1 TO 5 DO WRITEF("%N! = %I4*N", I, FACT(I)) RESULTIS 0)$AND FACT(N) = N = 0 -> 1, N * FACT(N - 1)
ตวอยางโปรแกรมภาษาบจากตวอยางหนงสอท Ken Thompson เปนผเขยน
/* The following function will print a non-negative number, n, to the base b, where 2<=b<=10, This routine uses the fact that in the ASCII character set, the digits 0 to 9 have sequential code values. */ printn(n,b) { extrn putchar; auto a; if(a=n/b) /* assignment, not test for equality */ printn(a, b); /* recursive */ putchar(n%b + '0');}
แตเนองจากตวภาษาบเองนน เปนภาษาโปรแกรมทมโครงสรางขอมลและรปแบบการควบคมภายในยงมขอจำกดอยพอสมควร ทำใหการพฒนาระบบปฏบตการ UNIX โดยใชภาษาบยงไมคอยประสบความสำเรจเทาทควร ดงนนทาง Dennis Ritchie จงไดพฒนาและปรบปรงภาษาบใหมคณสมบตทเหมาะสมในการเขยนระบบปฏบตการมากยงขน และในทสดกไดกลายมาเปนภาษาโปรแกรมตวใหมชอวา ภาษาซ (C Language) ตอมาทาง Thompson และ Ritchie ไดรวมกนพฒนาระบบปฏบตการ UNIX จากภาษาซใหมทงหมด ทำใหภาษาซกลายมาเปนภาษาโปรแกรมทไดรบความนยมในหมนกเขยนโปรแกรมอยางมากเนองจากเปนภาษาอเนกประสงคทเหมาะกบการใชเขยนโปรแกรมแบบตางๆและหลากหลาย ทงยงเปนภาษาโปรแกรมทสามารถทำความเขาใจไดงายและสามารถนำโคดโปรแกรมเกามาใชงานประยกตกบโปรแกรมใหมได ตอมาในป ค.ศ. 1974 Ritchie และ Thompson ไดตพมพผลงานการวจยและพฒนาระบบปฏบตการ UNIX ตวใหมน จนเปนผลใหทงสองไดรบรางวล ACM Turing Award ในป ค.ศ. 1984
15
Embedded Android Development สเสนทางนกพฒนา
จากผลงานดงกลาวทางบรษท AT&T ผเปนเจาของหองปฏบตการ Bell และเปนผถอลขสทธระบบปฏบตการ UNIX ไดอนญาตใหมหาวทยาลยตางๆ ใชระบบปฏบตการ UNIX โดยเสยคาธรรมเนยมเพยงเลกนอย เพอหวงใหเปนทนยมมากยงขน ในขณะนนดวยระบบปฏบตการจะมากบเครอง PDP-11 ซงยงทำงานไมมประสทธภาพดพอและยงใชงานยากอย จงทำใหเกดการวจยและพฒนาปรบปรงระบบปฏบตการ UNIX กนอยางกวางขวาง จนกระทงในทสดกไดเกดตวใหมขนทชอวา ระบบปฏบตการ BSD UNIX (Berkeley Software Distribution UNIX) ซงถกพฒนาโดย University of California (UC Berkeley) จนกลายเปนตวหนง ทไดรบความนยมและมการใชงานกนอยางแพรหลายในสถาบนการศกษา ตอมาหนวยงานกระทรวงกลาโหมของสหรฐฯ (Defense Advanced Research Projects Agency - DARPA) กไดใหทนกบทาง UC Berkeley เพอพฒนาระบบปฏบตการ UNIX ตอใหกลายเปน Version 4 BSD เพอรองรบการสอสารของเครอขาย DARPA ทใชมาตราฐานในการสอสารชอวา TCP/IP ตอมาในป ค.ศ. 1993 ทาง UC Berkley กไดออกตว BSD รน 4.4 ทรองรบการสอสารแบบโปรโตคอล X.25 แตเปนทนาเสยดายทในทสด UC Berkeley กไดหยดการพฒนาระบบปฏบตการ UNIX ในเวลาตอมา
หลงจากนนไมนานพฒนาการของเครองคอมพวเตอรกเรมมประสทธภาพสงขน ในขณะทราคาฮารดแวรกเรมถกลง ในทสดระบบปฏบตการ UNIX ทเคยอยในระดบมนคอมพวเตอรกสามารถนำมาใชบนคอมพวเตอรสวนบคคล (Personal Computer) ทเรยกวา “XENIX” แมในยคแรกของเครอง XENIX ยงมเพยงหนาจอทแสดงแตเพยงตวหนงสอ (Text Mode) จนกระทงชวงกลางทศวรรษ 1980 กไดมการพฒนา X-Window ขนมาทำใหการใชงาน UNIX กเรมม GUI (Graphic User Interface) เกดขน
บรษท AT&T ยงคงผลกดนการพฒนาระบบปฏบตการ UNIX จนกระทงถงรน System V Release 4 (SVR4) ทาง AT&T ไดพยายามรวมขอกำหนดและมาตราฐานตางๆ ของ BSD UNIX และ XENIX
16
Embedded Android Development สเสนทางนกพฒนา
รปท 1.3 ระบบปฏบตการ Unix ในวารสาร The Bell System Technical Journalcopies of the 1978 and 1984 special Unix issues of the Bell System Technical Journal (Link)
เขาไปดวยกน ซงทงสองสามารถถกนำไปใชงานไดบน SVR4 ไดดวยเหตการณครงนทำใหกลมนกพฒนาและบรษททเกยวของเรมวตกกงวลวาจะเกดการผกขาดในการกำหนดมาตราฐานของระบบปฏบตการ UNIX จากบรษท AT&T หรอไม ทงหมดจงไดรวมตวกนจดตงองคกร Open Software Foundation (OSF) ขนเพอรวมวจยและรวมกำหนดมาตราฐานตางๆของระบบ UNIX ในเวลาตอมา
นอกจาก UC Berkeley แลว กยงมบรษทรายอนๆทพฒนาเครองคอมพวเตอรระดบสงเพอใชในดานธรกจ เชน บรษทซนไมโครซสเตม (SunOS และ Solaris) บรษท DEC (เครอง Ultrix จนเปลยนชอเปน OSF/1) บรษทไมโครซอฟต (เครอง XENIX) บรษทไอบเอม (เครอง AIX) ซงสวนใหญจะยดแนวระบบปฏบตการของ BSD หรอไมก System V สำหรบระบบปฏบตการ UNIX นน ปจจบนไดกลายเปนเครองหมายการคาจดทะเบยน (Registered Trademark) ของหนวยงานทชอ The Open Group ซงเปนหนวยงานทกำหนดและรบรองมาตรฐานของระบบปฏบตการ UNIX ไว 2 แบบคอ
• ระบบปฏบตการทไดมาตรฐาน UNIX ซงใชมาตรฐานของ The Open Group ในการพฒนาขนมา เชน Digital UNIX, SCO UNIX, IBM's OpenEdition MVS• ระบบปฏบตการคลาย UNIX (UNIX Compatible) เปนระบบปฏบตการทมลกษณะคลายระบบ ปฏบตการ UNIX แตยงไมไดจดทะเบยนรบรองเปนทางการ เชน Sun Solaris, IBM AIX, Linux
โครงการ GNU (GNU Project) ไดถกรเรมจากนกวจยจาก M.I.T ชอ Richard Stallman เนองจากระบบปฏบตการ UNIX ไมไดฟรอกตอไปแลว โดยวตถประสงคหลกของโครงการนคอการพยายามเรมตนสราง C compiler (gcc), make (GNU make), Emacs, C library (glibc), และ coreutils (เชนคำสง ls, cp เปนตน) ใหมทงหมดเพอใหทกคนสามารถนำไปใชไดฟร แตอยางไรกตามโครงการนกยงคงขาดตวแกนกลางสำคญสำหรบระบบปฏบตการทเรยกวาเคอรเนล (Kernel) จนกระทงป ค.ศ. 1991 นกศกษา
17
Embedded Android Development สเสนทางนกพฒนา
รปท 1.4 TimeLine ของระบบปฏบต UNIX/LINUX
สาขาวทยาการคอมพวเตอร มหาวทยาลย Helsinki ประเทศฟนแลนดชอ Linus Torvalds ไดมแนวคดทจะสรางระบบปฏบตการแบบเปดและฟร โดยมพนฐานคลายระบบปฏบตการ UNIX ซงไดใชเครองมอจากโครงการ GNU ทงหมด ไมวาจะเปน C library, gcc, binutils, fileutils, make, emacs เปนตน รวมทงการพฒนา Kernel โดยพยายามพฒนาโปรแกรมทงหมดตามมาตราฐาน POSIX เชนเดยวกนระบบปฏบตการ UNIX จนในทสดกสามารถออกมาไดสำเรจในชอระบบปฏบตการ Minix และทาง Linus Torvalds กไดเปดเผยโคดโปรแกรมของระบบปฏบตการทงหมดสสาธารณะ เพอใหนกพฒนาทวโลกชวยกนปรบปรงแกไข จนกระทงออกเวอรชน 1.0 (ค.ศ. 1994) และ เวอรชน 2.2 (ค.ศ. 1999) ตามลำดบ จนไดชอวาระบบปฏบตลนกซ (Linux) ในทสด
ประเภทของ LICENSES
จากการเกดขนของโครงการ GNU โดย Richard Stallman ทตองการใหนกพฒนาและผใชงานสามารถนำไปใชไดฟรโดยไมมคาใชจาย แตกจะตองนำไปใชภายใตเงอนไขการคมครองตามลขสทธทผพฒนากำหนดไว ดงตวอยางลขสทธบางสวนตามตารางขางลางน
LICENSE เงอนไข
GNU General Public License (GPL)
หากมการนำโคดโปรแกรมไปทำการแกไข หรอ เขยนโปรแกรมขนมาใหมเพอเรยกใชฟงกชน คลาส หรอไลบราร โปรแกรมใหมทเกดขนนนจะตองม GPL license ตดไปดวย ซงลกษณะของสญญาอนญาต GPL มลกษณะ “เสร” ดงน - เสรภาพในการใชงาน ไมวาใชสำหรบจดประสงคใด - เสรภาพในการศกษาการทำงานของโปรแกรม และแกไขโคด - เสรภาพในการจำหนายโปรแกรม -เสรภาพในการปรบปรงและเปดใหบคคลทวไปใชและพฒนาตอโดยมเพยงเงอนไขวาการนำไปใชหรอนำไปพฒนาตอ จำเปนตองใชสญญาอนญาตเดยวกน
GNU Lesser General Public License (LGPL)
หากมการนำโคดโปรแกรมไปทำการแกไข หรอ เขยนโปรแกรมขนมาใหมเพอเรยกใชฟงกชน คลาส หรอไลบราร โปรแกรมใหมทเกดขนนนไมจำเปนตองตด LGPL (Lesser GPL) ไปดวย แตสวนของโคดโปรแกรมชดเดมกยงคงตองม LGPL ตดไปดวย โปรแกรมสวนทเขยนขนมาเองสามารถนำไปขายไดแตจะตองระบอยางชดเจนวาไดนำโปรแกรมสวนใดมาใชในการพฒนาบาง
18
Embedded Android Development สเสนทางนกพฒนา
LICENSE เงอนไข
Apache Licenseใหแสดงในเอกสารวาไดใชโคดโปรแกรม หรอ ไลบราร ทเปน Apache License สวนโปรแกรมทพฒนาขนมาใหมเองสามารถเลอกใช license แบบไหนกได
BSD Licensesโคดโปรแกรมทไดทำการแกไขไมจำเปนตองเปดเผยโคดโปรแกรม มเพยงขอความเจาของสญญาอนญาตเดมเทานนทตองแสดง
Creative Commons Licenses
ถกนำไปใชในลขสทธ ของผลงาน โดยอาจเปนผลงานการเขยน รปภาพ หรอการออกแบบ โดยเจาของผลงานสามารถเลอกไดวาผลงานของตวเองจะใหม license เปนแบบไหน เชน แสดงทมา , แสดงทมาไมใชเพอการคา , แสดงทมาไมใชเพอการคาไมดดแปลง เปนตน
ปรชญา และความรพนฐานของระบบปฏบตการลนกซ
ในอดตการใชงานระบบปฏบตการลนกซ เปนเรองทหลายคนคดวามความซบซอนและยากตอการทำความเขาใจ เพราะอาจตองใชความเขาใจในเชงลกเกยวกบระบบคอมพวเตอรและระบบเครอขายพอสมควร เชนการใชคำสงในการสงการระบบปฏบตการ การตงคาการทำงานบนบอรดสมองกลฝงตว หรอการเขยนโปรแกรมประยกตเพอใชในการควบคมจดการระบบการสอสารตางๆ หรอการตดตอสอสารขอมลระหวางฮารดแวร เหลาน ลวนตองใชความรและทกษะหลายดานประกอบกนจงทำใหมใชงานในอยวงจำกด ตวอยางเชน ศนยคอมพวเตอรแมขาย บรษททออกแบบอปกรณทมระบบสมองกลฝงตวทางดานระบบสอสารและโทรคมนาคม หองปฏบตการภายในมหาวทยาลย หรอหนวยวจยภาครฐ/ภาคเอกชน เปนตน
แตอยางไรกตามในปจจบนหลายคนกไมสามารถปฏเสธไดวาระบบปฏบตการ UNIX/LINUX เรมเขามามบทบาทในชวตประจำวนมากขน ไมวาจะเปนระบบอเมลในองคกร ระบบไฟลภายในองคกร เวปแอพพเคชนทโดงดงตางๆ (facebook, google, twitter) ลวนแลวแตทำงานอยภายใตระบบปฏบตการ UNIX/LINUX เกอบทงสน นอกจากนนภายในอปกรณเครองใชไฟฟา อปกรณสอสารชนดพาพก กถกสงการดวยระบบปฏบตการอนทรงพลงอยางระบบปฏบตการลนกซอยเบองหลงในการทำหนาทควบคมดแลการทำงานของระบบภายในอปกรณ ทำหนาทตดตอกบผใชผาน GUI (Graphic User Interface) และทำหนาทในการสอสารผานระบบเครอขายไปยงศนยกลาง เปนตน ดงนนนกพฒนาไมวาจะระดบใดหรอนสตนกศกษาทเรยนในสายวทยาศาสตรคอมพวเตอร เทคโนโลยสารสนเทศ วศกวรรมไฟฟา วศวกรรมคอมพวเตอร วศวกรรมระบบควบคม ทงหลาย จงมความจำเปนอยางยงทจะตองเรมทำความเขาใจหลกการทำงานของระบบปฏบตการลนกซ ไมวาจะเปนการใชคำสงพนฐาน การใชงานโปรแกรมประยกต
19
Embedded Android Development สเสนทางนกพฒนา
ตางๆ รวมทงการพฒนาภาษาโปรแกรม ภายใตระบบปฏบตการลนกซ เพอเพมโอกาสใหกบตวเองในอนาคต ในสายอาชพนกพฒนาโปรแกรม นกพฒนาระบบสมองกลฝงตว นกพฒนาระบบสอสารแบบใหม นกวจยทางดานการวศวกรรมการแพทย วศวกรรมชวภาพ นกธรกจทางดานบรการสารสนเทศ นกธรกจทางดานอปกรณใชเทคโนโลยขนสง เปนตน
จดเรมตนเพอกาวเขาสนกพฒนาทดทสดคอ การเรมตนการใชงานระบบปฏบตการลนกซ ทำความเขาใจปรญชาพนฐานของระบบปฏบตการลนกซแลวลงมอปฏบต ดวยการทดลองใชคำสงตางๆจากงายๆไปสยากและทำอยางตอเนอง ผลจากการเรยนรฝกฝนเหลานจะนำไปสเสนทางทยงใหญและเตมไปดวยทางเลอกมากมาย จะพบเจอกบแหลงความรอนมหาศาลทจะมโอกาสสรางสรรสงใหมๆใหเกดขนไดอยางเหลอเชอ ซงเนอหาภายในบทนเปนการรวบรวมและสรปคำสงและความรพนฐานทสำคญในการใชระบบปฏบตการลนกซซงจะเหมาะสำหรบนกพฒนารนเยาวจนถงนกพฒนาระดบกลาง ประกอบไปดวยหวขอดงตอไปน
- เรยนรกระบวนการทำงานของเชลล (Shell) และ Standard I/O Stream- ตวแปรภายในระบบ (Environment Variable)- การเรยกใชงานคำสงภายในเชลล และภายนอกเชลล- คำสงพนฐานสำหรบนกพฒนาดานระบบสมองกลฝงตว- คำสงพนฐานในการตงคาและดแลจดการบรการดานระบบเครอขาย
กระบวนการทำงานของเชลล และชดคำสงทเกยวของภายในระบบปฏบตการลนกซเกอบทกสงทกอยางทอยภายในระบบคอไฟลทงสน (Almost Every-
thing is File) ไดแก• ไฟลปกตทวไป (Regular files) เชนไฟลเอกสาร ไฟลมลตมเดย ไฟลโปรแกรม • ไดเรกทอร (Directories) ไฟลทบรรจรายการของไฟลตางๆ• ไฟลเชอมสญลกษณ (Symbolic links) ไฟลทอางองไปยงไฟลอน• ไฟลอปกรณ (Devices and Peripherals) ไฟลทเชอมตอกบอปกรณฮารดแวรของระบบ• ไฟลทอสงขอมล (Pipe) ไฟลทใชเปนทอเชอมระหวางโปรแกรม เพอสงคาผลลพธ (output) ของโปรแกรมหนง ใหเปนคานำเขา (input) ของอกโปรแกรมหนง
• ไฟลทอซอกเกต (Socket) ไฟลทเปนเปนทอเชอมตอการสอสารขอมลระหวางโปรเซส ทอยในเครองเดยวกน หรอตางเครองผานระบบเครอขายได
เชลล (Shell)shell เปนตวกลางในการรบคำสง (Command Line) จากผใชแลวจะทำการแปลชดคำสง
(Command Line Interpreter - CLI) ทผใชปอนเขามา โดยขบวนการภายในตว shell จะซอนรายละเอยดอนซบซอนของระบบปฏบตการเอาไว โดยทผใชจะไมรวาหลงจากทปอนคำสงไปแลวภายในจะ
20
Embedded Android Development สเสนทางนกพฒนา
ตองมขบวนการเชนไรบาง ตวอยางเชน ถาผใชตองการทราบหนวยความจำทเหลอหรอพนทของฮารดดสกทเหลออย ผใชเพยงพมพคำสง free/df ตว shell กจะทำหนาเชอมตอและเขาไปจดการในหนวยความจำหรอฮารดดสกใหตรวจสอบตวเองวาขณะนมการใชงานเกบขอมลไปเทาไหรแลวและเหลอพนทใหใชงานไดอกเทาไหร ซงขบวนการดงทไดกลาวขางตนเปนการตดตอสอสารในระดบลางทเรยกวาระดบเคอรเนล ซงถอไดวาเปนแกนกลางสำคญในการควบคมการทำงานระบบทงหมดภายในเครองคอมพวเตอร โดยจะกลาวถงรายละเอยดของเคอรเนลในบทถดๆไป
นอกจากนน shell ยงสามารถรองรบการเขยนชดคำสงมากกวาหนงคำสงพรอมกน และสามารถรบชดคำสงลวงหนาใหทำงานตามเงอนไขตางๆทไดกำหนดไวในลกษณะสครปท (Script) ทถกเกบลงในไฟลได ทำใหเพมความสะดวกและมประสทธภาพในการใชงานระบบปฏบตการลนกซ โดยเฉพาะผใชทมทกษะอยระดบหนงในการเขยนสครปทหรอทเรยกกนวาเชลลสครปท (Shell script) นน และนอกจากนนลกเลนความสามารถจะมากนอยเพยงใดกยงขนอยกบยหอหรอรนโปรแกรม shell นนดวย ในปจจบน shell ทมอทธพลและเปนทนยมมากทสดตวหนงคอ Bourne shell (ปจจบนกลายเปน Bourne Again shell) และ C shell
หนาจอรบคาสง
Shell
ประมวลผลคาสง
รนคาสงอานคาสง
รปท 1.5 ขบวนการทำงานของ Shell
ตวอยางการตรวจสอบชนดของ shell ทกำลงใชงานอยในระบบดวยคำสง echo และตรวจสอบรนของ shell ดวย --version
$ echo $SHELL/bin/bash
$ bash --versionGNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)Copyright (C) 2009 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software; you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.
21
Embedded Android Development สเสนทางนกพฒนา
หากตองการทราบถงรายการชดคำสงทถกฝงอยภายใน shell โดยใชคำสงดงขางลางน
$ bash -c helpGNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)These shell commands are defined internally. Type `help' to see this list.Type `help name' to find out more about the function `name'.Use `info bash' to find out more about the shell in general.Use `man -k' or `info' to find out more about commands not in this list.A star (*) next to a name means that the command is disabled.
job_spec [&] history [-c] [-d offset] [n] or hist> (( expression )) if COMMANDS; then COMMANDS; [ elif C> . filename [arguments] jobs [-lnprs] [jobspec ...] or jobs > : kill [-s sigspec | -n signum | -sigs> [ arg... ] let arg [arg ...] [[ expression ]] local [option] name[=value] ... alias [-p] [name[=value] ... ] logout [n] bg [job_spec ...] mapfile [-n count] [-O origin] [-s c> bind [-lpvsPVS] [-m keymap] [-f filen> popd [-n] [+N | -N] break [n] printf [-v var] format [arguments] builtin [shell-builtin [arg ...]] pushd [-n] [+N | -N | dir] caller [expr] pwd [-LP] case WORD in [PATTERN [| PATTERN]...)> read [-ers] [-a array] [-d delim] [-> cd [-L|-P] [dir] readarray [-n count] [-O origin] [-s> command [-pVv] command [arg ...] readonly [-af] [name[=value] ...] or> compgen [-abcdefgjksuv] [-o option] > return [n] complete [-abcdefgjksuv] [-pr] [-DE] > select NAME [in WORDS ... ;] do COMM> compopt [-o|+o option] [-DE] [name ..> set [--abefhkmnptuvxBCHP] [-o option> continue [n] shift [n] coproc [NAME] command [redirections] shopt [-pqsu] [-o] [optname ...] declare [-aAfFilrtux] [-p] [name[=val> source filename [arguments] dirs [-clpv] [+N] [-N] suspend [-f] disown [-h] [-ar] [jobspec ...] test [expr] echo [-neE] [arg ...] time [-p] pipeline enable [-a] [-dnps] [-f filename] [na> times eval [arg ...] trap [-lp] [[arg] signal_spec ...] exec [-cl] [-a name] [command [argume> true exit [n] type [-afptP] name [name ...] export [-fn] [name[=value] ...] or ex> typeset [-aAfFilrtux] [-p] name[=val> false ulimit [-SHacdefilmnpqrstuvx] [limit> fc [-e ename] [-lnr] [first] [last] o> umask [-p] [-S] [mode] fg [job_spec] unalias [-a] name [name ...] for NAME [in WORDS ... ] ; do COMMAND> unset [-f] [-v] [name ...] for (( exp1; exp2; exp3 )); do COMMAN> until COMMANDS; do COMMANDS; done function name { COMMANDS ; } or name > variables - Names and meanings of so> getopts optstring name [arg] wait [id] hash [-lr] [-p pathname] [-dt] [name > while COMMANDS; do COMMANDS; done help [-dms] [pattern ...] { COMMANDS ; }
สามารถทราบรายละเอยดของแตละคำสงทอยภายใน shell โดยพมพ help <ชอคำสง> ตวอยางเชน
$ help timestimes: times Display process times. Prints the accumulated user and system times for the shell and all of its child processes. Exit Status: Always succeeds.
22
Embedded Android Development สเสนทางนกพฒนา
Echo Echo เปนคำสงทใชในการแสดงขอความใดๆทตองการใหถกปรากฏบนหนาตางเทอรมนล ดงตวอยางการใชคำสงดงน
$ echo Welcome to Embedded SystemWelcome to Embedded System!$ echo Welcome to Embedded SystemWelcome to Embedded System!$ echo 'Welcome to Embedded System'Welcome to Embedded System!
จากตวอยางจะเหนวาคำสง echo จะไมสนใจชองวางวาจะมกชองวาง การแสดงผลจะถกตดชองวางเหลอเพยง 1 ชองวางเสมอ แตถาตองการใหแสดงผลลพธตามระยะหางทตองการจะตองใชเครองหมาย อญประกาศ (‘ -Apostrophe) หรอเครองหมายคำพด (“ - Quotation Mark) ครอบขอความนน เนองจากใน Bash shell นนจะใช white space (โดยการกดปม space bar) ในการแยกขอความออกเปน token หรอเรยกวา พารามเตอรเพอใชในการแสดงผล แตถามการใสเครองหมายครอบขอความเชน ‘Burapha University’ ขอความนนจะถกเกบไวใน token เพยงตวเดยว
การใชงานคำสง echo จะมตวเลอก (Option) หลายแบบ (ซงสามารถดรายละเอยดคำสงไดโดยพมพ man echo) ยกตวอยางเชน การใชตวเลอก -n ตอทายคำสง echo จะหมายถงการไมขนบรรทดใหม (New Line)
$ echo -n "My name is Android"My name is Android$
แตถาตองการขนบรรทดใหมตามอกขระพเศษ \n (new line) ตองระบตวเลอก -e หลงคำสง echo
$ echo -e "My name is \nAndroid"My name is Android
นอกจากอกขระ \n แลวยงมอกขระในการควบคมการแสดงผลขอความดงรายละเอยดในตารางขางลางน
ตาราง 1.1 แสดงการใชงานอกขระพเศษ
ESCAPE SEQUENCE รายละเอยด\a Alert (bell)
\b Backspace
23
Embedded Android Development สเสนทางนกพฒนา
ESCAPE SEQUENCE รายละเอยด\c หยดการขนบรรทดใหม (ลกษณะเดยวกบการใชงาน -n)
\f Form feed
\n New line
\r Carriage return
\t Horizontal tab
ในการใชงาน Bash shell นนยงมอกขระเฉพาะมากมายทไมสามารถนำมาใชแสดงเปนตวขอความได เนองจากถกใชเปนเครองมอในการจดการอนพทของคำสง เชน '|', '&', ';', '(', ')', '<', '>' แตถาตองการแสดงอกขระเหลานใหปรากฏอยในขอความจะตองเตมสญลกษณ \ นำหนาอกขระเสมอ หรอใชเครองหมายอญประกาศครอบทงขอความทมอกขระผสมอยกได
ตวอยางการใชสญลกษณ \ นำหนาอกขระทตองการแสดงเปนขอความ
$ echo I love Linux & Android[1] 30136I love LinuxAndroid: command not found[1]+ Done echo I love Linux[1]+ Done echo I love Linux$ echo I love Linux \& AndroidI love Linux & Android$ echo 'I love Linux & Android'I love Linux & Android
Command Sequences ผใชสามารถปอนคำสงมากกวาหนงคำสงไปพรอมกนโดยใชตวดำเนนการควบคม (Control Opera-tors) ไดแก ‘||’, ‘&&’, ‘&’, ‘;’, ‘;;’, ‘|’, ‘(‘, ‘)’ เปนตน ซงการเรยงชดคำสงอยางงายทสดในกรณทมมากกวา 1 คำสงเปนตนไป จะใชเครองหมาย ‘;’ อฒภาค (semicolon) shell จะรบคำสงและดำเนนการทละคำสงตามลำดบ ในกรณทจะมการตรวจสอบผลลพธการทำงานของแตละคำสงวาสำเรจหรอลมเหลวนน ระบบปฏบตการลนกซจะมการคนคากลบคอถาคนคากลบมาเลขศนยจะหมายถงคำสงดำเนนการสำเรจ แตถาเปนตวเลขอนๆจะถอวาคำสงนนทำงานลมเหลว ดงนนผใชสามารถกำหนดเสนทางการทำงานตามเงอนไขทออกมาโดยใชตวดำเนนการ AND ‘&&’ และ OR ‘||’ ตวอยางเชน
$ lsandroid ccache Downloads kernel output.txt Templates workspaceaosp Desktop error.log Music Pictures test.txt
24
Embedded Android Development สเสนทางนกพฒนา
bin Documents git one.txt Public Videos$ ls test.txt && echo "OK... File exists"test.txtOK... File exists$ ls mail.txt && echo "OK... File exists"ls: cannot access mail.txt: No such file or directory
จากคำสงขางตน ไฟล test.txt มอยในไดเรกทอรจงทำใหระบบปฏบตการลนกซคนคากลบมาเปนศนย คำสงถดไปจงทำงานตอได แตในขณะทไฟล mail.txt ไมไดอยในไดเรกทอร แสดงถงการทำงานลมเหลว ทำใหไมมการทำคำสงตวถดไป แตหากใชตวดำเนนการ ‘||’ คำสงถดมาจะถกทำงานในกรณทคำสงแรกมการคนคากลบมาไมเทากบศนย ดงตวอยางขางลาง
$ ls test.txt || echo "OK... File exists"test.txt$ ls mail.txt || echo "No File exists"ls: cannot access mail.txt: No such file or directoryON File exists
แตหากตองการนำตวดำเนนการ && และ || มาประยกตใชในการตรวจสอบเงอนไขเหมอนชดคำสง if (เงอนไข) ..(จรง).. else ..(เทจ).. หรอ if (เงอนไข) ? ..(จรง).. : ..(เทจ).. ในภาษาโปรแกรมทวไป จะมรปแบบการเขยนดงน
$ ls test.txt && echo "OK...File exists" || echo "Oh Bad... File not found"test.txtOK...File exists$ ls mail.txt && echo "OK...File exists" || echo "Oh Bad... File not found"ls: cannot access mail.txt: No such file or directoryOh Bad... File not found
Standard I/O รายละเอยดขบวนการทำงานของ Shell ในระบบปฏบตการลนกซ จะมพนฐานสำคญคอ วธการเชอมตอระหวางโปรแกรมและสงแวดลอมของตวโปรแกรมเองภายในเทอรมนล (Terminal) ทเรยกวา I/O ซงรปขางลางนเปนการแสดงการเชอมตอของอปกรณ I/O มาตราฐานพนฐานของระบบทมอย 3 ชนด ไดแก
25
Embedded Android Development สเสนทางนกพฒนา
คยบอรด
หนาจอ
โปรแกรม
Terminal
#0 stdin
#1 stdout
#2 stderr
รปท 1.6 Standard I/O
ตาราง 1.2 รายละเอยดพนฐานของ Standard I/O
STREAM มาตราฐาน FD รายละเอยด
stdin (Standard Input Stream) 0สำหรบรบคำสงจากผใชเพอสงตอใหโปรแกรม อาทเชนการ
รบขอมลคำสงจากการกดคยบอรด
stdout (Standard Output) 1สำหรบแสดงผลลพธทถกสงออกมาจากโปรแกรม เพอสง
ขอความผลลพธออกมาแสดงบนจอภาพ
stderr (Standard Error) 2สำหรบแสดงผลความผดพลาดเกดจากการทำงานของ
โปรแกรมทรบคำสงมาประมวลผล ออกจากหนาจอภาพ
Redirectionsระบบปฏบตการลนกซนนไดเตรยมเครองมอตวดำเนนการทสามารถควบคมกลไกการไหลของ
ขอมลจากทศทางหนงไปยงอกทศทางหนงหรออธบายงายๆคอการเปลยนเสนทางขอมลวาจะใหออกตว standard stream ตวใด โดยการใชตวดำเนนการ “<” แทน stdin (Standard Input) และ “>” แทน stdout (Standard Output) ซงตวดำเนนการ redirection นนมอยดวยกน 5 แบบตามรายละเอยดในตารางขางลาง
ตาราง 1.3 ตวดำเนนการ redirection
ตวดำเนนการ รายละเอยด
< ไฟล เปดไฟลสำหรบอานขอมลภายในไฟล
<< token ใชในกรณทเปนคำสงหรอเชลลสครปททตองการรบคาจนกระทงเจอ token
> ไฟล เปดไฟลสำหรบเขยนทบขอมลใหม
26
Embedded Android Development สเสนทางนกพฒนา
ตวดำเนนการ รายละเอยด
>> ไฟล เปดไฟลสำหรบเขยนตอทายจากขอมลเดม
n>&m เปลยนเสนทางของ File Descriptor (FD) เดม n ไปทใหม m
ยกตวอยางเชน การใชงานการสงอนพทจากไฟล /etc/passwd ใหกบคำสง grep และการสงอนพทจากการปอนขอความใหกบคำสง sort ดงแสดงขางลาง
$ grep -i student < /etc/passwdstudent:x:1000:1000:EE-Burapha Student,,,:/home/student:/bin/bash$ sort << END> 55233424 Wiroon Sriborrirux> 55237346 Nayot Kurukitkoson> 55236477 Panuwat Dankhang> END55233424 Wiroon Sriborrirux55236477 Panuwat Dankhang55237346 Nayot Kurukitkoson$ sort -k2 << END> 55233424 Wiroon Sriborrirux> 55237346 Nayot Kurukitkoson> 55236477 Panuwat Dankhang> END55237346 Nayot Kurukitkoson55236477 Panuwat Dankhang55233424 Wiroon Sriborrirux
เมอมการใชตวดำเนนการ “>” ผลลพธจากคำสงจะถกสงไปเกบไวในไฟล /tmp/results แทนทจะออกหนาจอ ดงตวอยางขางลาง
$ grep -i student /etc/passwd > /tmp/results$ ls /tmp/CRX_75DAF8CB7768 orbit-student ssh-pqdoFN1336 vmware-root-2hsperfdata_student pulse-Xti8iSZ9STOh VMwareDnD vmware-studentkeyring-27UIsq results vmware-root$ cat /tmp/results student:x:1000:1000:EE-Burapha Student,,,:/home/student:/bin/bash
ตวอยางการใชคำสง cat เพอแสดงขอมลภายในไฟล จะมการแสดงขอความผดพลาด (Error message) ออกทางหนาจอ ถาไฟลนนไมมอยในไดเรกทอร
$ cat one.txt two.txt 2>&1This is the data insidecat: two.txt: No such file or directory
27
Embedded Android Development สเสนทางนกพฒนา
สามารถกรองขอความผดพลาดใหไปเกบไวในไฟลชอ error.log ดวยตวดำเนนการ “2>”
$ cat one.txt two.txt 2> error.logThis is the data inside
ในกรณทไมตองการเกบขอความผดพลาด สามารถทำไดโดยสงไปใหไฟลชอ /dev/null
$ cat one.txt two.txt 2> /dev/nullThis is the data inside
บนทกขอความผดพลาดเพมตอเขาไปในไฟล error.log ดวยตวดำเนนการ “2>>”
$ cat one.txt two.txt three.txt 2>> error.logThis is the data inside$ cat error.log cat: two.txt: No such file or directorycat: two.txt: No such file or directorycat: three.txt: No such file or directory
ตวแปรสภาพแวดลอมของระบบตวแปรสภาพแวดลอม (Environment variables) เปนตวแปรทมความสำคญมากในระบบปฏบต
การลนกซ เนองจากเปนตวแปรกลางท shell หรอ โปรแกรมประยกตตางๆสามารถเรยกใชงานได อาทเชน ตวแปรทเกบขอมลของ shell หรอตวแปรทเกบขอมลของไดเรกทอรประจำตวของผใช (Home Di-rectory) และยงมตวแปรตางๆ อกมากมายท shell ไดมการตงคาไวในขณะท shell เรมทำงาน ตวอยางเชน bash shell จะมการเรยกไฟลเรมตนอย 2 ไฟลไดแก ไฟล .profile และไฟล .bashrc
$ cat .profile <---- ในกรณ Ubuntu เวอรชน 13.04 ขนไป# .bash_profile# Get the aliases and functionsif [ -f ~/.bashrc ]; then . ~/.bashrcfi# User specific environment and startup programsexport USE_CCACHE=0export CCACHE_DIR=~/ccacheexport JAVA_HOME=/usr/lib/jvm/jdkexport ANT_HOME=~/android/antexport ANDROID_SDK_HOME=~/android/sdkexport ANDROID_NDK_HOME=~/android/ndkexport AOSP_HOME=~/aospexport PATH=$HOME/bin:$JAVA_HOME/bin:$ANT_HOME/bin:$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform-tools:$ANDROID_NDK_HOME:$PATH$ cat .bashrc# .bashrc# User specific aliases and functionsHISTSIZE=1000
28
Embedded Android Development สเสนทางนกพฒนา
HISTFILESIZE=2000# some more ls aliasesalias ll='ls -alF'alias la='ls -A'alias l='ls -CF'alias rm='rm -i'alias cp='cp -i'alias mv='mv -i'
# Source global definitionsif [ -f /etc/bashrc ]; then . /etc/bashrcfi
เมอผใชเขาสระบบ Login โดยการใชงานผานหนาจอเทอรมนลซงนยมเรยกสนๆวา tty (Teletype-writer) เมอหนาจอเทอรมนลถกสรางขน ตวโปรแกรมสำหรบการเขาสระบบกจะถกเรยกขนมาเพอแสดงขอความใหผใชกรอกชอผใช (username) และรหสผาน (password) เมอเขาสระบบไดสำเรจกจะทำการเรยกโปรแกรม shell เพออานคาพนฐานทตงไวสำหรบสภาพแวดลอมของระบบ (system environ-ments) ดงขนตอนในรปขางลาง
สราง tty ใหมใหกบผใชอานการตงคาระบบหลกใน /etc/
profile หรอ /etc/bashrc
โปรแกรม agetty แสดงหนา login บน tty
โปรแกรม agetty เรยกคาสง /bin/login
โปรแกรม login เรมทางานบน shell
อานการตงคาระบบของผใชใน ~/.bashrc
แสดงขอความ login ทกาหนดอยในไฟล /etc/motd
Terminal
Login Shell
ผใช
รปท 1.7 ขนตอนการเขาสระบบปฏบตการผานเทอรมนล
นอกจากนนระบบจะมการตงคาตวแปรระบบพนฐาน ซงเปนตวแปรสำคญทจะพบเจอบอยไดแก
29
Embedded Android Development สเสนทางนกพฒนา
ตาราง 1.4 แสดงตวแปรระบบพนฐาน
ชอ คำอธบาย
USER เรยกชอผใชงานทใชในการเขาสระบบ
UID เรยกรหสผใชงานทใชในการเขาสระบบ
HOME เรยก Home Directory
PWD เรยก Directory ทกำลงใชงาน
SHELL เรยกชอ shell ทกำลงใชงาน
$ เรยก process id ทกำลงใชงาน
PPID เรยก process id ทไดรบการสบทอดมา
? The exit code of the last command
ยกตวอยางการใชคำสง echo เพอแสดงคาภายในตวแปรระบบ
$ echo $SHELL/bin/bash
$ echo -e " My Home directory is $HOME\n My username is $USER\n My current directory is $PWD" My Home directory is /home/student My username is student My current directory is /home/student
$ echo $PPID1927
$ ps -aux | grep 1927student 1927 0.0 0.5 192052 11236 ? Sl 08:15 0:33 gnome-terminal
env และ exportคำสง export เปนคำสงทผใชงานสามารถสรางตวแปรระบบเพมเตมไดเอง โดยการระบเขาไปใน
ไฟล .bashrc หรอพมพคำสงการตงคาไดโดยตรงใน terminal ดงตวอยางขางลาง
$ export my_project_codes=/home/student/embedded/sourcecode/$ echo $my_project_codes/home/student/embedded/sourcecode/
หากผใชตองการดคาตวแปรระบบทมการใชงานอย สามารถใชคำสง env หรอ export -p ดงน
$ envORBIT_SOCKETDIR=/tmp/orbit-studentSSH_AGENT_PID=1383TERM=xterm
30
Embedded Android Development สเสนทางนกพฒนา
SHELL=/bin/bash...USER=studentPATH=/home/student/bin:/usr/lib/jvm/jdk/bin:/home/student/android/ant/bin:/home/student/android/sdk/tools:/home/student/android/sdk/platform-tools:/home/student/android/ndk:/home/student/bin:/home/student/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/gamesANDROID_SDK_HOME=/home/student/android/sdkPWD=/home/studentJAVA_HOME=/usr/lib/jvm/jdkGDM_KEYBOARD_LAYOUT=usLANG=en_US.utf8GDM_LANG=en_US.utf8MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.pathGDMSESSION=gnomeSHLVL=1HOME=/home/studentGNOME_DESKTOP_SESSION_ID=this-is-deprecatedLOGNAME=studentDISPLAY=:0.0AOSP_HOME=/home/student/aospLESSCLOSE=/usr/bin/lesspipe %s %sCOLORTERM=gnome-terminalXAUTHORITY=/var/run/gdm/auth-for-student-9wtySF/database_=/usr/bin/env
$ export -pdeclare -x ANDROID_NDK_HOME="/home/student/android/ndk"declare -x ANDROID_SDK_HOME="/home/student/android/sdk"declare -x ANT_HOME="/home/student/android/ant"...declare -x USER="student"declare -x USERNAME="student"declare -x USE_CCACHE="0"declare -x WINDOWID="14722574"declare -x XAUTHORITY="/var/run/gdm/auth-for-student-9wtySF/database"declare -x XDG_CONFIG_DIRS="/etc/xdg/xdg-gnome:/etc/xdg"declare -x XDG_DATA_DIRS="/usr/share/gnome:/usr/local/share/:/usr/share/"
Execexec เปนคำสงทใชในการเรยกโปรแกรมอนขนมาแทนท shell เดมทใชงานอย ดงตวอยางคำสง
ขางลางเปนการใชงานคำสง exec โดยจะมการสราง bash shell ขนมาอกตวเพอใหเปนโปรเซสลก (PID 30779) ททำงานภายใน bash shell หลกทเปนโปรเซสแม (PID 19907) จากนนมการเรยกใชงานคำสง exec sh ซงเปนการเรยกตว sh shell ขนมาแทนท bash shell จะสงเกตไดจากหมายเลขโปรเซสเปนหมายเลขเดยวกน (PID 19907) ถาหากผใชงานตองการออกจาก shell ทไดทำการสรางขนมาจะตองใชคำสง exit เพอเปนจบการทำงานของโปรเซส (PID 30779) ทไดทำการสรางขนมา
$ ps PID TTY TIME CMD
19907 pts/1 00:00:00 bash <---- หมายเลขโปรเซสแม30777 pts/1 00:00:00 ps $ bash
31
Embedded Android Development สเสนทางนกพฒนา
$ ps PID TTY TIME CMD19907 pts/1 00:00:00 bash
30779 pts/1 00:00:00 bash <---- หมายเลขโปรเซสลก30796 pts/1 00:00:00 ps$ exec sh$ ps PID TTY TIME CMD19907 pts/1 00:00:00 bash30779 pts/1 00:00:00 sh30800 pts/1 00:00:00 ps$ exit$ ps PID TTY TIME CMD19907 pts/1 00:00:00 bash30802 pts/1 00:00:00 ps
การเรยกใชงานคำสงภายในเชลล และภายนอกเชลลคำสงพนฐานภายใน shell เองนนประกอบไปดวยคำสงหลกๆเพยงไมกคำสงเทานน สำหรบคำสง
อนๆทเปนโปรแกรมประยกตหรอโปรแกรมอรรถประโยชนจะถกอางองมาจากชดคำสงภายนอก shell (External Command) ทงสน โดยคำสงตางๆภายนอก shell จะเปนไฟลโปรแกรมทถกเกบอยในระบบไฟล (root filesystem) เชน /usr/bin เปนตน ดงนนการเขาถงไฟลโปรแกรมเหลานจำเปนตองรตำแหนงไดเรกทอรทเกบไฟลโปรแกรมเหลานนอย เมอผใชพมพคำสง โปรแกรม shell จะเขาไปอานไดเรกทอรทถกตงคาไวในตวแปรสภาพแวดลอมของระบบ (Environment Variables) ทชอวา $PATH โดยในการเขาถงคำสงนน shell จะทำการตรวจสอบคำสงตงแตไดเรกทอรแรกจนถงไดเรกทอรสดทาย (โดยม ‘:’ คนระหวางไดเรกทอร) ภายในตวแปร PATH ดงนนกรณทผใชงานตองการทราบวาคำสงทใชนนถกเกบอยในไดเรกทอรใด กสามารถตรวจสอบไดดวยคำสง which ดงน
$ which ls cat date ifconfig uname whoami ps find grep echo set/bin/ls/bin/cat/bin/date/sbin/ifconfig/bin/uname/usr/bin/whoami/bin/ps/usr/bin/find/bin/grep/bin/echo
ถาตองการทราบรายละเอยดทสำคญบางอยาง เชน เปนคำสงทอยภายใน shell หรอ เปนคำสงทเกดจากการทำ alias (การทำนามแฝงใหกบคำสงทจำยาก หรอซบซอน ใหกลายเปนคำสงทเราจำไดงายขน หรอ
32
Embedded Android Development สเสนทางนกพฒนา
เรยกไดสนๆ เชน alias ls=`ls -al --color=auto`) กสามารถใชคำสง type เพอตรวจสอบได ดงน
$ type ls cat date ifconfig uname whoami ps find grep echo setls is aliased to `ls -al --color=auto'cat is hashed (/bin/cat)date is /bin/dateifconfig is /sbin/ifconfiguname is /bin/unamewhoami is /usr/bin/whoamips is hashed (/bin/ps)find is /usr/bin/findgrep is aliased to `grep --color=auto'echo is a shell builtinset is a shell builtin
สงเกตวาไดเรกทอรสวนใหญทอยใน PATH จะลงทายดวย bin ดวยเหตผลการวางโครงสรางของระบบไฟลภายในระบบปฏบตการลนกซ ใหเกบไฟลโปรแกรมไวในไดเรกทอร /bin และ /usr/bin
คำสงพนฐานสำหรบนกพฒนาบนระบบสมองกลฝงตว
คำสงตรวจสอบทรพยากรระบบการใชงานระบบปฏบตการลนกซภายใตระบบสมองกลฝงตวทมทรพยากรจำกด ไมวาจะเปน
ความเรวของหนวยประมวลผลกลาง ขนาดของหนวยความจำ หรอขนาดพนทจดเกบขอมล นกพฒนาจำเปนจะตองศกษาเกยวกบวธการตดตามการใชทรพยากรของระบบภายในสมองกลฝงตว และสามารถประเมนเพอหลกเลยงความผดพลาดทอาจจะเกดขนในกรณททรพยากรถกใชมากเกนไปเพอทำใหระบบสามารถทำงานไดอยางมประสทธภาพและมความเสถยรภาพสงสด
topเปนคำสงแรกๆทผดแลหรอนกพฒนาระบบจำเปนตองทำความรจก เพราะเปนคำสงทใชแสดง
สถานะการใชงานทรพยากรของระบบ รวมทงแสดงรายการโปรเซสทถกเรยกใชงานอย โดยเรยงตามการครอบครองทรพยากร ซงเชอมโยงกบ virtual filesystem (VFS) ไฟล /proc/loadavg ดงตวอยางขางลาง
33
Embedded Android Development สเสนทางนกพฒนา
รปท 1.8 แสดงผลลพธคำสง top
จากรปขางบน จะมสวนรายละเอยดสำคญ ไดแกUptime หมายถง เวลาปจจบน ระยะเวลารวมทระบบถกเปด และจำนวนผใชงานทอยในระบบload average หมายถง ขอมลทแสดงการเปรยบเทยบการใชงานหนวยประมวลผลกลาง (CPU) ทใชงานอย กบความสามารถในการรองรบการใชงาน โดยแสดงออกมา 3 คา ซงไดแก คา 0.10 ณ ชวงเวลา 1 นาทกอนหนา, คา 0.11 ณ ชวงเวลา 5 นาทกอนหนา และ คา 0.04 ณ ชวงเวลา 15 นาทกอนหนานอกจากนนสามารถใชคำสง uptime เมอตองการดคาทงสองอยางนโดยเฉพาะ (uptime และ load average) ดวยคำสงขางลางน
$ uptime 01:24:59 up 17:18, 4 users, load average: 0.08, 0.08, 0.02
$ watch -n 1 uptime <--- รนคำสง uptime ทกๆ 1 วนาทEvery 1.0s: uptime Tue Aug 20 01:26:37 201301:26:37 up 17:19, 4 users, load average: 0.01, 0.05, 0.01
34
Embedded Android Development สเสนทางนกพฒนา
อยางไรกตามการตความคา load average นนกยงมนกพฒนาจำนวนไมนอยทไมเขาใจความหมายทแทจรงของคาน เนองจากคาทไดไมใชจำนวนเปอรเซนต บางครงคาตวเลขกเกน 1.0 ดงนนเพอใหเหนภาพ นกพฒนาลองทำการจนตนาการตามวาเครองทมหนวยประมวลผลกลางแบบคอรเดยว (single-core CPU) เปรยบไดกบถนนเดนรถทางเดยว (one-way lane) บนสะพานขามแมนำ และสมมตใหระบบปฏบตการลนกซเปนตำรวจจราจรคอยจดการการเดนรถบนสะพานแหงน ซงในบางชวงเวลาของแตละวนปรมาณรถทวงขนสะพานอาจจะมากนอยไมเทากนขนอยกบชวงเวลาเรงดวน (rush hour) ดงนนตำรวจจราจรจำเปนจะตองมการประเมนสภาพการจราจรในรปแบบของระบบตวเลข (numbering sys-tem) เชน
• 0.00 หมายถง ไมมการจราจรบนถนน• 0.50 หมายถง การจราจรคลองตว • 1.00 หมายถงการจราจรหนาแนนแตเคลอนตวได • ถา 2.00 อาจหมายถง รถเตมตลอดถนนบนสะพาน และมจำนวนรถทปรมาณเทากนรออยตนสะพาน
• ถา 3.00 อาจหมายถง รถเตมตลอดถนนบนสะพาน และมจำนวนรถทปรมาณ 2 เทา รออยตนสะพาน เปนตน
รปขางลางแสดงปรมาณรถบนถนนทางเดยวบนสะพาน และรถทตองรออยทตนสะพาน
load เทากบ 1.00
load เทากบ 0.50
load เทากบ 1.50
รปท 1.9 แสดงการเปรยบเทยบสภาพจราจรกบ Load
เปรยบเทยบรถทกำลงเคลอนทขามสะพาน กคอโปรเซสทจะเขามาใชเวลาของหนวยประมวลผล กลางใหทำงานให (slice of CPU time) หรอการรอควเพอใชหนวยประมวลผลกลาง โดยระบบปฏบตการลนกซ จะมการอางถงความยาวของคว (run-queue length) ซงมาจากผลรวมของจำนวนโปรเซส บวกดวยจำนวนของโปรเซสทกำลงรอคว ซงคาทเปนอดมคตทดสดคอ 1.00 ซงหมายถงสะพานสามารถรบปรมาณรถไดเตมท และยงคงเคลอนตวไดด เปรยบไดกบ จำนวนโปรเซสรออยเตมควพอด และหนวยประมวณผลกลางกยงสามารถทำงานใหไดอยางตอเนอง ทางเทคนคจะเรยกคานวา คา “Utilization”
35
Embedded Android Development สเสนทางนกพฒนา
ดงนนการประเมนสภาพภาระโดยเฉลย (load average) ของหนวยประมวลผลกลางนน โดยหลกการทวไป (Rule of Thumb) แลว ควรไมเกน 0.70 ซงนกพฒนาจะตองรบตรวจสอบภาระโดยเฉลยในกรณทเกน 0.70 ทเกดตอเนองมาสกระยะนง เพราะอาจจะเกดปญหาใหญตามมาได
คำสงตรวจสอบการใชหนวยความจำระบบ
free, pmapหนวยความจำ (Memory) เปนทรพยากรสำคญในระบบสมองกลฝงตว ดงนนการตรวจสอบวาม
การใชงานหนวยความจำมากนอยเพยงใดจงมความสำคญสง ในระบบปฏบตการ Embedded Linux นนการตรวจสอบและแสดงผลการใชงานหนวยความจำไดมการกำหนดใหใชคำสง free ซงเชอมโยงกบ virtual filesystem (VFS) ไฟล /proc/meminfo สำหรบการแสดงผลสามารถเลอกการแสดงผลโดยการใสตวเลอกเขาไปไดดงตวอยางตอไปน โดยท -k แสดงในรปแบบกโลไบต , -m แสดงในรปแบบเมกาไบต, -g แสดงผลในรปแบบกกาไบต
$ free -m -t total used free shared buffers cachedMem: 2001 1649 351 0 193 1145-/+ buffers/cache: 311 1690Swap: 16381 93 16288Total: 18383 1743 16640
นอกจากนนการดรายละเอยดของการเขาใชจบจองหนวยความจำและการอางองกบไลบรารตางๆของโปรเซส กเปนสงจำเปนสำหรบนกพฒนาทจะตองรวาโปรแกรมทไดพฒนามการทำงานเปนอยางไรเมอถกโหลดขนสหนวยความจำ ดงนนคำสง pmap จงถกนำมาชวยวเคราะหไดด ดงตวอยางคำสงขางลางน
สรางไฟล hello.c โดยมโคดภาษาซดงน
$ cat hello.c
#include <stdio.h>int main()
{ printf("Hello World!\n"); while (1) {
} return 0;}
$ gcc -o hello hello.c$ ./hello &[1] 11958
36
Embedded Android Development สเสนทางนกพฒนา
Hello World!
$ pmap 1195811958: ./hello0000000000400000 4K r-x-- /home/student/hello0000000000600000 4K r---- /home/student/hello0000000000601000 4K rw--- /home/student/hello00007f34087ca000 1512K r-x-- /lib/libc-2.11.1.so00007f3408944000 2044K ----- /lib/libc-2.11.1.so00007f3408b43000 16K r---- /lib/libc-2.11.1.so00007f3408b47000 4K rw--- /lib/libc-2.11.1.so00007f3408b48000 20K rw--- [ anon ]00007f3408b4d000 128K r-x-- /lib/ld-2.11.1.so00007f3408d52000 12K rw--- [ anon ]00007f3408d69000 12K rw--- [ anon ]00007f3408d6c000 4K r---- /lib/ld-2.11.1.so00007f3408d6d000 4K rw--- /lib/ld-2.11.1.so00007f3408d6e000 4K rw--- [ anon ]00007fff77ad1000 84K rw--- [ stack ]00007fff77bff000 4K r-x-- [ anon ]ffffffffff600000 4K r-x-- [ anon ] total 3864K
คำสงตรวจสอบการใชพนทสำหรบเกบขอมล
df, duการเกบขอมลในระบบสมองกลฝงตว อปกรณทถกใชเปนตวเกบขอมลจะแตกตางกบเครอง
คอมพวเตอรทวไป เนองจากไมมฮารดดสก แตจะใชอปกรณเกบขอมลชนดแฟลชแทน เชน NAND Flash, USB Storage หรอ MMC/SD Card เปนตน ซงมขนาดความจนอยมากเมอเทยบกบฮารดดสกทวไป ดงนนการเฝาตรวจสอบพนทของตวเกบขอมลจะตองใหความสำคญมากเปนพเศษ คำสงทมการใชงานกนอยางแพรหลายในระบบปฏบตการลนกซ ทสามารถแสดงผลไดทงจำนวนพนททมการใชงานไปแลวในระบบ และพนทวางทสามารถใชงาน ไดแกคำสง df (disk free) ดงตวอยางตอไปน
$ df -hFilesystem Size Used Avail Use% Mounted on/dev/sda1 99G 62G 37G 63% /none 997M 276K 997M 1% /devnone 1001M 92K 1001M 1% /dev/shmnone 1001M 88K 1001M 1% /var/runnone 1001M 0 1001M 0% /var/locknone 1001M 0 1001M 0% /lib/init/rw
คำสง du (disk usage) หมายถงคำสงทใชในการตรวจสอบขนาดการใชงานไดเรกทอรทชอย (mount point) รวมถงไดเรกทอรยอยๆลงไปจากตำแหนงปจจบน และการใชงานคำสง du จะมลกษณะทคลาย
37
Embedded Android Development สเสนทางนกพฒนา
กบการใชงานคำสง df นนคอคำสง du สามารถทจะเตมตวเลอก -h เขาไปทายคำสงเพอเปนการแปลงขอมลใหอยในลกษณะทบคคลทวไปสามารถอานไดงายดงตวอยางตอไปน
$ du -h busybox-1.21.0/44K busybox-1.21.0/libpwdgrp108K busybox-1.21.0/findutils536K busybox-1.21.0/miscutils24K busybox-1.21.0/coreutils/libcoreutils684K busybox-1.21.0/coreutils...
116K busybox-1.21.0/archival/libarchive/unxz484K busybox-1.21.0/archival/libarchive824K busybox-1.21.0/archival16M busybox-1.21.0/
นอกจากตวเลอก -h แลว สามารถใชอกตวเลอกคอ -s ซงจะแสดงผลรวมทไดจากไดเรกทอรตางๆ เขามาอยในบรรทดเดยว ดงตวอยางขางลาง
$ du -sh busybox-1.21.0/16M busybox-1.21.0/
คำสงสำหรบการบรหารจดการโปรเซสในการบรหารจดการโปรเซสทเกดขนในระหวางเครองทำงานอย จะเปนหนาทหลกของระบบปฏบต
การลนกซ ทจะตองจดลำดบการรองขอจากแตละโปรเซสเพอเขาใชทรพยากรของระบบ ดงนนโปรเซสทกตวจะตองมหมายเลขประจำของตวเอง ซงจะถกกำหนดมาใหจากระบบปฏบตการเอง เรยกวา PID (process id) แตอยางไรกตามผใชหรอนกพฒนากสามารถควบคมและบรหารจดการกบโปรเซสทเกดจากการเรยกดวยตวผใชเอง โดยสามารถบรหารจดการแยกเปนกลมไดแก
• การตดตามดสถานะของโปรเซสโดยรวมดวยคำสง jobs• เลอกดเฉพาะโปรเซสทตองการ และคาตางทตองการ• การสงสญญาณ (signals) แบบตางไปยงโปรเซส
jobs, psคำสงทเกยวกบการตดตามดสถานะของโปรเซสโดยรวมนน หลกมอย 2 คำสงคอ jobs และ ps
(process snapshot) โดยคำสง jobs นนจะแสดงหมายเลขของงานทถกเรยกขนมาตามลำดบ และมหมายเลขโปรเซส (PID) อยดวย นอกจากนนคำสงนจะบอกสถานะของโปรเซสทงหมดวาเปนอยางไรบาง เชน กำลงทำงาน (running) ถกหยดการทำงาน (stopped) ถกสงใหสนสดการทำงาน (killed) เปนตน ดงตวอยางคำสงขางลาง
38
Embedded Android Development สเสนทางนกพฒนา
$ jobs -l[1] 11958 Running ./hello &[2]- 12458 Stopped emulator & (wd: ~/aosp)[3]+ 12794 Killed gcalctool
สำหรบคำสง ps มหนาทในการแสดงรายละเอยดโปรเซส ตวอยางเชน ถารบรายการ PID มาจากคำสง jobs ทระบตวเลอก -p (การลำดบ process group leader) กจะแสดงรายละเอยดของหมายเลขโปร เซสเหลานน ดงตวอยางขางลาง
$ jobs -p119581245812818$ ps $(jobs -p) PID TTY STAT TIME COMMAND11958 pts/0 R 63:41 ./hello12458 pts/0 Sl 2:25 /home/student/android/sdk/tools/emulator64-x8612818 pts/0 S 0:00 gcalctool
ในกรณทผดแลระบบตองการทราบถงสถานะโปรเซสทงหมดททำงานอยในระบบ ผดแลระบบจำเปนตองมการเพมตวเลอก -ef ตอทายคำสง ps เพอแสดงผลโปรเซสทงหมดททำงานอยในระบบในขณะนน ดงตวอยางขางลาง
$ ps -efUID PID PPID C STIME TTY TIME CMDroot 1 0 0 Aug19 ? 00:00:01 /sbin/initroot 2 0 0 Aug19 ? 00:00:00 [kthreadd]root 3 2 0 Aug19 ? 00:00:01 [migration/0]root 4 2 0 Aug19 ? 00:00:08 [ksoftirqd/0]root 5 2 0 Aug19 ? 00:00:00 [watchdog/0]root 6 2 0 Aug19 ? 00:00:01 [migration/1]root 7 2 0 Aug19 ? 00:00:08 [ksoftirqd/1]root 8 2 0 Aug19 ? 00:00:00 [watchdog/1]root 10 2 0 Aug19 ? 00:00:01 [events/1]root 11 2 0 Aug19 ? 00:00:00 [cpuset]root 12 2 0 Aug19 ? 00:00:00 [khelper]root 13 2 0 Aug19 ? 00:00:00 [netns]root 14 2 0 Aug19 ? 00:00:00 [async/mgr]root 18 2 0 Aug19 ? 00:00:00 [bdi-default]root 19 2 0 Aug19 ? 00:00:00 [kintegrityd/0]root 20 2 0 Aug19 ? 00:00:00 [kintegrityd/1]root 21 2 0 Aug19 ? 00:00:01 [kblockd/0]root 306 2 0 Aug19 ? 00:00:05 [jbd2/sda1-8]root 1268 1 0 Aug19 tty3 00:00:00 /sbin/getty -8 38400 tty3root 1272 1 0 Aug19 tty6 00:00:00 /sbin/getty -8 38400 tty6root 1275 1 0 Aug19 ? 00:00:07 /usr/sbin/irqbalancestudent 11825 11824 0 05:21 ? 00:00:00 gnome-pty-helperstudent 11826 11824 0 05:21 pts/0 00:00:00 bashstudent 11958 11826 99 05:22 pts/0 01:24:29 ./hellostudent 12458 11826 5 05:42 pts/0 00:03:43 /home/student/android/sdk/tools/student 12515 1 0 05:43 pts/0 00:00:00 adb fork-server serverstudent 12818 11826 0 06:26 pts/0 00:00:00 gcalctool
39
Embedded Android Development สเสนทางนกพฒนา
root 12856 2 0 06:32 ? 00:00:00 [flush-8:0]student 12929 11826 0 06:47 pts/0 00:00:00 ps -ef
จากผลลพธทได จะสามารถทราบไดวามโปรเซสไหนบางทเกดจากการเรยกของผใชคนใด (UID) มหมายเลขโปรเซสอะไร (PID) และเกดขนจากการเรยกของโปรเซสใด (PPID) เปนตน รายละเอยดดงอธบายในตารางตอไปน
ตาราง 1.5 รายละเอยดของคำสง ps
คอลมน ความหมายUID แสดง user เจาของโปรเซส
PID แสดงหมายเลขโปรเซส (Process ID)
PPID แสดงหมายเลขโปรเซสหลกทไดรบการสบทอดมา (Parent Process ID)
C แสดงการใชงาน CPU
STIME แสดงเวลาทโปรเซสเรมตน
TTY แสดงรหสเทอมนอลทโปรเซสทำงานอย
TIME เวลาโดยรวมทเขาไปใชงาน CPU
CMD ชอคำสงทใชในการสรางโปรเซสขนมา
เมอตองการดเฉพาะโปรเซสทเกดขนจากการเรยกใชใน bash shell สามารถใชตวเลอก เชน -f (full), -j (jobs), -l (long), --forest, --sort ดงตวอยางการใชงานขางลาง
$ ps PID TTY TIME CMD11826 pts/0 00:00:00 bash11958 pts/0 01:19:16 hello12458 pts/0 00:03:31 emulator64-x8612515 pts/0 00:00:00 adb12818 pts/0 00:00:00 gcalctool12905 pts/0 00:00:00 ps
$ ps -fUID PID PPID C STIME TTY TIME CMDstudent 11826 11824 0 05:21 pts/0 00:00:00 bashstudent 11958 11826 99 05:22 pts/0 01:19:17 ./hellostudent 12458 11826 5 05:42 pts/0 00:03:31 /home/student/android/sdk/tools/student 12515 1 0 05:43 pts/0 00:00:00 adb fork-server serverstudent 12818 11826 0 06:26 pts/0 00:00:00 gcalctoolstudent 12906 11826 0 06:42 pts/0 00:00:00 ps -f
$ ps -j --forest PID PGID SID TTY TIME CMD
40
Embedded Android Development สเสนทางนกพฒนา
11826 11826 11826 pts/0 00:00:00 bash11958 11958 11826 pts/0 01:19:31 \_ hello12458 12458 11826 pts/0 00:03:31 \_ emulator64-x8612818 12818 11826 pts/0 00:00:00 \_ gcalctool12908 12908 11826 pts/0 00:00:00 \_ ps12515 12514 11826 pts/0 00:00:00 adb
$ ps -aj --sort sid,comm PID PGID SID TTY TIME CMD12515 12514 11826 pts/0 00:00:00 adb12458 12458 11826 pts/0 00:04:26 emulator64-x8612818 12818 11826 pts/0 00:00:00 gcalctool11958 11958 11826 pts/0 01:42:27 hello13020 13020 11826 pts/0 00:00:00 ps
การหยดการทำงานของโปรเซส (Process Killing) ในระบบปฏบตการลนกซนนจะใชหลกการสงขอความของระบบในระดบลาง (low-level system message) ทเรยกกนวา สญญาณ (Signal) โดยสญญาณจะถกสงไปขดจงหวะโปรเซส เพอบอกกบโปรเซสตามวตถประสงคของสญญาณนน ซงในระบบปฏบตการลนกซจะมชนดของสญญาณอยทงสน 64 ชนด สามารถดรายละเอยดไดจากการพมพคำสง kill -l ดงขางลางน$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGCONT 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
ตวอยางสญญาณทสำคญและใชงานบอย ตวอยางเชน
41
Embedded Android Development สเสนทางนกพฒนา
• สญญาณหมายเลข 1 (SIGHUP) คอ Hang Up Signal เปนสญญาณทถกสงออกไปในขณะท terminal ถกปดลงเพอทำใหโปรเซสทถกเรยกภายใต terminal ถกปดลงตามดวย
• สญญาณหมายเลข 3 (SIGQUIT) คอ Quit Signal เปนสญญาณทถกสงออก ในขณะทผใชงานไดมการสงให โปรเซสนนปดตวลง
• สญญาณหมายเลข 6 (SIGABRT) คอ Abort Signal เปนสญญาณทถกสงออกมาจากโปรเซสทตองการปดตวเองลง
• สญญาณหมายเลข 9 (SIGKILL) คอ Kill Signal ลกษณะชอง signal ประเภทนจะคลายกบการดงสายไฟออกจากเครองคอมพวเตอร กลาวคอเปนการสงใหโปรเซสปดตวลงทนทไมวาจะทำงานอะไรอยกตาม
• สญญาณหมายเลข 18 (SIGCONT) คอ Continue Signal เปนสญญาณทสงใหโปรเซสนนกลบมาทำงานปกตเชนเดม เชนเดยวกนการสงใหโปรเซสกลบมาทำงานเบองหนา (foreground)
• สญญาณหมายเลข 20 (SIGTSTP) คอ การสง Stop Signal ดวย Keyboard (Ctrl+Z) เปนสญญาณทสงใหโปรเซสนนถกทำใหไปทำงานเบองหลง (background) เชนเดยวกบการกดปม Ctrl+Z บนคยบอรด
ตวอยางการสงสญญาณผานคยบอรด เปนวธการหนงของการสงสญญาณใหกบโปรเซส โดยเมอมกดคำสงบนคยบอรดดงนCtrl-C
สงสญญาณ INT (SIGINT) ไปยงโปรเซสททำงานอยยตการทำงานทนทCtrl-Z
สงสญญาณ TSTP (SIGTSTP) ไปยงโปรเซสททำงานอยใหหยดชวคราวCtrl-\
สงสญญาณ ABRT (SIGABRT) ไปยงโปรเซสททำงานอยใหยตการทำงานของโปรเซสนนทนท เหมอน Ctrl-C แตเปนคำสงทดกวาคอสามารถแกไขได
$ jobs -l[1] 11958 Running ./hello &[2]- 12458 Running emulator & (wd: ~/aosp)[3]+ 12818 Running gcalctool &
$ kill -s SIGTSTP 12818$ jobs -l[1] 11958 Running ./hello &[2]- 12458 Running emulator & (wd: ~/aosp)[3]+ 12818 Stopped gcalctool
$ kill -s SIGCONT 12818$ jobs -l[1] 11958 Running ./hello &[2]- 12458 Running emulator & (wd: ~/aosp)
42
Embedded Android Development สเสนทางนกพฒนา
[3]+ 12818 Running gcalctool &
$ kill -s SIGKILL 12818$ jobs -l[1] 11958 Running ./hello &[2]- 12458 Running emulator & (wd: ~/aosp)[3]+ 12818 Killed gcalctool
$ kill -s SIGTERM 11958$ jobs -l[1] 11958 Terminated ./hello[2]- 12458 Running emulator & (wd: ~/aosp)
การอานสถานะของทรพยากรระบบจากไดเรกทอร /PROC
ไดเรกทอร /proc เปรยบเสมอนหนาตางของลนกซคอรเนล (Kernel Windows) ซงเปนไดเรกทอรพเศษทเปนระบบไฟลเสมอน (virtual filesystem) ทสามารถเขาถงสถานะการทำงานของอปกรณในระดบฮารดแวรของเครอง และสถานะขอมลตางๆของระบบโดยคาทงหมดจะถกเกบอยในหนวยความจำ
เมอใชคำสง ls /proc จะพบกลมของไฟลจำนวนมาก รวมทงไดเรกทอรทเปนตวเลข ซงไดเรกทอรเหลานคอสถานทเกบขอมลของระบบทกำลงทำงานอยและถกจะอางองจากหมายเลขโปรเซสนนเอง นอกจากนนแลวในไดเรกทอร /proc ยงมไฟลพเศษทแทนฮารแวรตางๆในระบบ ไดแก
ตาราง 1.6 ตวอยางไฟลสำคญในไดเรกทอร /proc
ไฟล คำอธบาย/proc/modules dynamically loaded modules
/proc/devices registered character and block major numbers
/proc/iomem on-system physical RAM and bus device addresses
/proc/ioports on-system I/O port addresses (especially for x86 systems)
/proc/interrupts registered interrupt request numbers
/proc/softirqs registered soft IRQs
/proc/kallsyms running kernel symbols, including from loaded modules
/proc/partitions currently connected block devices and their partitions
/proc/filesystems currently active filesystem drivers
/proc/swaps currently active swaps
/proc/cpuinfo information about the CPU(s) on the system
/proc/meminfo information about the memory on the system, viz., RAM, swap
43
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการอานคาสถานะของระบบจากไฟลภายในไดเรกทอร /proc/
$ cat /proc/partitions major minor #blocks name
8 0 104857600 sda 8 1 104855552 sda1 8 16 16777216 sdb 8 17 16775168 sdb1$ cat /proc/interrupts CPU0 CPU1 0: 286 0 IO-APIC-edge timer 1: 14606 732 IO-APIC-edge i8042 3: 1 0 IO-APIC-edge 4: 32225 881 IO-APIC-edge 6: 3 0 IO-APIC-edge floppy...TRM: 0 0 Thermal event interruptsTHR: 0 0 Threshold APIC interruptsMCE: 0 0 Machine check exceptionsMCP: 259 259 Machine check polls
$ cat /proc/cpuinfo processor : 0vendor_id : GenuineIntelcpu family : 6model : 58model name : Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHzstepping : 9cpu MHz : 2293.993cache size : 6144 KBfpu : yesfpu_exception : yescpuid level : 13wp : yes...processor : 1vendor_id : GenuineIntelcpu family : 6model : 58model name : Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHzstepping : 9cpu MHz : 2293.993cache size : 6144 KBfpu : yesfpu_exception : yescpuid level : 13wp : yesflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss syscall nx rdtscp lm con-stant_tsc arch_perfmon pebs bts rep_good xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 x2apic popcnt aes xsave avx hypervisor lahf_lm ida arat tpr_shadow vnmi ept vpidbogomips : 4587.98clflush size : 64cache_alignment : 64
44
Embedded Android Development สเสนทางนกพฒนา
address sizes : 40 bits physical, 48 bits virtualpower management:
คำสงเกยวกบการเปดอานขอมลภายในไฟล
Cat, less, od, และ splitคำสง cat คอคำสงทใชแสดงขอมลทอยในไฟลออกมาแสดงครงเดยวพรอมกนทงหมด ในบางครงก
ใชในการรวมไฟลหลายไฟลเขาดวยกนมาเปนไฟลเดยว แตอยางไรกตามถาไฟลทตองการเปดอานขอมลมความยาวมาก ตวอยางเชนไฟลทเกบ log ของระบบ ถาใชคำสง cat เพอเปดไฟล log ยอมไมเปนผลดกบผอานเองเพราะจะแสดงขอมลออกมาอยางรวดเรวเกนกวาจะจบใจความทนได ดงนนคำสง less จงเปนคำสงยอดนยมอกคำสงหนงทผดแลระบบหรอนกพฒนาจะนยมนำมาใช เนองจากมนจะชวยใหการแสดงขอมลของไฟลทมขนาดใหญใหสามารถเลอนหนาจอขนลงไดหรอแมกระทงคนหาคำไดลกษณะคลายกบการใช text editor ในการเลอนหนาจอของคำสง less นนสามารถใชงานไดทงลกศรขนลงหรอการใชปม PageUp PageDown ในการควบคม สำหรบในการคนหานนจะคนหาไดโดยการพมพเครองหมาย / แลวตามดวยขอความทตองการคนหา คำสง less จะทำหนาทแสดงคำทผดแลระบบตองการคนหาออกมา ถาหากในกรณทตองการคนหาคำถดไป คำสง less ไดออกแบบใหมการกดแปนพมพ n เพอเลอนไปยงคำถดไป
นอกจากคำสง less จะมความสามารถในการคนหาแลวนนความสามารถของคำสง less ยงสามารถแสดงขอมลทมการเปลยนแปลงทบรรทดสดทายได โดยการกดปม F เชนกรณของไฟล log ทจะมขอมลเขามาตลอดเวลา less สามารถแสดงขอมลเหลานนไดทนทโดยไมจำเปนตองเปดไฟลใหม แมไฟล log จะถกบบอดเปน .gz กยงสามารถเปดไดดวยคำสง less ไดทนท ตวอยางการใชคำสงดงแสดงขางลาง
$ cat Departments.txt <---- เปดไฟลทมอยแลว1 Electrical2 Computer3 Telecommunication
$ cat >Universities.txt <---- เปดไฟลใหม และปอนขอมลลงไฟลทนทBurapha UniversityPrince of Songkhla UniversityThammasat University
กด Ctrl+D <---- กดปม Ctrl+D เพอสนสดการใสขอมล
$ cat Departments.txt Universities.txt > All.txt$ cat All.txt 1 Electrical2 Computer3 TelecommunicationBurapha UniversityPrince of Songkhla UniversityThammasat University
45
Embedded Android Development สเสนทางนกพฒนา
$ less /var/log/syslog
รปท 1.10 แสดงผลลพธการเปดไฟล /var/log/syslog ดวยคำสง less
จากคำสงขางตนจะเนนการเปดไฟลชนดขอความ (text file) ทวไป แลวแสดงผลเปนขอความปกต
แตในบางกรณทนกพฒนาระบบสมองกลฝงตวตองการมองขอความภายในไฟลในลกษณะอน เชน แปลงเปนเลขฐานแปด ฐานสบ หรอ ฐานสบหก คำสงทนยมใชกนทวไปคอ od (Octal Dump) ซงมตวเลอก -A ทไวสำหรบระบรากทตองการ (Radix) และ -t สำหรบระบรปแบบการแสดงวาจะเปนเลขฐานตางๆ เชน เลขฐานแปด เลขฐานสบ เลขฐานสบหก หรอ รหสแอสก ดวย คา o, d, x, c ตามลำดบ ดงตวอยางขางลาง
$ od Departments.txt 0000000 020061 066105 061545 071164 061551 066141 031012 0414400000020 066557 072560 062564 005162 020063 062524 062554 0675430000040 066555 067165 061551 072141 067551 0051560000054$ od -t x Departments.txt 0000000 6c452031 72746365 6c616369 4320320a0000020 75706d6f 0a726574 65542033 6f63656c0000040 6e756d6d 74616369 0a6e6f690000054$ od -A d -t c Departments.txt 0000000 1 E l e c t r i c a l \n 2 C0000016 o m p u t e r \n 3 T e l e c o0000032 m m u n i c a t i o n \n0000044
46
Embedded Android Development สเสนทางนกพฒนา
ไฟลทใชกนสวนใหญอาจจะมขนาดเลกแตเมอใดทมไฟลขนาดใหญนกพฒนาจำเปนทจะตองทำการแยกออก (split) มาใหเปนไฟลชนเลกๆทสะดวกตอระบบสมองกลฝงตวในการสงไปทละกอน หรอแมแตตองการสงผานอเมลในขนาดทพอเหมาะตอขนาดความจของชองขอมล ดงนนคำสงทสามารถแยกไฟลออกเปนชนไดคอ คำสง split ซงสามารถจะเลอกแยกเปนไฟลชนเลกๆตามขนาดไบท (Byte) หรอ บรรทด (line) ทหนจากตวไฟลตนฉบบ เพอตองการนำไฟลยอยทถกแบงออกมา กลบมารวมเปนไฟลเหมอนตนฉบบดงเดม กเพยงแคใชคำสง cat เพอทำการรวมทงหมด ดงตวอยางคำสงขางลางน
$ split -l 1 Departments.txt <---- แบงออกทละบรรทด$ ls x*xaa xab xac
$ cat xaa xab xac <---- แสดงขอมลในไฟลทงสามพรอมกน1 Electrical2 Computer3 Telecommunication
$ cat xaa xab xac > Departments_copies.txt <---- รวมไฟลทงหมดมาเปนไฟลเดยว$ cat Departments_copies.txt 1 Electrical2 Computer3 Telecommunication
สามารถใชคำสง md5sum ทำการตรวจสอบไฟลทงสองวามขนาดและขอมลภายในเหมอนกนหรอไม$ md5sum Departments.txt c4eef8b561262f39d7ae748566100fe5 Departments.txt$ md5sum Departments_copies.txt c4eef8b561262f39d7ae748566100fe5 Departments_copies.txt
Wc, head, and tailคำสง wc (Word Count) จะเหมาะกบการตรวจสอบรายละเอยดของขอมลภายในไฟลวามขนาด
ใหญเทาไหร มบรรทดทงหมดจำนวนเทาไหร จำนวนคำทงหมดเทาไหร นอกจากนน 2 คำสงทเหมาะสมในการดไฟลทมขนาดใหญเชนเดยวกน แตจะเนนดเพยงแคสวนหวไฟลดวยคำสง head และสวนทายไฟลดวยคำสง tail ซงสามารถใชตวเลอก option -n <บรรทด> เพอระบจำนวนบรรทดทตองการแสดง ดงตวอยางคำสงขางลาง
$ wc -l /var/log/dmesg1386 /var/log/dmesg
$ head -n 5 /var/log/dmesg[ 0.000000] Initializing cgroup subsys cpuset[ 0.000000] Initializing cgroup subsys cpu[ 0.000000] Linux version 2.6.32-42-server (buildd@batsu) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) ) #96-Ubuntu SMP Wed Aug 15 19:52:20 UTC 2012 (Ubuntu 2.6.32-42.96-server 2.6.32.59+drm33.24)
47
Embedded Android Development สเสนทางนกพฒนา
[ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-2.6.32-42-server root=UUID=4fb97098-124c-489b-a0d1-3eb8846d2f67 ro quiet[ 0.000000] KERNEL supported cpus:
$ tail -n 5 /var/log/dmesg[ 18.896413] acpiphp_glue: Slot 262 already registered by another hotplug driver[ 18.896434] acpiphp_glue: Slot 263 already registered by another hotplug driver[ 19.031705] ENS1371 0000:02:02.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16[ 19.602812] vmmemctl: started kernel thread pid=907[ 19.602826] VMware memory control driver initialized
ในกรณทผดแลระบบ หรอนกพฒนาสมองกลฝงตว ตองการเฝาดการเปลยนแปลงของไฟลวามขอมลเขามาหรอไม กสามารถใชตวเลอก -f สำหรบคำสง tail เพอเฝาดเหตการณการเปลยนแปลงไดทนท ดงรป
รปท 1.11 แสดงผลลพธการตดตามการเปลยนแปลงขอมลในไฟลดวยคำสง tail
คำสงคนหาขอความและไฟลดวยชด REGULAR EXPRESSIONS
find, grepการคนหาไฟลในระบบปฏบตการลนกซสามารถทำไดหลายวธ หนงในคำสงทไดรบความนยมคอคำ
สง find เพราะมความยดหยนสงในการคนหาไฟลแตละชนดดงตารางแสดงพารามเตอร (parameter) เพอใชระบชนดไฟลทตองการคนหา
ตาราง 1.7 สญลกษณบอกชนดไฟล
สญลกษณ ชนดไฟลf ไฟลทวไป
d ไดเรกทอร
b block
c character
48
Embedded Android Development สเสนทางนกพฒนา
สญลกษณ ชนดไฟลp pipe
l Symbolic link
s Socket
ในกรณทตองการระบใหคนหาเฉพาะไฟลทวไป (f) หรอ ไดเรกทอร (d) สามารถใชตวเลอก -type เพอระบประเภทไดดงตวอยางขางลาง
$ ls -ltotal 28-rw-r--r-- 1 student student 53 2013-08-21 05:16 error.log-rwxr-xr-x 1 student student 8497 2013-08-21 06:05 hello-rw-r--r-- 1 student student 92 2013-08-21 06:05 hello.cdrwxr-xr-x 2 student student 4096 2013-09-17 18:03 out-rw-r--r-- 1 student student 57 2013-08-21 05:16 result.txt
$ find . -type f./error.log./result.txt./.my_hidden_file./hello./hello.c
$ find . -type d../.my_hidden_directory./out
ในกรณทตองการคนหาไฟลหรอไดเรกทอรทถกซอนอย
$ find . -type f -name ".*"./.my_hidden_file
เนองจากระบบไฟลภายใตระบบปฏบตการลนกซจะเปนแบบ case sensitive (สนใจตวพมพเลก-พมพใหญ) ดงนนในการคนหาไฟลทใกลเคยงทงหมดโดยไมสนใจกรณ case sensitive สามารถระบโดยการใช -iname เขาไปดงตวอยางขางลาง
$ find -iname "MyProgram.c"./myprogram.c./unix/myprogram.c./programming/MyProgram.c./MyProgram.c
49
Embedded Android Development สเสนทางนกพฒนา
การระบระดบความลกของชนไดเรกทอรในการคนหา สามารถทำไดโดยการใช -mindepth [level] และ -maxdepth [level] ตวอยางเชน ตองการคนหาตงแตไดเรกทอร root (level 1) และลกลงไปอก 2 ชน (level 2 - level 3) สามารถใชคำสงดงน
$ find / -maxdepth 3 -name shadow/etc/bash_completion.d/shadow/etc/shadow
เมอตองการระบวาใหคนหาไฟลทอยเฉพาะระดบความลกท 2 ถง 4 (level 2 - level 4)
$ find / -mindepth 2 -maxdepth 4 -name shadow/etc/bash_completion.d/shadow
การคนหาดวยคำสง find แตละครง สามารถตงชดคำสงพเศษหลงตวเลอก -exec ในกรณทเจอไฟลตามทตองการคนหา ตวอยางเชนใหทำการเชคคา checksum ไฟลทเจอดวยคำสง md5sum
$ find -iname "MyProgram.c" -exec md5sum {} \;ed832d42670ee3af4041e4a50f851755 ./myprogram.ced832d42670ee3af4041e4a50f851755 ./unix/myprogram.c7562d93e8b9a19dc80959d4eb7e2c7ca ./programming/MyProgram.cae96bf65a87976abba3fdc57f47a55a2 ./MyProgram.c
ถาตองการระบการคนหาตามสทธของไฟลนน (file permission) สามารถใช -perm ไดดงตวอยางขางลาง
$ find . -perm -g=r -type f -exec ls -l {} \;-rw-r--r-- 1 student student 53 2013-08-21 05:16 ./error.log----r----- 1 student student 57 2013-08-21 05:16 ./result.txt-rw-r--r-- 1 student student 0 2013-09-17 18:04 ./.my_hidden_file-rwxr-xr-x 1 student student 8497 2013-08-21 06:05 ./hello-rw-r--r-- 1 student student 92 2013-08-21 06:05 ./hello.c
$ find . -perm g=r -type f -exec ls -l {} \;----r----- 1 student student 57 2013-08-21 05:16 ./result.txt
หรอระบเปนเลขฐานแปด (Octal)
$ find . -perm 040 -type f -exec ls -l {} \;----r----- 1 student student 57 2013-08-21 05:16 ./result.txt
งานดานระบบสมองกลฝงตวขนาดของไฟลขอมลคอนขางเปนประเดนทตองใหความสนใจ เนองจากพนทเกบขอมลมขนาดจำกด ดงนนการนำคำสง find มาประยกตใชเพอคนหาไฟลตามขนาดไฟลทตองการจงมความสำคญเชนกน ดงตวอยางตอไปน
50
Embedded Android Development สเสนทางนกพฒนา
เมอตองการคนหาไฟลทมขนาดใหญ 5 อนดบแรก
$ find . -type f -exec ls -s {} \; | sort -n -r | head -580 ./testing/ktest/ktest.pl64 ./perf/util/trace-event-parse.c64 ./perf/util/symbol.c60 ./lguest/lguest.c56 ./perf/util/header.c
หรอขนาดเลกสด 5 อนดบแรก แตไมตองการรวมไฟลทมขนาดศนยไบต (Empty file)
$ find . -not -empty -type f -exec ls -s {} \; | sort -n | head -54 ./firewire/list.h4 ./firewire/Makefile4 ./firewire/nosy-dump.h4 ./include/tools/be_byteshift.h4 ./include/tools/le_byteshift.h
ในกรณทตองการระบขนาดไฟล (byte) อยางชดเจน สามารถใช -size [byte] ดงตวอยางขางลาง
$ find . -size +200M <------ ไฟลทมขนาดมากกวา 200 เมกะไบต$ find . -size -200M <------ ไฟลทมขนาดนอยกวา 200 เมกะไบต$ find . -size 200M <------ ไฟลทมขนาด 200 เมกะไบต
นกพฒนาสามารถสรางคำสงเฉพาะดวย alias เพอความสะดวกในการคนหาไฟลขนาดทตองการ เพอลบทง ดงตวอยางขางลาง$ alias rm50m="find / -type f -name *.tar -size +50M -exec rm -i {} \;"$ alias rm1g="find / -type f -name *.tar -size +1G -exec rm -i {} \;"$ alias rm3g="find / -type f -name *.tar -size +3G -exec rm -i {} \;"$ alias rm5g="find / -type f -name *.tar -size +5G -exec rm -i {} \;"
นอกจากนนถาตองการคนหาไฟลโดยดจากเวลาของไฟลทถกเขาถง (Access time) ถกเปลยนแปลงขอมลภายใน (Modification time) หรอ มการเปลยนแปลงไอโหนด/สถานะ (Change time) สามารถระบตวเลอกดงรายละเอยดในตารางขางลาง
ตาราง 1.8 ตวเลอกการเขาถงไฟลของคำสง find
ตวเลอก คำอธบาย--- Access Time ---
amin m เวลา m นาททผานมา ทไฟลถกเขาถง atime d เวลา d*24 ชวโมงทผานมา ทไฟลถกเขาถง
--- Modification Time --- mmin m เวลา m นาททผานมา ทไฟลถกเปลยนแปลงขอมลภายใน
51
Embedded Android Development สเสนทางนกพฒนา
ตวเลอก คำอธบายmtime d เวลา d*24 ชวโมงทผานมา ทไฟลถกเปลยนแปลงขอมล
ภายใน
--- Change Time --- cmin m เวลา m นาททผานมา ทไฟลถกเปลยนสถานะหรอคาไอโหนดctime d เวลา d*24 ชวโมงทผานมา ทไฟลถกสถานะหรอคาไอโหนด
$ cd unix/$ vim hello.c <------ แกไขขอมลภายในไฟล hello.c$ chmod 755 result.txt <------ เปลยนสทธของไฟล result.txt
คนหาไฟลภายในไดเรกทอร unix ทมการถกแกไขขอมลภายในไฟล เมอ 10 นาททผานมา
$ find ~/unix/ -mmin -10/home/student/unix//home/student/unix/hello.c
คนหาไฟลภายในไดเรกทอร unix ทมการถกเปลยนแปลงสทธไฟลเมอ 10 นาททผานมา
$ find ~/unix/ -cmin -10/home/student/unix//home/student/unix/result.txt/home/student/unix/hello.c
ในกรณทไมตองการใหแสดงผลไฟลทถกซอน (hidden file) ในผลลพธของการคนหา สามารถใช -regex ดงตวอยางขางลาง
$ find ~/unix/ -amin -10 \( ! -regex ".*/\..*" \)/home/student/unix//home/student/unix/hello.c
ในการคนหาไฟลทตองการบางครง ถาผใชตองการตงเงอนไขแยกเปน 2 สวนคอ ตรวจสอบสทธ และตรวจสอบขนาดไฟล สามารถเขยนใหอยในรปแบบดงตวอยางขางลาง
$ find / \( -perm -4000 -fprintf ~/unix/suid.txt '%#m %u %p\n' \) , \( -size +100M -fprintf ~/unix/big.txt '%-10s %p\n' \)
$ cat big.txt510743705 /home/student/aosp/out/host/linux-x86/bin/clang357304855 /home/student/aosp/out/host/linux-x86/bin/llvm-rs-cc
52
Embedded Android Development สเสนทางนกพฒนา
138665118 /home/student/aosp/out/host/linux-x86/obj/STATIC_LIBRARIES/libclangSema_intermediates/libclangSema.a138104274 /home/student/aosp/out/host/linux-x86/obj/STATIC_LIBRARIES/libclangStaticAnalyzerCheckers_intermediates/libclangStaticAnalyzerCheckers.a160314665 /home/student/aosp/out/host/linux-x86/obj/lib/libbcc.so... $ cat suid.txt04755 root /bin/ping604755 root /bin/su04755 root /bin/fusermount04755 root /bin/umount04755 root /bin/mount04755 root /bin/ping04755 root /usr/bin/chfn06755 daemon /usr/bin/at04755 root /usr/bin/lppasswd04755 root /usr/bin/sudoedit04755 root /usr/bin/arping04755 root /usr/bin/gpasswd...
grepคำสง grep (Generalized Regular Expression Parser) เปนคำสงทมการใชงานบอยครงตงแต
ระดบคอมพวเตอรตงโตะจนไปถงบอรดสมองกลฝงตวทมระบบปฏบตการลนกซอยภายในโดยหนาทของคำสงนคอการคนหาขอความทอยภายในไฟลทตองการตามเงอนไขทตงไว ตวอยางเชน
$ grep ".*passwd" suid.txt 04755 root /usr/bin/lppasswd04755 root /usr/bin/gpasswd04755 root /usr/bin/passwd04755 student /home/student/Downloads/poky-dylan-9.0.0/build/tmp/work/i586-poky-linux/shadow/4.1.4.3-r13/package/usr/bin/passwd.shadow...
ตาราง 1.9 ตวดำเนนการสำหรบคำสง grep
ตวดำเนนการ คำอธบาย? เจออยางนอย 1 ตวอกขระ
* เจออยางนอย 0 หรอ มากกวาหลายตวอกขระ
+ เจออยางนอย 1 หรอ มากกวาหลายตวอกขระ
^ คนหาเฉพาะขนตนบรรทด
53
Embedded Android Development สเสนทางนกพฒนา
ตวดำเนนการ คำอธบาย$ คนหาเฉพาะทายบรรทด
[ ] คนหาตวอขระใดตวอกขระหนงทอยใน [ ]
{n} เจอซำเปนจำนวน n ครง
{n,} เจอซำเปนจำนวนตงแต n ครง หรอมากกวา
{n,m} เจอซำเปนจำนวนตงแต n ครงจนถง m ครง
\char คนหาตวอกขระ char
-E ‘pattern1 .* pattern2’ คนหา pattern1 และ pattern2
-E ‘pattern1 | pattern2’ คนหา pattern1 หรอ pattern2
ตวอยางการใชคำสง grep เพอคนหาคำจากผลลพธของคำสง ls -al
$ ls -altotal 61drwxr-xr-x 4 student student 4096 2013-09-20 05:09 .drwxr-xr-x 37 student student 4096 2013-09-11 20:53 ..-rw-r--r-- 1 student student 5160 2013-09-18 00:04 big.txt-rw-r--r-- 1 student student 53 2013-08-21 05:16 error.log-rwxr-xr-x 1 student student 8497 2013-08-21 06:05 hello-rw-r--r-- 1 student student 93 2013-09-17 19:16 hello.cdrwxr-xr-x 2 student student 4096 2013-09-17 18:04 .my_hidden_directory-rw-r--r-- 1 student student 0 2013-09-17 18:04 .my_hidden_file-rw-r--r-- 1 student student 0 2013-09-20 05:09 mytest.txt-rw-r--r-- 1 student student 72 2013-09-20 05:09 number-rw-r--r-- 1 student student 0 2013-09-20 04:48 test1.txt-rw-r--r-- 1 student student 0 2013-09-20 04:48 test.txt$ ls -al | grep test?.txt-rw-r--r-- 1 student student 0 2013-09-20 04:48 test1.txt
ในกรณทจะใชตวดำเนนการ “+” จำเปนตองใชโปรแกรมรนใหมของโปรแกรม grep คอโปรแกรม egrep (Extended Grep) ดงตวอยางขางลาง
$ ls -al | egrep test+.txt-rw-r--r-- 1 student student 0 2013-09-20 05:09 mytest.txt-rw-r--r-- 1 student student 0 2013-09-20 04:48 test.txt
ในกรณทตองการคนหาตวเลขตามจำนวนหลกทตองการ สามารถใชตวดำเนนการ [ ] และ {n} ดงตวอยางขางลาง
$ cat numbersID 3710166Telephone No. 0891234122
54
Embedded Android Development สเสนทางนกพฒนา
City Code 20131Phone No. 038191772
$ grep "[0-9]\{5\}$" numbersCity Code 20131
ถาตองการคนหาทมตวเลขตงแต 7 หลกขนไปจะใชตวดำเนนการ {m, } ดงตวอยางขางลาง
$ grep "[0-9]\{7,\}$" numbersID 3710166Telephone No. 0891234122Phone No. 038191772
การคนหาขอมลภายในไฟล log นกพฒนาสามารถทำการวเคราะหเบองตนไดดวยตวดำเนนการ -E ‘pat-tern1 | pattern2’ ดงตวอยางของขอมล log ขางลางน
$ cat data.log 1 Station01 Temp_Sensor 35.42 Station02 Flow_Sensor 12.43 Station03 Light_Sensor 554 Station04 Motion_Sensor ON5 Station05 Current_Sensor 1.42
สามารถใชคำสง grep เพอคนหาขอมลภายในได 4 รปแบบ ไดแก
(แบบท 1) $ grep -i 'station01\|station03' data.log 1 Station01 Temp_Sensor 35.43 Station03 Light_Sensor 55
(แบบท 2) $ grep -i -E 'station01|station03' data.log 1 Station01 Temp_Sensor 35.43 Station03 Light_Sensor 55
(แบบท 3) $ grep -i -e station01 -e station03 data.log 1 Station01 Temp_Sensor 35.43 Station03 Light_Sensor 55
(แบบท 4) $ egrep -i 'station01|station03' data.log 1 Station01 Temp_Sensor 35.43 Station03 Light_Sensor 55
เมอตองการคนหาคำทอยตำแหนงตนบรรทด จะใช “^” นำหนาคำทตองการคนหา หรอคำทอยตำแหนงปลายบรรทด จะใช “$” ตอทายคำทตองการคนหา ดงตวอยางขางลาง
$ grep "^Sep 11" messages.1 Sep 11 21:16:58 EE-Burapha rsyslogd: [origin software="rsyslogd" swVersion="4.2.0" x-pid="691" x-info="http://www.rsyslog.com"] rsyslogd was HUPed, type 'lightweight'.Sep 11 21:44:29 EE-Burapha kernel: [ 3077.192891] e1000: eth0 NIC Link is DownSep 11 21:45:17 EE-Burapha kernel: [ 3125.462088] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
55
Embedded Android Development สเสนทางนกพฒนา
Sep 11 21:46:58 EE-Burapha kernel: [ 3222.009399] e1000: eth0 NIC Link is DownSep 11 21:47:04 EE-Burapha kernel: [ 3227.275574] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None...
$ grep "Link is Down$" messages.1 Sep 11 21:44:29 EE-Burapha kernel: [ 3077.192891] e1000: eth0 NIC Link is DownSep 11 21:46:58 EE-Burapha kernel: [ 3222.009399] e1000: eth0 NIC Link is DownSep 11 21:47:07 EE-Burapha kernel: [ 3230.682704] e1000: eth0 NIC Link is DownSep 11 21:53:34 EE-Burapha kernel: [ 3310.165309] e1000: eth0 NIC Link is DownSep 11 21:54:02 EE-Burapha kernel: [ 3338.102673] e1000: eth0 NIC Link is Down...
การคนหาคำทมอกขระพเศษอยดวยนน จะตองใชตวดำเนนการ \ นำหนาตวอกขระพเศษเสมอ ดงตวอยางขางลาง
$ grep "255\.255\.255\.255" syslog.1 Sep 18 11:36:12 EE-Burapha dhclient: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3Sep 18 11:36:13 EE-Burapha dhclient: DHCPREQUEST of 172.16.56.134 on eth0 to 255.255.255.255 port 67Sep 18 19:54:11 EE-Burapha dhclient: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3Sep 18 19:54:12 EE-Burapha dhclient: DHCPREQUEST of 172.16.56.134 on eth0 to 255.255.255.255 port 67Sep 20 04:50:05 EE-Burapha dhclient: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5Sep 20 04:50:06 EE-Burapha dhclient: DHCPREQUEST of 172.16.56.134 on eth0 to 255.255.255.255 port 67
ตาราง 1.10 ตวดำเนนการเพมเตมสำหรบคำสง grep
OPERATOR DESCRIPTION
[:digit:] เฉพาะตวเลขตงแต 0 ถง 9[:alnum:] ทงตวอกษร A ถง Z หรอ a ถง z และตวเลขตงแต 0 ถง 9[:alpha:] ตวอกษร A ถง Z หรอ a ถง z[:blank:] เฉพาะชองวาง (Space) และแทป (TAB) เทานน
จากตารางขางตน เปนการระบตวอกขระในแตละประเภทเพอใหการคนหามประสทธภาพมากขน ดงตวอยางการใชงานดงน
$ grep "anacron\[[[:digit:]]\+\]" /var/log/syslog.1Sep 18 08:50:17 EE-Burapha anacron[27155]: Job `cron.daily' terminatedSep 18 08:50:17 EE-Burapha anacron[27155]: Job `cron.weekly' startedSep 18 08:50:17 EE-Burapha anacron[27530]: Updated timestamp for job `cron.weekly' to 2013-09-18Sep 18 08:50:18 EE-Burapha anacron[27155]: Job `cron.weekly' terminated...
56
Embedded Android Development สเสนทางนกพฒนา
การรวมคำสงเขาดวยกน ดวยสญญลกษณทเรยกวา Pipe (|) โดยเอาทพตของคำสงแรกจะเปนอนพตของคำสงถดไป จนกระทงถงคำสงสดทายทจะแสดงผลลพธสหนาจอ ดงตวอยางการใชดงน
$ ls <ไดเรกทอร> | grep <คำคนหา>
$ ls -al | grep "^d"drwxr-xr-x 4 student student 4096 2013-09-21 02:21 .drwxr-xr-x 37 student student 4096 2013-09-11 20:53 ..drwxr-xr-x 2 student student 4096 2013-09-17 18:04 .hidden_directorydrwxr-xr-x 2 student student 4096 2013-09-17 18:03 out
awkAwk ยอมาจากตวอกษรแรกของนกพฒนาทงสามคนไดแก Aho, Weinberger, และ Kernighan
ถอวาเปนภาษาโปรแกรมชนดหนงซงมไวสำหรบการเขาถงขอมลทมลกษณะเปนโครงสราง (structured data) และสามารถสรางออกมาใหอยในรปแบบรายงานได คณสมบตสำคญของ awk ประกอบไปดวย
• awk จะมองไฟลขอมลในลกษณะคลายฐานขอมลทม เรคอรด (record) และ ฟลด (field)
• awk จะมตวแปร (variables) ชดคำสงตรวจสอบเงอนไข (conditional statement) และชดคำสงทำ ซำ (loop statement) เหมอนภาษาโปรแกรมทวไป
• awk เตรยมตวดำเนนการทางดานเลขคณต (arithmetic) และขอความ (string)
• awk สามารถสรางออกมาใหอยในรปแบบรายงานได
รปแบบคำสงการใชงาน
awk '/search pattern1/ {Actions} /search pattern2/ {Actions}' file
โดยท search pattern กคอชด regular expression สวน Actions กคอชดคำสงเชงโปรแกรม ดงตวอยางการใชคำสงขางลาง
$ cat data.log 1 Station01 Temp_Sensor 35.42 Station02 Flow_Sensor 12.43 Station03 Light_Sensor 554 Station04 Motion_Sensor ON5 Station05 Current_Sensor 1.42$ awk '/Station01/> /Station02/' data.log 1 Station01 Temp_Sensor 35.42 Station02 Flow_Sensor 12.4
57
Embedded Android Development สเสนทางนกพฒนา
awk สามารถแยกเรคคอรดในแตละบรรทดทคนดวยอกขระชองวางออกมาเปนฟลดยอยๆและถกเกบไวในตวแปร $n โดยท n คอจำนวนเลขฟลด โดยเรมตนท $0 จะแทนดวยขอความทงหมดของบรรทดนนๆ สวน $1 จนถง $n นนจะเกบขอความทถกแยกดวยชองวางแตละคอลมน ดงตวอยางขางลาง
$ awk '{print $2,$4;}' data.log Station01 35.4Station02 12.4Station03 55Station04 ONStation05 1.42
สามารถใช $NF เพอระบคาฟลดตวสดทายได ดงตวอยางขางลาง
$ awk '{print $2,$NF;}' data.log Station01 35.4Station02 12.4Station03 55Station04 ONStation05 1.42
คำสง awk จะมรปแบบสำคญอกสวนหนงทใชในการกระทำคำสงตอนเรมตน (Initialization) กอนทจะเรมดำเนนการวเคราะหแตละบรรทดภายในไฟล และจะกระทำคำสงตอนสนสด (Final) หลงจากบรรทดสดทายดำเนนการเสรจเรยบรอยแลว โดยการใช BEGIN และ END ดงรปแบบการเรยกใชคำสงดงน
BEGIN { Actions }{Action} # Action for every lines in a fileEND { Actions }# is for comments in Awk
ตวอยางการใชคำสง awk แบบเตมรป
$ awk 'BEGIN {print "Station Name\tSensor Type\t\t\tValue";}> {print $2,"\t",$3,"\t\t\t",$NF;}> END{print "Report Generated\n--------------";> }' data.logStation Name! Sensor Type!! ! ValueStation01 ! ! Temp_Sensor ! ! ! 35.4Station02 ! ! Flow_Sensor ! ! ! 12.4Station03 ! ! Light_Sensor ! ! ! 55Station04 ! ! Motion_Sensor ! ! ! ONStation05 ! ! Voltage_Sensor ! ! ! 1.42Report Generated--------------
58
Embedded Android Development สเสนทางนกพฒนา
เพอความสะดวกยงขน นกพฒนาสามารถเกบคำสงลงในไฟลสครปทได เชน เกบลงในไฟล datalog.script ตวอยางการใชคำสงเชน
$ cat datalog.script BEGIN {! print "Station Name\tSensor Type\t\t\tValue";}{! print $2,"\t",$3,"\t\t\t",$NF;}END {! print "Report Generated\n--------------";}
$ awk -f datalog.script data.log Station Name! Sensor Type!! ! ValueStation01 ! ! Temp_Sensor ! ! ! 35.4Station02 ! ! Flow_Sensor ! ! ! 12.4Station03 ! ! Light_Sensor ! ! ! 55Station04 ! ! Motion_Sensor ! ! ! ONStation05 ! ! Voltage_Sensor ! ! ! 1.42Report Generated--------------
ในการใชงานในระบบสมองกลฝงตวนนการดคาสถานะตางๆนนบอรดสมองกลฝงตวอาจจะมโปรแกรมจำลองตวเองใหมบรการ Web Server เพอใหผใชสามารถเขามาดสถานะผานโปรแกรมเวปบราวเซอรทวไปได ดงนนนกพฒนาสามารถจดรปแบบการแสดงผลขอมลโดยเพมแทก HTML (HTML Tag) ดวยคำสง awk ไดอยางงายดาย ดงตวอยางขางลาง$ cat datalog_html.script BEGIN{title="Sensor Station";print "<html>\n<title>"title"</title><body bgcolor=\"#ffffff\">\n<table bor-der=1><th colspan=2 align=centre>Station Details</th>";}{station_name=$2;sensor=$3;value=$NF;print "<tr><td>"station_name"</td><td>"sensor"</td><td>"value"</td></tr>";}END {print "</table></body>\n</html>";}
วธการเรยกใช script ทสรางขนมา (datalog_html.script) และเกบผลลพธทไดอยในรปแบบแทก HTML ลงในไฟลใหมชอ sensor.html ดงตวอยางคำสงขางลาง
$ awk -f datalog_html.script data.log > sensor.html
59
Embedded Android Development สเสนทางนกพฒนา
$ cat sensor.html <html><title>Sensor Station</title><body bgcolor="#ffffff"><table border=1><th colspan=2 align=centre>Station Details</th><tr><td>Station01</td><td>Temp_Sensor</td><td>35.4</td></tr><tr><td>Station02</td><td>Flow_Sensor</td><td>12.4</td></tr><tr><td>Station03</td><td>Light_Sensor</td><td>55</td></tr><tr><td>Station04</td><td>Motion_Sensor</td><td>ON</td></tr><tr><td>Station05</td><td>Voltage_Sensor</td><td>1.42</td></tr></table></body></html>
ทดสอบเปดไฟล sensor.html ผานโปรแกรมบราวเซอรเพอดผลลพธทเกดขน
รปท 1.12 แสดงการนำเสนอขอมลในรปแบบ HTML
คำสงจดการดานระบบเครอขาย iptables iptables เปนเครองมอสำคญอกตวหนงทถกนำมาใชในการจดการระบบความปลอดภยในระบบเครอขายทเรยกวา ไฟรวอลล (firewall) โดยพนฐานในการกำหนดการควบคมการเขาออกของขอมลนน ผดแลระบบหรอแมแตนกพฒนาทางดานระบบสมองกลฝงตวควรเขาใจโครงสรางและหลกการทำงานของ iptables เปนอยางด ภายใน iptables นนมดวยกนหลายตาราง (tables) โดยแตละตารางจะประกอบไปดวยหลายรายการทเรยกวา chain (ท iptables เตรยมมาใหแลวหรอผใชกำหนดขนเอง) และภายในแตละ chain จะประกอบไปดวยขอกำหนดการควบคมการเขาออกของขอมลทเรยกวา rule ดงโครงสรางแสดงในรปขางลาง
60
Embedded Android Development สเสนทางนกพฒนา
Rule 1
Rule 2
Rule 3
Chain 1
Rule 1
Rule 2
Rule 3
Chain 2
Rule 1
Rule 2
Rule 3
Chain 1
Rule 1
Rule 2
Rule 3
Chain 2
Table 1 Table 2
รปท 1.13 ตารางทใชในการกำหนดกฏของ iptables
iptables จะถกเตรยมตารางใหแลว 4 ตาราง (4 built-in tables) ไดแก 1. Filter Table2. NAT Table3. Mangle Table4. Raw Table
สวนประกอบของ iptables จะมสวนประกอบหลก 3 สวนไดแก• INPUT คอสวนของขอมลทเขามาสเครองคอมพวเตอร• OUTPUT คอสวนของขอมลทออกจะเครองคอมพวเตอร• FORWARD คอสวนทสงตอขอมลจากระบบเครอขายภายในสเครอขายภายนอก ซงการบลอกพอรตกจะใชสวนนเปนหลก
RoutingDecision Forward
Input Output
Incoming Outgoing
Local Process
รปท 1.14 โฟลวชารตแสดงการควบคมการไหลของขอมล
61
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการแสดงรายละเอยดของตารางภายใน iptables
$ sudo iptables --listChain INPUT (policy ACCEPT)target prot opt source destinationACCEPT tcp -- anywhere anywhere tcp dpt:sshDROP all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)target prot opt source destination
Chain OUTPUT (policy ACCEPT)target prot opt source destination
โดยท • ACCEPT คอไฟรวอลลจะยอมใหแพกเกต (packet) ผานไปยงปลายทางได• DROP คอไฟรวอลลจะทงแพกเกตทนท แตจะไมแจงผสงเกยวกบขอความทสงไมสำเรจ• REJECT คอไฟรวอลลจะทงแพกเกตทนท และผสงจะไดรบขอความผาน ICMP ตอบกลบถงขอความทสง ไมสำเรจ• QUEUE คอไฟรวอลลจะสงตอแพกเกต ไปยงสวนระบบบนทตดตอกบผใช (userspace)• RETURN คอไฟรวอลลจะหยดการทำงานภายใน chain แลวกลบไปยง Chain เดมทเรยกกอนหนาน
ตวอยางแสดงการเปดพอรตดวยคำสง iptables โดยหลกการสำคญคอ ควรปดพอรตทงหมดกอนแลวจงคอยเลอกเปดพอรตทใชทละพอรตจะเปนวธทมความปลอดภยทสด
$ IPTABLES -P FORWARD DROP #CLOSE PORT ALL$ IPTABLES -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT$ IPTABLES -A FORWARD -p tcp --dport 53 -j ACCEPT #DNS$ IPTABLES -A FORWARD -p udp --dport 53 -j ACCEPT #DNS$ IPTABLES -A FORWARD -p udp --dport 67 -j ACCEPT #DHCP$ IPTABLES -A FORWARD -p udp --dport 69 -j ACCEPT #TFTP$ IPTABLES -A FORWARD -p udp --dport 111 -j ACCEPT #NFS$ IPTABLES -A FORWARD -p udp --dport 2049 -j ACCEPT #NFS$ IPTABLES -A FORWARD -p udp --dport 32700 -j ACCEPT #NFS$ IPTABLES -A FORWARD -p tcp --dport 80 -j ACCEPT #HTTP$ IPTABLES -A FORWARD -p tcp --dport 8080 -j ACCEPT #HTTP$ IPTABLES -A FORWARD -p tcp --dport 443 -j ACCEPT #HTTPS$ IPTABLES -A FORWARD -p tcp --dport 8443 -j ACCEPT #HTTPS$ IPTABLES -A FORWARD -p tcp --dport 20 -j ACCEPT #FTP$ IPTABLES -A FORWARD -p udp --dport 20 -j ACCEPT #FTP$ IPTABLES -A FORWARD -p tcp --dport 21 -j ACCEPT #FTP$ IPTABLES -A FORWARD -p udp --dport 21 -j ACCEPT #FTP$ IPTABLES -A FORWARD -p tcp --dport 22 -j ACCEPT #SSH$ IPTABLES -A FORWARD -p tcp --dport 23 -j ACCEPT #TELNET
62
Embedded Android Development สเสนทางนกพฒนา
พอรตพนฐานทจะถกเปดไวสำหรบบอรดสมองกลฝงตว เพอใชในการตดตง bootload-er,ลนกซคอรเนลและ เรยก root filesystem ไดนนจะมดวยกนอยางนอย 4 ถง 5 พอรต ไดแก
ตาราง 1.11 รายการ services ทถกเปดใชในระบบสมองกลฝงตว
SERVICE PORT NAME PORT NO. TCP/IP PROTOCOL
DHCP bootps 67 UDP
TFTP tftp 69 UDP
NFS
sunrpc 111 UDP
NFS nfs 2049 UDPNFS
mountd 32700 หรอ 32772 UDP
ในกรณทตองการปดการทำงานของไฟรวอลล เพอเขาสโหมดบำรงรกษาระบบสามารถใชคำสงดงตอไปน
$ sudo /etc/init.d/iptables off
TCP UDP
IPEthernet, Token-Right, FDDI, X.25, Wireless,ATM,SNA...
HTTP Kerb Xwin SMTP Telnet FTP DNS TFTP RPC
NFS
NCS SNMP
PING Trace Route
ICMP ARP RARP
MIME
รปท 1.15 รายละเอยดของโปรโตคอลในแตละชนของ TCP/IP
TFTP
การทำงานของ Trivial File Transfer Protocol (TFTP) เปนการทำงานทเปนการสงไฟลระหวางระบบ โดยทวไปผใชจะรจก FTP ซงเปนโปรโตคอลทมการใชงานอยางกวางขวางทอนญาตใหผใชสามารถมองเหนโครงสรางระบบไฟลและสามารถดาวนโหลดหรออพโหลดไฟลได แตสำหรบ TFTP นนขนตอนการทำงานจะนอยกวา FTP กลาวคอไมตองมขนตอนการรบรองตวตน (authentication) และเปนการสงขอมลผานโปรโตคอล UDP แตอยางไรกตาม TFTP กยงถกมการใชงานอยางกวางขวางในการสงไฟล configuration ตางๆบนระบบเครอขายคอมพวเตอร ขนตอนการตดตงโปรแกรม TFTP ลงในเครอง host เพอใชในการเกบไฟล image สำหรบเครองลกขายทเปนบอรดสมองกลฝงตว
ในกรณทใช Ubuntu เวอรชน 12.04 ขนไป จะใชคำสงดงน
$ sudo apt-get install xinetd tftp-hpa tftpd-hpa
63
Embedded Android Development สเสนทางนกพฒนา
แตถาในกรณทใช Ubuntu เวอรชน 11.10 ลงมา จะใชคำสงดงน
$ sudo apt-get install xinetd tftp tftpd$ sudo mkdir /tftpboot
หลงจากตดตงโปรแกรมและสรางไดเรกทอร tftpboot เรยบรอยแลว จะตองมการตงคาในไฟล /etc/xinetd.conf และแกไขตำแหนงไดเรกทอร TFTP_DIRECTORY ทถกระบอยในไฟล /etc/default/tftpd-hpa (ในกรณทใช Ubuntu เวอรชน 12.04 ขนไป)
$ sudo vim /etc/xinetd.confservice tftp{ socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot disable = no }
$ sudo vim /etc/default/tftpd-hpa (ในกรณทใช Ubuntu เวอรชน 12.04 ขนไป)TFTP_USERNAME="tftp"TFTP_ADDRESS="0.0.0.0:69"TFTP_OPTIONS="--secure"TFTP_DIRECTORY="/home/training/tftpboot"
ทำการเรมตนบรการ xinetd ใหมดวยคำสง
$ sudo /etc/init.d/xinetd restart
ทำการสรางไฟลตนฉบบไวในไดเรกทอร /tftpboot/ บนเครอง Host
$ sudo echo ‘This is a data’ > /tftpboot/myfile
ผใชสามารถทดสอบการดาวนโหลดไฟลโดยการทำการเชอมตอไปยง TFTP server ดงตวอยางคำสงขางลางน
$ tftp <Host IP> <----- ระบหมายเลข IP ของเครอง TFTP servertftp> get myfileReceived 16 bytes in 0.1 secondstftp> quit
64
Embedded Android Development สเสนทางนกพฒนา
DHCP บอรดสมองกลฝงตวในหลายงานประยกตอาจจะตองรองขอหมายเลข IP Address ใหกบตวมนเอง หรอในระหวางการพฒนาบอรดสมองกลฝงตวจะถกเชอมตออยในระบบเครอขายเดยวกนกบเครอง Host ดงนนภายในระบบเครอขายจะมเครองแมขายททำหนาทจายหมายเลข IP Address ผานโปรโตคอล DHCP ใหกบลกขายหรอบอรดสมองกลฝงตว (target board) ในกรณทเปนเครอง Host นกพฒนาจะตองทำการตดตง DHCP server เพมเตมเอง ดงขนตอนดงน
$ sudo apt-get install isc-dhcp-server
แกไขไฟล /etc/dhcp/dhcpd.conf เพอทำการตงคาใหเครอง Host เปน DHCP Server โดยเพมบรรทดดงตอไปน
$ sudo vim /etc/dhcp/dhcpd.confsubnet 192.168.0.0 netmask 255.255.255.0 { host targetboard { fixed-address 192.168.0.2;! server-name "192.168.0.1"; option router "192.168.0.1"; hardware ethernet 12:34:56:78:9a:bc; option root-path "/rootfs"; filename uImage; } }
จากตวอยางภายในไฟล dhcpd.conf ขางตน เครอง DHCP server จะจาย IP Address ใหกบบอรดสมองกลฝงตวทม MAC address เปน 12:34:56:78:9a:bc ดงนนผใชจะตองปรบคา MAC address บนบอรดสมองกลฝงตว ใหตรงตามคา MAC Address ทเครอง DHCP Server รจกใหตรงกน
NFSnfs เปนโปรโตคอลทไดรบการออกแบบมาเพอการเชอมโยงทรพยากรฮารดดสกจากเครองอนๆท
อยบนเครอขายคอมพวเตอรทอยหางออกไปใหเปนเสมอนระบบไฟลของอปกรณเอง สำหรบนกพฒนาระบบสมองกลฝงตวแลวการใชงาน nfs มผลทำใหในระหวางการปรบแตงระบบปฏบตการ หรอการพฒนาโปรแกรมเพอใชในระบบสมองกลฝงตวคลองตวและสะดวกมากยงขนและไมมขอจำกดของขนาดในการเกบขอมล โดยการนำไฟล root file system (RFS) ไปวางไวในไดเรกทอรทถกตงคาใหเปนไดเรอทอรทถกแชรผานโปรโตคอล NFS
เนองจากโดยทวไปแลวเมอนกพฒนาไดปรบแตงระบบปฏบตการเสรจ และพฒนาโปรแกรมฝงเขาไป root file system เรยบรอยกจะถกนำไปเขยนลงในตวเกบขอมลทอยภายในบอรดสมองกลฝงตว เชน Flash Memory เปนตน
65
Embedded Android Development สเสนทางนกพฒนา
บอรดTarget
เครองHost
DHCP
TFTP
NFS mount
NFS rootFS
ตงคา IP
Kernel image
ระบบเรมทางาน
เครอง Host บอรด Target
Makefile NFS Server
ไดเรกทอรทถกแชร
NFS Cient
ไดเรกทอรทถกแชร
รปท 1.16 แสดงขนตอนการ mount พนทบนเครอง Host ดวยโปรโตคอล NFS
ในระบบปฏบตการลนกซบนระบบสมองกลฝงตว การเชอมตอระบบเขากบ Network File System นนในขนตอนการทำงานจะมลกษณะเดยวกบการเชอมตอของระบบปฏบตการลนกซโดยทวไป ขนตอนการตดตง nfs-kernel-server และตงคาในไฟล /etc/exports ดงน
$ sudo apt-get install rpcbind nfs-kernel-server$ sudo mkdir /rootfs$ sudo vim /etc/exports/rootfs 192.168.0.2(rw,sync,no_subtree_check,no_root_squash)/rootfs localhost(rw,sync,no_subtree_check,no_root_squash)
ทำการเรยก service ทเกยวของทงหมด ดวยคำสง
$ sudo service xinetd restart$ sudo service tftpd-hpa restart$ sudo service isc-dhcp-server restart$ sudo service rpcbind-boot stop$ sudo service nfs-kernel-server stop$ sudo service rpcbind-boot start$ sudo service nfs-kernel-server start
ไฟล /etc/exports เปนไฟลทไดถกสรางขนจากเครองแมขาย เพอระบวาจะใหไดเรกทอรใดในเครองแมขายทจะใหเครองลกขายสามารถทำการ mount ไดเรกทอรได ดวยคำสงขางลาง
$ mount –t nfs nfs_server_Address:/rootfs/ /mnt/rfs
*ตวอยาง shell script สำหรบชวยในการตดตง tftp & nfs บนเครองแมขาย http://goo.gl/XuB1EZ
66
Embedded Android Development สเสนทางนกพฒนา
บทท 2 พนฐานลนกซคอรเนลสำหรบนกพฒนา
เคอรเนล (Kernel) สามารถแยกออกมาได 3 ประเภท ไดแก • Monolithic kernel เชน Linux Kernel, MS-DOS, Microsoft Windows 9x Series• Micro kernel เชน AIX, AmigaOS, Android OS, Haiku, L4 microkernel family เปนตน• Hybrid kernel เชน BeOS kernel, NetWare kernel, ReactOS kernel, NT kernel Windows NT kernel (Windows 2000/Windows XP/Windows 2003/Windows Vista), 8.XNU kernel (ใชใน Mac OS X) เปนตน
และเปนททราบกนดวาลนกซคอรเนลโดยสวนใหญนนจะเปนชนด monolithic kernel ซงหมายถงหนาทหลกโดยสวนใหญของระบบปฏบตการจะถกเรยกผาน Kernel ทงหมด ดงแสดงในรปขางลาง
Usermode
Application
Kernelmode
System
Operating sytem
VFS, System call
IPC, File System
Scheduler, Virtual Memory
Device Drivers, Dispatcher...
Hardware
รปท 2.1 แสดงการรายละเอยดการทำงานของ Monolithic Kernel
แตกตางจาก Micro Kernel ทบางสวนของระบบปฏบตการยงคงทำใน Kernel เชน การสอสารระหวางโปรเซส (inter-process communication) การจดลำดบงานของอปกรณอนพต/เอาทพต (basic input/output scheduling) การจดการหนวยความจำ (memory management) สวนหนาทอนๆจะทำภายนอก Kernel ตวอยางเชน drivers, network stack, file systems
67
Embedded Android Development สเสนทางนกพฒนา
Kernelmode
Usermode
Application
Application IPC
Hardware
UNIX Server
Device Driver
File Server
IPC, Virtual Memory, Scheduling
Kernelmode Kernel
mode
Usermode
รปท 2.2 แสดงการรายละเอยดการทำงานของ Micro Kernel
Linux Kernel
ลนกซคอรเนลซงเปนตวกลางสำคญของระบบปฏบตการลนกซในการตดตอระหวางฮารดแวรและซอฟตแวร โดยฮารดแวรนนหมายถงอปกรณตางๆภายในและอปกรณรอบขางเครองคอมพวเตอร ตวอยางเชน หนวยประมวลผลกลาง หนวยความจำ การดแสดงผล ฮารดดสก อปกรณอนพตและเอาทพต เมาส คยบอรด เปนตน สำหรบซอฟแวรนนประกอบไปดวยโปรแกรมของระบบปฏบตการและโปรแกรมประยกตตางๆ โดยภายใน Kernel จะประกอบไปดวย 2 สวนสำคญคอ Kernel Module และ Device Driver ทงสองจะทำหนาทในการดแลจดการการรองขอทเกดขนจากฮารดแวรและซอฟตแวร แลวทำการประมวลผลขอมลในเบองตนเพอสงตอใหระบบปฏบตการตอไป เพอใหบรหารจดการการใชงานทรพยากรทงหมดไดอยางมระบบ
C Library
โปรแกรม A
โปรแกรม Bไลบราร A
Linux Kernel
Hardware
เรยก Kernel module แจงผลลพธ และรายละเอยดขอมลตางๆ
จดการฮารดแวร แจงผลลพธ
รปท 2.3 แสดงการสอสารระหวางโปรแกรมในระบบปฏบตการและอปกรณ
68
Embedded Android Development สเสนทางนกพฒนา
จดเดนสำคญอกจดหนงคอลนกซคอรเนลสามารถรองรบสถาปตยกรรมทมอยตงแตในอดตจนถงปจจบน ซงสามารถดรายชอไดจากไดเรกทอร /arch โดยสามารถแยกเปนกลมสถาปตยกรรมได 2 แบบคอแบบ 32 บต เชน arm, avr32, blackfin, m68k, microblaze, mips, score, sparc, um, x86, powerpc และกลมสถาปตยกรรมแบบ 64 บต เชน alpha, arm64, ia64, sparc64, tile, x86_64, powerpc
รายละเอยดของแตละสถาปตยกรรมเหลานนกพฒนาสามารถเขาไปอานเพมเตมไดจากไดเรกทอร arch/<arch>/Kconfig, arch/<arch>/README ห ร อ ใ น ไ ด เ ร ก ท อ ร Documentation/<arch>/ นอกจากนนลนกซคอรเนลยงถกปรบปรงโคดภายใน ใหทำงานไดอยางมประสทธภาพ และมความยดหยนสงกบสถาปตยกรรมทหลากหลายอยางตอเนองและรองรบการเขากนไดกบมาตราฐานฮารดแวรรนใหมๆแตยงคงไดรบการควบคมจากผเชยวชาญทดแลซอรสโคดจากทวโลกเพอไมใหใครแอบซอนโคดทไมพงประสงคหรอสรางความไมปลอดภยใหกบระบบโดยรวม
สำหรบนกพฒนาระบบสมองกลฝงตวสามารถทจะเลอกใชฟงกชนบางตวในลนกซคอรเนลเพอใหเหมาะสมกบระบบฮารดแวรทมอยบนบอรดสมองกลรวมทงสามารถเลอกโปรแกรมประยกตบางตวทตองการใหทำงานอยในบอรดสมองกลฝงตวได
LINUX VERSIONING
โดยปกตทก 2-3 ป จะมการออกรนเสถยร (stable) ของลนกซคอรเนลทเปนเลขค เชน 1.0.x, 2.0.x, 2.2.x, 2.4.x, 2.6.x, 3.0.x เมอมการพฒนาปรบปรงฟงกชนใหมๆเขาไปและมการเปลยนแปลงโคดชดใหญ กจะออกเลขรนโดยใชเปนเลขค เชน 2.1.x, 2.3.x, 2.5.x แตสำหรบการปรบปรงเปลยนแปลงในระดบเลกลงมา (Minor release) จะใชเปลยนเลขรนหลกทสาม เชน 2.5.12, 2.6.39
2.4.22.4.12.4.0 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8
2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1
Stable
Development Stable
รปท 2.4 แสดงการออกเลขเวอรชนของ Linux Kernel
ตงแตป ค.ศ. 2003 ถง ค.ศ. 2011 รน 2.6.x เปนรนทมระยะการใชงานยาวนานมากเปนพเศษ อาจเนองมาจากชวงนนเปนยคของการเตบโตและเปลยนแปลงของคอมพวเตอรรวมทงอปกรณอารดแวรภายใน
69
Embedded Android Development สเสนทางนกพฒนา
เครองและอปกรณตอพวงรอบขางอยางรนแรงและยงเปนการเกดขนของยคคอมพวเตอรชนดพกพา เชน Laptop, Netbook, Mobile Internet Device, Smart Phone, Tablet
ในทสดลนกซคอรเนลรน 3.0 กเรมประกาศเปนทางการในเดอน กรกฏาคม ปค.ศ. 2011 ซงเปนการเปลยนขยบตวเลขจาก 2.6 ไปส 3.0 ทยาวนานแตกลบไมไดเปนการแกไขในระดบโคดมากแตอยางใด ขนาดภายในลนกซคอรเนล 3.x จะมขนาดโดยรวมอยประมาณ 434 MB ดวยจำนวนไฟลถง 39,400 กวาไฟล (มากกวา 14,800,000 บรรทด) ดงนนถาตองการจะทำการบบอดใหมขนาดเลกทสดควรจะเปนนามสกล .xz (ลดลงไปไดประมาณ 85.7%)
กรณการพฒนาระบบสมองกลฝงตวนนสามารถใชลนกซคอรเนลเลกทสดดวยขนาดเพยง 1.3 MB เพอใหเหมาะสมกบขอจำกดของทรพยากรภายในบอรดเมอเทยบกบเครองคอมพวเตอรทวไป
โครงสรางไดเรกทอร และขนาดพนทของลนกซคอรเนล 3.2
arch/<arch>
char
mm
drivers
fs
block
net
include
mtd/ide net pci serial usb ...
linux asm-<arch>
init kernel ipc lib scripts tools
crypto firmware security sound ...
linux
รปท 2.5 แสดงโครงสรางไดเรกทอรของลนกซเคอรเนล
70
Embedded Android Development สเสนทางนกพฒนา
รปท 2.6 แสดงรายละเอยดการใชพนทของแตละไดเรกทอรของลนกซเคอรเนล
รปท 2.7 แสดงการเพมขนาดการใชพนทของลนกซเคอรเนลตงแตเวอรชน 2.2 ถง เวอรชน 3.3
drivers/54%
arch/21%
fs/7%
sound/5%
net/4%
include/4%
firmware/1%
kernel/1%
other3%
71
Embedded Android Development สเสนทางนกพฒนา
ตาราง 2.1 แสดงรายละเอยดโครงสรางไดเรกทอรของระบบปฏบตการลนกซ Kernel code
ไดเรกทอร รายละเอยดarch/<architecture> Architecture specific codearch/<architecture>/include/asm Architecture and machine dependent headersarch/<architecture>/mach-<machine>
Machine/board specific code
block Block layer codeCOPYING Linux copyright conditions (GNU GPL)CREDITS Linux main contributors crypto/ Cryptographic librariesDocumentation/ Kernel Documentation. Don’t miss!drivers/ All device drivers expect sound ones (usb, pci..)fs/ Filesystems (fs/ext3/, etc.)include/ Kernel headersinclude/linux Linux kernel core headersinit/ Linux initialization (including main.c) ipc/ Code used for process communicationKbuild Part of the kernel build systemKernel/ Linux kernel core (very small!)lib/ Misc library routinesMAINTAINERS Maintain of each kernel part. Very Useful!Makefile Top Linux Makefile (Set arch and version)mm/ Memory Management codenet/ Network support codes (not drivers)README Overview and Build InstructionsREPORTING-BUGS Bug report instructionsamples/ Sample codes (markers, kprobes, kobjects)scripts/ Scripts for internal or external usessecurity/ Security Model Implementation (SELinux...)sound/ Sound support codes and driversusr/ Code to generate an initramfs cpio archive.
72
Embedded Android Development สเสนทางนกพฒนา
พนฐานการปรบแตงและสราง Custom Kernel
ในการปรบแตงลนกซคอรเนลหรออพเดทเปนรนใหมเพอใหเหมาะสมกบเครองทใชงานไดนน นกพฒนาควรตรวจสอบรายละเอยดสถาปตยกรรมและรนของลนกซคอรเนลทใชงานอยภายในเครองกอน โดยใชคำสง uname ดงตวอยางขางลาง
$ uname -aLinux EE-Burapha 2.6.32-42-server #96-Ubuntu SMP Wed Aug 15 19:52:20 UTC 2012 x86_64 GNU/Linux
รายละเอยดของผลลพธจากคำสงขางตน:• ระบบปฏบตการทใชอยคอ Linux ใช Ubuntu Linux distro • รนลนกซคอรเนลคอ 2.6.32• สถาปตยกรรม x86_64 (64 บต)• สวนทเหลอ กจะเปนครงทและเวลาท Kernel ถกคอมไพลตามลำดบ
เมอมการตดตงระบบปฏบตการลนกซไมวาจะเปนยหอ Ubuntu, Fedora หรอ FreeBSD ผใชไมจำเปนจะตองตดตงโปรแกรมหรอปรบแตงลนกซคอรเนลอะไรเพมเตม แตในกรณทมลนกซคอรเนลรนใหมทจำเปนตองทำการอพเดทหรอมระบบปฏบตการรนใหมทถกแนะนำใหอพเกรด ตวระบบปฏบตการจะมการแจงเตอนใหผใชอยภายในอตโนมตอยแลว ดงแสดงในรปขางลาง
รปท 2.8 หนาตางโปรแกรม Update Manager
73
Embedded Android Development สเสนทางนกพฒนา
ในกรณทผใชหรอนกพฒนาตองการปรบแตงลนกซคอรเนลกจำเปนจะตองใชซอรสลนกซคอรเนลเพอมาตงคาตางๆ กอนจะทำการคอมไพลใหมทงหมดดวยเหตผลดงน
• ตองการทดสอบความสามารถบางอยาง ทยงไมมอยในลนกซคอรเนลตงแตแรก หรอเพอทดสอบการทำงานของ Linux Module ทไดพฒนาขนมาเอง
• ตองการเพม device driver สำหรบอปกรณฮารดแวรตวใหม ทยงไมมอยในลนกซคอรเนลเดม
• ตองการเรยนรหลกการทำงาน หรอ ดบกการทำงานของลนกซคอรเนลอยางละเอยด
5 ขนตอนพนฐานการคอมไพล LINUX KERNEL
กอนทนกพฒนาจะสามารถปรบแตงหรอพฒนาโปรแกรมในระดบลางภายในลนกซคอรเนลไดนนผเขยนจะขออธบาย 5 ขนตอนพนฐานในการเตรยมการคอมไพลซอรสโคดลนกซคอรเนลทเปนพนฐานทจะเชอมโยงตอไปยงบทถดๆไปของหนงสอเลมน รวมทงจะทำใหผอานเขาใจโครงสรางทสำคญของระบบปฏบตการลนกซทจะนำไปสระบบปฏบตการลนกซสำหรบระบบสมองกลฝงตวตอไปได
ขนตอนท 1 - ดาวนโหลดลนกซคอรเนลรนเสถยรตวลาสด (Latest Stable Linux Kernel) สามารถตรวจสอบรนของ Kernel และความสามารถใหมๆทถกเพมเตมหรอถกปรบปรงใหดขน ไดจากเวปไซตหลก http://www.kernel.org โดยมรายละเอยดคำสงดงน$ sudo su# cd /usr/src/# wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.3.tar.xz# tar -xvJf linux-3.9.3.tar.xz
ขนตอนท 2 - การตงคาลนกซคอรเนล (Kernel Configuration)
ภายในลนกซคอรเนลมรายละเอยดใหตงคาไดมากกวา 3,000 รายการเนองจากซอรสโคดลนกซคอรเนลนนจะบรรจโปรแกรมตางๆมากมายเพอรองรบผใชในแตละระดบใหไดกวางทสดและรองรบอปกรณฮารดแวรตางๆทงในอดตและปจจบนใหไดมากทสดเชนกน นอกจากนนนกพฒนาเองกสามารถพฒนาโคดโปรแกรมใหมๆของตนเพมเขาไปในลนกซคอรเนลไดเชนกน กอนทจะทำการตงคาในซอรสโคดลนกซคอรเนลผ ใชจำเปนตองตดต งไลบรารพ นฐานซ งไดแก ไลบราร libncurses และ libncurses-devel ลงในระบบปฏบตการลนกซทตนใชอยใหเรยบรอยเสยกอนดวยคำสง sudo apt-get install libncurses libncurses-devel หลงจากนนกสามารถเขาสการตงคาตางๆผานหนาตางในลกษณะเมน แลวจงบนทกคา configure ตางๆลงในไฟลชอวา “.config” เพอใชในการคอมไพลตอไป
74
Embedded Android Development สเสนทางนกพฒนา
วธการตงคามอยหลายแบบเชนใชคำสง make config, make menuconfig, make xconfig และ make oldconfig ซงแตละคำสงมวตถประสงคและรายละเอยดทแตกตางกนไปดงตวอยางการใชงานตอไปน
• make config คอคำสงพนฐาน ทรองรบรนเคอรเนลไดตงแตลนกซรนแรกๆ ทใชในการเลอกการตงคา option ตางๆ โดยผใชจะตองตอบคำถามรายละเอยดการตงคาตางในลกษณะ (y/n)
• make menuconfig คำสงนเรมมใหใชตงแตลนกซคอรเนลรน 1.3 และรน 2.0 เปนตนไป ซงเปนคำสงทนยม เนองจากใชงานงาย มการแสดงผลคลายหนาตางในรปแบบ Text mode และมการจดกลมการตงคาออกเปนประเภทๆ
75
Embedded Android Development สเสนทางนกพฒนา
• make xconfig คำสงนเรมมใหใชตงแตลนกซคอรเนลรน 1.3 และรน 2.0 เปนตนไปเชนเดยวกนคำสง make menuconfig สามารถใชงานไดงายเนองจากมการแสดงผลเมนในรปแบบ Graphic mode บน x-window แตจะตองทำการตดตงไลบรารของ qt เพมเตมเขาไปในระบบเสยกอน
• make oldconfig คำสงนจะอางองจากไฟล .config ทมอยแลว หรอนำมาจากไฟลทบนทกการตงคา default ของสถาปตยกรรมทตองการเชน สถาปตยกรรม ARM ทมใหเลอก System-on-Chip (SoC) จากหลายๆคายทถกบรรจไวในไดเรกทอร <linux>/arch/x86/configs/
ตวอยางเชน ตองการใชกบสถาปตยกรรม x86 รน i386 ของบรษท Intel กจะใชคำสง make i386_defconfig
สามารถคนหาไฟล defconfig ทลนกซไดเตรยมไวใหเพอใชเปนไฟล .config ตนแบบสำหรบแตละสถาปตยกรรม ดวยคำสงขางลางน
# find ./arch -name "*_defconfig" -type f./arch/x86/configs/x86_64_defconfig./arch/x86/configs/i386_defconfig./arch/x86/configs/goldfish_defconfig./arch/xtensa/configs/iss_defconfig./arch/xtensa/configs/s6105_defconfig./arch/xtensa/configs/common_defconfig./arch/cris/configs/etrax-100lx_defconfig... # cd linux-3.9.3# make menuconfig
เมอไดตงคาตางๆเรยบรอยแลวจะไดไฟลชอ “.config” ออกมาซงบรรจรายละเอยดของลนกซคอรเนลวาจะมการใชหรอไมใชฟงกชนใดบาง เพอใหเขากบสถาปตยกรรมนนๆ
76
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 3 - การคอมไพล Linux Kernel
ในปจจบนนเครองคอมพวเตอรสวนใหญจะใชหนวยประมวลผลกลาง (CPU) แบบหลายแกน ทนยมเรยกกนวา Multi-core CPU ดงนนเพอใหการคอมไพลลนกซคอรเนลเปนไปไดอยางมประสทธภาพและใชเวลาทเหมาะสมตามทรพยากรของเครองคอมพวเตอร ผใชสามารถเพมตวเลอก -j ตามดวยจำนวนแกนคณสอง (cores x 2) เชน make -j8 โดยทตวเลข 8 หมายถงจำนวนแกนของหนวยประมวลผลกลางทอยในเครองนน (4-core) คณสอง ซงม 3 ขนตอนยอยดงน# make -j8
เปนการสราง Kernel Image เอาไวสำหรบการบตเขาระบบปฏบตการซงจะไดไฟลมาเปน bzImage (สำหรบ x86) หรอ zImage (สำหรบ ARM) ซงจะเกบอยในไดเรกทอร arch/<ชอสถาปตกรรม>/boot/*Image
# make modules
77
Embedded Android Development สเสนทางนกพฒนา
คอการสราง Kernel modules ทตองการจะโหลด device drivers ตางๆ และโมดลสำคญของระบบตางๆ ซงจะมนามสกลไฟลเปน .ko
# make modules_install
เปนคำสงในการตดตง Kernel modules ทถกคอมไพลออกมา (.ko) เพอไปเกบไวในไดเรกทอร /lib/modules/3.9.3/
ขนตอนท 4 - การตดตงลนกซคอรเนลตวใหม
ดวยคำสงขางลางนจะเปนการสรางไฟลทจะใชในการบทเครองเพอเขาสระบบปฏบตการลนกซทใชลนกซคอรเนลรนใหมทไดมาจากการคอมไพลกอนหนาน ซงไฟลเหลานจะถกเกบไวในไดเรกทอร /boot หลงจากใชคำสงขางลาง
# make install
รายชอไฟลตางๆทถกสรางขนภายในไดเรกทอร /boot มดงน
arch/arm/kernel/head.o
arch/arm/kernel/init-atask.o
init
usr/built-in.o
arch/arm/kernel
arch/arm/mm
arch/arm/common
arch/arm/mach-ixp4xx
arch/arm/nwfpe
kernel
mm
fs
ipcsecuritylib/lib.aarch/arm/lib
lib
drivers
net
vmlinux
78
Embedded Android Development สเสนทางนกพฒนา
• vmlinuz-3.9.3 (actual kernel) • System.map-3.9.3 (symbols exported by the kernel)
• initrd.img-3.9.3 (initrd image is temporary RFS used during boot process)
• config-3.9.3 (kernel configuration file)
• vmlinuz-3.9.3 (actual kernel)
รปท 2.9 รปแสดงรายละเอยดภายในไฟล vmlinux
ตาราง 2.2 แสดงรายละเอยดของไฟลไบนารภายในไฟล vmlinux
COMPONENT DESCRIPTION
arch/arm/kernel/head.o Kernel architecture-specific startup code.
init_task.o Initial thread and task structs required by kernel.
init/built-in.o Main kernel-initialization code.
usr/built-in.o Built-in initramfs image.
arch/arm/kernel/built-in.o Architecture-specific kernel code.
arch/arm/mm/built-in.o Architecture-specific memory-management code.
arch/arm/common/built-in.o Architecture-specific generic code. Varies by architecture.
arch/arm/mach-ixp4xx/built-in.o
Machine-specific code, usually initialization.
arch/arm/nwfpe/built-in.o Architecture-specific floating point-emulation code.
kernel/built-in.o Common components of the kernel itself.
mm/built-in.o Common components of memory-management code.
ipc/built-in.o Interprocess communications, such as SysV IPC.
security/built-in.o Linux security components.
lib/lib.a Archive of miscellaneous helper functions.
arch/arm/lib/lib.a Architecture-specific common facilities. Var-ies by architecture.
lib/built-in.o Common kernel helper functions.
drivers/built-in.o All the built-in drivers not loadable modules.
sound/built-in.o Sound drivers.
net/built-in.o Linux networking.
.tmp_kallsyms2.o Symbol table.
79
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 5 - การบทระบบปฏบตการลนกซสตวใหม
เมอมการตดตงลนกซคอรเนลตวใหมลงภายในไดเรกทอร /boot รวมทงการเพมเมนเขาไปในไฟล grub.cfg เปนทเรยบรอบแลว ขนตอนนกเพยงบทเครองคอมพวเตอรใหมเขาสระบบปฏบตการลนกซอกครงโดยการพมพคำสงดงน
# reboot หรอ shutdown -r now
เมอเขาสระบบปฏบตการลนกซแลว ผใชสามารถตรวจสอบรนของ Kernel ตวใหมไดโดยพมพคำสง
$ uname -r3.9.3
หมายเหต: ในกรณทตองการลบไฟลตางๆทถกสรางในระหวางทกำลงคอมไพลลนกซคอรเนลกสามารถใชคำสงดงขางลางนเพอลบสวนทไมตองการออก
• make clean คอการลบไฟลทไดเกดจากการตงคา (./configure) และถกคอมไพล (make) เปนไบนารเกอบทงหมด
• make mrproper คอการลบไฟลทไดถกคอมไพลเปนไบนารทงหมด รวมทงลบไฟล .config
• make distclean คอการลบไฟลทไดเกดจากการตงคา (./configure) และถกคอมไพล (make) เปนไบนารทงหมด
80
Embedded Android Development สเสนทางนกพฒนา
คอมไพลลนกซคอรเนล 3.X สำหรบ UBUNTU ทใชอย
ในกรณทผใชไดตดตง Linux distro อยางเชน Ubuntu โดยปกตแลวตว Ubuntu ตงแตรน 10.x ขนไปจะใชลนกซคอรเนลรน 2.6.32 เปนพนฐานหลกดงนนถาตองการอพเกรดลนกซคอรเนลเปนรนใหมไมวาจะเปนรน 3.9.3, 3.8, 3.7, 3.4.6, 3.3, 3.2, 3.1 หรอ 3.0.x แนะนำใหเรมตนทรน 3.0 เพอใหเขาใจขนตอนการปรบแตง Kernel อยางมหลกการทดพอเพราะถาเกดความผดพลาดในการตงคาอาจจะทำใหไมสามารถเขาสระบบปฏบตการไดอก เมอนกพฒนาเรมมความเชยวชาญมากขนในระดบนงแลวกคอยทำการ patch ใหเปนรนสงขนตามทตองการได ตวอยางขางลางจะแสดงการอพเกรดลนกซคอรเนลเปนรน 3.0.0 เรมตนดวยการตดตงไลบราร และเครองมอทเกยวของในการคอมไพล Kernel โดยใชคำสงดงตอไปน (ในกรณทเปน ubuntu 12.04)
$ sudo apt-get install git-core libncurses5 libncurses5-dev libelf-dev asciidoc binutils-dev linux-source qt3-dev-tools libqt3-mt-dev libncurses5 libncurses5-dev fakeroot build-essential crash kexec-tools makedumpfile kernel-wedge kernel-package
ดาวนโหลดลนกซคอรเนลจาก kernel.org แลวแตกไฟลไวในไดเรกทอร /usr/src/
$ sudo su# cd /usr/src/# wget https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.0.tar.xz# tar -xvJf linux-3.0.0.tar.xz
เนองจากลนกซคอรเนลนนมโคดทรองรบหลากหลายสถาปตยกรรมและมรายละเอยดของการตงคาอยพอสมควร ดงนนเพอใหงายและเขากนไดกบสถาปตยกรรมและระบบฮารดแวรทมอยภายในเครอง นกพฒนาสามารถนำไฟล .config เดมทอยในเครองมาใชไดทนท
# cp -vi /boot/config-`uname -r` .config
ในกรณทมไฟล .config เดมอยแลวซงไดถกตงคาตางๆใหรองรบระบบฮารดแวรพนฐานของเครองเดม หากตองการใหรองรบ Linux Kernel Modules เดมทอยในรนปจจบนดวย สามารถใชคำสงดงน
# make oldconfig ใหกด Enter ไปเรอยๆเพอใชคา defaults ของ Kernel รนใหม# make localmodconfig
ขนตอนถดไปเปนการตงคาทตองการเพมเตมของ Kernel รนใหม (3.0.0) โดยใชคำสงดงน
81
Embedded Android Development สเสนทางนกพฒนา
# make menuconfig หรอ make xconfig
เพอใหตวเคอรเนลตวใหมนสามารถถกแยกแยะออกไดจากตวหลกทมในระบบเดม สามารถระบ local version ตอทายจากเลขเวอรชนเชน คำวา “-burapha” โดยกำหนดเพมเตมในเมน General Setup แลวเขาไปใน “Local version” เพอใสชอทตองการ โดยเลอก “Automatically append version info”
และใหเลอกใช file system เปน ext4 โดยเลอกเมน “File systems”
เรมตนการคอมไพลลนกซคอรเนลรวมถง Kernel Modules ทไดเลอกไวดวยชดคำสงดงน
# make -j4
82
Embedded Android Development สเสนทางนกพฒนา
# make modules_install <----- ตดตง modules ลงในไดเรกทอร /lib/modules/# update-initramfs -u -k 3.0.0-burapha# make install <----- ตดตงไฟลหลกลงในไดเรกทอร /boot/
ผลลพธจากการคำสงขางตน จะไดไฟลหลกดงน•vmlinuz-3.0.0-burapha•System.map-3.0.0-burapha•initrd.img-3.0.0-burapha•config-3.0.0-burapha
ขนตอนกอนทจะรบทเขาสระบบดวย Kernel รนใหม จะตองทำการอพเดทไฟล grub.cfg ซงอยภายใตไดเรกทอร /boot/grub/ ดวยคำสง
# update-grubGenerating grub.cfg ...Found linux image: /boot/vmlinuz-3.0.0-buraphaFound initrd image: /boot/initrd.img-3.0.0-buraphaFound linux image: /boot/vmlinuz-3.0.0-burapha.oldFound initrd image: /boot/initrd.img-3.0.0-buraphaFound linux image: /boot/vmlinuz-2.6.32-42-serverFound initrd image: /boot/initrd.img-2.6.32-42-serverFound memtest86+ image: /boot/memtest86+.bindone
เมอเขาสระบบปฏบตการตวใหมแลว ผใชสามารถตรวจสอบรนของลนกซคอรเนลทไดอพเกรดดวยคำสงขางลางน
$ uname -r3.0.0-burapha
$ uname -aLinux EE-Burapha 3.0.0-burapha #2 SMP Sun Aug 4 03:32:15 PDT 2013 x86_64 GNU/Linux
83
Embedded Android Development สเสนทางนกพฒนา
การพฒนา Linux Kernel Module
ลนกซคอรเนลบนเครองคอมพวเตอรนนโดยสวนใหญจะเปนชนด monolithic kernel การทำงานภายใน Kernel ของระบบปฏบตการลนกซจะมการเรยกใชโมดลตางๆทเรยกกนวา Linux kernel modules (LKMs) ซงจะถกนำเขา-ออกจากหนวยความจำอยบอยครงตามการใชงานจรง โดยโครงสรางไฟล LKM (สำหรบ kernel 2.6) ดงแสดงในรปขางลาง
#include <linux/module.h> #include <linux/kernel.h>
MODULE_LICENSE("GPL"); MODULE_AUTHOR("EE - Burapha University"); MODULE_DESCRIPTION("hello world test driver");
static int __init module_start(void) { printk(KERN_INFO "Hello world ! module is loaded\n"); return 0; }
static void __exit module_unload(void) { printk(KERN_INFO "Goodbye world ! module is removed\n"); }
module_init(module_start); module_exit(module_unload);
Modulemacros
Module Constructor/Destructor
Exitmacros
รปท 2.10 สวนประกอบภายในไฟล Linux Kernel Module
LKM เปนสวนประกอบทสำคญของลนกซคอรเนลซงทำหนาทในการดแลการรองขอทเกดขนจากฮารดแวรและซอฟตแวร แลวทำการประมวลผลกบขอมลในเบองตนเพอสงตอใหระบบปฏบตการสามารถนำรายละเอยดเหลานนไปบรหารจดการการใชงานทรพยากรทงหมดไดอยางมระบบ ไมวาจะเปนดานการจดการหนวยความจำ (Memory Management) การตดตอสอสารระหวางโปรเซส (Inter-processing Communication - IPC) และการจดลำดบโปรเซส (Scheduling) โดยลนกซคอรเนลจะทำการโหลดตว LKM ขนมาในขณะทระบบปฏบตการกำลงทำงานอยดวยคำสง insmod หรอ mod-probe
84
Embedded Android Development สเสนทางนกพฒนา
Linux KernelModuleregister_capability()module_init()
Kernel functions
module_exit() unregister_capability()
capabilities[]
Module functions
Function call
Function pointer
Data pointer
insmod
rmmod
รปท 2.11 รายละเอยดการทำงานภายใน Kernel เมอมการเรยกใชโมดล
จากรปขางบนเปนขบวนการการทำงานของ LKM ภายในลนกซคอรเนลเวอรชน 2.6.x โดยมขนตอนดงน เมอมการโหลด LKM จากระดบสวนของผใช (user-space) ดวยคำสง insmod (insert module) ฟงกชน module_init() กจะทำการลงทะเบยน (register) กบตวลนกซคอรเนลผานฟงกชนชอวา register_capability() แลวทำการสงคาตวช (pointer) เพอชไปยงตวแปรอาเรยชอ “capabili-ties” หลงจากนนระบบปฏบตการกจะทำการกำหนดรปแบบทจะใหโปรแกรมประยกตนน สามารถเขาถงขอมลภายในของตวแปร capabilities เพอเรยกใชงานฟงกชนภายใน Kernel ตางๆผานทาง system calls ไดตอไปจนกระทงเมอมการเรยกคำสง rmmod (remove module) จากระดบสวนของผใช (user-space) ฟงกชน module_exit() กจะสงสนสดการทำงานแลวถอนตว LKM นนออกจากลนกซเคอรเนล จากรปขางลางเปนการแสดงการวางลำดบชนของฟงกชนตางๆ ทอยภายในสวนของผใช (user-space) และภายในสวนของเคอรเนล (kernel-space)
User-spa
ceKe
rnel-
spac
e
rmmodinsmod
init_module delete_module
sys_init_module sys_delete_module
. . . . . .
Utilities
System Calls
KernelFunctions
รปท 2.12 องคประกอบของฟงกชนทเกยวของกบ Linux Kernel Module
85
Embedded Android Development สเสนทางนกพฒนา
ตวโปรแกรมไดรเวอร (driver) อาจจะถกคอมไพลรวมอยในไฟลเคอรเนล โดยเมอเรมบทเขาสระบบปฏบตการพวกมนกจะถกโหลดขนลนกซคอรเนลในระหวางขนตอนของการบททนท (Boot Processes) เราจะเรยกไดรเวอรเหลานนวา Static Module ในขณะทไดรเวอรบางตวจะถกคอมไพลใหทำงานแบบ LKM เพอทจะถกโหลดหรอถกนำออกจากลนกซคอรเนลเมอใดกได ซงจะเรยกไดรเวอรเหลานวา Dy-namic Module
Applicationfile_open = write("/dev/foo", buffer, count);
data buffer
Character device driver
dev_write {copy_data_buffer_from_app();}
fops
chrdevs
Filedescriptor
syscallTable
major:251
minor:5
major:251minor:5
User-space
Kernel-space
รปท 2.13 แสดงขนตอนการทำงานของโปรแกรมไดรเวอร
จากรปขางบนแสดงขบวนการทำงานของโปรแกรมไดรเวอรในสวนของการเขยนขอมล (write op-eration) โดยเมอโปรแกรมเรยกฟงกชน write() กจะมการสงผานคาอนเตอรรพท (INT instruction) ทอางองทอยของการเขยนขอมล (write operation) ทอยภายในตาราง system call (syscall[ ] table) ในขณะทตวแปร fieldes จะบรรจคาหมายเลขอปกรณหลก (major device number) เพอทจะใหฟงกชน write ภายในลนกซคอรเนลสามารถเขาถงภายในโครงสรางของระบบไฟลนนได หลงจากนนลนกซคอรเนลกจะคดลอกขอมลทอยในตวแปร buffer จากสวนของระดบผใช (user-space) มายงสวนของระดบเคอรเนล (kernel-space) เพอเตรยมบนทกลงในตวเกบขอมลตอไป
ในทางปฏบตโดยทวไปแลวการพฒนาโปรแกรมไดรเวอรจะเปนลกษณะแบบ Dynamic Kernel module จะมความยดหยนสงและจะใชหนวยความจำไดอยางมประสทธภาพซงไฟล LKM ทงหมดจะถกเกบอยภายใตไดเรกทอร /lib/modules/$(uname -r) ดงตวอยางไฟลภายใน ทแสดงอยดานลาง
$ ls /lib/modules/$(uname -r)build modules.dep modules.pcimapkernel modules.dep.bin modules.seriomapmodules.alias modules.ieee1394map modules.symbolsmodules.alias.bin modules.inputmap modules.symbols.bin
86
Embedded Android Development สเสนทางนกพฒนา
modules.builtin modules.isapnpmap modules.usbmapmodules.builtin.bin modules.ofmap sourcemodules.ccwmap modules.order
สวนไฟลไดรเวอรทงหมดกจะถกเกบไวอยภายใตไดเรกทอร /lib/modules/$(uname -r)/kernel/drivers/ ลงไปอกชน ดงตวอยางไฟลภายใน ทแสดงอยดานลาง
$ ls /lib/modules/$(uname -r)/kernel/drivers/acpi edac infiniband mmc rtc videoata firewire input mtd scsi virtioatm firmware isdn net serial w1auxdisplay gpio leds parport spi watchdogblock gpu md pci ssb xenbluetooth hid media pcmcia stagingchar hwmon memstick platform telephonycrypto i2c message power uiodca idle mfd pps usbdma ieee1394 misc regulator uwb
ตวอยางการใชคำสง modprobe และ modinfo ในการดรายละเอยด และจดการกบ kernel module
$ sudo su# modinfo lp.kofilename: lp.kolicense: GPLalias: char-major-6-*srcversion: 84EA21D13BD2C67171AC994depends: parportvermagic: 3.0.0-burapha SMP mod_unload modversions parm: parport:array of charpparm: reset:bool
นอกจากนนยงมอกหลายคำสงทนาสนใจ ตวอยางเชน คำสง lsmod ทใชในการแสดงรายการ LKM ทกำลงถกโหลดใชงานอย ณ ขณะน
$ lsmodModule Size Used bybinfmt_misc 7568 1 acpiphp 17958 0 snd_ens1371 22663 2 gameport 9869 1 snd_ens1371snd_ac97_codec 125146 1 snd_ens1371btusb 13027 0 ac97_bus 1450 1 snd_ac97_codecsnd_pcm_oss 39673 0 snd_mixer_oss 15604 1 snd_pcm_osssnd_pcm 87151 3 snd_ens1371,snd_ac97_codec,snd_pcm_osssnd_seq_dummy 1750 0 snd_seq_device 6594 5 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_rawmidi,snd_seq
87
Embedded Android Development สเสนทางนกพฒนา
bluetooth 94536 1 btusbsnd 70476 14 snd_ens1371,snd_ac97_codec,snd_pcm_oss,snd_mixer_oss,snd_pcm,snd_seq_oss,snd_rawmidi,snd_seq,snd_timer,snd_seq_deviceintel_agp 11978 1 ppdev 6504 0 lp 9893 0 parport_pc 29880 1 serio_raw 4720 0 intel_gtt 16812 1 intel_agpi2c_piix4 8879 0 soundcore 7860 1 sndsnd_page_alloc 8500 1 snd_pcmjoydev 10705 0 shpchp 28186 0 parport 37333 3 ppdev,lp,parport_pcusbhid 39022 0 hid 87524 1 usbhidfloppy 63772 0 e1000 103861 0 vmw_pvscsi 15397 0 mptspi 16441 2 mptscsih 34985 1 mptspimptbase 93915 2 mptspi,mptscsihvmxnet3 39295 0
คำสง modprobe (หรอ insmod) ทใชในการโหลด LKM เขาสระบบปฏบตการ และ modprobe -r (หรอ rmmod) ทใชในการถอน LKM ออกจากระบบปฏบตการ ตามลำดบ
$ modprobe ppdev หรอ insmod ppdev.ko$ modprobe -r ppdev หรอ rmmod ppdev.ko
พนฐานการเขยน LINUX MODULE
การพฒนาโปรแกรมในระดบลนกซคอรเนลทเรยกวา Linux Module นนนกพฒนาจะตองเตรยมระบบเพมเตมนอกเหนอจากตวพนฐานทตดมากบเครอง ตวอยางเชนตว Ubuntu จะจดเตรยมโปรแกรมระบบ โปรแกรมประยกต และคอมไพลเลอรสำหรบการเขยนโปรแกรมพนฐานเทานน แตจะไมไดจดเตรยมไวใหสำหรบการพฒนาในระดบลนกซคอรเนลดงนนนกพฒนาจะตองทำการตดตงซอรสโคดของลนกซคอรเนลและตดตงไฟลเฮดเดอร (linux header) เพมเตมเขาไปกอน เพอใหสามารถเรยกใช API (Application Programming Interface) ทเปนไลบรารพนฐานได โดยทำตามคำสงขางลางนคนหาซอรสโคดทตรงกบรนของ Ubuntu ทใช
$ apt-cache search linux-source*linux-source - Linux kernel source with Ubuntu patcheslinux-source-2.6.32 - Linux kernel source for version 2.6.32 with Ubuntu patches$ apt-cache search linux-headers-$(uname -r)
88
Embedded Android Development สเสนทางนกพฒนา
linux-headers-2.6.32-42-server - Linux kernel headers for version 2.6.32 on x86_64
แลวทำการตดตงดวยคำสงดงน
$ sudo apt-get install linux-headers-$(uname -r) linux-source-2.6.37$ cd /usr/src/$ lslinux-headers-2.6.32-42-server.tar.bz2 linux-source-2.6.32.tar.bz2$ tar -xjvf linux-headers-2.6.32-42-server.tar.bz2 linux-source-2.6.32.tar.bz2
ตวอยางการสรางโปรแกรม Kernel Module “Hello world”
เรมตนการพฒนาโปรแกรม kernel module อยางงาย โดยการสรางไฟลชอ hello-driver.c แลวเกบลงในไดเรกทอร ~/kernel_module/
$ mkdir ~/kernel_module$ vim hello-driver.c
/* * hello-driver.c - The simplest kernel module. */ #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_INFO */ static int __init module_start(void) { printk(KERN_INFO "Hello world ! module is loaded\n");
/* * A non 0 return means init_module failed; module can't be loaded. */ return 0; }
static void __exit module_unload(void) { printk(KERN_INFO "Goodbye world ! module is removed\n"); }
module_init(module_start); module_exit(module_unload);MODULE_LICENSE("GPL");MODULE_AUTHOR("EE - Burapha University"); /* Who wrote this module? */MODULE_DESCRIPTION("hello world test driver"); /* What does this module do */
89
Embedded Android Development สเสนทางนกพฒนา
ทำการสรางไฟล Makefile สำหรบใชกำหนดคาการคอมไพลใหกบโปรแกรม hello-driver.c
$ vim Makefile
obj-‐m = hello-‐driver.o
all: make -‐C /lib/modules/$(shell uname -‐r)/build M=$(PWD) modules
clean: make -‐C /lib/modules/$(shell uname -‐r)/build M=$(PWD) clean
ใชคำสง make ในฐานะสทธ root เพอทำการสรางโมดล
$sudo su# make make -C /lib/modules/2.6.32-42-server/build M=/home/student/kernel_module modules make[1]: Entering directory `/usr/src/linux-headers-2.6.32-42-server' CC [M] /home/student/kernel_module/hello-driver.o Building modules, stage 2. MODPOST 1 modules CC /home/student/kernel_module/hello-driver.mod.o LD [M] /home/student/kernel_module/hello-driver.komake[1]: Leaving directory `/usr/src/linux-headers-2.6.32-42-server'
# lshello-driver.c hello-driver.mod.c hello-driver.o modules.orderhello-driver.ko hello-driver.mod.o Makefile Module.symvers
ทดสอบโหลดตวโมดลดวยคำสง insmod และสามารถตรวจสอบผลลพธการทำงานดวยคำสง dmesg (debug kernel message) ดงตวอยางขางลาง
# insmod hello-driver.ko # dmesg | tail -n1 [68587.257467] Hello world ! module is loaded
ถอนโมดลออกจากลนกซคอรเนลดวยคำสง rrmod
# rmmod hello-driver.ko # dmesg | tail -n1 [68621.602044] Goodbye world ! module is removed
90
Embedded Android Development สเสนทางนกพฒนา
โครงสรางภาพรวมของ Linux kernel moduleจากรปโครงสรางไฟลขางลางแบงไดเปน 5 สวน โดยสวนทเปนโคดโปรแกรมหลกจะอยในฟงกชน
init และ exit และจะทำงานกตอเมอมการโหลดหรอถอน LKM ภายในลนกซเคอรเนล
#include <linux/module.h> #include <linux/kernel.h>
MODULE_LICENSE("GPL"); MODULE_AUTHOR("EE - Burapha University"); MODULE_DESCRIPTION("hello world test driver");
void my_procedure(void) { printk(KERN_INFO "Here is procedure...\n"); } static int __init module_start(void) { printk(KERN_INFO "Hello world ! module is loaded\n"); my_procedure(); return 0; }
static void __exit module_unload(void) { printk(KERN_INFO "Goodbye world ! module is removed\n"); }
module_init(module_start); module_exit(module_unload);
Modulemacros
Module Constructor/Destructor
Exitmacros
C Headers
Proceduremodule
รปท 2.14 โครงสรางแบบเตมของ Linux Kernel Module
จากโครงสรางขางตนสวนบนสดคอสวนเรยกใชไลบราร (C Headers) โดยจะอางองไลบรารหลกๆอยางนอยสองตวคอ linux/module.h และ linux/kernel.h สวนถดมาคอโปรแกรมยอย (Procedure Program) ซงเปนสวนฟงกชนยอยทจะถกเรยกจากโปรแกรมหลก และสวนสดทายคอสวนรายละเอยดของโมดล (modules description) ทใชอธบายรายละเอยดของโมดลทออกแบบซงจะถกแสดงออกมาเมอมการเรยกใชคำสง modinfo ดงตวอยางขางลาง
MODULE_LICENSE("GPL");MODULE_AUTHOR("EE -‐ Burapha University"); /* Who wrote this module? */MODULE_DESCRIPTION("hello world test driver"); /* What does this module do */
$ modinfo hello-driver.ko filename: hello-driver.ko description: hello world test driver author: EE - Burapha University license: GPL srcversion: E36F5E4D3F232F0A1C18AEF depends: vermagic: 2.6.32-42-server SMP mod_unload modversions
91
Embedded Android Development สเสนทางนกพฒนา
พนฐานการเขยนโปรแกรมไดรเวอรสำหรบ CHARACTER DEVICE
พนฐานในการเขยนโปรแกรมไดรเวอรจะเกยวกบไฟลภายในระบบปฏบตการลนกซตามคณลกษณะในการสงขอมลของฮารดแวรนนๆ ซงระบบปฏบตการลนกซแบงไฟลชนดทเปนอปกรณ (device) ออกเปน 2 ประเภท ไดแก 1. Character device ซงเปนการสงขอมลแบบสตรม (stream) สามารถเขาถงไดทละเพยง 1 โปร เซสเสมอนโปรแกรมไดรเวอรปกตทวไป 2. Block device เปนการสงขอมลเแบบกอน (block) ใชกรณหนวยประมวลผลกลางตองการเคลอนยายขอมลขนาดใหญระหวางหนวยความจำหรอระหวางตวเกบขอมล เชน ฮารดดส เปนตน
Application
Virtual Filesystem
Hardware
Device Driver
User-space
Kernel-space
/dev/ttyUSB0
Device file
major:116minor:7
major:116
minor:7
...
...
Read/Write
รปท 2.15 แสดงการอางองคา major และ minor
จากรปขางบนเปนตวอยางการทำงานของโปรแกรมทตองการเขาถงไฟล /dev/ttyUSB0 ทถกเชอมตออยกบพอรต USB ทมการสงขอมลในรปแบบอนกรม ซงจะสงเกตวาตวโปรแกรมจะตองทำการอางองหมายเลข (major และ minor) เพอระบประเภทฮารดแวรหลกและตวยอยลงไปทโปรแกรมตองการจะตดตอสอสารขอมลดวย
ตวอยางโปรแกรม chardev.c จะแสดงจำนวนครงทมการอานขอมลจากไฟล device ชอ /dev/chardev ทถกสรางขนมา/* * chardev.c: Creates a read-only char device that says how many times * you've read from the dev file */
#include <linux/kernel.h>#include <linux/module.h>#include <linux/fs.h>#include <asm/uaccess.h> /* for put_user */
92
Embedded Android Development สเสนทางนกพฒนา
/* * Prototypes - this would normally go in a .h file */int init_module(void);void cleanup_module(void);static int device_open(struct inode *, struct file *);static int device_release(struct inode *, struct file *);static ssize_t device_read(struct file *, char *, size_t, loff_t *);static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
#define SUCCESS 0#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */#define BUF_LEN 80 /* Max length of the message from the device */
/* * Global variables are declared as static, so are global within the file. */
static int Major; /* Major number assigned to our device driver */static int Device_Open = 0; /* Is device open? * Used to prevent multiple access to device */static char msg[BUF_LEN]; /* The msg the device will give when asked */static char *msg_Ptr;static char msg_data[BUF_LEN] ="NONE \n" ; /*initial msg for write mode */
static struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release};
/* * This function is called when the module is loaded */int init_module(void){ Major = register_chrdev(0, DEVICE_NAME, &fops);
if (Major < 0) { printk(KERN_ALERT "Registering char device failed with %d\n", Major); return Major; }
printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major); printk(KERN_INFO "the driver, create a dev file with\n"); printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major); printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n"); printk(KERN_INFO "the device file.\n"); printk(KERN_INFO "Remove the device file and module when done.\n");
return SUCCESS;
93
Embedded Android Development สเสนทางนกพฒนา
}
/* * This function is called when the module is unloaded */void cleanup_module(void){ /* * Unregister the device */ unregister_chrdev(Major, DEVICE_NAME); printk(KERN_ALERT "Error in unregister_chrdev:\n");}
/* * Methods */
/* * Called when a process tries to open the device file, like * "cat /dev/mycharfile" */static int device_open(struct inode *inode, struct file *file){ static int counter = 0;
if (Device_Open) return -EBUSY;
Device_Open++; sprintf(msg, "I already told you %d times . Data in device is %s \n", coun-ter++,msg_data); msg_Ptr = msg; try_module_get(THIS_MODULE); return SUCCESS;}
/* * Called when a process closes the device file. */static int device_release(struct inode *inode, struct file *file){ Device_Open--; /* We're now ready for our next caller */
/* * Decrement the usage count, or else once you opened the file, you'll * never get get rid of the module. */ module_put(THIS_MODULE);
return 0;}
94
Embedded Android Development สเสนทางนกพฒนา
/* * Called when a process, which already opened the dev file, attempts to * read from it. */static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */ char *buffer, /* buffer to fill with data */ size_t length, /* length of the buffer */ loff_t * offset){ /* * Number of bytes actually written to the buffer */ int bytes_read = 0; /* * If we're at the end of the message, * return 0 signifying end of file */ if (*msg_Ptr == 0) return 0; /* * Actually put the data into the buffer */ while (length && *msg_Ptr) { /* * The buffer is in the user data segment, not the kernel * segment so "*" assignment won't work. We have to use * put_user which copies data from the kernel data segment to * the user data segment. */ put_user(*(msg_Ptr++), buffer++);
length--; bytes_read++; } /* * Most read functions return the number of bytes put into the buffer */ return bytes_read;}/* * Called when a process writes to dev file: echo "hi" > /dev/hello */static ssize_t device_write(struct file *filp, const char *buff, size_t length, loff_t * off){
int bytes_write ; for (bytes_write = 0; bytes_write < length && bytes_write < BUF_LEN; bytes_write++){ get_user(msg_data[bytes_write], buff + bytes_write); }
95
Embedded Android Development สเสนทางนกพฒนา
return bytes_write ; }
ทำการสรางไฟล Makefile สำหรบชวยในการคอมไพลโปรแกรม chardev.c
# cat Makefileobj-m = chardev.o
all: ! make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean: ! make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
คอมไพลโปรแกรมเพอใหไดไฟล chardev.ko ออกมาดวยคำสงขางลางน
# makemake -C /lib/modules/2.6.32-42-server/build M=/home/student/kernel_module modules make[1]: Entering directory `/usr/src/linux-headers-2.6.32-42-server' CC [M] /home/student/kernel_module/chardev.o Building modules, stage 2. MODPOST 1 modules CC /home/student/kernel_module/chardev.mod.o LD [M] /home/student/kernel_module/chardev.komake[1]: Leaving directory `/usr/src/linux-headers-2.6.32-42-server'# lschardev.c chardev.mod.o hello-driver.ko hello-driver.o modules.orderchardev.ko chardev.o hello-driver.mod.c Makefile Module.symverschardev.mod.c hello-driver.c hello-driver.mod.o Makefile_hello
สดทายทำการทดสอบโหลดโมดลเขาสลนกซคอรเนลดวยคำสง insmod และครวจสอบผลลพธดวยคำสง dmesg ดงขางลางน
# insmod chardev.ko# dmesg| tail -n6 [70707.121856] I was assigned major number 250. To talk to[70707.121858] the driver, create a dev file with[70707.121860] 'mknod /dev/chardev c 250 0'.[70707.121861] Try various minor numbers. Try to cat and echo to[70707.121862] the device file.[70707.121863] Remove the device file and module when done.
96
Embedded Android Development สเสนทางนกพฒนา
ทำการทดสอบตดตอไดรเวอรตวนอกครง โดยเรมตนใหสรางไฟลแทนไฟลเดม (/dev/chardev) เนองจากโปรแกรมไดรเวอร chardev.ko ไดสรางและลบออกไปเรยบรอยแลว ดวยการสรางไฟลอปกรณตวใหมชอ /dev/my_chardev แตยงคงใหใชหมายเลข major และ minor เดม (major:250 และ minor:0) ดวยคำสงขางลาง
# mknod /dev/my_chardev c 250 0# ls -al /dev/my_chardev crw-r--r-- 1 root root 250, 0 2013-09-23 22:22 /dev/my_chardev
ใชคำสง cat เพอแสดงขอมลทไดมาจาก /dev/my_chardev
# cat /dev/my_chardev I already told you 0 times . Data in device is NONE
จากผลลพธจะสงเกตเหนวายงไมมขอมลอยใน device เลย ดงนนใหลองทดสอบสงขอความไปยงไฟล /dev/my_chardev ดวยคำสง echo ดงตวอยางขางลาง
# echo "Hi...My device" > /dev/my_chardev # cat /dev/my_chardev I already told you 2 times . Data in device is Hi...My device
การเพม LINUX MODULE ใหมเขาไปยง LINUX SOURCE TREE
เมอนกพฒนาไดพฒนาโปรแกรมไดรเวอรหรอ LKM เสรจเรยบรอยแลว แตตองการรวมโคดโปรแกรมของตนเขาไปอยในโครงสรางหลกเดยวกบลนกซคอรเนลเพอใหผใชหรอนกพฒนาคนอนๆสามารถเขาถงการตงคาจากคำสง make menuconfig เพอเลอกใชโปรแกรมไดรเวอรของเราไดสะดวกขน
ทำไดโดยการนำโปรแกรม LKM ทไดพฒนาขนมานไปเกบไวภายใตไดเรกทอร drivers/misc ของซอรสลนกซคอรเนลในทนขอยกตวอยางไฟล hello-driver.c
$ cp ~/kernel_module/hello-driver.c /usr/src/linux-source-$(uname -r)
ขนตอนถดไป ใหเปดไฟล drivers/misc/Kconfig เพอเพมเมนเขาไปในลนกซคอรเนลดงตวอยางขางลางน
config HELLO_WORLD_MODULE tristate "hello world module" depends on X86 <----- สามารถระบสถาปตยกรรมทโมดลตวนทำงานไดเพม เชน ARM default m if X86 <----- สามารถระบใหเปน m หรอ y ได และเพมสถาปตยกรรมได help
97
Embedded Android Development สเสนทางนกพฒนา
hello world module.
แกไขไฟล drivers/misc/Makefile โดยการเพมบรรทดขางลางน เพอใหมการคอมไพล LKM เพมเตมobj-‐$(CONFIG_HELLO_WORLD_MODULE)+= hello-‐driver.o
และใหทำการเรมตนการคอมไพลเพอสรางลนกซคอรเนลตวใหมโดยการเขาสเมนการตงคาดวยคำสง make menuconfig แลวเขาไปในเมน Device Drivers เลอกโมดลทตองการดงตวอยางการตงคาขางลางน
98
Embedded Android Development สเสนทางนกพฒนา
ขนตอนสดทายทำการคอมไพลโมดลและตดตงโมดลเพมเขาไปใน root file system ตวใหม ดงคำสงขางลางน
$ make modules$ make modules_install INSTALL_MOD_PATH=$ROOTFS
99
Embedded Android Development สเสนทางนกพฒนา
บทท 3 EMBEDDED LINUX DEVELOPMENT
ความเปนมาของระบบสมองกลฝงตวยคเรมตนของคอมพวเตอรตงแตป ค.ศ. 1930 ซงเปนคอมพวเตอรขนาดใหญและสามารถทำการ
ประมวลผลไดเพยงทละงาน (single task) เทานนแตเมอเวลาผานไปการพฒนาและววฒนาการของเทคโนโลยสงมากขน ทำใหชฟและอปกรณอเลกทรอนกสภายในเลกลงอยางตอเนอง จนกระทงในป ค.ศ. 1940 ไดเรมมการนำระบบสมองกลฝงตวมาควบคมขปนาวธนำวถ (Missile) สำหรบกองทพทหาร ซงหนงในระบบสมองกลฝงตวททนสมยทสดในยคนนกคอเครอง "Apollo Guidance Computer" ถกสรางขนโดย Charles Stark Draper ณ แลป MIT Instrumentation แตโปรเจคตวนยงถกมองวามความเสยงในการใชงานเนองจากตองนำวงจรทเคยมขนาดใหญมากมายอใหเลกลงรวมทงนำหนกจะตองเบาลงเพอใหสามารถนำไปฝงไวภายในผลตภณฑทตองการได แตในทสดผลงานชนแรกจากแลป MIT กถกพฒนาปรบปรงขนมาไดจนสำเรจโดยตงชอวา Autonetics D-17 guidance computer และไดถกนำไปใชในการทหารของโครงการชอ Minute missile
ตงแตชวงป ค.ศ. 1961 จนถงป ค.ศ. 1966 ไดมการปรบปรงการออกแบบของวงจรจากเดมทใชตวทรานซสเตอรขนาดใหญและใชฮารดดสภายนอกในการเกบขอมล มาเปนการนำชฟประมวลผลแบบใหมเขามาใชงานแทนทตวทรานซสเตอรเดมจนทำใหไดวงจรมขนาดเลกลงและมประสทธภาพสงมากขน จนสามารถออกมาเปนผลตภณฑระบบสมองกลฝงตวรนใหมได โดยใชชอวา Minuteman II
เทคโนโลยดานระบบสมองกลฝงตวไดถกพฒนาอยางตอเนองเพอใหมขนาดและราคาทลดลงแตยงคงประสทธภาพสงขน มาจนกระทงในป ค.ศ. 1971 กไดเรมเขาสยคไมโครโปรเซสเซอรยคแรกอยางเตมตวดวยการเปดตวของหนวยประมวลผล Intel 4004 ทถกออกแบบขนมาสำหรบเปนหนวยประมวลผลกลางในเครองคดเลข แตกยงคงใชฮารดดสภายนอกในการเกบหนวยความจำตางอย จนมาถงในป ค.ศ. 1980 กไดมการผนวกหนวยความจำกบตวชปประมวลผลเขาดวยกนไดสำเรจซงถอไดวาเปนจดเรมตนทสำคญของวงการไมโครคอลโทรเลอรตงแตนนเปนตนมา โดยตวไมโครคอนโทรเลอรตวแรกของโลกคอ Intel 8048 และตอมาในป ค.ศ. 1980 กเปนจดเปลยนของวงการไมโครคอลโทรเลอรอกครงหนง เมอ Intel ไดเปดตว Intel 8051 ทมาพรอมกบเครองมอชวยในการพฒนาโปรแกรม (software develop-ments tools) จนไดรบการตอบรบการผใชอยางกวางขวางและเปนทนยมทงในระดบมหาวทยาลย บรษทพฒนาทางดานระบบสมองกลฝงตว
แตกยงมขอจำกดในการพฒนาโปรแกรมเพราะสามารถเขยนโปรแกรมลงไปในไมโครคอนโทรเลอรไดเพยงครงเดยว (PROMs) แตหลงจากนนไมนานกไดมการพฒนาเพมมาอกขนเพอทำใหสามารถลบโปรแกรมภายในแลวบนทกไดใหมโดยใชเทคโนโลย EPROM ทเปนการลบดวยแสงยว (UV) และตอมาภายหลงกไดมการสรางเครองลบโปรแกรมชนดกลองสรางแสง UV ทสามารถลบขอมลใน EPROM โดยใชเวลาประมาณ 5-10 นาทจนกระทงป ค.ศ. 1993 ไดมการพฒนาจาก EPROM มาเปน EEPROM ท
100
Embedded Android Development สเสนทางนกพฒนา
สามารถลบหรอแกไขโปรแกรมไดโดยทไมตองเอาออกจากคอมพวเตอรเหมอน EPROM แตอยางไรกตาม EEPROM จะตองลบขอมลทงหมดกอนทจะใสขอมลใกมเขาไปทกครง ซงยงมขอจำกดอยทจำนวนครงการลบหรอแกไข ตอมาตงแตป ค.ศ. 1992 ทง 12 บรษทยกษใหญทางดานคอมพวเตอรกไดรวมกนจดตงกลมสมาคม PC/104 Consortium เพอกำหนดแนวทางในการนำเทคโนโลยเครองคอมพวเตอรทวไปมาปรบใหเหมาะสมกบการประยกตใชในระบบสมองกลฝงตว โดยไดออกแบบเมนบอรดและปรบขนาดของกลองใหมขนาดเลกกระทดรดเพอใหสามารถวางซอนกนเปนชนไดดวยขนาดกวางยาวเพยง 4 นว และมความหนาเพยง 1 นว ดวยการนำเสนอของกลมสมาคม PC/104 ทำใหไดรบการตอบรบจากภาครฐและภาคเอกชนอยางคาดไมถง ดงนนกลมตลาดทางดานการทหารและการแพทยจงเปนกลมแรกทไดนำแนวคดและเทคโนโลยสมองกลฝงตวไปประยกตใชงานจรง
จนกระทงเทคโนโลยสมองกลฝงตวเรมไดรบความนยมอยางกวางขวาง และประสทธภาพของตวประมวลผลภายในเองกเพมขนอยางรวดเรวจงเรมนำไปสการพฒนาในอตสาหกรรมสอมลตมเดยโดยเรมตนจากการไดสรางต PC/104-based Kiosk ขนมาเปนตวแรก จนถงวนนไดมบรษทมากกวา 100 แหงทเขารวมกลมสมาคม PC/104 Embedded Consortium เพอรวมกำหนดมาตราฐานของผลตภณฑตวอยางเชน Ethernet card, FireWire, hard drives, RAM drives, video cards, audio cards, general I/O, flash cards, modems, GPS, cellular telephone, wireless Internet และอกมากมาย นอกจากนนกยงมอกปจจยหนงทกระตนกลมนกพฒนาและผสนใจเทคโนโลยสมองกลฝงตวคอการออกนตยสารทางดานระบบสมองกลฝงตว ซงเรมออกสสายตานกพฒนามาตงแตป ค.ศ. 1988 ในชอวา “Embedded Systems Programming” และเพงมาเปลยนชอเปน “Embedded Systems De-sign” เมอป ค.ศ. 2005 จนกระทงถงปจจบนน
รปท 3.1 นตยสาร Embedded System Design
ดงนนสามารถสรปนยามของระบบสมองกลฝงตวไดวา เปนระบบทถกออกแบบสำหรบใชงานในวตถประสงคเฉพาะดานทไมเหมอนกบคอมพวเตอรทใชงานทวไป เพราะระบบสมองกลฝงตวจะถกกำหนดการทำงานตามความตองการอยางชดเจนไวลวงหนาเรยบรอยแลวซงคณลกษณะของระบบสมองกลฝงตวทสำคญไดแก - เปนการออกแบบเพอทำงานอยางใดอยางหนง โดยจะทำงานตามโปรแกรมทตงไว - เปนการประมวลผลแบบครงละงาน (Single Task)
101
Embedded Android Development สเสนทางนกพฒนา
- สามารถเรยกใชไดหลายฟงกชนแตไดทละฟงกชนจนสำเรจเทานน - ราคาถก - ใชงานงาย - มจดเชอมตอนอย ใชงานงาย - มฟงกชนการทำงานทเพยงพอและรวดเรว - ใชพลงงานตำ - รองรบการสงงานจากภายนอก - สามารถคำนวณไดแมนยำและแสดงผลแบบ real-time
ซงในงานทไมซบซอนมากนกระบบสมองกลฝงตวกจะใชเพยงไมโครโปรเซสเซอรเดยวและโปรแกรมควบคมกจะถกเกบอยภายในหนวยความจำชนดอานไดอยางเดยวหรอเรยกสนๆวา ROM (Read-only Memory) แตในกรณทตองมการประมวลผลทซบซอนหลายสวนพรอมกนภายในตวระบบสมองกลฝงตวจำเปนตองมระบบปฏบตการ (Operating System) ฝงอยภายในเพอคอยจดการงานและหนวยความจำอยางมระบบและมประสทธภาพ ตวระบบปฏบตการลนกซจงเปนตวเลอกทนาสนใจทสดในกลมนกพฒนาทางดานระบบสมองกลฝงตว ดวยเหตผลท เปนระบบปฏบตการท มความยดหย นและมประสทธภาพสง สามารถรองรบสถาปตยกรรมไดไมนอยกวา 30 สถาปตยกรรมและเปนทรกนดวาลนกซคอรเนลนนสวนใหญถกเขยนดวยภาษาซและแอสเซมบลบางสวน จงทำใหงายตอการปรบแตงและนำไปใชในสถาปตยกรรมไดหลากหลาย นอกจากนนในมมมองการเตบโตและความไดเปรยบของการแขงขนในตลาดกไมทำธรรมดาเพราะตงแตป ค.ศ. 2005 จำนวนนกพฒนาลนกซคอรเนลกเพมขนจากเดมเกอบสามเทาตวโดยทกๆวนจะมโคดใหมเพมโดยเฉลย 10,000 บรรทด และทกๆชวโมงจะมประมาณ 5.45 patch files ทถกอพโหลดเขาสเวปไซตลนกซคอรเนล (อางอง: Linux Foundation Analysis) รวมทงผผลตอปกรณรายใหญๆและผจำหนายซอฟแวรทไดรบการรองรบมาตราฐาน (ISV: Independent Software Vendors) จำนวนมากกยงหนมาสนบสนนระบบปฏบตการลนกซกนอยางจรงจง และทสำคญ GNU GPL (General Public License) ยงใหสทธแกผใชอสระในการใชโปรแกรมการแกไขภายในโปรแกรมและคดลอกแจกจายใหผอนอยางไมมจำนวนจำกดอกดวย
ระบบปฏบตการลนกซมการเตบโตในระดบสงตอปอยางตอเนองและเรมเขามามบทบาทสำคญในตลาดทางดานอตสาหกรรมเทคโนโลยระบบสมองกลฝงตวตงแตป ค.ศ. 2002 เปนตนมา โดยในชวงแรกตงแตป ค.ศ. 2001 ถง ค.ศ. 2002 ผลการสำรวจระบบปฏบตการทถกใชใน smart gadgets มากทสดคอระบบปฏบตการลนกซ (15.5%) ซงเอาชนะระบบปฏบตการ WinCE/WinCE.Net (6%) และ XPe (5%) จากคาย Microsoft และ VxWorks (10.3%) จากคาย Wind River ในชวงเวลาตอมาตงแตป ค.ศ. 2003 ถง ค.ศ.2005 ผลการสำรวจพบวาจำนวนผทใชระบบปฏบตการลนกซภายในบรษทเพอสรางผลตภณฑอยางตอเนองอยทประมาณ 49-52% และหลงจากป ค.ศ. 2006 เปนตนมาถอไดวาเปนชวงเรมตนของการขยายตวของระบบสมองกลฝงตวไมวาจะเปนการแขงขนของชพประมวลผลกลาง (CPU) เชน ARM, x86, PowerPC, MIPS, Coldfire, DSP เปนตน การแขงขนดานระบบปฏบตการเชน OpenZaurus,
102
Embedded Android Development สเสนทางนกพฒนา
Ångström distribution, Familiar Linux, webOS from Palm, Inc., Maemo based on Debian เปนตน นอกจากนนกยงมระบบปฏบตการทคนหกนดในวงการนกพฒนาไทย ทฝงอยในอปกรณเครอขาย อปกรณชนดพกพาไมวาจะเปน PDA, Pocket PC, Smart Phone, Netbook ตางๆ ตวอยางเชน AirOS (Ubiquiti Network), CatOS/Cisco IOS/IOS-XR (Cisco Systems), DD-WRT (NewMedia-NET), JunOS (Juniper Networks), OpenWRT (LinkSys), Palm OS (Palm Inc.), Symbian OS (Nokia), Windows CE/Mobile (Microsoft), iPhone (Apple), OpenZaurus (Sharp), Maemo (Nokia), Qtopia/Qt Embedded (TrollTech), Openmoko (based on Ångström), Mobilinux (Monta-vista), Android (Google), Moblin (Intel), Ubuntu Mobile และ Meego (Maemo+Moblin) เปนตน โดยผจดจำหนายทเนนขายระบบปฏบตการลนกซสำหรบระบบสมองกลฝงตวไดแก Monta-Vista, Koan, Sysgo, Denx, Metrowerks, FSMLabs, LynuxWorks, Wind River, และ TimeSys เปนตน จงทำใหเทคโนโลยสมองกลฝงตวกลายเปนองคประกอบสำคญในตลาดทางดานอปกรณอเลกทรอนกสและมการใชระบบปฏบตการลนกซเปนระบบปฏบตการหลกเชนเดยวกน โดยสามารถแบงกลมตลาดหลกๆไดดงน
• กลมอตสาหกรรมยานยนต (Automotive) ไดแก ระบบควบคมภายในยานพาหนะ (ECU-Electronic Control Unit) ระบบความปลอดภยภายใน
• เครองใชไฟฟารวมถงอปกรณ Set-top-Box อปกรณสำหรบการสอสารและใชงานผานระบบอนเทอรเนต
• ระบบควบคมอตสาหกรรม (Industrial Automation) ไดแก ระบบควบคมขบวนการผลตทงหมด ระบบควบคมหนยนตในสายการผลต รวมไปถงระบบควบคมไฟฟากำลงสง (HVAC System) เปนตน
• เครองมอแพทย ไดแก ระบบเฝาตดตามอาการผปวยอตโนมต ระบบบำบดอาการปวย ระบบตรวจสอบและวเคราะหผล ระบบชวยในการผาตด และระบบตรวจวเคราะหดวยเสยงและภาพ เปนตน
• โทรศพทเคลอนท และคอมพวเตอรชนดพกพา
• เครองมอทางทหารและอวกาศ ไดแก ระบบนำรองและควบคมการบน ระบบสอสารผานดาวเทยม
• อปกรณสำนกงาน ไดแก เครองถายเอกสาร แฟกซ เครองพมพ เครองแสกน โทรศพท VoIP เครองสำรองขอมลขนาดใหญ เปนตน
• ระบบสอสารแบบสายและไรสาย ไดแก อปกรณเครอขายตงแตระดบ LAN, MAN และ WAN
จากการขยายตวอยางสงของเทคโนโลยสมองกลฝงตวไปยงตลาดทไดกลาวมาขางตน เกดจากปจจยสำคญไดแก
• การเพมจำนวนของนกพฒนาทางดานฮารดแวรและซอฟแวรระบบสมองกลฝงตวมแนวโนมสงขน โดยเฉพาะนกพฒนาซอฟแวร
103
Embedded Android Development สเสนทางนกพฒนา
• การขยายตวของอปกรณสมองกลฝงตวทมอยเดมประมาณสองพนลานตวและมแนวโนมจะเพมไดถงสองแสนลานตวภายในป ค.ศ. 2013
• ระบบปฏบตการลนกซไดรบการตอบรบและสนบสนนเปนอยางดจากบรษทยกษใหญตางๆ ตวอยางเชน Sony, Motorola, Philips, Panasonic, Google, Samsung และ Siemens เปนตน
• ภาษาซยงคงถกใชเปนภาษาหลกในการเขยนโปรแกรมทางดานฮารดแวร (Device Programming) ตามมาดวยภาษา Assembly, C++ และ embedded C++
อางองสวนหนงมาจาก: http://www.ecti-thailand.org/emagazine/views/66
สถาปตยกรรมในระบบสมองกลฝงตว
รปท 3.2 แสดงตวอยางผลตภณฑทางดานสมองกลฝงตว
Photo from: http://free-electrons.com
สถาปตยกรรมไมโครโปรเซสเซอรและอปกรณฮารดแวรสำคญของระบบสมองกลฝงตวระบบปฏบตการลนกซไดถกพฒนาปรบปรงอยางตอเนองเพอใหสามารถรองรบการสถาปตยกรรม
ตางๆของหนวยประมวลผลกลางทออกมาในตลาดใหไดมากทสดซงรายละเอยดทางดานเทคนคภายในโคดของลนกซคอรเนลสำหรบแตละสถาปตยกรรมจะถกบรรจอยภายใตไดเรกทอร /arch ของลนกซคอรเนล โดยในปจจบนระบบปฏบตการลนกซสามารถรองรบสถาปตยกรรมตางๆไดไมตำกวา 30 สถาปตยกรรม เชน สถาปตยกรรม ARM, AVR32, Intel x86, Intel x86_64, MIPS, Motorola 68000 (M68K) , PowerPC, และ Super-H เปนตน โดยแตละสถาปตยกรรมจะมวตถประสงคในการนำไปทแตกตางกนตวอยางเชน
104
Embedded Android Development สเสนทางนกพฒนา
• สถาปตยกรรม x86 and x86-64 สำหรบเครองคอมพวเตอรทวไป • สถาปตยกรรม ARM จะถกนำไปใชในหลากหลายงานประยกตไมวาจะเปนอปกรณเครองใชไฟฟา อปกรณโทรศพท (Mobile Internet Device) อปกรณสำหรบงานมลตมเดย (Set-top-Box, DVD Player) หรอ อปกรณควบคมในอตสาหกรรมการผลต เปนตน
• สถาปตยกรรม PowerPC จะถกนำไปใชมากอยในอปกรณทางดานโทรคมนาคม ระบบเครอขาย โดยเฉพาะทตองทำงานแบบเวลาจรง (real-time)
• สถาปตยกรรม MIPS ยงคงมใชอยหลากหลายในอปกรณทางดานระบบเครอขาย • สถาปตยกรรม SuperH ถกพฒนาโดยบรษท Hitachi (1990s) ในสมยกอนจะพบเหนบอยในอปกรณทางดานมลตมเดย เชน อปกรณ Set-top-box จนกระทงในปจจบนนทางบรษท Renesus กยงคงนำมาใชในระบบนำทาง อปกรณทางดานเครอขาย เครองพมพ และกลองถายรป
• สถาปตยกรรม Blackfin ถกพฒนาและทำตลาดโดยบรษท Analog Devices ซงจะถกเนนไปในงานดานประมวลสญญาณดจตอล (Signal Processing) ทเนนทำใหตว Blackfin CPU เองมราคาถก
• สถาปตยกรรม Motorola 68000 จะไดรบความนยมในชวงป 1980s - 1990s ในอปกรณคอมพวเตอรสวนบคคล เชน Apple Macintosh, Commodore Amiga, Atari ST ซงจะเปนคแขงสำคญกบบรษท Intel
ตาราง 3.1 การรองรบมาตราฐานการเชอมตอของแตละสถาปตยกรรมO P T I O N X 8 6 A R M P P C M I P S S H M 6 8 K
Parallel Port support X X X
IEEE 1394 support X X X X
IrDA support X X X X
USB support X X X X
Bluetooth support X X X
หนวยความจำและตวเกบขอมล
สำหรบระบบปฏบตการลนกซพนฐานทมขนาดเลกทสดจะสามารถทำงานไดภายใตหนวยความจำขนาดเพยง 8 MB แตอยางไรกตามถาจะตองใหสามารถใชงานประยกตไดดในระดบหนงทไมชามากเกนไปกควรจะตองมขนาดหนวยความจำใหอยทประมาณ 32 MB สวนขนาดของตวเกบขอมล (Storage) นนสามารถใชขนาดเลกสดอยทขนาด 4 MB ในกรณทตองการเกบหรอสำรองขอมลเพมขน กอาจจะเพมตวเกบขอมลประเภทแฟลช (Flash storage) เชน NAND/NOR Flash หรอ ตวเกบขอมลประเภทบลอค (Block storage) เชน SD/MMC card และ eMMC เปนตน
105
Embedded Android Development สเสนทางนกพฒนา
การตดตอสอสารกบอปกรณรอบขาง
สวนของเคอรเนลในระบบปฏบตการลนกซสามารถรองรบระบบการสอสารในมาตราฐานตางๆได ไมวาจะเปนระบบบสพนฐานในการสอสารภายในอปกรณระหวางกนเองเชน I2C, SPI, CAN, 1-wire, SDIO, UART และ USB ระบบการสอสารระดบสงเชน Ethernet, Wifi, Bluetooth, และ CAN รวมถงโปรโตคอลมาตราฐานในระดบระบบเครอขาย (TCP/IP) กมโปรแกรมไดรเวอรพรอมอยภายในตวระบบปฏบตการลนกซเอง
กอนจะเปนบอรดสมองกลฝงตว
ในปจจบนนบอรดสมองกลฝงตวมออกมาหลากหลายรนหลายยหอ ทงในราคาทนกพฒนาหรอผใชทวไปสามารถหาซอไดไมวาจะเปน BeagleBoard, PandaBoard, BeagleBone, ODROID, Raspberry Pi, Freescale i.MX53, AM335x Sitara, Friendly ARM เปนตน โดยใชหนวยประมวลผลกลาง (CPU) จากผผลตตางๆ เชน Texas Instrument, Samsung, Qualcomm, Nvidia ซงสวนใหญแลวจะใชสถาปตยกรรม ARM อยภายใน
รปท 3.3 แสดงตวอยางบอรดพฒนาระบบสมองกลฝงตว
ซงกวาจะกลายมาเปนบอรดสมองกลฝงตวไดนนไมเพยงแตตองหาชฟตางๆมาเพอประกอบเปนบอรดเพอนำไปใชในงานประยกตแตนกพฒนาควรจะตองเขาใจฟงกชนการทำงานและความสามารถพเศษทบอรดสมองกลนนมอย
สถาปตยกรรม ARMชด Instruction set,
กาหนดการตดตอกบ MMU, อนเตอรรพท
เนนการกาหนดคณลกษณะ (specification)
ARM Coreการออกแบบการทางานภายใน
หนวยประมวลผลเพอใหเขากบ
สถาปตยกรรมทกาหนดไว
อยในรปแบบของ netlist หรอ โคด Verilog เพอสงตอใหผซอลขสทธ
System-on-Chip
การรวมอปกรณ/ชพตางๆเขาไป เพอเชอมตอภายใน ARM Core รนนนๆ
ขายออกมาในรปแบบของชพรนท
บรษทจดจาหนาย (SoC Brand)
บอรดสมองกลฝงตวบอรดประยกตทมการรวม SoC และพอรตสาหรบเชอมตออปกรณ
ภายนอก
ขายออกมาในรปแบบบอรดสมอง
กลฝงตวสาเรจรป
รปท 3.4 แสดงลำดบตงแตสถาปตยกรรมจนมาเปนบอรดสมองกล
106
Embedded Android Development สเสนทางนกพฒนา
หวใจสำคญของสวนนจะเรมตนจากตว System-on-Chip (SoC) ซพยซงม ARM Core อยภายในทถกเชอมโยงดวยชพเซทตางๆ (Chipset) ททำใหบอรดสมองกลตวนนสามารถรองรบการสอสารไดหลากหลายรปแบบ ตวอยางเชน Ethernet, AUX, USB, SATA, LCD, HDMI จากรปขางลางแสดงขบวนการตงแตสถาปตยกรรม ARM จนกลายมาเปน System-on-Chip ทบรษทและเหลานกพฒนาสามารถนำมาออกแบบเปนบอรดสมองกลฝงตวเพอนำไปใชในงานประยกตตางๆไดในทสด
ARMv6
ARMv7
ARM1176JZF-S
ARM Cortex-A8
ARM Cortex-A15
Marvell PJ48
BCM2835
TI AM335x
Samsung Exynos 5
MarvellArmada XP
Raspberry Pi
BeagleBone
Arndale
PlatHomeOpenBlocks AX3-4
สถาปตยกรรม ARM ARM Core System-on-Chip บอรดสมองกลฝงตว
รปท 3.5 แสดงตวอยาง SoC ทนยมอยในปจจบน และตวอยางองคประกอบภายใน SoC
บรษท ARM ไมไดทำตวเองเปนผผลตไมโครโปรเซสเซอร แตจะเปนผทออกแบบและกำหนดการทำงานภายในสถาปตยกรรม เชนชดคำสง Instruction Set, การเชอมตอกบตวจดการหนวยความจำ (MMU) หรอการควบคมสญญาณอนเตอรรพตางๆ (Interrupts) เปนตน เพอตองการขายลขสทธ (Li-cense fee) การใชสถาปตยกรรมแกบรษทรวมทางธรกจ (Business Partner) ทจะรวมออกแบบกบทางบรษท ARM จนมาเปน ARM Core แตละรน และจะทำการออกแบบการเชอมตอกบ Chipset ภายใน
107
Embedded Android Development สเสนทางนกพฒนา
ตางๆ จนในทสดกลายมาเปน System-on-Chip ตวอยางเชน TI OMAP, TI AM335x, Samsung Exy-nos, Rockchip, FreeScale i.Mx53 โดยบรษทรวมธรกจนจะตองจายคา Royalty fee ใหกบบรษท ARM เมอใดทมการนำไปสรางเปนบอรดสมองกลฝงตวสำหรบสนคาทางดานอเลกทรอนกสและสนคาเทคโนโลยตางๆ เชน โทรศพทมอถอ (Smart Phone), แทปเลต (Tablet), อปกรณเครองใชไฟฟาหรอระบบอเลกทรอนกสภายในยานพาหนะ เปนตน ซงจากรปขางลางแสดงโมเดลทางธรกจของบรษท ARM และระยะเวลาในการออกแบบวจยพฒนาจนกวาจะมาเปนผลตภณฑในตลาดในทสด
20+ ปสรางบอรดสมองกลฝงตวสาหรบงานประยกตตางๆ
และดาเนนธรกจ
3-4 ปบรษทหนสวนนาไปพฒนาเปน SoC
2-3 ปออกแบบพฒนา ARM Core
เงนลงทน
รปแบบธรกจของ ARM
จายคาลขสทธ (Royalty Fee)
จายคาใบอนญาต (Upfront License Fee)
SoC
รปท 3.6 รปแบบการดำเนนการธรกจของ ARM
108
Embedded Android Development สเสนทางนกพฒนา
เรมตนสการพฒนาบนระบบปฏบตการลนกซแบบฝงตว
ระบบปฏบตการลนกซทถกฝงเขาไปอยในบอรดสมองกลจะถกเรยกวา ระบบปฏบตการลนกซแบบฝงตว (Embedding Linux) ซงเปนระบบทถกปรบแตงเคอรเนลและโปรแกรมระบบใหสามารถทำงานไดบนสถาปตยกรรมของหนวยประมวลผลกลางของบอรดนนๆ ซงเรยกวธการนเปนทบศพทภาษาองกฤษวาการ “Porting” นอกจากนนในปจจบนกมบรษทจำนวนมากทขายผลตภณฑทมระบบปฏบตการลนกซแบบฝงตวอยภายใน และกยงมอกหลายกลมบรษทททำธรกจเกยวกบการใหบรการแบบองครวมทางดานการพฒนาระบบปฏบตการลนกซแบบฝงตว ไมวาจะเปนลนกซคอรเนลทถกปรบแตงพเศษ เครองมอการคอมไพลสำหรบสถาปตยกรรมตางๆ (Cross-development tools) และ ไลบรารทางดานการทำงานแบบเวลาจรง (Real time extensions) เปนตน ถอไดวาระบบปฎบตการลนกซนนเปนระบบปฏบตการทเหมาะสำหรบการทำงานทางดานระบบสมองกลฝงตวมากทสด เนองจากมโปรแกรมไลบรารตางๆ มชดเครองมอในการพฒนาทครบถวนเพยงพอสำหรบระบบสมองกลฝงตว
องคประกอบการเตรยมสภาพแวดลอมสำหรบ EMBEDDED LINUX
องคประกอบทนกพฒนาหรอผสนใจดานเทคโนโลยระบบสมองกลฝงตวควรทำความเขาใจดงแสดงในตารางขางลาง
ตาราง 3.2 องคประกอบสำคญพนฐานในการเตรยมสำหรบบอรดสมองกลฝงตว
องคประกอบ รายละเอยด
BSP (Board Support Package)ภายในบรรจตว bootloader และ Kernel ทรองรบและเขากนไดกบรน
ของฮารดแวรทใชในบอรดสมองกลฝงตวทเลอกใช
Cross Toolchains เครองมอพฒนาทสามารถแปลงรหสเพอใหทำงานขามแพลตฟอรมได
Third-party componentsไลบรารตางๆ และโปรแกรมพเศษจากนกพฒนาภายนอก ซงอาจจะม
ลขสทธการใชงาน เชน GPLv3, Apache, MIT เปนตน
109
Embedded Android Development สเสนทางนกพฒนา
องคประกอบ รายละเอยด
Hardware และ Accessories
- เครอง Host คอ เครองคอมพวเตอรทตดตงระบบปฏบตการลนกซ
สำหรบปรบแตงลนกซคอรเนลและคอมไพลโปรแกรมตางๆสำหรบบอรด target
- เครอง Target คอ บอรดสมองกลฝงตว เชน Beagleboard, Versatile Express, Pandaboard, ODROID, FriendlyARM เปนตน
- สาย Cable ตางๆ เชน LAN Cable, Serial Cable, USB-to-Serial เปนตน
- MMC/SD Card
สำหรบขนตอนสำคญของการพฒนาระบบสมองกลฝงตวนน สามารถแบงออกไดเปน 4 สวนหลกคอ
การเรมทำงานของบอรดสมองกลฝงตว: เนองจาก
บอรดสมองกลฝงตวจำเปนตองม bootloader ทมการตงคาเกยวกบตำแหนงของ Kernel Image, root file
system และคาพารามเตอรทจำเปน เพอใหบอรดสามารถบทเขาส ระบบปฏบตการลนกซแบบฝงตวได
สมบรณแบบ ซงถาบอรดเชอมตออยกบ Ethernet LAN กสามารถเขาสระบบผาน telnet หรอ ssh เขาไปได แต
อยางไรกตามในระหวางการพฒนาควรใช serial con-sole เพอใชสำรองการเชอมตอในกรณไมสามารถตอ
LAN ได
การตงคาและสราง Linux kernel: เนองจาก
บอร ดสมองกลฝ งต วส วน ใหญ ถ งแม จะม ประส ทธ ภาพส งแต ก ไม สามารถใช คอมไพล
Kernel ไดดวยขอจำกดของทรพยากรภายใน เชน หนวยความจำ พลงงานทจำกด ดงนนงานเหลาน
ทงหมดจะทำอยบนเครอง Host กอนจะ Porting เขาบอรดสมองกลฝงตว
การตงคาและสราง Root File System: ภายใน root
file system จะบรรจโปรแกรมของระบบและโปรแกรมสำหร บผ ใช ท สามารถทำงานก บ เคอร เนลและ
สถาปตยกรรมนนๆได ถาปราศจาก root file system แลวจะเกดเหตการณแสดงขอความดงน “Kernel
panic” และหยดทำงานในทสด ซงตำแหนงการวาง root file system นนมอยอยางนอย 2 แบบคอเกบไว
ใน Flash Storage เชน MMC, SDCard และเกบไวในระบบเครอขายเชน NFS
การคอมไพลและดบกโปรแกรม: เนองจากบอรด
สมองกลฝงตวไมสามารถคอมไพล Kernel ดวยตวเองได จงจำเปนตองทำอยบนเครอง Host ไมวาจะ
เปนการคอมไพลโปรแกรมดวยเคร องมอในการคอมไพลทเรยกกนวา Cross Toolchain หรอการ
ดบกโปรแกรมทกำลงทำงานบนบอรดสมองกลฝงตวดวย gdb เปนตน
โครงสรางสถาปตยกรรมของระบบปฏบตการลนกซแบบฝงตว จะไมแตกตางมากเมอเทยบกบระบบปฏบตการลนกซทวไป ดงแสดงในรปขางลาง
110
Embedded Android Development สเสนทางนกพฒนา
System call interface
โปรแกรม #1 โปรแกรม #2 โปรแกรม #3 โปรแกรม #N
C library
จดการโปรเซส จดการหนวยความจา
ควบคมอปกรณ ระบบไฟลตางๆ การสอสารระบบเครอขาย
ชนดระบบไฟล
Block device drivers
Networkdevice drivers
Characterdevice drivers
CPU/MMU support code
CPUsupport code
User-space
Kernel-space
Hardware
รปท 3.7 สถาปตยกรรมภายในระบบปฏบตการลนกซ
จากโครงสรางขางตน แตละชนมรายละเอยดดงน1. Hardware Layer - อปกรณฮารดแวรภายในบอรด ตวอยางเชน หนวยประมวลผลขนาด 32 บตขนไป หนวยจดการหนวยความจำ (MMU - Memory Management Unit) หนวยความจำขนาดเลก (RAM) หนวยความจำแบบอานไดอยางเดยว (ROM) ตวบนทกขอมลประเภทแฟลช เชน MMC/SD Card เปนตน
2. Linux Kernel Layer (Kernel-space) - ทำหนาทควบคมจดการอปกรณฮารดแวรทงหมด จดการการจดควของโปรเซสตางๆ จดเตรยมฟงกชนสำคญ (System Calls) ใหกบโปรแกรมประยกต เปนตน ซงจะมองคประกอบภายในทมหนาทสำคญๆ ไดแก
•Low-level interfaces:- จดเตรยมชด APIs (Application Programming Interface) สำหรบการตดตอกบฮารดแวร แบบทไมขนอยกบรนของฮารดแวร
- เปนสวนดแลและจดการฮารดแวรตางๆเชน การทำงานของหนวยประมวลผลกลาง การทำงานของหนวยความจำ ตดตอกบพอรตสอสาร และ I/O Devices เปนตน
• High-level abstractions:- จะจดเตรยมฟงกชนใหโปรแกรมประยกตสามารถสอสารระหวางกนได และทำงานแบบ
multi-tasking ได เชน IPC, Threading, Socket, Signalling เปนตน - โคดโปรแกรมสวนใหญสามารถนำไปใชตอไดเกอบทกสถาปตยกรรม
• Filesystems:- สามารถรองรบระบบ filesystems ตางๆทมอยในปจจบนไดไมนอยกวา 40 ชนด
111
Embedded Android Development สเสนทางนกพฒนา
- จะม Virtual Filesystem layer ททำใหการเรยกใช filesystems ทแตกตางเหลานนงายและสะดวกขนโดยทไมตองเขยนโคดใหม
• Networking protocols- รองรบโปรโตคอลมาตราฐานตางๆทใชกนอยในปจจบนไดไมนอยกวา 50 ชนด- มฟงกชน Socket APIs ทใชในการจดการและกำหนดการเชอมตอในแตละแบบของระบบเครอขายนนๆ
3. Libraries (User-space) - ไลบรารทอยในระดบของ user space ทมความหลากหลายมากกวาทมอยในเคอรเนล ไมวาจะเปนไลบรารทางดานการคำนวณ การแสดงผลกราฟฟก การประมวลผลขอมลดจตอล การสอสารขอมลผานระบบเครอขาย การเขารหส/ถอดรหส และ การตดตอกบอปกรณฮารดแวรทมาเชอมตอกบบอรด เปนตน ดงนนถาโปรแกรมประยกตตองการจะตดตอกบเคอรเนลจะเรยกผานไลบรารชอวา glibc (ซงประกอบไปดวยตวยอยคอ uClibc และ eglibc)
การเตรยมระบบและการเชอมตอระหวางเครอง HOST และ บอรด TARGET
การเตรยมระบบสำหรบการพฒนาโปรแกรมหรอระบบปฏบตการสำหรบระบบสมองกลฝงตวนน จะตองมการเตรยมระบบฮารดแวร ซงประกอบไปดวยฮารดแวร 2 สวนหลกๆไดแก
1. เครองคอมพวเตอรสำหรบพฒนาหรอเรยกวาเครอง “Host” (ซงกเปนเครองคอมพวเตอรสวนบคคลทวไป)
2. บอรดสมองกลฝงตวหรอเรยกวาบอรด “Target”รปแบบการเชอมตอกนระหวางเครอง Host และบอรด Target นนมอยางนอย 3 แบบคอ
• สายอนกรม RS-232 (RS-232 Serial Cable) เพอใหนกพฒนาสามารถดรายละเอยดการบทของบอรด ในขณะทเรมตรวจสอบคาในระดบ low level การโหลดตว Kernel และการโหลดตว root file system เรยกหนาจอแสดงผลนวา “Console”
• สาย LAN (Ethernet LAN Cable) เพอใหนกพฒนาสามารถวาง Kernel Image และ Root file system ไวบนเครองภายในระบบเครอขาย ผานโปรโตคอล bootp, tftp หรอ NFS เปนตน ในกรณทบทเขาสระบบปฏบตการลนกซแบบฝงตว (Embedded Linux) ภายในบอรดไดแลว ถาไมตองการดผานหนาจอ Console กสามารถเขาสระบบแบบระยะไกล (Remote Login) ผานโปรแกรม telnet หรอ ssh ไดเชนกน
• สาย JTAG (JTAG Cable) ใชในกรณทนกพฒนาตองการดบกการทำงานของโปรแกรม คารจสเตอร และรายละเอยดภายในหนวยความจำของบอรดสมองกล เปนตน
112
Embedded Android Development สเสนทางนกพฒนา
เครอง Host
Ethernet Hub
บอรดสมองกลฝงตว (Target)
สาย RS-232
สาย LAN
ARM, PowerPC, MIPS(Linux OS)
x86, x86_64 (Desktp OS)
สาย LAN
รปท 3.8 แสดงการตอสำหรบการพฒนาระหวางเครอง Host และบอรด Target
จากรปดานบนแสดงการเชอมตอระหวางเครอง Host และบอรด Target โดยภายในเครอง Host จะมระบบปฏบตการลนกซ (เชน Ubuntu, Red Hat, Fedora, SuSE หรอ Debian เปนตน) และเครองมอหรอโปร แกรมอตถประโยชน (เชน Serial Console Software, Cross Toolchain, Network shar-ing Software) สำหรบการพฒนาระบบสมองกลฝงตวอยภายในโดยถกเชอมตอผานสายอนกรม (RS-232 Cable) เรยบรอยแลว ซงในปจจบนเครองคอมพวเตอรหรอโนตบคสวนใหญจะไมมพอรตอนกรมใหอกแลว แตจะมการเตรยมพอรต USB มาใหแทน ดงนนนกพฒนาจะตองจดหาสาย USB-to-Serial มาเพมเตมเพอใหสามารถตอเขากบบอรด Target รวมทงจะตองเชอมตอระบบเครอขายภายในเขากบอปกรณเครอขายเชน Ethernet Hub หรอ Switch Hub
กอนเรมบทบอรดสมองกลฝงตวและเหนการแสดงผลตางๆผานหนา Serial Console บนเครอง Host ไดนนนกพฒนาจะตองมโปรแกรม Serial Console ตวอยางเชนโปรแกรม Minicom, Picocom, Gtkterm, Putty, Cutecom ทสามารถตดตอกบพอรตอนกรม (Serial Port) หรอพอรต USB โดยระบบปฏบตการลนกซจะมองเหนเปน /dev/ttySx หรอ /dev/ttyUSBx ยกตวอยางการใชโปรแกรม mini-com และ Gtkterm ดงขางลางน
$ minicom -b 115200 /dev/ttyS0 หรอ $ minicom -b 115200 /dev/ttyUSB0
113
Embedded Android Development สเสนทางนกพฒนา
หรอใชโปรแกรม Gtkterm เพอเปด Serial Console ดงแสดงในรปขางลาง
114
Embedded Android Development สเสนทางนกพฒนา
115
Embedded Android Development สเสนทางนกพฒนา
เครองมอ Cross Toolchains
ระบบปฏบตการลนกซไดจดเตรยมเครองมอพนฐานสำหรบการพฒนาไวเบองตนอยแลวซงเรยกวา “Native Toolchain” ซงตว native toolchain จะเปนเครองมอหลกในการสรางรหสโปรแกรมทใหสามารถทำงานได บนแพลตฟอรมของเครองคอมพวเตอรนนๆ (เชน x86 Platform) แตในกรณการพฒนาโปรแกรมสำหรบระบบสมองกลฝงตวนน ไมสามารถใช native toolchain ทมากบระบบปฏบตการได เนองจากระบบสมองกลฝงตวมขอจำกดในเรองของขนาดหนวยความจำและการเกบขอมล การทำงานชากวาเครองคอมพวเตอรสวนบคคลและทสำคญไมสามารถจะตดตงเครองมอพฒนาทงหมดใหอยบนระบบสมองกลฝงตวได
ดงนนตองใชเครองมอพฒนาทสามารถแปลงรหสเพอใหสามารถใชขามแพลตฟอรมไดซงจะถกเรยกวา “Cross-compiling Toolchain” หรอ “Cross Toolchains” ดงรปขางลางแสดงใหเหนวา cross-compiling toolchain จะคอมไพลโปรแกรมทเขยนขนมาใหสามารถทำงานไดบนสถาปตยกรรมนนๆ (เชน สถาปตยกรรม ARM) ตามทถกตงคาไวกอนเรมทำการคอมไพล ดงตวอยางขางลาง
$ export ARCH=ARM$ export CROSS_COMPILE=arm-linux-gnueabi-$ make
โคดโปรแกรม
Native toolchain Cross-compilingtoolchain
ARM binaryx86 binary
เครอง Host (x86)
บอรด Target (ARM)เครอง Host (x86)
รปท 3.9 แสดงการคอมไพลโคดโปรแกรมสำหรบแพลตฟอรมทง 2 แบบ
116
Embedded Android Development สเสนทางนกพฒนา
ประเภทของ CROSS TOOLCHAINS
ในปจจบนนมเครองมอ cross toochains ทชวยในการพฒนางานดานสมองกลฝงตวอยหลายตว โดยอาจแบงออกไดเปน 2 กลมใหญๆ ไดแก
1. Toolchains สำเรจรป
•CodeSourcery (http://www.codesourcery.com/)
CodeSourcery เปนตวทออกแบบเพอใหสามารถใชกบ Sourcery G++ และ Eclipse IDE ททำงานรวมกนกบ GNU Toolchain (gcc, gdb เปนตน) ทรองรบสถาปตยกรรม ARM, Coldfire, MIPS, SuperH และ PowerPC
• Linaro (http://linaro.org/)
Linaro เปนองคกรทไมแสวงหากำไร ซงเปนการรวมตวกนของเหลาวศวกรมอด เพอรวมกนสรางและปรบแตง open source และเครองมอตางๆ ใหกบสถาปตยกรรม ARM ทาง Linaro เองกไดจางคนทพฒนา CodeSourcery เพอเนนใหเปนเครองมอทเหมาะกบสถาปตยกรรม ARM ใหมากทสด
•DENX ELDK (http://www.denx.de/)
DENX Embedded Linux Development Kit (ELDK) จะเปนชดเครองมอทเหมาะกบระบบสมองกลฝงตวททำงานแบบเวลาจรง (real-time) บนสถาปตยกรรม ARM, PowerPC และ MIPS ชดเครองมอทสามารถใชไดฟรตามเงอนไข GPL และ Free Software Licenses ประกอบไปดวย Cross Development Tools (Compiler, Assembler, Linker เปนตน), Native Tools (Shell, commands และ libraries), U-Boot, Linux kernel ทมโคดโปรแกรม ไลบรารสำหรบบอรดสมองกล, Xenomai (RTOS Emulation framework) และ SELF (Simple Embedded Linux Framework)
• Scratchbox (http://www.scratchbox.org/)
Scratchbox เปนเครองมอทใชในการพฒนา Maemo (Nokia 770, N800, N810 Internet Tab-lets และ Nokia N900) ซงเนนสนบสนนสถาปตยกรรม ARM และ x86
2. Toolchain ทตองสรางเอง
•Buildroot (http://buildroot.uclibc.org/)
Buildroot เปนเครองมอทสมบรณทนยมตวหนงสำหรบการพฒนาในระบบสมองกลฝงตว และรองรบสถาปตยกรรมหลากหลาย นกพฒนาสามารถสราง RFS image (Root File System Image) ทพรอมจะสามารถเขยนลงแฟลช (flash) ไดทนท นอกจากนนยงสามารถปรบแตงหรอเพมเตม open
117
Embedded Android Development สเสนทางนกพฒนา
source อนเขาไปใน RFS Image ได โดยตว buildroot นจะสนบสนนไลบรารเพยง uClibc แตไมสนบสนนไลบราร glibc
•Crosstool-NG (http://crosstool-ng.org/)
Crosstool-NG เปนเครองมอพฒนาทไดรบความนยมไมแพตว buildroot โดยมรปแบบในการปรบแตงเคอรเนลผาน make menuconfig เชนเดยวกบตว buildroot สามารถรองรบไดทง uClibc และ glibc และมาพรอมกบเครองมอในการดบกโปรแกรม เชน gdb, strace, dmalloc
• Bitbake
Bitbake คอเครองมออยางงายทใชในการสรางชดแพกเกต ซงถกนำมาใชในโครงการ OpenEm-bedded เชน บอรด Ångström เปนตน
อางองมาจาก: http://www.wikipedia.com
องคประกอบหลกภายใน CROSS TOOLCHAINS
รายละเอยดภายในเครองมอ cross toolchains ทจะตองนำมาใชในการตงคาการคอมไพลตวซอรสของลนกซคอรเนล โปรแกรมทจำเปนสำหรบระบบสมองกลฝงตว (เชน BusyBox, Openssh, Di-rectFB เปนตน) และไลบรารทเกยวของตางๆ ประกอบไปดวย
• Binutils - เปนชดเครองมอทเอาไวใชในการสรางและจดการไบนารภายในโปรแกรมเพอใหเหมาะกบสภาพแวดลอมบนสถาปตยกรรมนนๆตวอยางคำสงไดแก as (Assembler), ld (Linker), ar, ranlib (สำหรบสรางไลบรารแบบ static), objdump, readelf, size, nm, strings, strip เปนตน
• GCC Compiler - ชด GNU C Compiler ซงเปนชดทแจกฟรสำหรบใชในการคอมไพลภาษาโปรแกรมตางๆ เชน C, C++, Ada, Fortran, Java, Objective-C, Objective-C++ เปนตน เพอใหสามารถทำงานไดบนสถาปตยกรรมทหลากหลายเชน ARM, AVR, Blackfin, CRIS, FRV, M32, MIPS, MN10300, PowerPC, SH, v850, i386, x86_64, IA64, Xtensa เปนตน
• C/C++ Libraries - เปนชดไลบรารทมความสำคญตอระบบปฏบตการลนกซเปนอยางมากซงทำหนาทเปนตวกลางในการเชอมตอระหวางโปรแกรมและลนกซคอรเนลสำหรบการพฒนาในระบบสมองกลฝงตว C Libraries มอยหลายแบบเชน glibc, uClibc, eglibc, dietlibc, newlib เปนตน
• GDB Debugger - GDB เรมพฒนาโดยนายรชารด สตอลแมน เมอ พ.ศ. 2529 เพอใหเปนสวนหนงของระบบ GNU หลงจากทเขาพฒนา GNU Emacs จนมความเสถยรในระดบทนาพอใจ ซงแนวความคดของ GDB นนไดมาจาก Dbx ซงเปนโปรแกรมดบกเกอรทมากบระบบปฏบตการ Unix BSD และในปจจบน GDB กไดถกดแลโดย GDB Steering Committee ซงเปนคณะกรรมการทถกตงโดยมลนธซอฟตแวรเสร (FSF) โดย GDB จะทำงานในแบบการพมพคำสง (command line)
118
Embedded Android Development สเสนทางนกพฒนา
ผานหนาจอ Console แตถาหากตองการดบกผานโปรแกรมในลกษณะกราฟฟก (GUI) กสามารถใชโปรแกรมชอวา DDD แทนได ซงโปรแกรมนจะทำการเรยกใชคำสงของ GDB อกตอหนง
รปขางลางเปนตวอยางการนำชดเครองมอ Buildroot มาใชในการสรางและประกอบลนกซเคอรเนล ไลบรารและโปรแกรมประยกต เพอนำไปฝงเขาไปในบอรดสมองกลทมสถาปตยกรรม ARM ตอไปได
บอรด Target (ARM)
Pre-compiled ToolchainOpensshsource
BusyBoxsource
DirectFBsource
specific Librarysource
Kernelsource
gcc binutils
gdb Libc
Target File System
Openssh BusyBox
SpecificLibrary DirectFB
Application
Kernel Image
เครอง Host (x86)Toolchain
Opensshheaders & lib
DirectFBheaders & lib
Specific Library headers & lib
gcc
gdb
binutils
Libc
Host's utilities เชน pkg-config..
Buildroot
Input
Output
รปท 3.10 แสดงรายละเอยดโปรแกรมตางๆ และผลลพธจากการสรางระบบไฟลดวย Buildroot
119
Embedded Android Development สเสนทางนกพฒนา
ขนตอนการเตรยมระบบสำหรบพฒนาบน Embedded Linux
ในการเตรยมระบบนนจะมองคประกอบสำคญทตองเตรยมไวสำหรบตดตงลงไปในเครอง Host และบอรด Target ภายใต Embedded Linux ซงประกอบไปดวย
เครองคอมพวเตอร (Host)
Tools
บอรดสมองกลฝงตว (Target)
Compiler
Debugger
IDE
โปรแกรม
ระบบไฟล
Kernel
โปรแกรม
Bootloader
ไลบราร ไลบราร
รปท 3.11 องคประกอบสำคญภายในเครอง Host และบอรด Target
1) การเตรยมและตดตงชดเครองมอ Cross-compiling toolchains เพอไวสำหรบตดตงไลบรารทเกยวของ สำหรบการคอมไพลโคดตางๆทจะถกใชบนบอรดสมองกลฝงตว
2) การเตรยมและตดตง Bootloader เขาไปในบอรดสมองกลฝงตวเพอใหถกเรยกใชงานในครงแรก ตงแตเรมจายไฟเลยงใหบอรด โดยตว bootloader จะโหลดคาพนฐานตางๆทตองเรมตนสถานะการทำงานใหกบฮารดแวรภายในบอรดแลวจงจะโหลดเคอรเนลเพอเรมเขาสระบบปฏบตการลนกซแบบฝงตว เปนลำดบตอไป
3) ลนกซเคอรเนลซงเปนเคอรเนลทถกตงคาและปรบแตงใหเหมาะสมและสามารถทำงานเขากนไดกบสถาปตยกรรมภายในบอรดสมองกลฝงตวโดยไดบรรจตวจดการโปรเซส ตวจดการหนวยความจำ ตวจดการการเชอมตอระบบเครอขาย device drivers และบรการตางๆสำหรบโปรแกรมประยกตทตองการเรยกใชงาน
4) Filesystem หรออาจใชคำวา Root file system ซงภายในไฟลนจะบรรจโปรแกรมระบบ โปรแกรมประยกตทสำคญตางๆและโปรแกรมทถกพฒนาขนมาเอง นอกจากนนกยงมไลบรารและคำสงสครปททเตรยมไวสำหรบการเรยกใชงานจากโปรแกรมประยกตภายในระบบปฏบตการลนกซแบบฝงตวบนบอรดสมองกล
120
Embedded Android Development สเสนทางนกพฒนา
การเตรยมสภาพแวดลอมใหกบเครอง HOST
ระบบปฏบตการลนกซเชนตว Ubuntu ทอยในเครอง Host ในเบองตนถงแมวา Ubuntu จะมการ
จดเตรยมสภาพแวดลอมสำหรบการใชงานแกผใชในแตละระดบอยบางแลวกตามท แตสำหรบงานพฒนา
บนระบบสมองกลฝงตวนนกยงตองมโปรแกรมและไลบรารสำหรบการพฒนาภาษาโปรแกรมใหทำงานได
บนสถาปตยกรรมอนๆ รวมทงอาจจะตองมเครองมอพเศษเพมเตมทตองตดตงเขาไป อยางเชน auto-conf automake libtool libncurses5-dev ncurses-dev bison flex patch curl cvs texinfo build-essential subversion python-dev
texi2html nfs-kernel-server tftp minicom gtkcom เปนตน การพฒนาอยบน
เครอง Host นนบางครงนกพฒนาอาจจะไมจำเปนจะตองใสสทธ super user (หรอ root) ในการตงคา
(Configuration) การคอมไพล (Make) แตในบางกรณกจำเปนตองใชสทธในฐานะ root เชน การสราง
device node สำหรบใชใน root file systems (คำสง mknode) การตดตงโปรแกรมหรอไลบรารเพม
เตมดวยชดคำสง APT การตงคาบรการระบบเครอขาย (/etc/init.d/nfs-kernel-server,
/etc/init.d/networking)หรอการตดตงไลบราร/เครองมอจากโปรเจคภายนอก (make in-
stall)
แตอยางไรกตามสทธ root นนกเรมมความจำเปนนอยลงเรอยๆ เนองจากเรมมชดโปรแกรมทชวย
อำนวยความสะดวกในการพฒนาระบบสมองกลฝงตวแบบกงสำเรจรปใหใชมากขน ตวอยางเชน Buil-
droot, CodeSourcery (Sourcery G++ Lite), Linaro, crossTool NG เปนตน
ตวอยางขางลางนแสดงขนตอนการตดตงชดโปรแกรมเครองมอและชดโปรแกรมสำเรจรปพนฐานเพมเตม
ใหกบ Ubuntu
$ sudo apt-get install autoconf automake libtool libncurses5-dev ncurses-dev bison flex patch curl cvs texinfo build-essential subver-sion python-dev g++ gcc texi2html nfs-kernel-server tftp minicom gtkterm
ตวอยางการตดตงเครองมอทจะชวยในการพฒนาระบบสมองกลฝงตวดวย Buildroot ดงรปขางลาง
$ wget http://buildroot.uclibc.org/downloads/buildroot-2013.05.tar.gz$ tar -xzvf buildroot-2013.05.tar.gz $ cd buildroot-2013.05/ $ make menuconfig
121
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการตดตงเครองมอชอวา Sourcery G++ Lite ดงรปขางลาง$ wget http://www.codesourcery.com/sgpp/lite/arm/portal/package6490/public/arm-none-linux-gnueabi/arm-2010q1-202-arm-none-linux-gnueabi.bin$ chmod 755 arm-2010q1-202-arm-none-linux-gnueabi.bin$ ./arm-2010q1-202-arm-none-linux-gnueabi.bin
ตวอยางการตดตงเครองมอชวยในการพฒนาระบบสมองกลฝงตวดวย Croostool-NG ดงรปขางลาง$ mkdir -p ctool-ng$ cd ctool-ng/
122
Embedded Android Development สเสนทางนกพฒนา
$ wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.18.0.tar.bz2$ tar -xjvf crosstool-ng-1.18.0.tar.bz2 $ cd crosstool-ng-1.18.0/$ ./configure$ make$ sudo make install$ ct-ng list-samples$ ct-ng arm-unknown-linux-gnueabi$ ct-ng menuconfig
TOOLCHAIN OPTIONS ทสำคญในระหวางการใชชดโปรแกรม toolchain นนนกพฒนาอาจจะตองมการกำหนดคาสำคญคาหนงท
เรยกวา ABI (Application Binary Interface) ซงเปนมาตรฐานหนงทถกพฒนาโดยบรษท ARM รวมกบบรษทพนธมตร โดยท ABI นนจะเปนการระบวธการเชอมตอและเรยกใชในระดบลางระหวางโปรแกรมและระบบปฏบตการหรอระหวางโปรแกรมดวยกนเองตวอยางเชน รปแบบขอมลไฟล การผานคาอารกวเมนต/การสงคากลบระหวางฟงกชน การจดเรยงคาภายในโครงสรางแสตกขอมล การเรยกใชรจสเตอร เปนตน
ดงนนจำเปนอยางยงทจะตองระบชนด ABI ทจะใชภายในเคอรเนลและโปรแกรมททำงานอยภายใตระบบปฏบตการลนกซแบบฝงตวเดยวกน ซงในปจจบนสถาปตยกรรม ARM จะนยมใช ABI ทเรยกวา EABI (Embedded Application Binary Interface) เปนตวหลกในการเชอมตอและเรยกใชในระดบลาง
นอกจากนนนกพฒนาควรจะทำความเขาใจในการตงคา Floating Point เน องจากบางสถาปตยกรรมรองรบการคำนวณแบบ floating point ไดในระดบฮารดแวรแตบางสถาปตยกรรมอาจจะ
123
Embedded Android Development สเสนทางนกพฒนา
ไมไดรองรบ (ไมม Floating Point Unit - FPU) แตจะถกตงคาใหใชการจำลองการคำนวณ floating point ในระดบซอฟทแวรแทน เชน สถาปตยกรรม ARMv4 และ สถาปตยกรรม ARMv5 ซงถาถกตงคาใหรองรบการคำนวณแบบ floating point ตว toolchain เองจะทำการสราง hard float code เพอเรยกใชชดคำสง floating point ใหโดยตรงดวยพารามเตอร -mfloat-abi=hard ในกรณทไมม FPU กจะถกตงคาเปน -mfloat-abi=softfp แทนและสดทายเพอไมใหเกดปญหาในระดบลางกจะตองตงคาใหถกตองกบรนสถาปตยกรรมนนๆ โดยสามารถระบพารามเตอรตามสถาปตยกรรมและรน ARM Core เพมเตมโดยการตงคาดงน -march=armv7 -mcpu=cortex-a8
Bootloadersbootloader เปนสวนสำคญอกสวนหนงของระบบสมองกลฝงตวทมหนาทในการเตรยมการให
ระบบฮารดแวรพนฐาน (Hardware Initialization) เชน หนวยประมวลผลกลาง (CPU) หนวยความจำ (DRAM) และ MMC Controller ใหพรอมทจะทำงานได ในขนตอนตอมากจะทำการโหลด Kernel image (bzImage, zImage) ทถกบบอดและเกบอยในอปกรณจดเกบขอมล (เชน MMC/SD card, NAND Flash, USB Storage หรอผานระบบเครอขายดวยโปรโตคอล tftp NFS เปนตน) หลงจากนนกจะทำการแตกโปรแกรมไบนารทถกบรรจอยภายใน Kernel image ทถกบบอดนนอย เพอนำไปโหลดขนสหนวยความจำภายใน (RAM) เพอตดตอกบอปกรณอนๆ เชน พอรต Ethernet หรอ พอรต USB เปนตน ในระหวางการทำงานของ Bootloader นนสามารถทจะเขาสหนาตางคอนโซล (console) เพอเรยกใชชดคำสงทเตรยมไวให เชนการดาวนโหลดขอมลผานระบบเครอขายหรอจากอปกรณจดเกบขอมลทางดานตรวจสอบสถานะของหนวยความจำ ตรวจสอบสถานะการทำงานของฮารดแวรภายใน เปนตน
เพอใหนกพฒนาไดเหนภาพมากขนจงขอสรปขนตอนการทำงานของ bootloader ตงแตเรมบทเขาระบบของบอรดสมองกลฝงตวไดดงน (ดงแสดงในรปท 3.12 และ 3.13)
1.หนวยประมวลผลกลางจะเรมอานทตำแหนงของหนวยความจำ ROM ทไดถกกำหนดไว และดำเนนการทำตามชดคำสงภายในโคดทถกเกบอยภายใน
2.เรมตนเตรยมระบบฮารดแวรพนฐานสำคญ เชน หนวยประมวลผลกลาง สวนควบคมหนวยความจำ (SDRAM Controller) สวนควบคมตวบนทกขอมล (MMC Controller) สวนควบคมอนพท/เอาทพท (I/O Controllers) และ สวนควบคมการแสดงผล (Graphics Controllers) เปนตน
3.เรมตนเตรยมระบบหนวยความจำ SDRAM โดยการจดสรรพนทภายในหนวยความจำใหกบฟงกชนทจะใชควบคมฮารดแวรของแตละสวน และจดสรรพนทใหกบตวเคอรเนลทถกเกบอยภายในอปกรณบนทกขอมล
124
Embedded Android Development สเสนทางนกพฒนา
4.เมอเคอรเนลไดถกโหลดขนหนวยความจำ SDRAM แลว จะทำการตดตอและตรวจสอบสถานะการทำงานของฮารดแวรสวนทเหลอทงหมดเพอเตรยมทำการโหลดระบบปฏบตการในสวนทเหลอทเรยกวา root file system ซงบรรจสครปท ไลบราร และโปรแกรมตางๆเอาไว
5.เมอ root file system ถกโหลดไดสำเรจ ระบบปฏบตการกจะเรยกโปรแกรมระบบพนฐานทงหมดทเกยวกบการจดการระบบไฟล (file system) โปรแกรมจดการโปรเซส (process) โปรแกรมจดการลำดบการทำงานของโปรเซส (process scheduling) และเตรยมระบบสำหรบผใชเพอสามารถใชโปรแกรมประยกตภายในระบบปฏบตการสมองกลฝงตว
หนวยความจา Flash SDRAM
หนวยประมวลผลกลางROM
อปกรณรอบขาง
1st Boot: (ROM boot)- อานการตงคาระบบพนฐานตางๆ เชน ความเรวหนวยประมวลผลกลาง, ตาแหนงหนวยความ-จาตางๆ เปนตน- อานขอมลจากหนวยความจา Flash ไปยง SDRAM- เรยกขอมลจาก SDRAM
2nd Boot: (Boot loader)- ทาการตงคาการทางานระบบพนฐานตางๆ เชน ความเรวหนวยประมวลผลกลาง, ความเรวบส, ขนาดบส เปนตน - คนหาเพอตงคา และทดสอบการทางานของอปกรณรอบขาง- รนสครปทการบต (boot script) และรนคอนโซล
รปท 3.12 ขนตอนการบทระบบ
ขนตอนการทำงานเรมตนของลนกซคอรเนล (Kernel Initialisation)
Bootloader
เรมตนการทางานในระดบลาง (ฮารดแวร) แลว
ทาการโหลด Kernel ขนหนวยความจา
เรมการทางานของ Kernel
init process
เรมตนการทางานของโปร เซสระบบ และโปรเซสในระดบ user-space
รปท 3.13 ขนตอนการเรมตนของ Linux Kernel
ตวอยางขนตอนการทำงานจรงของ bootloader บนบอรดสมองกลฝงตวทใช OMAP3 SoC ของบรษท TI ดงแสดงในรปขางลาง
125
Embedded Android Development สเสนทางนกพฒนา
ROM Codeถกเกบอยใน ROM (ภายใน CPU)
X-Loaderถกเกบอยใน NAND หรอ MMC และถกโหลด
เขาเพอรนจาก SDRAM
U-Bootถกเกบอยใน NAND หรอ MMC และถกโหลด
เขาเพอรนจาก SDRAM
Linux Kernelถกเกบอยใน NAND, MMC หรอ ระบบเครอขาย และถกโหลดเขาเพอรนจาก SDRAM
ROM Code:เกบการตงคาระบบพนฐานทสำคญ และคนหา bootstrap image จากตวเกบขอมลตางๆ เพอโหลดเขาไปในหนวยความจำ SDRAM โดยขนาดโคดจะไมเกน 64 KB
X-Loader: ไฟลชอ MLOอานการตงคาจากหนวยความจำ SDRAM แลวทำการโหลด bootloader เขามาใน SDRAM เพอทำการตงคาระบบพนฐานตางๆ
U-boot: ไฟลชอ u-boot.binทำการตงคาอปกรณตางๆ เชน USB, Ethernet เปนตน หลงจากนนจะโหลด Kernel image จากตวอปกรณเกบขอมลหรอจากตวเกบขอมลผานระบบเครอขาย ขนหนวยความจำ SDRAM แลวเขาส shell ของ bootloader
Linux Kernel: ไฟลชอ zImageถกรนจากหนวยความจำ เพอเขาสระบบปฏบตการลนกซ ซงไมจำเปนตองใช bootloader อกตอไป
รปท 3.14 แสดงขนตอนการทำงานของ bootloader บน OMAP3 SoC
รายละเอยดภายใน KERNEL IMAGE ทใชในบอรดสมองกลฝงตวไฟลสำคญตางๆทถกสรางหลงจากการคอมไพลลนกซเคอรเนลไดแก Kernel image (เชน
bzImage, zImage) และ root file system (RFS) ซงไฟล Kernel image จะถกนำมาบรรจลงอยในบอรดสมองกลเพอทำหนาทตามขนตอนทไดอธบายไปกอนหนาน แตกอนทจะกลายมาเปนไฟล Kernel image ไดนนจะถกประกอบมาจากไฟลไบนารตางๆ ทถกเกบอยในไดเรกทอร <linux version>/arch/arm/boot/compressed/ ดงตวอยางผลจากการคอมไพลดวยเครองมอ buildroot สำหรบสถาปตยกรรม ARM ทใช SoC รน Versatile
$ ls ~/buildroot/output/build/linux-3.9.4/arch/arm/boot/compressedashldi3.o head-shark.S misc.c piggy.xzkern.Sashldi3.S head-sharpsl.S misc.o sdhi-sh7372.catags_to_fdt.c head-shmobile.S mmcif-sh7372.c sdhi-shmobile.cbig-endian.S head-xscale.S ofw-shark.c sdhi-shmobile.hdecompress.c lib1funcs.o piggy.gzip string.cdecompress.o lib1funcs.S piggy.gzip.o string.ohead.o libfdt_env.h piggy.gzip.S vmlinuxhead.S ll_char_wr.S piggy.lzma.S vmlinux.ldshead-sa1100.S Makefile piggy.lzo.S vmlinux.lds.in
126
Embedded Android Development สเสนทางนกพฒนา
จากรปขางลางแสดงรายละเอยดของการประกอบไฟลไบนารทมหนาทแตกตางกนไป โดยนำคำสงของชดเครองมอ Binutils มาใชประกอบในแตละขนตอนจนไดมาเปนไฟล Kernel image ทถกบบอดในชอวา zImage ในทสด
vmlinux Imagepiggy.gz
piggy.gzip.S
piggy.gzip.o
head.o
misc.o
head-cpu.o
decompress.o
libfuncs.o
vmlinuxzImage
objcopy gzip as ld objcopy
Raw kernel executable
(ELF object)
Stripped kernel binary
(binary object)Compressed kernel binary
asm wrapper + bootstrap code
compositekernel image(ELF object)
kernel imagefor bootloader(binary object)
รปท 3.15 ขนตอนการสรางไฟล Kernel Image
Linux File Systems
VIRTUAL FILESYSTEMS
ระบบไฟลเสมอนหรอเรยกอกชอวา Virtual Filesystem Switch (VFS) ไดเตรยมชดการเชอมตอหรอฟงกชนสำหรบการเขาถงทรพยากรระบบ (System Call Interface) ระหวางโปรแกรมในสวนผใช (user-space) และระบบไฟลทแตกตางกนของอปกรณเกบขอมล เพอไมตองใหนกพฒนาตองพยายามทำความเขาใจในรายละเอยดทางดานเทคนคเชงลกภายในระบบไฟลของอปกรณเกบขอมลชนดนนๆ (ระบบไฟล Ext3 ในฮารดสก หรอ ระบบไฟล ISO 9660 ในซดรอม เปนตน) ซงสถาปตยกรรมของระบบไฟลภายในระบบปฏบตการลนกซนนถอไดวาเปนตวอยางทนาสนใจอยางยงทสามารถจดการความซบซอนในการเขาถงระบบไฟลทมหลายหลากในปจจบนใหกลายเปนเรองงายในการเรยกใชงาน (abstrac-tion layer) ซงจะจดเตรยม uniform interface สำหรบระบบไฟลของอปกรณเกบขอมลชนดตางๆ เชน ext3 NTFS (ฮารดดสก) CDFS (ซดรอม) NFS/CIFS (Network Interface Card) และ USBFS (USB Storage) เปนตน ดงแสดงในรปขางลาง
127
Embedded Android Development สเสนทางนกพฒนา
ผใช
Block layer / Device drivers
Abstraction layer
ext3 NTFS CDFS NFS/CIFS USBFS
รปท 3.16 แสดงโครงสรางของชน Virtual Filesystem
ฟงกชนพนฐาน (system call functions) ทระบบปฏบตการลนกซไดเตรยมไวใหตวอยางเชน ฟงกชน read() ทสามารถอานขอมลออกมาเปนไบตจากไฟลทถกเกบอยในอปกรณเกบขอมลโดยไมตองสนใจวาอปกรณเกบขอมลนนใชระบบไฟลชนดใด แตจะเปนหนาทของลนกซคอรเนลซงอยในโปรแกรมระดบ kernel-space เองทจะเขาถงระบบไฟลวาจะตองใชเทคนคในการอาน/เขยนอยางไร ตามรปแบบมาตราฐานโปรโตคอลของเทคโนโลยนนๆ ดงแสดงในรปขางลาง
Linux Kernel
Virtual File System (VFS)
Filesystem drivers
Block device drivers
โปรแกรม GNU C Library
User-space
Kernel-space
read()
syscall(SYS_read)
รปท 3.17 ตวอยางการเรยกใชฟงกชน (system call) ของ Virtual Filesystem
พารทชน (partition) คอสวนของพนท ทอาจจะถกแบงเปนตวบนทกขอมลเสมอน (logical disk) อยบนพนทของอปกรณจดเกบขอมล (physical disk) เชน ฮารดดสหรออปกรณชนด flash memory ซงพนทของพารทชนจะเปนสวนเกบขอมลของระบบไฟลทเรยกกนวา file system ดงแสดงในรปขางลาง
128
Embedded Android Development สเสนทางนกพฒนา
PartitionFile System Metadata
File System Data
Flash MemoryโครงสรางPartition
รปท 3.18 โครงสรางภายในพารทชนของหนวยความจำแฟลช
หากตองการทราบรายละเอยดตางๆภายในเครองวามการแบงพนทเปนกพารทช นและเปนชนดใด สามารถใช คำสง fdisk ซงคำสงนสามารถตรวจสอบชนดของพารทชนทมอยในปจจบนไดไมนอยกวา 90 ชนด ดงตวอยางการใชงานขางลาง
$ sudo fdisk -lDisk /dev/sda: 107.4 GB, 107374182400 bytes255 heads, 63 sectors/track, 13054 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x00000c74
Device Boot Start End Blocks Id System/dev/sda1 * 1 13055 104855552 83 Linux
Disk /dev/sdb: 17.2 GB, 17179869184 bytes255 heads, 63 sectors/track, 2088 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x0001e836
Device Boot Start End Blocks Id System/dev/sdb1 1 2089 16775168 82 Linux swap / Solaris
จากผลลพธขางตน คาจำนวน heads ท 255 บงถงจำนวนของจาน platters หรอ disks ซงจะถกตงชอของแตละ disk เปน D1, D2, ... D255 โดยแตละแผนจะม track ในลกษณะวงกลมและจะเรมนบจากวงนอกเขาสวงในสดซงมจำนวนทงสน 13,054 tracks/disk โดยจะตงชอแตละ track วาเปน T1, T2, ...T13054
ซงแตละ track ของแตละชนของ disk จะถกแบงออกเปนสวนๆเรยกวา cylinder ใหอยในตำแหนงเดยวกน ยกตวอยางเชน tracks ท T2 ของแผน ตงแต D1, D2, ถง D255 จะรวมกนเปน
129
Embedded Android Development สเสนทางนกพฒนา
cylinder C2 จากผลลพพธคำสง fdisk ขางตน แตละ track จะม logical sectors เหมอนกนคอมคาเทากบ 63 sectors ซงจะถกตงชอเปน S1, S2, ... S63 ตามลำดบโดยแตละ sector จะมขนาดความจเทากบ 512 bytes
รปท 3.19 รายละเอยดของการเกบขอมลภายในจานแมเหลก
ดงนนเมอคำนวณพนทของฮารดดสทสามารถใชไดดวยสตรขางลางน จะมพนทเทากบ
ขนาดพนทฮารดดสทสามารถใชงานได (Byte) = (จำนวน heads หรอ disks) * (จำนวน tracks ตอ disk) * (จำนวน sectors ตอ track) * (จำนวน bytes ตอ sector หรอ sector size)
ตวอยางการคำนวณจากคาทไดจากคำสง fdisk ขางตน ดงน ขนาดพนทฮารดดสทสามารถใชงานได = 255 * 13054 * 63 * 512 = 107,372,805,120 bytes
หมายเหต:
คาทคำนวณจากสตรขางตนจะแตกตางเลกนอยจากขนาดพนทความจของฮารดดสกจรง (107,374,182,400 bytes) เนองจากสตรไมไดสนใจจำนวนไบตในสวนทายสดของ cylinder หรอความไมสมบรณของสวน cylinder
ตวอยางโปรแกรม partition_info.c ทใชในการอานรายละเอยดของพารทชน
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>
130
Embedded Android Development สเสนทางนกพฒนา
#define SECTOR_SIZE 512#define MBR_SIZE SECTOR_SIZE#define MBR_DISK_SIGNATURE_OFFSET 440#define MBR_DISK_SIGNATURE_SIZE 4#define PARTITION_TABLE_OFFSET 446#define PARTITION_ENTRY_SIZE 16 // sizeof(PartEntry)#define PARTITION_TABLE_SIZE 64 // sizeof(PartTable)#define MBR_SIGNATURE_OFFSET 510#define MBR_SIGNATURE_SIZE 2#define MBR_SIGNATURE 0xAA55#define BR_SIZE SECTOR_SIZE#define BR_SIGNATURE_OFFSET 510#define BR_SIGNATURE_SIZE 2#define BR_SIGNATURE 0xAA55 typedef struct { unsigned char boot_type; // 0x00 - Inactive; 0x80 - Active (Bootable) unsigned char start_head; unsigned char start_sec:6; unsigned char start_cyl_hi:2; unsigned char start_cyl; unsigned char part_type; unsigned char end_head; unsigned char end_sec:6; unsigned char end_cyl_hi:2; unsigned char end_cyl; unsigned long abs_start_sec; unsigned long sec_in_part;} PartEntry; typedef struct { unsigned char boot_code[MBR_DISK_SIGNATURE_OFFSET]; unsigned long disk_signature; unsigned short pad; unsigned char pt[PARTITION_TABLE_SIZE]; unsigned short signature;} MBR; void print_computed(unsigned long sector) { unsigned long heads, cyls, tracks, sectors; sectors = sector % 63 + 1 /* As indexed from 1 */; tracks = sector / 63; cyls = tracks / 255 + 1 /* As indexed from 1 */; heads = tracks % 255; printf("(%3d/%5d/%1d)", heads, cyls, sectors);} int main(int argc, char *argv[]) { char *dev_file = "/dev/sda"; int fd, i, rd_val; MBR m;
131
Embedded Android Development สเสนทางนกพฒนา
PartEntry *p = (PartEntry *)(m.pt); if (argc == 2) { dev_file = argv[1]; } if ((fd = open(dev_file, O_RDONLY)) == -1) { fprintf(stderr, "Failed opening %s: ", dev_file); perror(""); return 1; } if ((rd_val = read(fd, &m, sizeof(m))) != sizeof(m)) { fprintf(stderr, "Failed reading %s: ", dev_file); perror(""); close(fd); return 2; } close(fd); printf("\nDOS type Partition Table of %s:\n", dev_file); printf(" B Start (H/C/S) End (H/C/S) Type StartSec TotSec\n"); for (i = 0; i < 4; i++) { printf("%d:%d (%3d/%4d/%2d) (%3d/%4d/%2d) %02X %10d %9d\n", i + 1, !!(p[i].boot_type & 0x80), p[i].start_head, 1 + ((p[i].start_cyl_hi << 8) | p[i].start_cyl), p[i].start_sec, p[i].end_head, 1 + ((p[i].end_cyl_hi << 8) | p[i].end_cyl), p[i].end_sec, p[i].part_type, p[i].abs_start_sec, p[i].sec_in_part); } printf("\nRe-computed Partition Table of %s:\n", dev_file); printf(" B Start (H/C/S) End (H/C/S) Type StartSec TotSec\n"); for (i = 0; i < 4; i++) { printf("%d:%d ", i + 1, !!(p[i].boot_type & 0x80)); print_computed(p[i].abs_start_sec); printf(" "); print_computed(p[i].abs_start_sec + p[i].sec_in_part - 1); printf(" %02X %10d %9d\n", p[i].part_type, p[i].abs_start_sec, p[i].sec_in_part); } printf("\n"); return 0;}
นอกจากนนคำสง fdisk ทใชดรายละเอยดของพารทชนแลว ยงสามารถใชคำสงอนๆเชน คำสง parted ทสามารถแบงหรอปรบขนาดของพารทชนและสามารถตรวจสอบระบบไฟลนนวาเปนชนดใด ดงตวอยางการใชงานขางลาง
$ parted -lModel: VMware, VMware Virtual S (scsi)
132
Embedded Android Development สเสนทางนกพฒนา
Disk /dev/sda: 107GBSector size (logical/physical): 512B/512BPartition Table: msdos
Number Start End Size Type File system Flags 1 1049kB 107GB 107GB primary ext4 bootModel: VMware, VMware Virtual S (scsi)Disk /dev/sdb: 17.2GBSector size (logical/physical): 512B/512BPartition Table: msdos
Number Start End Size Type File system Flags 1 1049kB 17.2GB 17.2GB primary linux-swap(v1)
$ cat /etc/fstab # /etc/fstab: static file system information.## Use 'blkid -o value -s UUID' to print the universally unique identifier# for a device; this may be used with UUID= as a more robust way to name# devices that works even if disks are added and removed. See fstab(5).## <file system> <mount point> <type> <options> <dump> <pass>proc /proc proc nodev,noexec,nosuid 0 0/dev/sda1 / ext4 errors=remount-ro 0 1/dev/sdb1 none swap sw 0 0/dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0
สำหรบระบบสมองกลฝงตวนนไมเพยงแตเคอรเนลจะเปนสวนสำคญสวนหนงของระบบปฏบตการ
ลนกซแลว ยงมอกสวนหนงทเปนสวนสำคญไมนอยกวากนคอ Root file system (RFS) ซงบรรจชดโปรแกรมพนฐานไลบรารและโปรแกรมประยกตตางๆทจะทำใหบอรดสมองกลฝงตวสามารถทำงานไดอยางมระบบและตามเงอนไขการทำงานทไดถกกำหนดไว โดย RFS นนจะถกบนทกเกบไวในอปกรณจดเกบขอมล ซงเมอบอรดสมองกลถกจายไฟและเรมบทตวเองขนตว bootloader ทอยภายใน ROM กจะเรมทำงานและโหลดไฟล Kernel image ขนสหนวยความจำ (RAM) หลงจากนน Kernel จะทำการโหลด RFS ทถกเกบอยบนพารทชนของตวอปกรณบนทกขอมลหรอภายในพารทชนทอยบนเครองคอมพวเตอรภายในระบบเครอขาย เพอเรมขนตอนเขาสระบบปฏบตการลนกซอยางเตมรปแบบ ซงตวอปกรณบนทกขอมลจะมรปแบบระบบไฟลอยหลกๆ 2 แบบคอ แบบ Block และ แบบ Flash
แบบ Block จะสามารถอานและเขยนเพมเตมลงไปไดโดยไมจำเปนตองทำการลบกอนทจะทำการเขยนซำ ตวอยางของอปกรณทเปนแบบ Block ไดแก ฮารดดส แผนดสกแบบออน (floppy disk) และ ดสกหนวยความจำ (RAM disk) เปนตน แตอยางไรกตามกยงมอปกรณบนทกขอมลแบบ Flash ทใชวธการบนทกขอมลแบบ Block ตวอยางเชน Compact Flash, Smart Media, Memory Stick, Multimedia Card , Flash Drive, MMC/SD card แตสำหรบอปกรณบนทกขอมลแบบ Flash เชน NOR flash หรอ NAND flash จะตองทำการลบขอมลเดมกอนทจะเขยนขอมลตวใหมเพมเขาไป โดยตว NOR flash นนจะทนตอการลบและเขยนขอมลไดประมาณ 10,000 ครง ซงความเรวในการอานขอมล
133
Embedded Android Development สเสนทางนกพฒนา
จะเรว แตความเรวในการเขยนและลบขอมลจะคอนขางชา ดงนนจงเหมาะทจะนำมาใชแทนหนวยความจำ ROM ทไมตองเขยนหรอลบขอมลบอยๆ เชน BIOS (Basic Input/Output System) ของเครองคอมพวเตอร, เกบเฟรมแวร (firmware) บนบอรดไมโครคอลโทรเลอร และเกบ bootloader ภายในระบบสมองกลฝงตว เปนตน
สำหรบอปกรณ NAND flash นนไดถกสรางโดยบรษทโตชบา ในป ค.ศ. 1989 ซงสามารถลบและเขยนขอมลไดรวดเรวกวา ชพมขนาดเลกกวา ความจสงกวาและมราคาตำกวาตว NOR flash นอกจากนนกยงมความทนทานกวาถงสบเทา แตกยงทำงานไดชากวาในกรณการเขาถงขอมลแตละไบตในรปแบบไมเรยงตามลำดบ (random access) และอาจมโอกาสเกดความผดพลาดในระดบบตสงกวาอปกรณ NOR Flash อกดวย
การปองกนขอมลภายในระบบไฟลระบบไฟลแตละชนดจะมวธการปองกนการสญหายของขอมลทแตกตางกน ซงระบบไฟลสมยกอน
(Traditional BLock Filesystems) ในกรณทเกดการผดพลาดของระบบหรอมการปดตวระบบแบบกระทนหน ระบบจะไมสามารถเกบสถานะการทำงาน (State) ขณะกอนปดระบบได จำเปนจะตองมการตรวจสอบและซอมแซมทงหมดอกครงเมอเปดเครองเพอเขาสระบบใหม ตวอยางเชน ext2 (Linux filesystem), vfat (Windows filesystem) ตางๆ จะตองมคำสงทสามารถทำการซอมแซมในกรณทระบบไฟลเกดความผดพลาดไดแกคำสง fsck.ext2 หรอ fsck.vat เปนตน
แตในปจจบนระบบไฟลกไดมการพฒนาท ฉลาดข น โดยมพ นฐานของระบบไฟลเปนชนด Journaled Filesystems ซงไดถกออกแบบมาใหสามารถเกบสถานะการทำงานทอยในตำแหนงทถกตองกอนทจะเกดเหตการณผดพลาดหรอมการปดตวระบบแบบกระทนหน โดยใชวธการบนทกสถานะทงหมดลงใน Journal ดงแสดงขนตอนในรปขางลาง
บนทกขอมล entry ลงใน journal
เขยนขอมลลงไฟล
ลางขอมล entry ภายใน journal
โปรแกรมUser-space
Kernel-space
รปท 3.20 ขนตอนการบนทกขอมลลง journal
134
Embedded Android Development สเสนทางนกพฒนา
เมอระบบกลบมาทำงานอกครงระบบไฟลแบบ Journal นจะทำการตรวจสอบ journal ทอยในไฟลกอนทระ บบปดทำงานกอนหนานวามหรอไม ถามกจะทำการกระบบไฟลทเสยหายเหลานนกลบคนมาดวยขนตอนดง แสดงในรปขางลาง
รสตารทเครอง
Journalวางหรอไม?
ละทงสวน journal entries
ทไมสมบรณ
เรยกใช journal
Filesystem OK
No
Yes
รปท 3.21 ขนตอนการอานขอมลจาก journal ในขณะบทเครอง
ซงระบบปฏบตการลนกซในปจจบนไดเปลยนมาใชระบบไฟลแบบ ext3 และ ext4 ซงเปนแบบ journal ทงหมดแลว ซงพฒนาตอยอดมากจาก ext2 โดยเพมความสามารถของระบบไฟลแบบ journal และปรบปรงใหรองรบขนาดความจขอมลทสงขนของอปกรณจดเกบขอมล เมอผใชตองการตรวจสอบและซอมแซมระบบไฟลดวยตวเองกสามารถใชคำสง e2fsck ดงตวอยางขางลาง$ sudo e2fsck /dev/sda1e2fsck 1.41.11 (14-Mar-2010)/dev/sda1 is mounted.
WARNING!!! The filesystem is mounted. If you continue you ***WILL*** cause ***SEVERE*** filesystem damage.
Do you really want to continue (y/n)?
หลงจากเปดตวระบบไฟล ext3 และ ext4 ของระบบปฏบตการลนกซตงแตป ค.ศ. 2008 นาย Theodore Ts'o ซงเปนนกพฒนาหลกของระบบไฟล ext2 ext3 และ ext4 ไดใหความเหนวาในอนาคตอนใกลนอาจจะมระบบไฟลตวใหมเขามาทดแทนชอวา Btrfs (B-tree filesystem) ทถกพฒนาโดยบรษท Oracle เนองจากทง ext3 และ ext4 เกดขนจากพนฐานเทคโนโลยเกาซงอาจจะไมเหมาะกบการเปลยนแปลงของเทคโนโลยการจดเกบขอมลในอนาคตทตองการความเสถยรภาพ (reliability) ความสามารถในการขยายตว (scalability) และงายตอการดแลจดการ
135
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการสรางระบบไฟลชนด ext2, ext3, ext4 โดยการใชคำสง mkfs.ext<หมายเลข> เพอสราง empty filesystem
$ mkfs.ext2 /dev/hda3$ mkfs.ext3 /dev/sda2$ mkfs.ext4 /dev/sda3
ในกรณทตองการสรางระบบไฟลสำหรบไฟล image เดมทมอยแลว
$ mkfs.ext2 disk.img
ในกรณทตองการกำหนดขนาดระบบไฟลในรปแบบไฟล image สามารถทำตามคำสงขางลางน
# dd if=/dev/zero of=rootfs.image bs=1MB count=10241024+0 records in1024+0 records out1024000000 bytes (1.0 GB) copied, 15.3415 s, 66.7 MB/s
# mkfs.ext3 rootfs.imagemke2fs 1.41.11 (14-Mar-2010)rootfs.image is not a block special device.Proceed anyway? (y,n) yFilesystem label=OS type: LinuxBlock size=4096 (log=2)Fragment size=4096 (log=2)Stride=0 blocks, Stripe width=0 blocks62592 inodes, 250000 blocks12500 blocks (5.00%) reserved for the super userFirst data block=0Maximum filesystem blocks=2600468488 block groups32768 blocks per group, 32768 fragments per group7824 inodes per groupSuperblock backups stored on blocks: 32768, 98304, 163840, 229376
Writing inode tables: done Creating journal (4096 blocks): doneWriting superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 25 mounts or180 days, whichever comes first. Use tune2fs -c or -i to override.
# mkdir /mnt/rootfs# mount rootfs.image /mnt/rootfs/ -o loop# rsync -a ~/busybox/_install/ /mnt/rootfs/# chown -R root:root /mnt/rootfs/# sync# umount /mnt/rootfs
136
Embedded Android Development สเสนทางนกพฒนา
ขอมลทเพมเขาไปใน /mnt/rootfs/ กจะถกเกบอยใน rootfs.image เชนเดยวกน
สำหรบนกพฒนาทอยากจะสรางไดเรกทอรตางๆเพอประกอบเปน rootfs ขนมาเอง นอกจากจะตองมความเขาใจในโครงสรางไดเรกทอรของ rootfs เปนอยางดแลวจะตองเขาใจการสรางไฟลชนด device พนฐานสำคญได ดงตวอยางการสราง rootfs ขางลางน
$ mkdir ~/rootfs$ cd ~/rootfs
$ mkdir bin dev etc lib proc sbin tmp usr var$ chmod 1777 tmp$ mkdir usr/{bin,lib,sbin}$ mkdir var/{lib,lock,log,run,tmp}$ chmod 1777 var/tmp# cd dev/# mknod -m 600 mem c 1 1 // Physical memory access# mknod -m 666 null c 1 3 // Null device# mknod -m 666 zero c 1 5 // Null byte source# mknod -m 644 random c 1 8 // Nondeterministic rnd nbr # mknod -m 600 tty0 c 4 0 // Current virtual console# mknod -m 600 tty1 c 4 1 // First virtual console# mknod -m 600 ttyS0 c 4 64 // First UART serial port# mknod -m 666 tty c 5 0 // Current TTY device# mknod -m 600 console c 5 1 // System console
$ ln -s /proc/self/fd fd$ ln -s /proc/self/fd/0 stdin$ ln -s /proc/self/fd/1 stdout$ ln -s /proc/self/fd/2 stderr
Embedded Linux File System
เทคโนโลยจำนวนไมนอยทมการพฒนาระบบ file system เพอรองรบระบบปฏบตการลนกซโดยเฉพาะอยางยงทมการใชระบบไฟลแบบ Flash ซงเหมาะกบการนำไปใชในเทคโนโลยระบบสมองกลฝงตว จากรปขางลางแสดงถงการใชอปกรณจดเกบขอมลชนด NOR Flash ในขณะทในสวนของ device driver จะถกดแลจดการผานตว MTD Drivers
137
Embedded Android Development สเสนทางนกพฒนา
Root File System
JFFS2 CRAMFS RAMFS
MTDDrivers
NOR Flash RAM
User-space
Kernel-space
Hardware
รปท 3.22 การจดการอปกรณจดเกบขอมลผาน MTD driver
นกพฒนาทางดานระบบสมองกลฝงตวตงแตระดบพนฐานจะเจอกบไฟลทชอวา initrd (initial RAM disk) ซงเปนระบบไฟลทถกบบอด (compressed filesystem) โดยในชวงเรมตนของตวระบบไฟล initrd นไดถกพฒนาขนดวยวตถประสงคเพอเปนตวการในการนำระบบปฏบตการลนกซแบบยอใหสามารถถกนำไปบรรจลงในแผนดสกแบบออน (floppy disk) ไดและยงสามารถทำการบทและตดตงระบบปฏบตการลนกซตวเตมลงในฮารดดสกไดอกดวย ซงหลงจากลนกซเคอรเนลรน 2.6 ไดถกปลอยออกมา ตวระบบไฟล initrd กไดถกเรยกในชอใหมวา “initramfs” (Initial RAM FileSystem)
ซงในปจจบนจะพบเหนในลกษณะแผน Live CD (เชน Knoppix เปนตน) จนถงการทำ Live USB กนมากขน ซง Live CD หรอ Live USB นนโดยมระบบปฏบตการลนกซแบบยอทสามารถถกโหลดขนมาอยบนหนวยความจำของเครองคอมพวเตอร (DDRAM) ไดทนท โดยไมจำเปนตองมฮารดดสกอยภายในเครองแตอยางใดดงตวอยางในรปขางลาง แตอยางไรกตามผใชกยงสามารถตดตงระบบปฏบตการลนกซลงในฮารดดสกผานเมนในระหวางบทเขาสระบบไดเชนกน
138
Embedded Android Development สเสนทางนกพฒนา
รปท 3.23 แสดงหนาตางการบทเขาสระบบปฏบตการลนกซ
การใช Live CD นนยงมขอจำกดหลายอยางกลาวคอขนาดไฟลของ initramfs จะตองมขนาดไมเกนความจของแผน CD-ROM ทวไปซงมขนาด 700 MB เทานน แตถาตองการระบบปฏบตการทมขนาดใหญขน Live USB จงกลายเปนทางเลอกทนาสนใจทสดไมวาจะเปนระบบปฏบตการลนกซหรอระบบปฏบตการวนโดส เปนตน
ระบบไฟลในระบบสมองกลฝงตวตวอยางระบบไฟลทนยมใชในระบบสมองกลฝงตวไดแก
ระบบไฟลชนด cramfs
cramfs เปนระบบไฟลถกบบอดเอาไว และอานไดอยางเดยว ซงถกพฒนาขนโดย Linus Torvalds และตอมากไดถกบรรจอยในลนกซคอรเนลเปนทเรยบรอยแลว ระบบไฟลนจะถกบบอดขอมลในลกษณะแยกเปน เพจ (page) และสามารถเขาถงขอมลไดในลกษณะไมเรยงตามลำดบ (random access) ขอดของการทำใหพารทชนเปนแบบอานไดอยางเดยวของ cramfs นนคอการสรางความนาเชอถอของระบบเพราะจะไมมเหตการณไฟลระบบเสยหายหรอสญหายอยางแนนอน
139
Embedded Android Development สเสนทางนกพฒนา
ระบบไฟลชนด ramfs
ramfs ไดถกพฒนาขนโดย Linus Torvalds เชนเดยวกน ซงจะทำการโหลดไฟลทงหมดขนไวในหนวยความจำเครอง (RAM) แตจะเปนระบบไฟลทถกใชอยบนอปกรณชนด flash เปนหลก จงทำใหสามารถเกบขอมลทมการเปลยนแปลงหรอเพมเตมไดแตจะไมเหมอนกบระบบไฟลชนด initrd หรอ initramfs ทถกกำหนดขนาดตายตวและไมสามารถเปลยนแปลงไดระบบไฟลชนด jffs2
jffs2 เปนระบบไฟลยอดนยมตวหนงซงสามารถเขยน/อาน และถกบบอดในรปแบบ journalling flash filesystem โดยตว jffs2 นไดถกนำไปใชในอปกรณชนด Flash memory มากกวาจะเปนชนด RAM เพราะสามารถเกบขอมลทเปลยนแปลงไดเชนเดยวกบระบบไฟลชนด ramfs แตจะมขอดทสำคญอกอยางคอระบบไฟล jffs2 นนสามารถตรวจสอบและกคนขอมลในขณะเกดความผดพลาดภายในระบบไฟลไดเหมอน ext2/ext3
ตาราง 3.3 แสดงรายละเอยดคณสมบตของแตละระบบไฟล
FILE SYSTEM WRITE PERSISTENT POWER DOWN RE-LIABILITY
COMPRES-SION
LIVES IN RAM
CRAMFS No No N/A Yes No
JFFS2 Yes Yes Yes Yes No
RAMFS Yes Yes Yes No Yes
YAFFS2 Yes Yes Yes No No
Ext2 over NFTL Yes Yes No No No
Ext3 over NFTS Yes Yes Yes No No
Ext2 over RAM disk Yes No No No Yes
MEMORY TECHNOLOGY DEVICES (MTD)MTD เปนชฟหนวยความจำแบบ flash ทมพนฐานจาก NAND/NOR flash ทถกนำไปใชในการเกบ
ขอมลทไมคอยถกเปลยนแปลงบอย (non-volatile data) ตวอยางเชนไฟล boot image และเกบคา config ตางๆภายใน bootloader
ถงแมวาอปกรณ MTD เปนชนด flash แตระบบไฟลจะไมเหมอนกบอปกรณชนด flash เชน USB sticks, MMC/SD cards เพราะอปกรณ MTD จะเปนตวเกบขอมลทสามารถถกแบงเปนพารทชนไดเหมอนฮารดดสก แตกมการทำงานทแตกตางจากฮารดดสกและหนวยความจำ (RAM) ในหลายๆดานซงจดทแตกตางชดเจนทสดคอเซกเตอรของฮารดดสจะสามารถถกเขยนขอมลไดทนท แตในขณะทเซกเตอรของอปกรณ MTD นนจะตองถกลบกอนทจะถกเขยนลงไป (ทนยมเรยกกนวา erase-block)
140
Embedded Android Development สเสนทางนกพฒนา
นอกจากนนจำนวนการเขยนของอปกรณ MTD กจำกดจำนวนครงเพยง 1,000 ถง 10,000 ครงเทานน แตในปจจบนอปกรณ MTD กยงถกนำมาใชหลกๆสำหรบบอรดสมองกลฝงตวเพอเกบ bootloaders และ Kernel image
ตวอยางการอานรายละเอยดของพารทชนของอปกรณ MTD โดยอานผานไฟล /proc/mtd
$ cat /proc/mtd dev: size erasesize name mtd0: 000a0000 00020000 "misc" mtd1: 00420000 00020000 "recovery" mtd2: 002c0000 00020000 "boot" mtd3: 0fa00000 00020000 "system" mtd4: 02800000 00020000 "cache" mtd5: 0af20000 00020000 "userdata"
รปแสดงการแบงเซกเตอรของแตละพารทชนภายในอปกรณ MTD
Partition
Partition
Partition
Partition
sectorsectorsectorsector
รปท 3.24 แสดงรายละเอยดของ sector ภายในพารทชน
จากทไดอธบายขบวนการเขยนขอมลลงในอปกรณ MTD ขางตนวาจะตองมการลบกอนจะเขยนขอมลใหมลงไป สามารถดขนตอนการทำงานไดจากรปขางลางน
old data
new data 1 new data 2
old data
new data 1erased sector
old data
new data 2
temp buf
รปท 3.25 แสดงขบวนการเขยนขอมลลงอปกรณ MTD
141
Embedded Android Development สเสนทางนกพฒนา
จากรปดานบนแสดงขบวนการเขยนขอมลลงไปในอปกรณ MTD สงเกตจากดานซายจะพบวาหลงจากการลบครงลาสดกเรมการเขยนขอมลใหมตวแรก (new data 1) ลงในตำแหนง offset ทศนย เมอผใชตองการจะเขยนขอมลใหมตวถดมา (new data 2) ลงในตำแหนงเดมของขอมลตวแรก ตวอปกรณ MTD จะตองคดลอกขอมลเกาทอยดานลางสดไปพกไวในบฟเฟอรชวคราวกอน (temp buf) แลวจงสามารถดำเนนการลบเซกเตอรนนทงหมดได แลวจงคอยนำขอมลเกา (temp buf) และขอมลตวใหม (new data 2) มาเกบตามลำดบ ซงขนตอนเหลานจะถกดำเนนการในชนของ flash translation layer (FTL) เพอลดความยงยากในการเขยนโปรแกรมสำหรบผใช ซงเทคนคนไดถกนำไปใชในอปกรณ MTD เชน JFFS2 และ YAFFS โดยทง JFFS2 และ YAFFS file systems นนจะไมสามารถสรางเปน loopback device และไมสามารถถกทำการ mount ตวระบบไฟลได (ดวยคำสง -o loop) เหมอนกบ linux filesystem ทวไป เนองจากไมไดเปนอปกรณทเปนแบบ block ดงทอธบายไปขางตน ดงนนวธการทจะใหสามารถอปกรณ MTF สามารถถก mount ตวระบบไฟลของทงสองตวได จะตองทำการโหลด MTD Driver ชอวา mtdram module เสยกอน โดยโปรแกรมไดรเวอรนจะทำการจำลองอปกรณ MTD ขนมาดงตวอยางคำสงขางลางน
# modprobe mtdram total_size=65536 erase_size=128
สามารถตรวจสอบอปกรณ MTD ทถกจำลองขนดวยคำสง
# cat /proc/mtddev: size erasesize namemtd0: 04000000 00020000 "mtdram test device"
ใชคำสง dd เพอสราง jffs2 file system และตงชออปกรณใหมชอ mtdblock0
# dd if=rootfs.jffs2 of=/dev/mtdblock0
mount ตว jffs2 filesystem ดวยคำสง
# mount -t jffs2 /dev/mtd0 ~/rootfs
ตวอยางการเขยนโปรแกรมเพอเขาถงอปกรณ MTD
ตวอยางโปรแกรมแสดงรายละเอยดพนฐานของอปกรณ MTD #include <stdio.h>#include <fcntl.h>#include <sys/ioctl.h>
142
Embedded Android Development สเสนทางนกพฒนา
#include <mtd/mtd-user.h> int main(){ mtd_info_t mtd_info; int fd = open("/dev/mtd5", O_RDWR);ioctl(fd, MEMGETINFO, &mtd_info); printf("MTD type: %u\n", mtd_info.type); printf("MTD total size : %u bytes\n", mtd_info.size); printf("MTD erase size : %u bytes\n", mtd_info.erasesize); return 0;}
ตวอยางชดคำสงเพอใชในการอานและเขยนขอมลลงในอปกรณ MTD
unsigned char buf[64];unsigned char data[7] = { ‘B’, ‘U’, ‘R’, ‘A’ , ‘P’ , ‘H’ , ‘A’ };/* read something from last sector */lseek(fd, -mtd_info.erasesize, SEEK_END);read(fd, buf, sizeof(buf));/* write something to last sector */lseek(fd, -mtd_info.erasesize, SEEK_END);write(fd, data, sizeof(data));
ตวอยางโปรแกรมประยกตเพอใหตดตอกบอปกรณ MTD ผานไฟล device ชอ /dev/mtd0#include <stdio.h>#include <fcntl.h>#include <sys/ioctl.h>#include <mtd/mtd-user.h>
int main() { mtd_info_t mtd_info; // the MTD structure erase_info_t ei; // the erase block structure int i;
unsigned char data[20] = { 0xDE, 0xAD, 0xBE, 0xEF, // our data to write 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF }; unsigned char read_buf[20] = { 0x00 }; // empty array for reading
int fd = open("/dev/mtd0", O_RDWR); // open the mtd device for reading and // writing. Note you want mtd0 not mtdblock0 // also you probably need to open permissions // to the dev (sudo chmod 777 /dev/mtd0)
ioctl(fd, MEMGETINFO, &mtd_info); // get the device info
143
Embedded Android Development สเสนทางนกพฒนา
// dump it for a sanity check, should match what's in /proc/mtd printf("MTD Type: %x\nMTD total size: %x bytes\nMTD erase size: %x bytes\n", mtd_info.type, mtd_info.size, mtd_info.erasesize);
ei.length = mtd_info.erasesize; //set the erase block size for (ei.start = 0; ei.start < mtd_info.size; ei.start += ei.length) { ioctl(fd, MEMUNLOCK, &ei); // printf("Eraseing Block %#x\n", ei.start); // show the blocks erasing // warning, this prints a lot! ioctl(fd, MEMERASE, &ei); }
lseek(fd, 0, SEEK_SET); // go to the first block read(fd, read_buf, sizeof(read_buf)); // read 20 bytes
// sanity check, should be all 0xFF if erase worked for (i = 0; i < 20; i++) printf("buf[%d] = 0x%02x\n", i, (unsigned int) read_buf[i]);
lseek(fd, 0, SEEK_SET); // go back to first block's start write(fd, data, sizeof(data)); // write our message
lseek(fd, 0, SEEK_SET); // go back to first block's start read(fd, read_buf, sizeof(read_buf)); // read the data
// sanity check, now you see the message we wrote! for (i = 0; i < 20; i++) printf("buf[%d] = 0x%02x\n", i, (unsigned int) read_buf[i]);
close(fd); return 0;}
ขนตอนการโหลดระบบไฟลเพอเขาสระบบฏบตการ EMBEDDED LINUX
เพอทำใหระบบสมองกลฝงตวทำงานขนมาไดนน จะตองมการเตรยมไฟลหลกๆไดแกไฟล Kernel Image (initrd, vmlinux, bzImage, zImage เปนตน) และไฟล Root file system (ext2/3/4, cramfs, jffs2, hfffs เปนตน) แลวนำไปวางไวในพารทชนของอปกรณจดเกบขอมลทบอรดสมองกลฝงตวสามารถเขาถงได ดงตำแหนงพารทชนเหลาน•พารทชนบนฮารดดสก หรอ USB Storage‣ root=/dev/sdXY ทซง X แทนดวยชออปกรณ และ Y แทนดวยหมายเลขพารทชน เชน root=/dev/sdb2 (พารทชนท 2 ของดสกท 2)
•พารทชนบน MMC/SD Card‣ root=/dev/mmcblkXpY ทซง X แทนดวยหมายเลขอปกรณ และ Y แทนดวยหมายเลขพารทชน เชน root=/dev/mmcblk0p2 (พารทชนท 2 ของดสกแรก)
144
Embedded Android Development สเสนทางนกพฒนา
•พารทชนบน NAND flash‣ root=/dev/mtdblockX ทซง X แทนหมายเลขพารทชน เชน root=/dev/mtdblock3
(พารทชนท 4)•พารทชนบน NFS ของเครองภายในระบบเครอขาย•หนวยความจำภายใน (ROM)รปขางลางแสดงการใชพนทของหนวยความจำหลกของระบบ (RAM) ในขณะทอยในสภาวะกอนทำงานและสภาวะกำลงทำงาน และแสดงขนตอนการโหลด Kernel image และ root filesystem ทถกเกบอยภายใน ROM ของเครอง
CompressedKernel
RootFS image
Bootloaderหนวยความจาระบบ
RootFS image
Bootloader
Kernel
RootFS
UserMemory
ROM
RAM RAM
ROM
หนวยความจาระบบ (ระบบเรมทางาน)
CompressedKernel
รปท 3.26 แสดงการโหลดเคอรเนล และ RootFS ภายในบอรด
รปขางลางแสดงขนตอนการโหลด Kernel image และ root filesystem ทถกเกบอยในเครองอน ทอยภายในระบบเครอขาย
145
Embedded Android Development สเสนทางนกพฒนา
ระบบเครอขาย
Bootloader
RAM
ROM
เครอง Host/เครอง Server
DHCP Server
/tftproot/- Compressed Kernel
(zImage)
TFTP Server
/nfsroot/- Root Filesystem directory
NFS Server
Kernel
ระบบ
เครอ
ขาย
(Eth
erne
t/Int
erne
t)
Target IP: 192.168.0.5Server IP: 192.168.0.1Kernel: zImageNFS mount: /nfsroot/
รปท 3.27 แสดงการโหลดเคอรเนลและ RootFS จากเครอง server
ตารางแสดงการรองรบการเขาถง filesystem ทนยมสงสดในการเกบขอมล 5 อนดบแรกของระบบปฏบตการยอดนยมในปจจบน
ตาราง 3.4 แสดงการรองรบการเขาถงระบบไฟลชนดตางๆของแตละระบบปฏบตการ
FS WINDOWS MAC LINUX ANDROID CHROME OS IPAD XBOX360 PS3
FAT32 Yes Yes Yes Yes Yes (1) Yes Yes
EXFAT Yes(2) No(3) (3) Yes No No No No
EXt3 (4) Yes Yes No(6) Yes No No No
NTFS Yes Yes Yes (8) Yes No No[9] No
HFS+ No[10] Yes (11) (8) (12) (1) No No
โดยท:(1) iPads (ไมรวม iPhones) สามารถอานอปกรณจดเกบขอมล ทใชระบบไฟล FAT และ HFS ได แตจะอานไฟลทเปนชนดรปภาพ และวดโอไดเทานน
(2) exFAT ทปรบปรงมาจาก FAT ซงทำงานไดดบนระบบปฏบตการ Vista / Windows 7 / Windows 8, และ XP
(3) ตองตดตงโปรแกรม FUSE เพมเขาไป เพอใหสามารถอานและเขยนขอมลได(4) ระบบปฏบตการ Windows จะตองตดตงโปรแกรม explore2fs, Ext2Fsd หรอ Ext2IFS เพอใหสามารถอานระบบไฟลประเภท ext2/ext3/ext4 ได
(5) จะตองตดตงโปรแกรม OSXFUSE fuse-ext2, หรอ Paragon(6) เฉพาะบาง ROMs ทถกปรบแตงใหสนบสนนระบบไฟล ext3 เทานน
146
Embedded Android Development สเสนทางนกพฒนา
(7) ระบบปฏบตการ MacOS โดยพนฐานสามารถอานระบบไฟล NTFS ไดอยางเดยว ถาตองการเขยนได จะตองตดตง OSXFUSE with NTFS-3G, Paragon หรอ Tuxera
(8) บนระบบปฏบตการ Android ตองตดตงโปรแกรม Paragon app เพอใหสามารถเขาถง ระบบไฟล NTFS และ HFS ได
(9) Xbox 360 ของบรษท Microsoft เอง ไมสนบสนนระบบไฟล NTFS(10)จะตองตดตงโปรแกรม Paragon เพมเตม(11)ระบบปฏบตการลนกซ สามารถอานระบบไฟล HFS+ ไดอยางเดยว ถาตองการเขยนได กจะตองปดความสามารถของ journalling ไป
(12)สามารถอานระบบไฟล journaled HFS+ ไดอยางเดยว
BusyBox มดพกพาสารพดประโยชนBusyBox ไดถกพฒนาขนโดยนาย Bruce Perens ในป ค.ศ. 1996 ซงเดมทถกนำมาใชเปน
โปรแกรมชวยในการตดตงและกคนในแผนดสกเกตแบบบทตวเองไดของระบบปฏบตการ Debian (bootable Debian Linux system) โดยมเงอนไขวาลนกซคอรเนลและโปรแกรมพนฐานทงหมดจะมขนาดรวมกนแลวไมเกน 1.4 MB ถง 1.7 MB เนองจากขอจำกดในการเกบขอมลภายในแผนดสกเกตในยคนน ดงนนหลกการสำคญทจะตองทำให BusyBox มขนาดเลกแตยงคงเตมไปดวยชดคำสงมากมายคอการใชสวนฟงกชนพนฐานทเหมอนกนรวมกนตวอยางเชน ตว Busy-
Box จะทำการรวมโปรแกรม grep และ find เปนโปรแกรมเดยวกนเนองจากใชหลกการคนหาไฟลโดยจะเขาไปถงภายในไดเรกทอรทกไดเรกทอร (recursive) เชนเดยวกน เปนผลใหขนาดไฟลทเกดจากการรวมโปรแกรมทงสองลดลงอยางมาก ดงนน BusyBox กสามารถใชหลกการนกบโปรแกรมอนๆทมฟงกชนพนฐานเดยวกนจากเดมทมขนาดทงสน 3.5 MB กสามารถลดลงเหลอเพยง 200 KB เทานนได
ดงนน BusyBox จงกลายมาเปนเครองมอสำคญทถกนำมาใชภายในระบบปฏบตการของระบบสมองกลฝงตวอนๆจนถกตงฉายาวาเปน “มดพกพาสารพดประโยชน” (Swiss Army Knife) ซงไดรวมชดโปรแกรมและชดคำสงอรรถประโยชนของคำสงพนฐานตางๆทจำเปนในระบบปฏบตการลนกซ ตวอยางเชน ชดโปรแกรมทใชจดการบรการตางๆของระบบในขณะเครองกำลงเรมทำงาน (Init program), ชดคำสงจดการระบบและตงคาระบบ (System & Configuration) เปนตน ตวอยางคำสงใน BusyBox ver-sion 1.13 ไดแก
[, [[ , addgroup, adduser, adjtimex, ar, arp, arping, ash, awk, base-name, bbconfig, bbsh, brctl, bunzip2, busybox, bzcat, bzip2, cal, cat, catv, chat, chattr, chcon, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, cp, cpio, crond, crontab,
147
Embedded Android Development สเสนทางนกพฒนา
รปท 3.28 มด Swiss Army Knife
cryptpw, cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devfsd, df, dhcprelay, diff, dirname, dmesg, dnsd, dos2unix, dpkg, dpkg_deb, du, dumpkmap, dumpleases, e2fsck, echo, ed, egrep, eject, env, envdir, envuidgid, ether_wake, expand, expr, fakeidentd, false, fbset, fbsplash, fdflush, fdformat, fdisk, fetchmail, fgrep, find, findfs, fold, free, freeramdisk, fsck, fsck_minix, ftpget, ftpput, fuser, getenforce, getopt, getsebool, getty, grep, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostid, hostname, httpd, hush, hwclock, id, ifconfig, ifdown, ifenslave, ifup, inetd, init, inotifyd, insmod, install, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, lash, last, length, less, linux32, linux64, linuxrc, ln, load_policy, load-font, loadkmap, logger, login, logname, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lzmacat, makedevs, man, matchpathcon, md5sum, mdev, mesg, microcom, mkdir, mke2fs, mkfifo, mkfs_minix, mknod, mkswap, mktemp, modprobe, more, mount, mountpoint, msh, mt, mv, nameif, nc, netstat, nice, nmeter, nohup, nslookup, od, openvt, parse, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, poweroff, printenv, printf, ps, pscan, pwd, raidautorun, rdate, rdev, readahead, readlink, readprofile, realpath, reboot, renice, re-set, resize, restorecon, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run_parts, runcon, runlevel, runsv, runsvdir, rx, script,
sed, selinuxenabled, sendmail, seq, sestatus, setarch, setconsole, se-tenforce, setfiles, setfont, setkeycodes, setlogcons, setsebool, set-sid, setuidgid, sh, sha1sum, showkey, slattach, sleep, softlimit, sort, split, start_stop_daemon, stat, strings, stty, su, sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, taskset, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, top, touch, tr, traceroute, true, tty, ttysize, tune2fs, udhcpc, udhcpd, udpsvd, umount, uname, uncompress, unexpand, uniq, unix2dos, unlzma, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, vlock, watch, watchdog, wc, wget, which, who, whoami, xargs, yes, zcat, zcip
ตวอยางขางลางแสดงแนวคดการสรางโปรแกรมเพอทจะทำใหกลายเปนการรนมาจากเพยงโปรแกรมเดยวใหผใชรสกวามหลายคำสงโปรแกรมใหเรยกใชงานได แตจรงๆแลวเปนชดคำสงทอยภายในโปรแกรมเพยงตวเดยวเทานน เชนเดยวกนโปรแกรม BusyBox ทจะใชหลกการการสงผานคาอารกวเมนต (argu-ment passing) ไปยงฟงกชนภาษาซ// myBusyBox.c#include <stdio.h>int main( int argc, char *argv[] ){ int i;
for (i = 0 ; i < argc ; i++) { printf("argv[%d] = %s\n", i, argv[i]); }
return 0;
148
Embedded Android Development สเสนทางนกพฒนา
}
จากขางบนตว argc เปนตวแปรเกบจำนวนของอารกวเมนต และ argv เปนตวแปรชนดอะเรยทเกบขอความแตละอารกวเมนต
หลงจากนนทำการคอมไพลโปรแกรม และทดสอบการเรยกโปรแกรมพรอมการสงผานคาอารกวเมนตดงน
$ gcc -o myBusyBox myBusyBox.c $ ./myBusyBox arg1 arg2argv[0] = ./myBusyBoxargv[1] = arg1argv[2] = arg2
สรางไฟลชนด symbolic link ชอวา my_grep และ my_find แลวใหชไปยงชอโปรแกรม myBusyBox เดม
$ ln -s myBusyBox my_grep$ ln -s myBusyBox my_find$ ls -al my*-rwxr-xr-x 1 student student 8503 2013-08-13 08:21 myBusyBox-rw-r--r-- 1 student student 162 2013-08-13 08:21 myBusyBox.clrwxrwxrwx 1 student student 9 2013-08-13 08:27 my_find -> myBusyBoxlrwxrwxrwx 1 student student 9 2013-08-13 08:22 my_grep -> myBusyBox
$ ./my_grep -R 'declare' /usr/include/argv[0] = ./my_grepargv[1] = -Rargv[2] = declareargv[3] = /usr/include/
$ ./my_find /usr/include/ -name 'declare' -printargv[0] = ./my_findargv[1] = /usr/include/argv[2] = -nameargv[3] = declareargv[4] = -print
จากโปรแกรมขางตนเปนการแสดงใหเหนแนวคดและวธการทำงานของโปรแกรม BusyBox ซงโปรแกรม myBusyBox ทไดสรางขนนนจะมฟงกชนพนฐานเกยวกบการคนหาขอมล (grep) และคนหาไฟล (find) อยภายใน ดงนนเมอผใชตองการเรยกใชคำสงใดกตามจะสงเกตเหนไดวาคาใน argv[0] จะบรรจชอคำสงทผใชพมพ ดงนนนกพฒนากสามารถทำการพฒนาฟงกชนตางๆเพอแทนคำสงนนๆตอไปได แลวตวโปรแกรม myBusyBox กจะนำคาภายใน argv[0] ไปตรวจเชคตอไปวาเปนตวฟงกชนใด
149
Embedded Android Development สเสนทางนกพฒนา
ดวยแนวคดการรวมฟงกชนพนฐานทใชรวมกนของชดคำสงตางๆในระบบปฏบตการลนกซใหกลายมาเปน BusyBox เพยงโปรแกรมเดยวนน จะสามารถลดขนาดโปรแกรมลงไดถง 3 ถง 4 เทาเมอเทยบกบการใชโปรแกรมพนฐานทงหมด ซงจะสงเกตจากการใชคำสง ls -al ดงรปขางลางวาทกคำสงจะถกช (symbolic link) ไปยงโปรแกรม busybox ทงสน
Busybox Inittab
เมอตองมการปรบแตงหรอสราง BSP (Board Support Package) ของตวเองขนมาเพอใชสำหรบระบบปฏบตการลนกซแบบฝงตว การตงคาการโหลดเรมตน (Initialization) เพอใชในการกำหนดลำดบการโหลดโปรแกรมสำหรบตงคาบรการของระบบ (System services) ตางๆ หรอใชในการโหลดโปรแกรมระบบ โปรแกรมประยกตทพฒนาขนเองในระหวางทบอรดสมองกลฝงตวกำลงเรมตนการทำงาน ดงนนนกพฒนาควรจะทำความเขาใจวธการสรางไฟล Inittab ทอยภายในไดเรกทอร /etc/ ซงภายในไฟล inittab นนมรปแบบการเขยนดงน
< id >:< runlevels >:< action >:< process >
150
Embedded Android Development สเสนทางนกพฒนา
โดยท:• < id > จะถกใชโดย BusyBox init เพอระบ console ทเปดขนมา (controlling tty) สำหรบโปรเซสทไดระบไวแตอยางไรกตามถา BusyBox ตรวจพบวามการใช serial console อยแลวคานกจะถกเพกเฉยไป
• < runlevels > คานจะไมมการใชใน BusyBox โดยเฉพาะในระบบสมองกลฝงตวเนองจากไมการแยกระดบของผใช แตจะใชเฉพาะในเครองคอมพวเตอรเทานน
• < action > ประกอบดวย sysinit, respawn, askfirst, wait, once, restart, ctrlaltdel, และ shutdown โดยมรายละเอยดดงน‣ sysinit กำหนดใหเรยกโปรเซสในระหวางทระบบกำลงจะเรมถกบทขน‣ respawn กำหนดใหเรยกโปรเซสใหมอกครงอตโนมต เมอใดกตามทโปรเซสนนถกปดลง ‣ askfirst มการทำงานคลายกบ respawn แตกอนจะเรมเรยกโปรเซสทกำหนดไว จะมการแสดงขอความดงน "Please press Enter to activate this console." เพอรอใหผใชกดปม Enter แลวจงทำการเรยกโปรเซสลำดบถดไป‣ ctrlaltdel กำหนดใหเรยกโปรเซส เมอ init ไดรบสญญาณ SIGINT ทมการกดปม CTRL-ALT-DEL พรอมกน
ตวอยางไฟล inittab
# Boot-time system configuration/initialization script.# This is run first except when booting in single-user mode.#::sysinit:/etc/init.d/rcS
# Put a getty on the serial line (for a terminal)::respawn:/sbin/getty -L ttyS 115200 vt100
# Stuff to do when restarting the init process::restart:/sbin/init
# Stuff to do before rebooting::ctrlaltdel:/sbin/reboot
151
Embedded Android Development สเสนทางนกพฒนา
การพฒนาระบบสมองกลฝงตวภายใตระบบจำลองเสมอนจรง
สมยกอนนกพฒนาทางดานระบบสมองกลฝงตวคอนขางจะมทางเลอกนอยในการหาซอบอรดสมองกลฝงตวทใชสถาปตยกรรมทตองการนำมาศกษาเพอทดลองพฒนาโปรแกรมหรอปรบแตงระบบตามโจทยในงานประยกตนนๆ แตไมกปทผานมาระบบสมองกลฝงตวกเรมเขามามบทบาทอยในชวตประจำวนมากยงขน ทำใหเกดการสรางสรรนวตกรรมใหมๆ ผลตภณฑใหมๆในวงกวาง สงผลดตอนกพฒนาในปจจบนทสามารถหาซอบอรด Evaluation Kit ทมวางจำหนายจากบรษทตางๆ ตวอยางเชนบอรด Mi-croBlaze, Sitara, Beagleboard, Beaglebone, Pandaboard, FriendlyARM, Raspberry Pi, ODROID, Versatile Express, Gumstix เปนตน โดยจะมราคาตงแตหลกพนกวาบาทถงหลายหมนบาททำใหมตวเลอกมากยงขน ทำใหนกพฒนาอสระ นกเรยนนกศกษา หรอนกพฒนาในบรษทตางๆสามารถเรมเรยนรเทคโนโลยทางดานระบบสมองกลฝงตวไดอยางลกซงมากขน ซงคาดวาในอกไมกปขางหนามลคาทางดานการออกแบบและพฒนาทางดานระบบสมองกลฝงตวนจะสงมากกวามลคาจากการผลตอยางเหนไดชด
ตาราง 3.5 บอรดสมองกลฝงตวแตละยหอทไดรบความนยม
บอรด SOC ความเรว RAM I/O ราคา
BeagleBone Sitara AM3358
500MHz(on
USB)/720MHz(on DC)
256MBUSB OTG, USB Host, Ethernet, onboard Serial, onboard JTAG, expansion head-ers, microSD
$89
BeagleBoard xM Davinci DM3730 1GHz 512MB
USB OTG, USB Host, Ethernet, expan-sion headers, microSD, DVI-D, LCD header, S-Video, Camera header, Stereo IN/OUT
$149
iMX53 QSB i.MX53 1GHz 1GBUSB OTG, USB Host, Ethernet, Serial, expansion headers, SD, microSD, SATA, VGA, LCD header, Stereo IN/OUT
$149
PandaBoard ES OMAP4 dual-core 1.2GHz 1GB
USB OTG, USB Host, Ethernet, WLAN, Bluetooth, Serial, expansion headers, SD, HDMI, DVI, LCD header, Camera header, Stereo IN/OUT
$182
AM335x Starter Kit Sitara AM3358 720MHz 256MB
USB OTG, USB Host, Ethernet, WLAN, Bluetooth, onboard Serial, onboard JTAG, expansion headers, microSD, capacity-touch LCD, Accelerometer, Ste-reo OUT
$199
OrigenBoard Exynos 4210 dual-core
1.2GHz 1GBUSB OTG, USB Host, Ethernet, WLAN, Bluetooth, Serial, JTAG, SD, HDMI, LCD header, Camera header, Stereo IN/OUT
$199
Origen 4 Quad Exynos 4 quad-core
1.4GHz 1GBUSB OTG, USB Host, Ethernet, SD, JTAG, Serial, HDMI, onboard LCD header, audio
$199
152
Embedded Android Development สเสนทางนกพฒนา
บอรด SOC ความเรว RAM I/O ราคา
ODROID-X2Quad core ARM Cortex-A9 MPCore
1.7GHz 2GBUSB OTG, USB Host, Ethernet, onboard Serial, expansion headers, SD, Stereo IN/OUT
$135
DragonBoard APQ8060A
Snapdragon dual-core
1.2GHz 1GB
USB OTG, USB Host, Ethernet, WLAN, Bluetooth, GPS, onboard Serial, onboard JTAG, expansion headers, microSD, capacity-touch LCD, Accelerometer, Ste-reo OUT
$499
Snapdragon MDPSnapdragon S4 dual-core 1.5GHz 1GB
USB OTG, WLAN, Bluetooth, GPS, Accel-erometer, Gyroscope, Compass, Proxim-ity sensor, Temperature sensor, SD, HDMI, LCD Panel , Camera, Stereo OUT
$999
RaspBerry Pi Broadcom ARM11 BCM2835
700MHz 512MBUSB OTG, USB Host, onboard Ethernet, onboard Serial, expansion headers, MMC, SD, VGA, HDMI, Stereo OUT
$35
SABRE i.MX53 1GHz 1GB
USB OTG, USB Host, Ethernet, WLAN, Bluetooth, GPS, ZigBee, Accelerometer, Light sensor, Serial, JTAG, eMMC, SD, SATA, NOR Flash, VGA, HDMI, LCD Panel, Camera, Stereo IN/OUT
$999
สำหรบอกทางเลอกหนงทเหมาะสำหรบนกพฒนามอใหม หรอนกพฒนาทยงไมไดตดสนใจซอบอรดสมองกลฝงตวคอการใชโปรแกรมจำลองเสมอนจรง (Virtualization) เพอจำลองสภาพแวดลอมและการทำงานใหเปนไปตามสถาปตยกรรมของหนวยประมวลผลกลางนนเชน ARM, MIPS, PowerPC, x86 เปนตน ซงโปรแกรมจำลองเสมอนจรงทนยมกนมานานและใชกนในระบบปฏบตการลนกซกคอโปรแกรม QEMU (Quick EMUlator) นกพฒนาสามารถพฒนาโปรแกรม และทดสอบการทำงานของโปรแกรมใหเปนไปตามเงอนไขทกำหนดบนสถาปตยกรรมนนๆ นอกจากนนกยงสามารถปรบแตงลนกซคอรเนล หรอทดสอบโปรแกรมทพฒนาในระดบเคอรเนลวาสามารถทำงานไดดบนสถาปตยกรรมนนหรอไม โปรแกรม QEMU สามารถรองรบโหมดการทำงานได 2 แบบไดแก
A.user-mode emulation คอการอนญาตใหโปรเซสทถกออกแบบมาใหทำงานบนหนวยประมวลผล กลางตวเดยว (เชนบนบอรด target) ใหสามารถทำงานไดบนหนวยประมวลผลกลางตวอนๆได (เชนบนเครอง Host) ดวยตว Dynamic Translator ตวอยางเชน การเรยกตวจำลองเลยนแบบ Wine Windows API (http://www.winehq.org) หรอเพอชวยใหการ cross-compile และ cross-debugging ขามสถาปตยกรรมสะดวกขน นอกจากนนกเปนการทำใหโปรเซสสามารถเขาถงทรพยากรของเครอง Host ซงสถาปตยกรรมทรองรบสำหรบโหมดนไดแก x86, PowerPC, ARM, 32-bit MIPS, Sparc32/64, ColdFire(m68k), CRISv32 and MicroBlaze CPUs
B.System-mode emulation คอการจำลองระบบสถาปตยกรรมทงระบบ ไมวาจะเปนหนวยประมวลผลกลาง อปกรณฮารดแวรรอบขางตางๆ เปรยบเสมอนเปนเครองเสมอนจรง (Virtual Machine) ตวอยางเชนการสรางเครองเสมอนจรงทใชสถาปตยกรรม PowerPC ทกำลงใชระบบ
153
Embedded Android Development สเสนทางนกพฒนา
ปฏบตการ Debian แตจรงๆแลวตวระบบจำลองนทำงานอยบนเคร องคอมพวเตอรท ใชสถาปตยกรรม x86-64 บต ภายใตระบบปฏบตการ Ubuntu เปนตน ตารางขางลางแสดงรายการสถาปตยกรรมท QEMU รองรบ ไดแก
ตาราง 3.6 สถาปตยกรรมตางๆทถกสนบสนนในโปรแกรม QEMU
สถาปตยกรรมสถาปตยกรรม
PC (x86 or x86_64 processor) Luminary Micro LM3S6965EVB (ARM Cortex-M3)
ISA PC (old style PC without PCI bus) Freescale MCF5208EVB (ColdFire V2)
PREP (PowerPC processor) Arnewsh MCF5206 evaluation board (ColdFire V2)
G3 Beige PowerMac (PowerPC processor) Palm Tungsten|E PDA (OMAP310 processor)
Mac99 PowerMac (PowerPC processor, in progress) N800 and N810 tablets (OMAP2420 processor)
Sun4m/Sun4c/Sun4d (32-bit Sparc processor) MusicPal (MV88W8618 ARM processor)
Sun4u/Sun4v (64-bit Sparc processor, in progress) Gumstix "Connex" and "Verdex" motherboards (PXA255/270)
Malta board (32-bit and 64-bit MIPS processors) Siemens SX1 smartphone (OMAP310 processor)
MIPS Magnum (64-bit MIPS processor) Syborg SVP base model (ARM Cortex-A8)
ARM Integrator/CP (ARM) AXIS-Devboard88 (CRISv32 ETRAX-FS)
ARM Versatile baseboard (ARM) Petalogix Spartan 3aDSP1800 MMU ref design (MicroBlaze)
ARM RealView Emulation/Platform baseboard (ARM) Luminary Micro LM3S811EVB (ARM Cortex-M3)
Spitz, Akita, Borzoi, Terrier and Tosa PDAs (PXA270 proc-essor)
ตวอยางการตดตงโปรแกรม QEMU ทถกปรบแตงโดย Linaro ซงเนนรองรบสถาปตยกรรม ARM เปนพเศษ
$ sudo add-apt-repository ppa:linaro-maintainers/tools$ sudo apt-get update$ sudo apt-get install qemu-user-static qemu-system$ qemu --versionQEMU PC emulator version 0.12.3 (qemu-kvm-0.12.3), Copyright (c) 2003-2008 Fabrice Bellard
ตวอยางชดคำสง QEMU สำหรบแตละสถาปตยกรรม
qemu-alpha qemu-ppc qemu-system-mips64elqemu-arm qemu-ppc64 qemu-system-mipselqemu-armeb qemu-ppc64abi32 qemu-system-moxieqemu-cris qemu-s390x qemu-system-or32qemu-ga qemu-sh4 qemu-system-ppcqemu-i386 qemu-sh4eb qemu-system-ppc64qemu-img qemu-sparc qemu-system-ppcemb
154
Embedded Android Development สเสนทางนกพฒนา
qemu-io qemu-sparc32plus qemu-system-s390xqemu-m68k qemu-sparc64 qemu-system-sh4qemu-microblaze qemu-system-alpha qemu-system-sh4ebqemu-microblazeel qemu-system-arm qemu-system-sparcqemu-mips qemu-system-cris qemu-system-sparc64qemu-mips64 qemu-system-i386 qemu-system-unicore32qemu-mips64el qemu-system-lm32 qemu-system-x86_64qemu-mipsel qemu-system-m68k qemu-system-xtensaqemu-mipsn32 qemu-system-microblaze qemu-system-xtensaebqemu-mipsn32el qemu-system-microblazeel qemu-unicore32qemu-nbd qemu-system-mips qemu-x86_64
qemu-or32 qemu-system-mips64
ขนตอนการทดสอบการรนโปรแกรมภาษาซ บน QEMU
ทำการตดตง Sourcery CodeBench ซงเปน cross-compiling toolchain ทพรอมสำหรบการพฒนาโปรแกรมภาษา C/C++ บนระบบสมองกลฝงตว โดยโหลดจากรนลาสดจากลงคของบรษท Men-tor Graphics
$ chmod +x arm-2013.05-24-arm-none-linux-gnueabi.bin $ ./arm-2013.05-24-arm-none-linux-gnueabi.bin Checking for required programs: awk grep sed bzip2 gunzipPreparing to install...Extracting the JRE from the installer archive...Unpacking the JRE...Extracting the installation resources from the installer archive...Configuring the installer for this system's environment...Launching installer...
155
Embedded Android Development สเสนทางนกพฒนา
ทำการสรางไดเรกทอรสำหรบทดสอบโปรแกรมโดยสรางโปรแกรมชอ init.c เพอใหแสดงขอความ “Hello World”
$ mkdir ~/qemu$ cd ~/qemu
$ vim init.c#include <stdio.h>void main() { printf("Hello World!\n"); while(1);}
คอมไพลโปรแกรมดวย cross-compiler และวางเขาไปในไฟล ramdisk
$ arm-none-linux-gnueabi-gcc -static init.c -o init$ echo init|cpio -o --format=newc > initramfs
ดาวนโหลดลนกซคอรเนลเวอรชน 3.9 $ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.tar.xz$ tar -xJvf linux-3.9.tar.xz$ cd linux-3.9$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- vexpress_defconfig$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- all$ cp arch/arm/boot/zImage ~/qemu$ cd ~/qemu$ ls -altotal 74488drwxr-xr-x 3 student student 4096 2013-08-16 11:05 .drwxr-xr-x 46 student student 4096 2013-08-16 11:16 ..-rwxr-xr-x 1 student student 648380 2013-08-16 03:50 init-rw-r--r-- 1 student student 76 2013-08-16 03:20 init.c-rw-r--r-- 1 student student 648704 2013-08-16 03:54 initramfsdrwxr-xr-x 24 student student 4096 2013-08-16 04:10 linux-3.9-rw-r--r-- 1 student student 72104164 2013-04-28 17:40 linux-3.9.tar.xz-rw-r--r-- 1 student student 699 2013-08-16 09:33 README-rwxr-xr-x 1 student student 2844736 2013-08-16 04:16 zImage
ทดสอบโปรแกรม init โดยการเรยกโปรแกรม qemu-system-arm ดงคำสงขางลาง
$ qemu-system-arm -M vexpress-a9 -kernel zImage -initrd initramfs -serial stdio -append "console=tty1"
156
Embedded Android Development สเสนทางนกพฒนา
ขนตอนการทดสอบ BUSYBOX ภายใน ROOT FILESYSTEM บน QEMU
ทำการคอมไพลลนกซคอรเนลรน 3.9 ทไดอธบายขางตน เพอรองรบสถาปตยกรรมของ ARM SoC ทชอวา versatile ดวยคำสงขางลางน
$ make mrproper$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- versatile_defconfig$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig
ปรบแตงคาเคอรเนล โดยการไมเลอก “Enable loadable module support” feature แตใหเลอก “Use the ARM EABI to compile the kernel” แทน ทอยในเมน Kernel Features
157
Embedded Android Development สเสนทางนกพฒนา
ทำการคอมไฟลเคอรเนลหลงจากตงคาตางๆเรยบรอยแลว
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- all
ดาวนโหลดโปรแกรม BusyBox รน 1.21.0 ลงในไดเรกทอร ~/qemu กอนหนานแลวทำการตงคาตามลำดบขนตอนดงน
$ wget http://busybox.net/downloads/busybox-1.21.0.tar.bz2$ tar -xjvf busybox-1.21.0.tar.bz2$ cd busybox-1.21.0$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- defconfig$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig
ตงคาใหสราง BusyBox เปนแบบ static binary โดยการเขาไปในเมน Busybox Setting -> Build Op-tions -> ทำการ check Build BusyBox as a static binary
158
Embedded Android Development สเสนทางนกพฒนา
ในกรณทตองการใหระบบปฏบตการลนกซแบบฝงตวสามารถเชอมตอหรอ mount ไดเรกทอรภายในพารทชนของ NFS (Network File System) ของเครองอนๆภายในระบบเครอขายไดจะตองตงคาใน BusyBox ซงอยภายในเมน “Linux System Utilities” ชอวา Support mounting NFS file systems on Linux ดงแสดงการตงคาในรปขางลาง
159
Embedded Android Development สเสนทางนกพฒนา
ทำการรนคำสง install เพอตดตง BusyBox ลงในไดเรกทอร _install
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- install..../_install//usr/sbin/ubimkvol -> ../../bin/busybox./_install//usr/sbin/ubirmvol -> ../../bin/busybox./_install//usr/sbin/ubirsvol -> ../../bin/busybox./_install//usr/sbin/ubiupdatevol -> ../../bin/busybox./_install//usr/sbin/udhcpd -> ../../bin/busybox--------------------------------------------------You will probably need to make your busybox binarysetuid root to ensure all configured applets willwork properly.--------------------------------------------------
สรางไดเรกทอรจำเปนพนฐาน สำหรบ root filesystem
$ cd _install$ mkdir proc sys dev etc etc/init.d$ ls -altotal 36drwxr-xr-x 9 student student 4096 2013-08-16 12:14 .drwxr-xr-x 34 student student 4096 2013-08-16 11:58 ..drwxr-xr-x 2 student student 4096 2013-08-16 11:58 bindrwxr-xr-x 2 student student 4096 2013-08-16 12:14 devdrwxr-xr-x 3 student student 4096 2013-08-16 12:14 etclrwxrwxrwx 1 student student 11 2013-08-16 11:58 linuxrc -> bin/busyboxdrwxr-xr-x 2 student student 4096 2013-08-16 12:14 procdrwxr-xr-x 2 student student 4096 2013-08-16 11:58 sbindrwxr-xr-x 2 student student 4096 2013-08-16 12:14 sysdrwxr-xr-x 4 student student 4096 2013-08-16 11:58 usr
สรางไฟล rcS เขาไปไดเรกทอร etc/init.d/ เพอทำการ mount ไดเรกทอร /proc และ /sysfs ซงเปน virtual filesystem
$ vim etc/init.d/rcS
เพม shell script เขาไปในไฟล rcS ดงน
#!/bin/shmount -t proc none /procmount -t sysfs none /sys/sbin/mdev -s
แปลงสทธไฟล rcS ใหสามารถรนได และเรมดำเนนการสราง root filesystem ชอ rootfs.img จากไดเรกทอร _install
$ chmod +x etc/init.d/rcS$ find . | cpio -o --format=newc > ../rootfs.img11984 blocks
160
Embedded Android Development สเสนทางนกพฒนา
$ cd ..$ gzip -c rootfs.img > rootfs.img.gz$ cp rootfs.img.gz ~/qemu
เรยกโปรแกรม qemu-system-arm เพอทดสอบคำสงพนฐานของ BusyBox
$ cd ~/qemu$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/bin/sh"
การสรางระบบจำลองสำหรบสถาปตยกรรม ARM ดวยชดเครองมอ BUILDROOT บนโปรแกรม QEMU
ทำการตดตงโปรแกรมและไลบรารทเกยวของ
$ sudo apt-get install autoconf automake libtool libexpat1-dev libncurses5-dev bison flex patch curl cvs texinfo build-essential sub-version gawk python-dev gperf ncurses-dev g++ gcc texi2html nfs-kernel-server
สรางไดเรกทอรสำหรบเกบ root filesystem ของระบบปฏบตการ Embedded Linux ดวยโปรโตคอลประยกต NFS (Network File System) ผานระบบเครอขาย LAN
$ mkdir ~/nfsroot
แลวทำการตงคาไดเรกทอรทตองการแชรผาน NFS ภายในไฟล /etc/exports ดวยคำสงขางลางน
161
Embedded Android Development สเสนทางนกพฒนา
$ sudo vim /etc/exports /home/student/nfsroot *(rw,sync,no_root_squash,no_subtree_check)
เรมเรยกบรการ NFS Server ใหมอกครง
$ sudo /etc/init.d/nfs-kernel-server restart
ตดตงเครองมอ buildroot ซงเปน cross-compiling toolchain
$ wget http://buildroot.uclibc.org/downloads/buildroot-2013.05.tar.gz$ tar -xzvf buildroot-2013.05.tar.gz $ cd buildroot-2013.05/
ตงคาระบบปฏบตการลนกซแบบฝงตวเพอใหรองรบรายละเอยดของสถาปตยกรรมและรายละเอยดอนๆดงน
$ make menuconfig
โดยใหตงคาดงน:Target Architecture ==> ARM (little endian)
Target Architecture Variant ==> arm926t
Target ABI ==> EABI
System Configuration ==> serial port to run getty on (ttyAMA0)
Package Selection ==> Busybox
FileSystem Images ==> cpio the root filesystem และ tar the root filesystem
Kernel ==>ระบชอ defconfig เปน “versatile”
Kernel ==> Kernel binary format to zImage
162
Embedded Android Development สเสนทางนกพฒนา
163
Embedded Android Development สเสนทางนกพฒนา
164
Embedded Android Development สเสนทางนกพฒนา
$ make$ ls -al output/images/total 6712drwxr-xr-x 2 student student 4096 2013-07-22 11:45 .drwxr-xr-x 8 student student 4096 2013-07-22 21:03 ..-rw-r--r-- 1 student student 1922560 2013-07-22 21:03 rootfs.cpio-rw-r--r-- 1 student student 858843 2013-07-22 21:03 rootfs.cpio.gz-rw-r--r-- 1 student student 2181120 2013-07-22 21:03 rootfs.tar-rw-r--r-- 1 student student 1895000 2013-07-22 11:44 uImage
$ cp output/images/uImage ~/qemu/
วาง root filesystem ไปยง ไดเรกทอร NFS ชอวา ~/nfsroot ทเครอง Host ไดเปดแชรไว
$ sudo tar -xvf rootfs.tar ~/nfsroot/$ sudo chown -R student:student ~/nfsroot
ขนตอนการสราง tun/tap device เพอกำหนดวงของระบบเครอขายทองถนภายในระหวาง QEMU และเครอง Host เพอใหระบบปฏบตการลนกซแบบฝงตวภายใน QEMU สามารถ mount ไดเรกทอร NFS ทเปดแชรไวบนเครอง Host ได โดยตงคา IP Address ใหกบเครอง Host เปน 192.168.1.1 และตงคา IP Address สำหรบอปกรณ target ซงในทนกคอ 192.168.1.101 ขนตอนตอไปทำการตดตงโปรแกรม uml-utilities (ทมคำสง tunctl) เพอใหสามารถจำลองสญญาณระบบเครอขาย (network traffic)
165
Embedded Android Development สเสนทางนกพฒนา
$ sudo apt-get install uml-utilities$ sudo tunctl -u $(whoami) -t tap1$ sudo ifconfig tap1 192.168.1.1$ sudo route add -net 192.168.1.0 netmask 255.255.255.0 dev tap1$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
ขนตอนสดทายทำการรนโปรแกรม QEMU เพอจำลองการทำงานบอรดสมองกลฝงตว (Versatile Board) และทำการโหลด root filesystem จากเครอง Host
$ qemu-system-arm -M versatilepb -m 128M -kernel ~/uImage -append "console=ttyAMA0 root=/dev/nfs rw nfsroot=192.168.1.1:~/nfsroot ip=192.168.1.101" -net nic -net tap,ifname=tap1,script=no -nographicSet 'tap1' persistent and owned by uid 1000SIOCADDRT: File existsUncompressing Linux... done, booting the kernel.Booting Linux on physical CPU 0x0Linux version 3.9.4 (student@marabuntu) (gcc version 4.7.3 (Buildroot 2013.05) ) #1 Mon Jul 22 11:44:32 PDT 2013CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00093177CPU: VIVT data cache, VIVT instruction cacheMachine: ARM-Versatile PBMemory policy: ECC disabled, Data cache writebacksched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956msBuilt 1 zonelists in Zone order, mobility grouping on. Total pages: 32512Kernel command line: console=ttyAMA0 root=/dev/nfs rw nfsroot=192.168.1.1:/home/student/nfsroot ip=192.168.1.101PID hash table entries: 512 (order: -1, 2048 bytes)Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)__ex_table already sorted, skipping sortMemory: 128MB = 128MB totalMemory: 126192k/126192k available, 4880k reserved, 0K highmemVirtual kernel memory layout: vector : 0xffff0000 - 0xffff1000 ( 4 kB) fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) vmalloc : 0xc8800000 - 0xff000000 ( 872 MB) lowmem : 0xc0000000 - 0xc8000000 ( 128 MB) modules : 0xbf000000 - 0xc0000000 ( 16 MB) .text : 0xc0008000 - 0xc0342850 (3307 kB) .init : 0xc0343000 - 0xc035f87c ( 115 kB) .data : 0xc0360000 - 0xc0385440 ( 150 kB) .bss : 0xc0385440 - 0xc039f78c ( 105 kB)NR_IRQS:224VIC @f1140000: id 0x00041190, vendor 0x41FPGA IRQ chip 0 "SIC" @ f1003000, 13 irqsConsole: colour dummy device 80x30Calibrating delay loop... 300.44 BogoMIPS (lpj=1502208)pid_max: default: 32768 minimum: 301Mount-cache hash table entries: 512CPU: Testing write buffer coherency: okSetting up static identity map for 0xc027e748 - 0xc027e7a0NET: Registered protocol family 16DMA: preallocated 256 KiB pool for atomic coherent allocationsSerial: AMBA PL011 UART driverdev:f1: ttyAMA0 at MMIO 0x101f1000 (irq = 44) is a PL011 rev1console [ttyAMA0] enableddev:f2: ttyAMA1 at MMIO 0x101f2000 (irq = 45) is a PL011 rev1
166
Embedded Android Development สเสนทางนกพฒนา
dev:f3: ttyAMA2 at MMIO 0x101f3000 (irq = 46) is a PL011 rev1...Console: switching to colour frame buffer device 80x60brd: module loadedphysmap platform flash device: 04000000 at 34000000physmap-flash physmap-flash.0: map_probe failedsmc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <[email protected]>eth0: SMC91C11xFD (rev 1) at c8800000 IRQ 57 [nowait]eth0: Ethernet addr: 52:54:00:12:34:56mousedev: PS/2 mouse device common for all miceTCP: cubic registeredNET: Registered protocol family 17VFP support v0.3: implementor 41 architecture 1 part 10 variant 9 rev 0eth0: link upIP-Config: Guessing netmask 255.255.255.0IP-Config: Complete: device=eth0, hwaddr=52:54:00:12:34:56, ipaddr=192.168.1.101, mask=255.255.255.0, gw=255.255.255.255 host=192.168.1.101, domain=, nis-domain=(none) bootserver=255.255.255.255, rootserver=192.168.1.1, rootpath=input: AT Raw Set 2 keyboard as /devices/fpga:06/serio0/input/input0input: ImExPS/2 Generic Explorer Mouse as /devices/fpga:07/serio1/input/input1VFS: Mounted root (nfs filesystem) on device 0:9.Freeing init memory: 112KStarting logging: OKInitializing random number generator... done.Starting network...ip: RTNETLINK answers: File exists
Welcome to Burapha Embedded System LabBurapha login: # ls# ls -altotal 20drwxr-xr-x 2 default default 4096 Jul 23 2013 .drwxr-xr-x 17 default default 4096 Jul 23 2013 ..-rw------- 1 root root 10 Jul 23 2013 .ash_history-rw-r--r-- 1 default default 0 May 31 2013 .bash_history-rw-r--r-- 1 default default 175 May 31 2013 .bash_logout-rw-r--r-- 1 default default 161 May 31 2013 .bash_profile#
167
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการสรางระบบจำลองเสมอนของบอรด RASPBERRY PI บน QEMU
ดาวนโหลดไฟล image ของบอรด Raspberry PI จาก http://www.raspberrypi.org/downloads และใหทำการเปลยนชอไฟลเปน wheezy-raspbian.img ดงขนตอนขางลางน
$ unzip 2013-07-26-wheezy-raspbian.zip$ mv 2013-07-26-wheezy-raspbian.img ~/qemu/wheezy-raspbian.img
ใชคำสง file เพอดรายละเอยดพารทชนภายในไฟล wheezy-raspbian.img
$ file wheezy-raspbian.imgwheezy-rasbian.img: x86 boot sector; partition 1: ID=0xc, starthead 130, startsector 8192, 114688 sectors; partition 2: ID=0x83, starthead 165, startsector 122880, 3665920 sectors, code offset 0xb8
นำคา startsector (122880) จาก partition 2 มาคณกบคา 512 จะไดคา offset เทากบ 62914560 แลวใหนำคา offset การใชในการ mount ไฟลชอ wheezy-raspbian.img เพอใหชไปยงไดเรกทอร /mnt ดงคำสงขางลางน
$ sudo mount wheezy-raspbian.img -o offset=62914560 /mnt
แกไขไฟล /mnt/etc/ld.so.preload แลวปดบรรทดคำสงดวยเครองหมาย # เพอไมใหโหลดไลบราร ดงขางลางน
...# /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so...
$ sudo umount /mnt
กอนรนโปรแกรม QEMU จำเปนตองดาวนโหลดลนกซคอรเนลเฉพาะสำหรบบอรด Raspberry Pi
168
Embedded Android Development สเสนทางนกพฒนา
$ cd ~/qemu/$ wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu$ qemu-system-arm -kernel ~/qemu/kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda ~/qemu/wheezy-raspbian.img
จากหนาตางขางบนจะสงเกตเหนวามการแสดงขอความลมเหลวจากการอานระบบไฟล (filesystem) เนองจากไมใชสทธ root ดงนนจะตองทำการซอมระบบไฟลดวยคำสงในฐานะ root อกครง
$ sudo fsck /dev/sda2
คำสง fsck กจะทำการตรวจสอบและซอมระบบไฟลดงแสดงในรปขางลาง
ในกรณตองการตงคาสำหรบบอรด Raspberry Pi โดยเฉพาะ สามารถรนคำสงดงน
root@raspberrypi# raspi-config
169
Embedded Android Development สเสนทางนกพฒนา
จากเมนดานบนสามารถตงคาอนตามทตองการไดเชน ตองการใหบทเขาส GUI Mode ดงนนใหเลอกขอท 3 (Enable Boot to Desktop) และเรมบทเขาระบบใหมอกครงกจะเขาส GUI Mode ดงแสดงขางลาง
รปท 3.29 แสดงการเขาสระบบปฏบตการภายใน Raspberry Pi บน QEMU
170
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการสรางระบบจำลองเสมอนของบอรด Friendly ARM (Mini2440) บน QEMU
บอรด FriendlyARM Mini2440 หรอนยมเรยกสนๆวาบอรด Mini2440 ไดถกออกแบบในลกษณะเปนบอรดชนด SBC (Single-Board Computer) ทใชหนวยประมวลผลกลาง ARM9 ซงเปน System-on-Chip รน Samsung S3C2440
รปท 3.30 บอรด Friendly ARM Mini2440
นกพฒนาสามารถเรยนรการทำงานของระบบปฏบตการภายในบอรด Mini2440 โดยเลนอยบนโปรแกรม QEMU ทจำลองการทำงานของบอรด โดยทำการตดตงโปรแกรมและแพกเกตทเกยวของดงตอไปน (อางองมาจาก http://project4fun.com/node/33)
$ sudo apt-get -y update$ sudo apt-get -y install build-essential$ sudo apt-get -y install git-core$ sudo apt-get -y install zlib1g-dev$ sudo apt-get -y install libsdl-console-dev$ sudo apt-get -y install ia32-libs$ sudo apt-get -y install bridge-utils$ sudo apt-get -y install uml-utilities$ sudo apt-get -y install qemu-utils$ sudo apt-get -y install nbd-client$ sudo apt-get -y install kpartx
ตดตง cross-compiling toolchains
# cd /opt# wget http://dl-12.one2up.com/onetwo/content/2012/12/24/614ca76f9a53c060bd8cfa7effd541f6.tgz# mv 614ca76f9a53c060bd8cfa7effd541f6.tgz arm920t-eabi.tgz
171
Embedded Android Development สเสนทางนกพฒนา
# tar xzvf arm920t-eabi.tgz -C /# export PATH=\$PATH:/opt/toolchains/arm920t-eabi/bin# export CROSS_COMPILE=arm-angstrom-linux-gnueabi-
คดลอกขอมลจาก git://repo.or.cz/qemu/mini2440.git ดงน
$ mkdir ~/eeburapha/qemu$ cd ~/eeburapha/qemu$ git clone git://repo.or.cz/qemu/mini2440.git...Receiving objects: 100% (xxxxx/xxxxx), xx.xx MiB | xxxx KiB/s, done.Resolving deltas: 100% (xxxxx/xxxxx), done.
คอมไพลไบนาร qemu ทซพพอรต Mini2440
$ cd mini2440$ wget http://dl-10.one2up.com/onetwo/content/2013/9/10/fde6b403a54066a6aa13838f7588b91e.patch$ mv fde6b403a54066a6aa13838f7588b91e.patch bug_SIGFPE.patch$ patch –p0 < bug_SIGFPE.patch$ ./configure --target-list=arm-softmmu$ make
แกไขไฟล mini2440_start.sh ใหมรายละเอยดดงขางลางน
$ vim ~/eeburapha/qemu/mini2440/mini2440/mini2440_start.shecho Starting in $basename_nand="$base/mini2440_nand.bin"name_sd="$base/sd.img"if [ ! -f "$name_nand" ]; thenecho $0 : creating NAND empty image : "$name_nand"dd if=/dev/zero of="$name_nand" bs=528 count=131072ficmd="$base/../arm-softmmu/qemu-system-arm \-M mini2440 $* \-serial stdio \-mtdblock "$name_nand" \-sd $name_sd \-show-cursor \-usb -usbdevice keyboard -usbdevice mouse \-net nic,vlan=0 \-net tap,vlan=0,ifname=tap1,script=/etc/qemu-ifup \-monitor telnet::5555,server,nowait"echo $cmd$cmd
สรางไฟล network.sh
$ vim network.sh
172
Embedded Android Development สเสนทางนกพฒนา
#!/bin/shsudo chown root.users /dev/net/tunsudo chmod g+rw /dev/net/tunsudo brctl addbr br0sudo ifconfig eth0 0.0.0.0 promiscsudo brctl addif br0 eth0sudo dhclient br0sudo tunctl -t tap1 -u `whoami`
$ chmod 755 network.sh
สรางไฟล qemu-ifup ไวในไดเรกทอร /etc/
$ vim qemu-ifup#!/bin/shecho "Executing /etc/qemu-ifup"echo "Bringing up $1 for bridged mode..."sudo /sbin/ifconfig $1 0.0.0.0 promisc upecho "Adding $1 to br0..."sudo /sbin/brctl addif br0 $1sleep 2
$ chmod 755 qemu-ifup
สรางไฟล u-boot.bin
$ cd ~/eeburapha/qemu/mini2440/mini2440$ mkdir uboot$ cd uboot$ git clone git://repo.or.cz/u-boot-openmoko/mini2440.git$ cd mini2440$ make mini2440_config$ make alldd if=u-boot.bin of=u-boot-nand2k.bin bs=2K conv=sync119+1 records in120+0 records out245760 bytes (246 kB) copied, 0.000734641 s, 335 MB/sdd if=u-boot.bin of=u-boot-nand16k.bin bs=16K conv=sync14+1 records in15+0 records out245760 bytes (246 kB) copied, 0.000435712 s, 564 MB/s
แลวใหทำการคดลอกไฟล u-boot.bin กลบไปยงไดเรกทอร ~/eeburapha/qemu/mini2440/mini2440
สรางไฟล sd image
$ cd eeburapha/qemu/mini2440/
173
Embedded Android Development สเสนทางนกพฒนา
$ qemu-img create sd.img 256MFormatting 'sd.img', fmt=raw size=268435456$ sudo modprobe nbd$ sudo modprobe dm-mod$ qemu-nbd -p 24561 sd.img &$ sudo nbd-client localhost 24561 /dev/nbd0Negotiation: ..size = 256MBbs=1024, sz=268435456 bytes$ sudo fdisk -u=cylinders /dev/nbd0Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabelBuilding a new DOS disklabel with disk identifier 0xe5f5bdf3.Changes will remain in memory only, until you decide to write them.After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
WARNING: cylinders as display units are deprecated. Use command 'u' to change units to sectors.
Command (m for help): oBuilding a new DOS disklabel with disk identifier 0x1999a406.Changes will remain in memory only, until you decide to write them.After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
WARNING: cylinders as display units are deprecated. Use command 'u' to change units to sectors.
Command (m for help): nPartition type: p primary (0 primary, 0 extended, 4 free) e extendedSelect (default p): pPartition number (1-4, default 1): 1First cylinder (1-32, default 1):Using default value 1Last cylinder, +cylinders or +size{K,M,G} (1-32, default 32): +50MB
Command (m for help): tSelected partition 1Hex code (type L to list codes): bChanged system type of partition 1 to b (W95 FAT32)
Command (m for help): nPartition type: p primary (1 primary, 0 extended, 3 free) e extendedSelect (default p): pPartition number (1-4, default 2): 2First cylinder (7-32, default 7):Using default value 7
174
Embedded Android Development สเสนทางนกพฒนา
Last cylinder, +cylinders or +size{K,M,G} (7-32, default 32):Using default value 32
Command (m for help): p
Disk /dev/nbd0: 268 MB, 268435456 bytes255 heads, 63 sectors/track, 32 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisk identifier: 0x1999a406
Device Boot Start End Blocks Id System/dev/nbd0p1 1 7 55203 b W95 FAT32/dev/nbd0p2 7 32 200813 83 Linux
Command (m for help): wThe partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: If you have created or modified any DOS 6.xpartitions, please see the fdisk manual page for additionalinformation.Syncing disks.
$ sudo kpartx -a /dev/nbd0$ sudo mkfs.vfat /dev/mapper/nbd0p1$ sudo mkfs.ext3 /dev/mapper/nbd0p2$ mkdir disk$ sudo mount /dev/mapper/nbd0p2 ./disk$ mkdir -p disk/boot$ sudo mount /dev/mapper/nbd0p1 ./disk/boot$ wget http://mini2440.googlecode.com/files/emdebian-grip-090306-armel-lenny-installed.tar.bz2$ (cd disk; sudo tar jxf ../emdebian-grip-090306-armel-lenny-installed.tar.bz2)$ sudo umount disk/boot disk$ sudo nbd-client -d /deb/nbd0
แลวใหทำการคดลอกไฟล sd.img ไปวางไวท ~/eeburapha/qemu/mini2440/mini2440 และเรมการรน mini2440 ดวยคำสง
$ cd ~/eeburapha/qemu/mini2440/mini2440$ ./network.shSet 'tap1' persistent and owned by uid 1000$ ./ mini2440_start.sh
*** Warning - bad CRC or NAND, using default environment
175
Embedded Android Development สเสนทางนกพฒนา
USB: S3C2410 USB DevicedERROR: usbd_device_event_irq(), 613: (3401ea64,1) NULL device or device->busERROR: usbd_device_event_irq(), 613: (3401ea64,2) NULL device or device->busERROR: usbd_device_event_irq(), 613: (3401ea64,3) NULL device or device->busIn: serialOut: serialErr: serialMAC: 08:08:11:18:12:27Hit any key to stop autoboot: 0 MINI2440 #
ทำการฟอรแมท nand
# nand scrub"NAND scrub: device 0 whole chipWarning: scrub option will erase all factory set bad blocks! There is no reliable way to recover them. Use this command only for testing purposes if you are sure of what you are doing!
Really scrub this NAND flash? <y/N>Erasing at 0x3ffc000 -- 100% complete.Bad block table not found for chip 0Bad block table not found for chip 0OK
สราง bad block table
# nand createbbtCreate BBT and erase everything ? <y/N>Skipping bad block at 0x03ff0000 Skipping bad block at 0x03ff4000 Skipping bad block at 0x03ff8000 Skipping bad block at 0x03ffc000
Creating BBT. Please wait ...Bad block table not found for chip 0Bad block table not found for chip 0Bad block table written to 0x03ffc000, version 0x01Bad block table written to 0x03ff8000, version 0x01
สรางทเกบขอมลตวแปรระบบ (env)
# dynenv set 40000device 0 offset 0x40000, size 0x3fc000045 4e 56 30 - 00 00 04 00
ขนตอนสดทายทำการ reset จะได emulator ทพรอมใชงานโดยสามารถคดลอกขอมลใส sd.img ได
# resetS3C: CLK=240 HCLK=240 PCLK=240 UCLK=57QEMU mini2440_reset: loaded default u-boot from NAND
176
Embedded Android Development สเสนทางนกพฒนา
QEMU mini2440_reset: loaded override u-boot (size 3c000)S3C: CLK=240 HCLK=240 PCLK=240 UCLK=48S3C: CLK=304 HCLK=304 PCLK=304 UCLK=48S3C: CLK=304 HCLK=101 PCLK=50 UCLK=48S3C: CLK=304 HCLK=76 PCLK=38 UCLK=48S3C: CLK=304 HCLK=76 PCLK=38 UCLK=48S3C: CLK=405 HCLK=101 PCLK=50 UCLK=48
U-Boot 1.3.2-moko12 (Jun 26 2009 - 18:16:16)
I2C: readyDRAM: 64 MBFlash: 2 MBNAND: 64 MiBFound Environment offset in OOB..USB: S3C2410 USB DevicedIn: serialOut: serialErr: serialMAC: 08:08:11:18:12:27Hit any key to stop autoboot: 0MINI2440 #
177
Embedded Android Development สเสนทางนกพฒนา
บทท 4 พนฐานการเขยนโปรแกรมภาษา C/C++ และ QT สำหรบนกพฒนา
พนฐานการเขยนโปรแกรมภาษา C/C++ สำหรบการพฒนาบนระบบสมองกลฝงตว
ในมมมองการพฒนาโปรแกรมภายใตระบบปฏบตการลนกซทอยบนระบบสมองกลฝงตวนนจะไมแตกตางจากการพฒนาโปรแกรมภายใตระบบปฏบตการลนกซบนเครองคอมพวเตอรทวไป ดงนนนกพฒนาทคนเคยกบการเขยนโปรแกรมพนฐานไมวาจะเปนโปรแกรมภาษาซ/ซพลสพลส ไมจำเปนตองเพมเตมทกษะอะไรมากมายเปนพเศษ เนองจากไลบรารหรอโปรแกรมทพฒนาจากนกพฒนาคนอนๆเกอบทงหมดนน จะยงคงสามารถนำมาคอมไพลและทำงานไดเชนเดม แตอยางไรกตามสงทนกพฒนาโปรแกรมภายใตระบบสมองกลฝงตวตองพงระวงคอขอจำกดทางดานทรพยากรภายในระบบสมองกลฝงตวไมวาจะเปนความเรวในการประมวลผลกลาง พนทหนวยความจำ พนทตวเกบขอมลแบบชวคราวหรอถาวร รวมทงการใชพลงงานไฟฟาจากแบตเตอร เปนตน
ภาษาโปรแกรมทเหมาะสมสำหรบระบบสมองกลฝงตวคงปฏเสธไมไดทจะเรมตนดวยภาษาซ (C Language) เนองจากเปนภาษาพนฐานทใชในการพฒนาโปรแกรมระบบภายในระบบปฏบตการลนกซและเปนไลบรารมากกวารอยละ 80 ดงนนเมอนกพฒนาตดตงระบบปฏบตการลนกซพนฐานลงไปในเครองคอมพวเตอรแลวกสามารถเรมตนเขยนโปรแกรมไดทนท รวมทงยงสามารถเรยกใชไลบรารพนฐานตางๆไดเชน การจดการระบบไฟล การจดการอปกรณ I/O การจดการระบบเครอขาย ระบบจดการโปรเซส เปนตน นอกจากนนภาษาซพลสพลส (C++) ซงมพนฐานของการเขยนโปรแกรมเชงวตถ (Object oriented Programming - OOP) เหมาะกบนกพฒนาทตองการพฒนาโปรแกรมประยกตทมความซบซอนและมขนาดใหญรวมถงการใชแนวคดในการพฒนาโปรแกรมแนวใหมดวยวธการแบบ OOP นกพฒนาจะตองตดตงตวคอมไพล (Compiler) เครองมอ (C++ Tools) และไลบราร (C++ library) เพมเตมเพอใหสามารถรองรบการเขยนโปรแกรมภาษาซพลสพลสไดอยางสมบรณ
178
Embedded Android Development สเสนทางนกพฒนา
พนฐานการสราง MAKEFILE
Makefile (GNU automake system) คอภาษาโปรแกรมประเภทหนงทเปนการรวมเอาคำสงหรอสครปททชวยใหการคอมไพลโคดโปรแกรมเพอใหสะดวกขน โดยขนตอนการคอมไพลนนจะใชคำสง make ซงเปนคำสงทสามารถถกเรยกใชงานไดอยบนเชลล โดยจะทำการอานรายละเอยดทอยภายในไฟลชอ “Makefile” ซงบรรจการตงคาการคอมไพลตางๆไว เชน การอางองไลบรารทเกยวของ โคดไฟลเสรมทเกยวของ เปนตน องคประกอบภายใน Makefile ประกอบไปดวย
(Macros)! VARIABLE DECLARATIONS
(Targets)! TARGET:! DEPENDENCIES! ! RULES TO BUILD TARGET
โดยท (Macros) จะถกเขยนอยในรปแบบการกำหนดคาตวแปร ตวอยางเชน
CC=gccOPT=-g
เมอถกเรยกภายใน (Targets) จะเขยนตามรปแบบขางลางน
$(CC) a_source_file.c
นอกจากนนยงสามารถระบไดมากกวาหนงตวแปรเพอใหกลายเปนตวแปรใหม ดงตวอยางขางลาง
COMP = $(CC) $(OPT)
รายการ (Targets) คอรายการทระบไววาใหทำการคอมไพลไฟลทระบไว (dependencies) ซงวธการเขยนนนคอนขางมรายละเอยดในการจดรปแบบโดยเฉพาะการใช whitespace (spacebar และ tab) ถาไมไดจดตามรปแบบดงแสดงขางลางคำสง make กอาจจะไมสามารถอานสครปทเพอใชคอมไพลได ดงแสดงขางลาง tab space space | | |target:" dependency1 dependency2 dependency3" rule1" rule2" rule3^^^^^|tab
179
Embedded Android Development สเสนทางนกพฒนา
ตวอยางไฟล Makefile อยางงายแบบท 1all: hello
hello: main.o factorial.o hello.o! g++ main.o factorial.o hello.o -o hellomain.o: main.cpp! g++ -c main.cppfactorial.o: factorial.cpp! g++ -c factorial.cpphello.o: hello.cpp! g++ -c hello.cppclean:! rm -rf *o hello
ตวอยางไฟล Makefile อยางงายแบบท 2ใช macro เพอสรางตวแปร CC และ CFLAGS
# the compiler to useCC=g++# options passed to the compilerCFLAGS=-c -Wall
all: hello
hello: main.o factorial.o hello.o! $(CC) main.o factorial.o hello.o -o hellomain.o: main.cpp! $(CC) $(CFLAGS) main.cppfactorial.o: factorial.cpp! $(CC) $(CFLAGS) factorial.cpphello.o: hello.cpp! $(CC) $(CFLAGS) hello.cppclean:! rm -rf *o hello
ตวอยางไฟล Makefile อยางงายแบบท 3สรางตวแปร SOURCES, OBJECTS และ EXECUTABLE เพอรวมไฟลโปรแกรมเขาดวยกน
CC=g++CFLAGS=-c -WallLDFLAGS=SOURCES=main.cpp hello.cpp factorial.cppOBJECTS=$(SOURCES:.cpp=.o)EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)!
180
Embedded Android Development สเสนทางนกพฒนา
$(EXECUTABLE): $(OBJECTS) ! $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected]:! $(CC) $(CFLAGS) $< -o $@clean:! rm -rf $(OBJECTS) $(EXECUTABLE)
ตวอยางไฟล Makefile อยางงายแบบท 4ในกรณทมการอางอง (include) ไฟล header (.h) เพมหรอไลบรารภายนอกเพมเตม จะตองใส option -I และ -l เพมเขาไป
CC=g++CFLAGS=-c -WallLDFLAGS=SOURCES=main.cpp hello.cpp factorial.cppOBJECTS=$(SOURCES:.cpp=.o)MY_INCLUDES=/home/student/project/myLib/MY_LIBRARIES=zlib fltkEXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)!$(EXECUTABLE): $(OBJECTS) ! $(CC) -I$(MY_INCLUDES) $(LDFLAGS) $(OBJECTS) -o $@ -l$(MY_LIBRARIES)@echo “Compile hello completed...” .cpp.o:! $(CC) $(CFLAGS) $< -o $@@echo “Compile all object files completed...”clean:! rm -rf $(OBJECTS) $(EXECUTABLE)@echo “Clean all object files and hello program done...”
การสรางและอางองไลบรารขบวนการคอมไพลในระบบปฏบตการลนกซจากโคดโปรแกรม (source code) จนกลายมาเปน
โปรแกรมทสามารถใชงานหรอรนได (executable file) นน ประกอบไปดวยหลายขนตอนดงแสดงในรปขางลาง โดยมขนตอนคอเมอมการคอมไพลโคดโปรแกรม (.c) จะไดไฟลออกมาเปนชนดไบนารไฟล ทเรยกวา ออพเจคโคด (object code) ซงมนามสกลไฟลเปน “.o” ไฟลออพเจคโคดเหลานสามารถถกรวมกนโดยใชโปรแกรม ar (archiver) เพอใหกลายเปนไฟลไลบรารหรอจะถกแปลงใหเปนโปรแกรมทสามารถรนได (executable file) ดวยโปรแกรม ld (linker)
181
Embedded Android Development สเสนทางนกพฒนา
ไฟลโคดโปรแกรม (.c)
Compiler ไฟลออปเจค (.o)
ไลบราร (.a หรอ .so)Archiver
โปรแกรม (executable)
ไฟลไลบรารทเกยวของ
ไฟลโคดโปรแกรม (.c)
Compiler ไฟลออปเจค (.o) Linker
ไฟล Embedded Binary/Hex)
Translator
รปท 4.1 แสดงขนตอนการสรางไฟลไลบรารและโปรแกรมสำหรบเขยนลงบอรดสมองกลฝงตว
ในกรณทเปนระบบคอมพวเตอรทวไป ตวไลบรารและไฟลออพเจคโคดนนจะถกเชอมรวมกนจนกลายเปนไฟลโปรแกรม (executable file) แตในกรณระบบสมองกลฝงตวทใชไมโครคอนโทรเลอรนนจะตองนำไฟลโปรแกรมมาแปลงใหเปนไฟลแบบไบนารหรอไมกเปนไฟลสกล .hex เสยกอนเพอทจะสามารถถกโหลดเขาไปในหนวยความจำแบบแฟลชของบอรดสมองกลฝงตวได
จากตวอยางขางลางเปนตวอยางพนฐานในการเขยนโปรแกรมทจะตองมการสรางไลบรารและพฒนาโปรแกรมเพอเรยกใชไลบราร ในตารางขางลางแสดงโคดโปรแกรมทมอย 2 ไดเรกทอรยอยไดแก ไดเรกทอร src/ และ ไดเรกทอร inc/
ไดเรกทอร SRC/ ไดเรกทอร INC/
main.c
func1.c func1.h
func2.c func2.h
182
Embedded Android Development สเสนทางนกพฒนา
ไดเรกทอร SRC/ ไดเรกทอร INC/
func3.c func3.h
รายละเอยดในการสรางไลบรารนนจะมดวยกน 2 แบบคอ สแตตกไลบราร (static library) และ ไดนามกไลบราร (dynamic library) ดงตวอยางขางลาง
ตวอยางการสรางไลบรารชนด static
$ gcc -c src/func1.c src/func2.c src/func3.c -I./inc
$ ar libmine.a func1.o func2.o func3.o
ตวอยางการสรางไลบรารชนด dynamic
$ gcc -shared -o libmine.so func1.o func2.o func3.o -I./inc
เมอสรางไลบรารเรยบรอยแลวสามารถนำไลบรารเหลานไปใชกบโปรเจคอนๆได ดงตวอยางขางลาง
$ gcc src/main.c libmine.a -I/inc -o myprogram
หรอ
$ gcc src/main.c -lmine -L./ -I/inc -o myprogram
เพอความสะดวกในการคอมไพลโปรแกรมและอางองไลบรารตางๆ สามารถสรางไฟล Makefile ดงตวอยางขางลาง CC=gccCFLAGS=-c -WallLDFLAGS=SOURCES=main.cOBJECTS=$(SOURCES:.c=.o)MY_INCLUDES=/home/student/project/inc/# MY_STATIC_LIBRARIES=libmine.aMY_DYNAMIC_LIBRARIES=mineEXECUTABLE=myprogram
all: $(SOURCES) $(EXECUTABLE)!$(EXECUTABLE): $(OBJECTS) ! $(CC) -I$(MY_INCLUDES) $(LDFLAGS) $(OBJECTS) -o $@ -l$(MY_DYNAMIC_LI-BRARIES)@echo “Compile hello completed...”
.c.o:! $(CC) $(CFLAGS) $< -o $@
183
Embedded Android Development สเสนทางนกพฒนา
@echo “Compile all object files completed...”
clean:! rm -rf $(OBJECTS) $(EXECUTABLE)@echo “Clean all object files and hello program done...”
การพฒนาโปรแกรมเพอเขาถงระบบไฟลในระบบสมองกลฝงตวนกพฒนามโอกาสในการทจะตองทำการบนทกขอมลทไดจากการรบคา
สถานะจากเซนเซอรตางๆเพอเกบลงไปในไฟลหรอจะทำการเปดอานไฟลทระบบปฏบตการไดบนทกขอมลไวแลว ดงนนการพฒนาโปรแกรมเพอเขาถงระบบไฟลจงเปนพนฐานแรกๆของการเรยนรของนกพฒนา โดยการเรยกฟงกชนทเตรยมไวใหภายในไลบราร stdio.h ดงตวอยางขางลาง
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);int fprintf(FILE *stream, const char *format, ...);int fscanf(FILE *stream, const char *format, ...);int fflush(FILE *stream);int fclose(FILE *stream);
การเขาถงระบบไฟลนนมอย 3 โหมดไดแก อานไดเทานน (O_RDONLY) เขยนไดเทานน (O_WRONLY) และ อานและแกไขได (O_RDWR)
ตวอยางโปรแกรมสำหรบการอานไฟลและแกไขไฟล// file_manipulation.c#include <stdio.h>#include <string.h>
int usage(){
printf("\n"); printf("Usage : file Manipulation [OPTION] [FILE]\n"); printf("Demo for text file operation, read and write. [Jamp II]\n"); printf(" -r \t\t read operation\n"); printf(" -w \t\t write operation\n"); printf("\n");
return 0;}
int check_operation(char *opt){
184
Embedded Android Development สเสนทางนกพฒนา
if(!strcmp(opt, "-r")){ // read operation return 0; } else if(!strcmp(opt, "-w")){ // write operation return 1; } else{ // error return -1; }}
int main(int argc, char *argv[]){
FILE *file; int opt;
// check for argument if(argc != 3){ usage();
return 0; }
// check for getting operation if((opt = check_operation(argv[1])) < 0){ usage();
return 0; }
// start file operation if(file = fopen(argv[2], (argv[1]+1))){ char dataBuf[256];
if(opt == 0){ // READ printf("****************** READ *******************\n");
while(fgets(dataBuf, 256, file) != 0){ printf("%s", dataBuf);
memset(dataBuf, 0, 256); } printf("*******************************************\n"); } else{ // WRITE printf("***************** WRITE *******************\n"); while(1){ memset(dataBuf, 0, 256);
gets(dataBuf);
185
Embedded Android Development สเสนทางนกพฒนา
if(!strcmp(dataBuf, ":exit")) break;
fprintf(file, "%s\n", dataBuf); }
printf("*******************************************\n"); }
fclose(file); } else{ printf("Can not open file\n"); }
return 0;}
ตวอยางไฟล Makefile สำหรบโปรแกรม file_manipulation.c เพอทำการคอมไพลดวยโปรแกรมคำสง arm-linux-gcc สำหรบสถาปตยกรรม ARM## Makefile!: File Manipulation sample Program ## Macro# CROSS_COMPILE= CROSS_COMPILE=arm-linux-CC=$(CROSS_COMPILE)gccCFLAGS=-OsLDFLAGS=-Os -static
# Targetsall: file_manipulation
fileOpt: file_manipulation.o! $(CC) $(LDFLAGS) $< -o $@
fileOpt.o: file_manipulation.c! $(CC) $(CFLAGS) -c -o $@ $<
clean: ! rm -rf *.o file_manipulation
186
Embedded Android Development สเสนทางนกพฒนา
การพฒนาโปรแกรมตดตอผานพอรตอนกรมการส อสารขอมลแบบอนกรมเปนรปแบบการส อสารขอมลรากฐานตวหน งท ใชกบอปกรณ
คอมพวเตอรผานพอรตอนกรมเชน โมเดม, เมาส หรอ คยบอรด โดยรปแบบการสอสารของพอรตชนดนจะเปนการสงขอมลแบบทละบต (bit-by-bit) บนมาตรฐานการสงขอมลแบบ RS-232 ซงจะตางจากพอรตขนาน (parallel port) ทจะมการสงขอมลพรอมกนทละหลายๆบต (8-bit) โดยความเรวของการสงขอมลแบบอนกรมจะขนอยกบความถทเลอกใชในการสงขอมล ขอดของการสอสารขอมลแบบอนกรมคอสามารถสงขอมลไดในระยะทางทไกลกวาและใชสายสญญาณทนอยกวาการสอสารขอมลแบบขนาน
ประเภทของการสอสารแบบอนกรมแบงตามลกษณะสญญาณในการสงได 2 แบบ ไดแก
1. การสอสารแบบซงโครนส (Synchronous) เปนการสอสารขอมลโดยใชสญญาณนาฬกาในการควบคมจงหวะของการรบสงสญญาณ
รปท 4.2 แสดงการสงขอมลแบบซงโครนส
2. การสอสารแบบอะซงโครนส (Asynchronous) เปนการสอสารทใชสายขอมลเพยงตวเดยว จะใชรปแบบของการสงขอมล (Bit Pattern) เปนตวกำหนดวาสวนไหนเปนสวนเรมตนขอมล สวนไหนเปนตวขอมล สวนไหนจะเปนตวตรวจสอบความถกตองของขอมล และสวนไหนเปนสวนปดทายของขอมล โดยตองกำหนดใหสญญาณนาฬกาเทากนทงภาคสงและภาครบ
รปท 4.3 แสดงการสงขอมลแบบอะซงโครนส
ระบบสอสารภายในระบบสมองกลฝงตวสวนใหญจะเปนแบบอะซงโครนส ซงมความสามารถในการทำหนาทรบและสงขอมลแบบไมตองมสญญาณนาฬกาพวงไปดวย เรยกวา UART (Universal Asyn-chronous Receiver Transmitter) โดยสวนใหญจะใชมาตรฐานการสอสารแบบ RS-232 ถาตดตงบนคอมพวเตอรทวไปจะเรยกวา COMPORT เมอเขามาตรฐาน RS-232 แลวระดบแรงดนตองปรบเปลยนใหเปนไฟบวกลบเพอลดสญญาณรบกวนและสามารถสงไปไดระยะทางหลายสบเมตร สำหรบในไมโครคอนโทรลเลอร เชน PIC, MCS-51 หรอ AVR สวนใหญจะมโมดล UART ทมอยภายในเพอชวยในการสอสารขอมลระหวางตวไมโครคอนโทรลเลอรและคอมพวเตอรแตจะมระดบสญญาณเปนระดบสญญาณ TTL (5V) หากตองการเชอมตอกบคอมพวเตอรโดยตรงจะตองตอวงจรเพมเตมเพอทำการแปลงระดบแรงดนดวยไอซ MAX232
187
Embedded Android Development สเสนทางนกพฒนา
ขาสญญาณทใชในการสอสารสวนใหญจะม 2 ขาหลกคอขารบขอมล (RxD) และ ขาสงขอมล (TxD) โดยมาตรฐานการสอสารจะตองตรงกนทงตวรบและตวสง เชนบอดเรต (baudrate) 9600 บตตอวนาท จำนวนบตเรม บตหยด บตพารต และจำนวนบตขอมล
ตาราง 4.1 ไฟลชนด character ตางๆทอยภายในไดเรกทอร /dev
อปกรณ ชอไฟล MAJOR MINOR
Parallel port 0 /dev/lp0 หรอ /dev/par0 6 0
Parallel port 1 /dev/lp1 หรอ /dev/par1 6 1
1st Serial port /dev/ttyS0 4 64
2nd Serial port /dev/ttyS1 4 65
IDE tape drive /dev/ht0 37 0
1st SCSI tape drive /dev/st0 9 0
2nd SCSI tape drive /dev/st1 9 1
System Console /dev/console 5 1
1st Virtual Terminal /dev/tty1 4 1
2nd Virtual Terminal /dev/tty2 4 2
Process current terminal /dev/tty 5 0
Sound card /dev/audio 14 4
ตวอยางการเขยนโปรแกรมเพอตดตอผานพอรตอนกรม (/dev/ttySx หรอ /dev/ttyUSBx) ภายใตระบบปฏบตการลนกซ// serial_thread.c#include <stdio.h> /* Standard input/output definitions */#include <string.h> /* String function definitions */#include <unistd.h> /* UNIX standard function definitions */#include <fcntl.h> /* File control definitions */#include <errno.h> /* Error number definitions */#include <termios.h> /* POSIX terminal control definitions */#include <pthread.h> /* Create pthread to run reading prog in background */
struct serial_data { int fd, nbytes, portsite; /* device file */ char *bufptr; /* set pointer of buffer */ char buffer[255], data[255]; /* target buffer to get from pointer */};
struct serial_data ffuart;
void *ffuart_thread() { ffuart.portsite = 1;
188
Embedded Android Development สเสนทางนกพฒนา
ffuart.fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY); if (ffuart.fd == -1) { /* Could not open the port. */ perror("open_port: Unable to open /dev/ttyS1 - "); } else { struct termios options; fcntl(ffuart.fd, F_SETFL, 0); tcgetattr(ffuart.fd, &options); cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); options.c_cflag |= (CLOCAL | CREAD); options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); options.c_oflag &= ~OPOST; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 10; tcsetattr(ffuart.fd, TCSANOW, &options); printf("Port is scanning. ^^\n"); ffuart.bufptr = ffuart.buffer; /* set buffer to get from pointer */ printf("Hey! You Reading yet.\n"); printf("Now working in ST Port.\n"); while (1) { printf("ReadingFF\n"); ffuart.nbytes = read(ffuart.fd, ffuart.buffer, 255); if (ffuart.nbytes != 0) { ffuart.buffer[8] = '\0'; printf("From %d side : %s\n", ffuart.portsite, ffuart.buffer); } } } close(ffuart.fd);}
int main() { pthread_t ff_tid; int rc; printf("FF_Thread creating!!\n"); rc = pthread_create(&ff_tid, NULL, ffuart_thread, (void *) NULL); if (rc) { printf("ERROR; return code from pthread_create() is %d\r\n", rc); exit(-1); } printf("FF_Thread created!!\t[Complete!!]\n"); pthread_join(ff_tid, NULL); printf("Created all!!\t[Complete!!]\n"); pthread_exit(NULL);}
189
Embedded Android Development สเสนทางนกพฒนา
ตวอยางไฟล Makefile สำหรบโปรแกรม serial_thread.c ททำงานไดบนสถาปตยกรรม ARM
## Makefile! : Serial communication Sample Program #
CROSS_COMPILE=arm-linux-uclibc-CC=$(CROSS_COMPILE)gccSOURCES=serial_thread.cOBJECTS=$(SOURCES:.c=.o)CFLAGS=-OsLDFLAGS=-Os -lm -staticLIBRARIES=pthreadEXECUTABLE=serial_thread
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) ! $(CC) $(LDFLAGS) $(OBJECTS) -o $@ -l$(LIBRARIES)
.c.o:! $(CC) $(CFLAGS) $< -o $@
clean:! rm -rf $(OBJECTS) $(EXECUTABLE)
ตวอยางถดไปคอตวอยางการสอสารผานพอรตอนกรมระหวางเครองคอมพวเตอร 2 เครอง
// serial_chat.c#include <termios.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <sys/signal.h>#include <sys/types.h>
#define BAUDRATE B38400#define MODEMDEVICE "/dev/ttyS1"#define _POSIX_SOURCE 1 //POSIX compliant source#define FALSE 0#define TRUE 1
volatile int STOP=FALSE;
void signal_handler_IO (int status); //definition of signal handlerint wait_flag=TRUE; //TRUE while no signal receivedchar devicename[80];long Baud_Rate = 38400; // default Baud Rate (110 through 38400)long BAUD; // derived baud rate from command linelong DATABITS;long STOPBITS;
190
Embedded Android Development สเสนทางนกพฒนา
long PARITYON;long PARITY;int Data_Bits = 8; // Number of data bitsint Stop_Bits = 1; // Number of stop bitsint Parity = 0; // Parity as follows: // 00 = NONE, 01 = Odd, 02 = Even, 03 = Mark, 04 = Spaceint Format = 4;FILE *input;FILE *output;int status;
main(int Parm_Count, char *Parms[]){ char version[80] = " POSIX compliant Communications test program version 1.00 4-25-1999\r\n"; char version1[80] = " Copyright(C) Mark Zehner/Peter Baumann 1999\r\n"; char version2[80] = " This code is based on a DOS based test program by Mark Zeh-ner and a Serial\r\n"; char version3[80] = " Programming POSIX howto by Peter Baumann, integrated by Mark Zehner\r\n"; char version4[80] = " This program allows you to send characters out the speci-fied port by typing\r\n"; char version5[80] = " on the keyboard. Characters typed will be echoed to the console, and \r\n"; char version6[80] = " characters received will be echoed to the console.\r\n"; char version7[80] = " The setup parameters for the device name, receive data for-mat, baud rate\r\n"; char version8[80] = " and other serial port parameters must be entered on the command line \r\n"; char version9[80] = " To see how to do this, just type the name of this program. \r\n"; char version10[80] = " This program is free software; you can redistribute it and/or modify it\r\n"; char version11[80] = " under the terms of the GNU General Public License as pub-lished by the \r\n"; char version12[80] = " Free Software Foundation, version 2.\r\n"; char version13[80] = " This program comes with ABSOLUTELY NO WARRANTY.\r\n"; char instr[100] ="\r\nOn the command you must include six items in the following order, they are:\r\n"; char instr1[80] =" 1. The device name Ex: ttyS0 for com1, ttyS1 for com2, etc\r\n"; char instr2[80] =" 2. Baud Rate Ex: 38400 \r\n"; char instr3[80] =" 3. Number of Data Bits Ex: 8 \r\n"; char instr4[80] =" 4. Number of Stop Bits Ex: 0 or 1\r\n"; char instr5[80] =" 5. Parity Ex: 0=none, 1=odd, 2=even\r\n"; char instr6[80] =" 6. Format of data received: 1=hex, 2=dec, 3=hex/asc, 4=dec/asc, 5=asc\r\n"; char instr7[80] =" Example command line: serial_chat ttyS0 38400 8 0 0 4 \r\n"; char Param_strings[7][80]; char message[90];
int fd, tty, c, res, i, error;
191
Embedded Android Development สเสนทางนกพฒนา
char In1, Key;//place for old and new port settings for serial port struct termios oldtio, newtio; //place tor old and new port settings for keyboard teletype struct termios oldkey, newkey; struct sigaction saio; //definition of signal action char buf[255]; //buffer for where data is put input = fopen("/dev/tty", "r"); //open the terminal keyboard output = fopen("/dev/tty", "w"); //open the terminal screen
if (!input || !output) { fprintf(stderr, "Unable to open /dev/tty\n"); exit(1); }
error=0; fputs(version,output); //display the program introduction fputs(version1,output); fputs(version2,output); fputs(version3,output); fputs(version4,output); fputs(version5,output); fputs(version6,output); fputs(version7,output); fputs(version8,output); fputs(version9,output); fputs(version10,output); fputs(version11,output); fputs(version12,output); fputs(version13,output); //read the parameters from the command line if (Parm_Count==7) //if there are the right number of parameters on the command line { for (i=1; i<Parm_Count; i++) // for all wild search parameters { strcpy(Param_strings[i-1],Parms[i]); } i=sscanf(Param_strings[0],"%s",devicename); if (i != 1) error=1; i=sscanf(Param_strings[1],"%li",&Baud_Rate); if (i != 1) error=1; i=sscanf(Param_strings[2],"%i",&Data_Bits); if (i != 1) error=1; i=sscanf(Param_strings[3],"%i",&Stop_Bits); if (i != 1) error=1; i=sscanf(Param_strings[4],"%i",&Parity); if (i != 1) error=1; i=sscanf(Param_strings[5],"%i",&Format); if (i != 1) error=1;
192
Embedded Android Development สเสนทางนกพฒนา
sprintf(message,"Device=%s, Baud=%li\r\n",devicename, Baud_Rate); //output the received setup parameters fputs(message,output); sprintf(message,"Data Bits=%i Stop Bits=%i Parity=%i Format=%i\r\n",D-ata_Bits, Stop_Bits, Parity, Format); fputs(message,output); } //end of if param_count==7 if ((Parm_Count==7) && (error==0)) //if the command line entrys were correct { //run the program tty = open("/dev/tty", O_RDWR | O_NOCTTY | O_NONBLOCK); //set the user console port up tcgetattr(tty,&oldkey); // save current port settings //so commands are interpreted right for this program// set new port settings for non-canonical input processing //must be NOCTTY newkey.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; newkey.c_iflag = IGNPAR; newkey.c_oflag = 0; newkey.c_lflag = 0; //ICANON; newkey.c_cc[VMIN]=1; newkey.c_cc[VTIME]=0; tcflush(tty, TCIFLUSH); tcsetattr(tty,TCSANOW,&newkey);
switch (Baud_Rate) { case 38400: default: BAUD = B38400; break; case 19200: BAUD = B19200; break; case 9600: BAUD = B9600; break; case 4800: BAUD = B4800; break; case 2400: BAUD = B2400; break; case 1800: BAUD = B1800; break; case 1200: BAUD = B1200; break; case 600: BAUD = B600; break; case 300:
193
Embedded Android Development สเสนทางนกพฒนา
BAUD = B300; break; case 200: BAUD = B200; break; case 150: BAUD = B150; break; case 134: BAUD = B134; break; case 110: BAUD = B110; break; case 75: BAUD = B75; break; case 50: BAUD = B50; break; } //end of switch baud_rate switch (Data_Bits) { case 8: default: DATABITS = CS8; break; case 7: DATABITS = CS7; break; case 6: DATABITS = CS6; break; case 5: DATABITS = CS5; break; } //end of switch data_bits switch (Stop_Bits) { case 1: default: STOPBITS = 0; break; case 2: STOPBITS = CSTOPB; break; } //end of switch stop bits switch (Parity) { case 0: default: //none PARITYON = 0;
194
Embedded Android Development สเสนทางนกพฒนา
PARITY = 0; break; case 1: //odd PARITYON = PARENB; PARITY = PARODD; break; case 2: //even PARITYON = PARENB; PARITY = 0; break; } //end of switch parity //open the device(com port) to be non-blocking (read will return immediately) fd = open(devicename, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) { perror(devicename); exit(-1); }
//install the serial handler before making the device asynchronous saio.sa_handler = signal_handler_IO; sigemptyset(&saio.sa_mask); //saio.sa_mask = 0; saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL);
// allow the process to receive SIGIO fcntl(fd, F_SETOWN, getpid()); // Make the file descriptor asynchronous (the manual page says only // O_APPEND and O_NONBLOCK, will work with F_SETFL...) fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd,&oldtio); // save current port settings // set new port settings for canonical input processing newtio.c_cflag = BAUD | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; //ICANON; newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio);
// loop while waiting for input. normally we would do something useful here while (STOP==FALSE) { status = fread(&Key,1,1,input); if (status==1) //if a key was hit { switch (Key)
195
Embedded Android Development สเสนทางนกพฒนา
{ /* branch to appropriate key handler */ case 0x1b: /* Esc */ STOP=TRUE; break; default: fputc((int) Key,output);// sprintf(message,"%x ",Key); //debug// fputs(message,output); write(fd,&Key,1); //write 1 byte to the port break; } //end of switch key } //end if a key was hit // after receiving SIGIO, wait_flag = FALSE, input is available and can be read if (wait_flag==FALSE) //if input is available { res = read(fd,buf,255); if (res>0) { for (i=0; i<res; i++) //for all chars in string { In1 = buf[i]; switch (Format) { case 1: //hex sprintf(message,"%x ",In1); fputs(message,output); break; case 2: //decimal sprintf(message,"%d ",In1); fputs(message,output); break; case 3: //hex and asc if ((In1<32) || (In1>125)) { sprintf(message,"%x",In1); fputs(message,output); } else fputc ((int) In1, output); break; case 4: //decimal and asc default: if ((In1<32) || (In1>125)) { sprintf(message,"%d",In1); fputs(message,output); } else fputc ((int) In1, output); break; case 5: //asc fputc ((int) In1, output); break; } //end of switch format
196
Embedded Android Development สเสนทางนกพฒนา
} //end of for all chars in string } //end if res>0// buf[res]=0;// printf(":%s:%d\n", buf, res);// if (res==1) STOP=TRUE; /* stop loop if only a CR was input */ wait_flag = TRUE; /* wait for new input */ } //end if wait flag == FALSE
} //while stop==FALSE // restore old port settings tcsetattr(fd,TCSANOW,&oldtio); tcsetattr(tty,TCSANOW,&oldkey); close(tty); close(fd); //close the com port } //end if command line entrys were correct else //give instructions on how to use the command line { fputs(instr,output); fputs(instr1,output); fputs(instr2,output); fputs(instr3,output); fputs(instr4,output); fputs(instr5,output); fputs(instr6,output); fputs(instr7,output); } fclose(input); fclose(output);} //end of main
/**************************************************************************** signal handler. sets wait_flag to FALSE, to indicate above loop that ** characters have been received. ****************************************************************************/
void signal_handler_IO (int status){// printf("received SIGIO signal.\n"); wait_flag = FALSE;}
ตวอยางไฟล Makefile สำหรบโปรแกรม serial_thread.c ททำงานบนสถาปตยกรรม x86 โดยถกตงคาการคอมไพลใหใชโปรแกรมคำสง gcc
## Makefile! : Serial chat sample Program #
# CROSS_COMPILE=arm-linux-uclibc-CC=$(CROSS_COMPILE)gcc
197
Embedded Android Development สเสนทางนกพฒนา
SOURCES=serial_chat.cOBJECTS=$(SOURCES:.c=.o)CFLAGS=-OsLDFLAGS=-Os -lm -staticLIBRARIES=EXECUTABLE=serial_chat
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) ! $(CC) $(LDFLAGS) $(OBJECTS) -o $@ -l$(LIBRARIES)
.c.o:! $(CC) $(CFLAGS) $< -o $@
clean:! rm -rf $(OBJECTS) $(EXECUTABLE)
จากโปรแกรมขางตนแสดงตวอยางการสอสารขอมลระหวางคอมพวเตอร 2 เครองผานพอรตอนกรม (COM1) โดยการรนโปรแกรมเพอเรมสอสารดงตอไปน
$ serial_chat /dev/ttyS0 38400 8 1 0 4
โดยท:- ผานพอรต /dev/ttyS0- baud rate ท 38,400 bps- ขนาดขอมล 8 บต- ขนาดบตหยด (stop bit) 1 บต- ไมม parity bit
- แสดงเปนเลขฐานสบ
การพฒนาโปรแกรมสอสารระหวางโปรเซสการสอสารระหวางโปรเซส (Interprocess Communication - IPC) เปนวธการแลกเปลยนขอมล
ระหวางโปรเซสทอยภายในคอมพวเตอรเดยวกนหรอโปรเซสทอาจจะอยตางคอมพวเตอรแตถกเชอมตอผานระบบเครอขายเดยวกน ตวอยางเชน การเรยกคำสงผานเชลลโดยผลลพธจากโปรเซสแรกจะสงไปเปนอนพทใหกบโปรเซสถดไป
$ ls -al | grep "source"drwxr-xr-x 24 root root 4096 2013-09-25 04:51 linux-source-2.6.32
จากคำสงขางตนจะมการใชสญลกษณไปป (Pipe) เพอเปนทอเชอมในการนำสงขอมลจากคำสงดานซายไปยงคำสงดานขวา ซงขบวนการในการสอสารระหวางโปรเซสนนมอยดวยกนหลายวธดงแสดงในตารางขางลาง
198
Embedded Android Development สเสนทางนกพฒนา
ตาราง 4.2 วธการสอสารในแบบตางๆของ IPC
M E T H O D D E S C R I P T I O N
File บนทกเกบไวในดสก โดยทโปรแกรมอนสามารถเขาถงได
Signalเปนการสงสญญาณของระบบในระดบลางไปขดจงหวะของโปรเซส เพอบอกใหโปรเซสทำตามวตถประสงคของสญญาณนนๆ หรออาจจะใชเปนการสงสญญาณระหวางโปรเซสดวยกน
Socketสงขอมลไปยงเครอขายเนทเวรคบนคอมพวเตอรเครองเดยวกนหรอไปยงคอมพวเตอรเครองอน
Pipe สตรมขอมลระหวางโพรเซสชนดทางเดยว หรอ half duplexMessage queue สตรมขอมลทไมระบคลายกบไปป แตเกบและเรยกขอมลจากในแพกเกจ
Named pipe ดำเนนการผานไฟลบนระบบไฟลแทนมาตรฐาน input และ output
Semaphoreโครสรางมาตรฐานทประสาน thread หรอกระบวนการทกระทำกบทรพยากรทใชรวมกน
Shared memoryเปนวธการสงขอมลไปไวในสวนของหนวยความจำทแชรใหกบโปรเซสอนๆใหสามารถเขาถงขอมลนนได
Message passing (shared nothing)
เหมอนกบ message queue
Memory-mapped fileแมพไฟลไปยง RAM และสามารถแกไขไดโดยการเปลยนทอยหนวยความจำโดยตรง
Pipeไปป (Pipe) เปนกระบวนการทใชในการตดตอระหวางโปรเซสทงายทสดคอการนำผลลพธทไดจาก
โปรแกรมหนงไปเปนอนพทของอกโปรแกรมหนง โดยไปปจะเปนตวกลางในการสงขอมลระหวางโปรเซสซงการสงขอมลจะเปนแบบทศทางเดยว (unidirectional)
pfd[1]
เขยนขอมลไปยงปลายทางpfd[0]
อานขอมลตำแหนงปลายทาง
Pipe
รปท 4.4 แสดงการสงขอมลแบบทศทางเดยวดวย Pipe
199
Embedded Android Development สเสนทางนกพฒนา
การพฒนาโปรแกรมสอสารดวยวธการสตรมขอมลระหวางโพรเซสชนดทางเดยวนจะใชฟงกชน pipe ทอยภายในไฟลไลบรารชอวา unistd.h
#include <unistd.h>int pipe ( int pipefd[2] ); <--- pipefd - ตวแปร array สำหรบเกบคา file descriptors
pipefd[0] - file descriptor สำหรบการอาน
pipefd[1] - file descriptor สำหรบการเขยน
สถานะการทำงานของ pipe
0 - ดำเนนการไดสำเรจ, -1 - การดำเนนการลมเหลว
จากรปขางบนแสดงการทำงานของฟงกชน pipe ซงจะสรางชองทางสอสารชนดทางเดยวระหวางโปรเซสโดยจะคนคา file descriptor ทงสองฝง ผานตวแปร pipefd[] กลาวคอ ปลายหนงสำหรบอาน (pipefd[0]) และอกปลายหนงสำหรบเขยน (pipefd[1]) คาของ file descriptor เปนชนดจำนวนเตม (int) ทระบบปฏบตการลนกซจะใชในการอางองถงแฟมทมการเปดใชงานดงนนเมอเรยกใชงานฟงกชน pipe จะตองสงอาเรยของจำนวนเตมทมสมาชก 2 ตวใหแก ฟงกชน pipe()
int pipefd[2]; // file descriptor ของ pipe
ตวอยางโปรแกรม pipe// pipe.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(int argc, char *argv[]){ pid_t pid; int mypipefd[2]; int ret; char buf[20];
ret = pipe(mypipefd); if(ret == -1) { perror("pipe"); exit(1); } pid = fork(); if(pid == 0) { /* Child Process */ printf("Child Process\n"); write(mypipefd[1], "Hello there!", 12); }else{ /* Parent Process */ printf("Parent Process\n"); read(mypipefd[0], buf, 15);
200
Embedded Android Development สเสนทางนกพฒนา
printf("buf : %s\n", buf); } return 0;}
คอมไพลโปรแกรม pipe.c และทดสอบการสงขอมลระหวางโปรเซสทงสอง (โปรเซส parent และโปรเซส child)
$ gcc -o pipe pipe.c $ ./pipe Parent ProcessChild Processbuf : Hello there!
Message Queuesจะมลกษณะคลายกบไฟล pipe คอสามารถสงบลอกขอมลจากโปรเซสหนงไปยงอกโปรเซสหนง
ผานลนกซคอรเนลเชนเดยวกน โดยแตละบลอกขอมลจะมหมายเลขอางองกำหนดไวใหเพอใหโปร เซสอนๆสามารถอางองหมายเลขขอมลทตองการนนได ซงจะไมเหมอนกนการสงขอมลผาน pipe ซงทงสองโปรเซสจะตองรอซงกนและกน ดงนนขนตอนการสงขอมลแบบ message queue จะมขนตอนคอ โปรเซสททำการเขยนขอมลไปยง queue (ดวยคำสง msgsnd) แลว กสามารถจบการทำงานไดทนท ถาโปรเซสใดตองการอาน กสามารถเขาไปอานขอมลใน queue ไดภายหลง (ดวยคำสง msgrcv) ดงแสดงในรปขางลาง
แตอยางไรกตาม message queue กยงมขอจำกดเรองขนาดบลอกขอมล ทจะถกจำกดขนาดไวรวมทงจำนวนบลอกทงหมดทมบนระบบกจะถกจำกดไวเชนกน ซงภายในระบบปฏบตการลนกซตวแปรบลอกขอมลจะประกอบไปดวย 2 สวนคอ MSGMAX(4096) และ MSGMNB(16384) ซงตวแรกจะหมายถงความจของแตละบลอกขอความ และตวทสองจะหมายถงความจทงหมดของ queue แตในบางระบบ คาเหลานอาจจะแตกตางกนไป หรออาจจะไมใชคานเลยกเปนได
...โปรเซส โปรเซส
โปรเซส
โปรเซส
msgsnd() msgrev()
msgget()
msgctl()
รปท 4.5 แสดงการสงขอมลแบบ message queue
201
Embedded Android Development สเสนทางนกพฒนา
รายการฟงกชนภายในไลบราร sys/msg.h ทใชใน Message Queues
#include<sys/msg.h>
int msgct1(int msqid, int cmd, struct msqid_ds *buf); int megget1(key_t key, int ms_gflg); int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg); int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);
ตวอยางโปรแกรมสำหรบสงบลอกขอมลเขาไปใน Message Queues/*** msg_sender.c -- writes to a message queue*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>
struct my_msgbuf { long mtype; char mtext[200];};
int main(void){ struct my_msgbuf buf; int msqid; key_t key;
if ((key = ftok("msg_sender.c", 'B')) == -1) { perror("ftok"); exit(1); }
if ((msqid = msgget(key, 0644 | IPC_CREAT)) == -1) { perror("msgget"); exit(1); } printf("Enter lines of text, ^D to quit:\n");
buf.mtype = 1; /* we don't really care in this case */ while(gets(buf.mtext), !feof(stdin)) { if (msgsnd(msqid, (struct msgbuf *)&buf, sizeof(buf), 0) == -1) perror("msgsnd"); }
if (msgctl(msqid, IPC_RMID, NULL) == -1) { perror("msgctl");
202
Embedded Android Development สเสนทางนกพฒนา
exit(1); }
return 0;}
ตวอยางโปรแกรมสำหรบอานบลอกขอมล ภายใน Message Queues/*** msg_receiver.c -- reads from a message queue*/
#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>
struct my_msgbuf { long mtype; char mtext[200];};
int main(void){ struct my_msgbuf buf; int msqid; key_t key;
if ((key = ftok("msg_sender.c", 'B')) == -1) { /* same key as msg_sender.c */ perror("ftok"); exit(1); } if ((msqid = msgget(key, 0644)) == -1) { /* connect to the queue */ perror("msgget"); exit(1); } printf("spock: ready to receive messages, captain.\n");
for(;;) { /* Spock never quits! */ if (msgrcv(msqid, (struct msgbuf *)&buf, sizeof(buf), 0, 0) == -1) { perror("msgrcv"); exit(1); } printf("spock: \"%s\"\n", buf.mtext); }
return 0;}
203
Embedded Android Development สเสนทางนกพฒนา
Threadนกพฒนาสามารถพฒนาโปรแกรมในลกษณะ multi-tasking programming โดยการสรางเทรด
(thread) เพอเพมประสทธภาพการทำงานของระบบปฏบตการลนกซใหสามารถรองรบการทำงานแบบหลายงานได ซงเทรดจะถกเรยกไดอกชอหนงวา “lightweight processes”
เนองจากโปรเซสทวไปภายในระบบปฏบตการลนกซประกอบดวยสถานะของหนวยประมวลผล (เชนคาภายในตวรจสเตอร AX,BX,DX), รายละเอยดของการจองหนวยความจำ (สำหรบเกบ code, globals, heap และ stack) และรายละเอยดทเกยวของกบระบบปฏบตการ (เชน การเปดไฟล, หมายเลขโปรเซส) ซงเทรดกจะคลายกน แตจะตางกนตรงท multiple processes จะแยกการเกบสถานะกนอยางชดเจน ในขณะท multiple threads จะมการใช code, globals และ heap รวมกน
เทรดจะสามารถทำงานไดดในกรณทเครองคอมพวเตอรนนมมากกวาหนงหนวยประมวลผล โดยในรปขางลางแสดงการทำงานของเทรดแตละตว (ไดแก main(), function1() และ function2()) ซงถาเครองมหนวยประมวลผลเพยงตวเดยวการทำงานของโปรแกรมนกจะทำตามลำดบของคำสงแตละบรรทด (program counter) ซงอาจจะใชเวลาทงสน 2 นาท แตถาเครองมหนวยประมวลผลจำนวน 3 ตวทงสามสวนกจะแยกกนทำงานไปแตละหนวยประมวลผลซงอาจจะใชเวลาทงสนเพยง 50 วนาทเทานน
main thread
thread 3
thread 2
เวลา (Time)
การทางานลกษณะแบบ Single-Thread
CPU #1
CPU #1
CPU #2
CPU #3
คอ main()
คอ ฟงกชน 2()
คอ ฟงกชน 1()
การทางานลกษณะแบบ Multi-Thread
เวลาเรมตน เวลาทใชทงหมดของโปรแกรมโดยใช multi-thread
เวลาทใชทงหมดของโปรแกรมโดยใช single-thread
รปท 4.6 เปรยบเทยบการประมวลผลโปรแกรมแบบ Single-Thread และ Multi-Thread
204
Embedded Android Development สเสนทางนกพฒนา
การสอสารกนระหวางเทรดจะสามารถตดตอผานกนไดทางหนวยความจำทใชงานรวมกนอยไดทนท ในขณะทการสอสารระหวางโปรเซสจะสามารถตดตอผานกนไดตองผานทางระบบปฏบตการเทานน เชนผานไฟล, ผานไปป หรอผานซอกเกต เปนตน
POSIX threadsไลบราร POSIX thread ถอวาเปนตวมาตราฐานหลกในการเขยนเทรดสำหรบโปรแกรมภาษา
C/C++ ซงเปนไลบรารทจดเตรยมฟงกชนตางๆเกยวกบการจดการเทรดและจะทำงานไดมประสทธภาพมากสำหรบระบบคอมพวเตอรทมหลายหนวยประมวลผลกลาง (multi-processor หรอ multi-core systems) เนองจากมฟงกชนในการจดตารางการทำงานของโปรเซสบนแตละหนวยประมวลผลกลางทอยภายในระบบคอมพวเตอรตวเดยวกน และเทรดทกตวทอยภายในโปรเซสเดยวกนนนกจะใชพนทในหนวยความจำเดยวกน (address space) ซงแตกตางจากเทคโนโลยในการเขยนโปรแกรมแบบขนาน (Parallel programming) เชน MPI และ PVM ทถกใชในสภาพแวดลอมการคำนวณแบบกระจาย (distributed computing) ไปยงระบบคอมพวเตอรเครองอนๆ ทอยไกลออกไปหรอตางสถานทกน
การพฒนาโปรแกรมเทรดโดยใชไลบราร Posix threads (pthread.h) จะมฟงกชนทสำคญดงน
#include <pthread.h> int pthread_create(pthread_t *new_thread_ID, const pthread_attr_t *attr, void * (*start_func)(void *), void *arg); int pthread_join(pthread_t target_thread, void **status);
ขบวนการทำงานของเทรดนนจะประกอบไปดวย thread creation, termination, thread synchro-nization (joins,blocking), scheduling, data management และ process interaction
Master Thread
Worker Thread
Worker Thread
pthread_create() pthread_join()
pthread_exit()
ตวลกเรมทางาน
ตวลกทางานเสรจสมบรณ
ทางาน
รปท 4.7 แสดงฟงกชนทเกยวของของการทำงานของเทรดลกตงแตเรมจนสนสด
205
Embedded Android Development สเสนทางนกพฒนา
พนททใชงานรวมกนของเทรดทงหมดภายในโปรเซส จะมประกอบไปดวย• ชดคำสงโปรเซส (Process instructions) • คา files descriptors ทมการเปดไว• สญญาณ (signals) และตวดำเนนการ (signal handlers)• ไดเรดทอรปจจบน (current working directory) • หมายเลข User และ Group
Thread #1
Registers
Thread #2
RegistersFiles
Heap Static Code
Stack Stack Stack
Thread #3
Stack
Registers
Thread #2
Stack
Registers
Thread #1
Stack
Registers
โครงสรางภายในโปรเซส
รปท 4.8 แสดงรายละเอยดของโครงสรางภายในโปรเซส
โดยแตละเทรดจะม:
◦ หมายเลขเทรด (Thread ID)
◦ กลมตวแปรรจสเตอร (set of registers) และ stack pointer
◦ สแตกสำหรบเกบคาตวแปร (local variables)
◦ signal mask
◦ คา priority
◦ คาสถานะทสงกลบ: errno
และเมอตองการคอมไพลโปรแกรมจะตองมการอางองไลบราร Posix threads ดวย -lpthread ดงตวอยางขางลาง
$ gcc -o main main.c –lpthread
206
Embedded Android Development สเสนทางนกพฒนา
ตวอยางโปรแกรม simple_threads.c
// simple_threads.c#include <stdio.h>#include <stdlib.h>#include <pthread.h>void *print_message_function(void *ptr);main(){ pthread_t thread1, thread2; const char *message1 = "Thread 1"; const char *message2 = "Thread 2"; int iret1, iret2;/* Create independent threads each of which will execute function */ iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) mes-sage1); iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) mes-sage2);/* Wait till threads are complete before main continues. Unless we *//* wait we run the risk of executing an exit which will terminate *//* the process and all threads before the threads have completed. */ pthread_join( thread1, NULL); pthread_join( thread2, NULL); printf("Thread 1 returns: %d\n",iret1); printf("Thread 2 returns: %d\n",iret2); exit(0);}void *print_message_function(void *ptr) { char *message; message = (char *) ptr; printf("%s \n", message);}
ทำการคอมไพล และทดสอบรนโปรแกรม
$ gcc -o simple_threads simple_threads.c –lpthread$ ./simple_threads Thread 2 Thread 1 Thread 1 returns: 0Thread 2 returns: 0
Thread Synchronizationนกพฒนาสามารถพฒนาโปรแกรมโดยเรยกใชความสามารถในการจดกลไกการทำงาน
ประสานกนระหวางเทรด (synchronization mechanisms) โดยไมใหเกดปญหาในกรณทเทรดแตละตวจะตองเขาไปใชทรพยากรตวเดยวกน ภายในเครองคอมพวเตอรเดยวกนโดยใชไลบราร pthread
207
Embedded Android Development สเสนทางนกพฒนา
ตวแปร (var)
Thread #1 Thread #2
mutex_varlock
ตงคา
blocked
รปท 4.9 แสดงการเขาไปกำหนดคาใน mutex ของเทรดทตองการเขาไปขอใชทรพยากร
จากรปดานบนแสดงการอนญาตเพยง thread #1 ตวเดยวทสามารถเขาไปกำหนดคา mutex (Mutual Exclusion Lock) เพอเขาถงทรพยากรหรอตวแปร โดยท thread #2 จะตองรอ (block) ควเพอเขาถงทรพยากรหรอตวแปรหลงจากท thread #1 ทำงานเสรจเรยบรอยแลว ตว thread #2 จงจะสามารถเขาไปกำหนดคา mutex เพอขอเขาถงทรพยากรหรอตวแปรนนตอไป
Mutexes จะเปนตวการสำคญในการชวยปองกนปญหาขอมลเกดความผดพลาดหรอการไมสอดคลองกนของขอมล (data inconsistency) เนองจากสาเหตการแยงเขาไปใชทรพยากรสวนกลาง ของเทรดหลายตวพรอมกน เชนหนวยความจำกลาง (shared memory) หรอตวแปรกลาง (global variable) ซงเรยกพนทสวนทถกเขาไปใชงานนนวา critical region แตอยางไรกตามการใช mutexes จะถกใชไดเพยงในกรณมหลายเทรดในโปรเซสตวเดยวกนเทานน แตในกรณทมหลายโปรเซสตองการเขาใชทรพยากรเดยวกน จะตองแกไขโดยการใชเทคนค semaphores แทน mutexes
208
Embedded Android Development สเสนทางนกพฒนา
กรณไมใช MUTEXกรณไมใช MUTEX กรณใช MUTEXกรณใช MUTEX
int counter=0;void func(){ counter++;}
int counter=0;void func(){ counter++;}
pthread_mutex_t var = PTHREAD_MUTEX_INTIALIZER;int counter=0;
void func(){ pthread_mutex_lock(&var); counter++; pthread_mutex_unlock(&var);}
pthread_mutex_t var = PTHREAD_MUTEX_INTIALIZER;int counter=0;
void func(){ pthread_mutex_lock(&var); counter++; pthread_mutex_unlock(&var);}
Thread #1 Thread #2 Thread #1 Thread #2
counter=0 counter=0 counter=0 counter=0
counter=1 counter=1 counter=1Thread #2 ถกบลอคไมใหเขาถงตวแปร counterแต Thread #1 สามารถเขาถงตวแปร counter ได
counter=2
ซงฟงกชนสำหรบ mutex ภายในไลบราร pthread ไดแก •pthread_mutex_lock() ใชสำหรบการเขาไปลอคคาในตวแปร mutex การเรยกฟงกชนนกจะถกบลอคเอาไวไมใหเทรดอนเขามา จนกวาเทรดตวทใชงานอยทำการปลอยตว mutex เทานน
•pthread_mutex_unlock() เพอปลอยหรอปลดลอคคา mutex จากเทรดทใช mutex อย•pthread_mutex_trylock() เพอใชตรวจสอบตวแปร mutex วากำลงถกใชลอคใชงานอยหรอไม ซงจะมประโยชนในการปองกนไมใหเกดเหตการณทเทรดแตละตวตางฝายตางรอใหแตละตวเสรจ (deadlock conditions)
ตวอยางแสดงการสรางเทรดจำนวน 10 เทรด โดยแตละตวจะเขาไปใชงานตวแปรกลางชอวา counter แตจะตองเพมคา counter ไดเพยงครงละ 1 เทรดเทานน// simple_mutex.c#include <stdio.h>#include <pthread.h>#define NTHREADS 10void *thread_function(void *);pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;int counter = 0;
main(){ pthread_t thread_id[NTHREADS]; int i, j;
for(i=0; i < NTHREADS; i++)
209
Embedded Android Development สเสนทางนกพฒนา
{ pthread_create( &thread_id[i], NULL, thread_function, NULL ); }
for(j=0; j < NTHREADS; j++) { pthread_join( thread_id[j], NULL); }// Now that all threads are complete I can print the final result. // Without the join I could be printing a value before all the threads // have been completed.
printf("Final counter value: %d\n", counter);}
void *thread_function(void *dummyPtr) { printf("Thread number %ld\n", pthread_self()); pthread_mutex_lock(&mutex1); counter++; pthread_mutex_unlock(&mutex1);}
คอมไพล และทดสอบรนโปรแกรม
$ gcc -o simple_mutex simple_mutex.c –lpthread$ ./simple_mutex Thread number 139638417069824Thread number 139638425462528Thread number 139638442247936Thread number 139638433855232Thread number 139638408677120Thread number 139638400284416Thread number 139638391891712Thread number 139638383499008Thread number 139638375106304Thread number 139638366713600Final counter value: 10
การพฒนาโปรแกรมสอสารบนระบบเครอขาย บอรดสมองกลฝงตวสวนใหญจะมพอรตสำหรบเชอมตอระบบเครอขาย (Ethernet Port) เปนพน
ฐาน รวมทงระบบปฏบตการลนกซแบบฝงตวเองกไดจดเตรยมไลบรารและชดโปรแกรมคำสงทางดานระบบเครอขายเปนพนฐานอยภายในไวใหแลวเชนกน ดงนนนกพฒนาสามารถทำใหบอรดสมองกลฝงตวตดตอสอสารกบบอรดอนๆ คอมพวเตอรอนๆ หรอเครองแมขายทอยภายในระบบเครอขายเดยวกนได โดยบอรดสมองกลฝงตวกยงสามารถบนทกขอมลทมขนาดใหญฝากไวในเครองคอมพวเตอรอนๆหรอ
210
Embedded Android Development สเสนทางนกพฒนา
เครองแมขาย แทนทจะบนทกขอมลขนาดใหญนนเกบไวในตวเอง นอกจากนนผใชกสามารถเขาถงเพอควบคมหรอดสถานะการทำงานของบอรดสมองกลฝงตวจากทไหนกได
ดงนนการพฒนาโปรแกรมจะตองทำความเขาใจวธการตงคาหมายเลข IP Addresses แตละตว ไมวาจะเปนหมายเลขเครอขาย (Network ID) หมายเลขเครอง (Host ID) หมายเลข Netmask Address เมอโปรเซสทงสองทอยตางเครองตองการสอสารกน จะตองมสถาปนาการเชอมตอดวยขนตอนตามเทคโนโลย TCP/IP ซงอยในระดบ Transport Layer และจะตองมการระบหมายเลขพอรต (Port Ad-dress) ไปยงโปรโตคอลแอพพเคชน (Application Protocol) ทโปรเซสแตละฝงใชอยดวย ตวอยางเชนโปรแกรมรบสงไฟลทใชโปรโตคอล FTP ในการกำหนดควบคมวธการสงไฟลระหวางกน เรยกการพฒนาโปรแกรมทางดานนวา Socket Programming
TCP UDP
IP
1 2 ... ... ... ... 65535 1 2 ... ... ... ... 65535
... ...TCP sockets UDP sockets
UDP portsTCP ports
Application Application Application
ระบหมายเลข port สาหรบ socket
Descriptor references
รปท 4.10 แสดงการเชอมตอระดบโปรแกรมประยกตและหมายเลขพอรตของ TCP/IP
ซอกเกต (socket) นนมอยดวยกน 3 ประเภทโดยยดตามมาตราฐานของเทคโนโลย TCP/IP ไดแกตาราง 4.3 ประเภทของ Socket
SOCKET คำอธบาย
Datagram Socket
เรยกอกชอหนงวา Connection less Socket ซงใชโปรโตคอล UDP (User
Datagram Protocol) เปนตวกำหนดวธการสอสาร โดยขอมลหรอแพกเกต
(packet) แตละตวจะถกสงบน datagram socket ทแยกเสนทางกนออกไป
ดงนนแพกเกตทสงจากเครองตนทางกจะถกลำเลยงกระจายออกไปในแตละเสน
ทาง จนถงเครองรบปลายทาง โดยแตละแพกเกตกอาจจะมาถงเครองปลายทาง
แบบไมไดเรยงตามลำดบตามทถกสงออกจากเครองตนทางกอนหนานน
211
Embedded Android Development สเสนทางนกพฒนา
SOCKET คำอธบาย
Stream Socket
เรยกอกชอหนงวา Connection-oriented Socket ซงใชโปรโตคอล TCP
(Transport Control Protocol) เปนตวกำหนดวธการสอสาร ซงจะมการ
สถาปนาการเชอมตอและการนตการรบสงแพกเกต ดงนนขอมลหรอแพกเกต
แตละตวจะถกสงบน stream socket และจะถกลำเลยงสงผานชองทางทถก
สรางขนมานไปยงเครองปลายทางจนครบถวนสมบรณ
Raw Socket
สวนใหญจะพบในอปกรณเครอขายเชน สวทซ (Switch) และ เราเตอร
(Router) ซงทำงานอยในระดบ Internet Layer ทมการรบ-
สงขอมลโดยไมไดมการใชโปรโตคอลเหมอน datagram และ stream socket
ในการกำหนดมาตราฐานการสอสาร
ความสมพนธระหวางโปรแกรม ซอกเกต โปรโตคอล และหมายเลขพอรตภายในเครองคอมพวเตอร เพอใชในการสอสารขอมลระหวางโปรเซสทอยตางเครองกน ประเดนทนาสนใจทนกพฒนาควรรไดแก
• โปรแกรมหนงโปรแกรมสามารถเปดซอกเกตไดหลายซอกเกตเพอรบการเชอมตอจากเครอง ภายนอกไดพรอมกนในเวลาเดยวกน
• โปรแกรมหลายโปรแกรมสามารถใชซอกเกตตวเดยวกนในเวลาเดยวกนแตไมคอยพบเหนการใช ในลกษณะน
• มากกวาหนงซอกเกตทสามารถถกเกยวของและใชงานพอรตอนเดยวกน• โปรแกรมประยกตแตละตวจะมการใชทง TCP และ UDP เพอใชในการจดการและรบสงขอมลตามวตถประสงคทแตกตางกนไป เชน ตองการเนนความเรวในการสงแมขอมลจะหายไดบางกจะใชชองทาง UDP หรอถาเนนความถกตองของขอมลโดยทขอมลจะตองไมสญหายกจะใชชองทาง TCP ในการรบสงแทน
• ไฟล /etc/services ภายในระบบปฏบตการลนกซจะบอกรายละเอยดของโปรแกรมใหบรการ และโปรโตคอลทใชหมายเลขพอรตในการสอสารผานซอกเกตในระดบของ Transport layer
212
Embedded Android Development สเสนทางนกพฒนา
socket socket
bind bind
recvfrom/sendto
sendto/recvfrom
close close
Connect Listen
Accept
Client Server
สราง socket
ทำการเชอม socket ไปยงพอรต
รองขอการเชอมตอไปยงเครอง server และรอตอบกลบ
รบและสงขอมล
สราง socket
ทำการเชอม socket ไปยงพอรต
การรองขอจากเครอง Client ทตองการเชอมตอ
ตอบรบการเชอมตอจากเครอง Client เพอพรอมรบ/สงขอมล
สงและรบขอมล
รปท 4.11 แสดงขบวนการเชอมตอระหวางเครองภายในระบบเครอขายผาน Socket
ตวอยางโปรแกรมเชอมตอผานซอกเกตตามขนตอนทอธบายในรปขางตน ตวลก (Client) จะเชอมตอไปยงเครองแม (Server) แลวสงขอความ Hello World of Socket ไปยงเครองแม เมอเครองแมไดรบขอความกจะแสดงออกทางหนาจอของเครองแม ดงน
โปรแกรมฝงเครองแม (Server):
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <stdlib.h>
int main(int argc, char *argv[]){ /* Variables */ int sock; struct sockaddr_in server; int mysock; char buff[1024];
213
Embedded Android Development สเสนทางนกพฒนา
int rval;
/* Create socket */ sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0){ perror("Failed to create socket"); exit(1); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(5000);
/* Call bind */ if(bind(sock, (struct sockaddr *)&server, sizeof(server))) { perror("bind failed"); exit(1); }
/* Listen */ listen(sock, 5);
/* Accept */ do { mysock = accept(sock, (struct sockaddr *) 0, 0); if(mysock == -1) { perror("accept failed"); }else{ memset(buff, 0, sizeof(buff)); if((rval = recv(mysock, buff, sizeof(buff), 0)) < 0 ) perror("reading stream message error"); else if(rval == 0) printf("Ending connection\n"); else printf("MSG: %s\n", buff); printf("Got the message (rval = %d)\n", rval); close(mysock); } }while(1); return 0;}
โปรแกรมฝงเครองลก (Client):#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>
214
Embedded Android Development สเสนทางนกพฒนา
#include <string.h>#include <stdlib.h>#include <unistd.h>
#define DATA "Hello World of Socket"
int main(int argc, char *argv[]){ int sock; struct sockaddr_in server; struct hostent *hp; char buff[1024]; sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("socket failed"); exit(1); }
server.sin_family = AF_INET; hp = gethostbyname(argv[1]); if(hp == 0) { perror("gethostbyname failed"); close(sock); exit(1); } memcpy(&server.sin_addr, hp->h_addr, hp->h_length); server.sin_port = htons(5000); if(connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("connect failed"); close(sock); exit(1); } if(send(sock, DATA, sizeof(DATA), 0) < 0 ) { perror("send failed"); close(sock); exit(1); } printf("Sent %s\n", DATA); close(sock);
return 0;}
215
Embedded Android Development สเสนทางนกพฒนา
คอมไพลและรนโปรแกรมทงสองเครองดงน
ตวอยางถดไปแสดงขนตอนการพฒนาโปรแกรมบรการฝงเครองแม (Server) โดยมการระบชอโปรแกรมใหบรการในฝงของเครองแมขายอยางชดเจนภายในไฟล /etc/services ดงแสดงในรปขางลาง
ClientProgram
ServerProgram
Port
: 333
3
xinetd
stdinstdin
stdout
socketsocket
stdout
172.16.56.134172.16.56.130
รปท 4.12 แสดงขบวนการเชอมตอเขาสพอรต 3333 ของเครองแมขาย
ขนตอนท 1 : สรางโปรแกรมเชลสครปทเพอเปนโปรแกรมบรการฝงเครองแมทำการสรางไฟลสครปท เพอทำหนาทเปนโปรแกรมฝงเครองแมขาย
$ vim hello_server.sh #!/bin/bash/bin/echo -n "Hello World:" | /usr/bin/tee /tmp/log.log/bin/date | /usr/bin/tee -a /tmp/log.log
เปลยนสทธใหไฟลสามารถถกรนได
$ chmod 755 hello_server.sh$ ./hello_server.shHello World:Mon Sep 30 01:44:24 PDT 2013
ขนตอนท 2 : กำหนดหมายเลขพอรตทจะเปดใหบรการ เพมเตมในไฟล /etc/services
เครองแม:
$ gcc -o server server.c$ ./serverMSG: Hello World of SocketGot the message (rval = 22)
เครองลก:
$ gcc -o client client.c
$ ./client <IP เครองแม>Sent Hello World of Socket
216
Embedded Android Development สเสนทางนกพฒนา
ทำการตรวจสอบหมายเลขพอรต 3333 ในไฟล /etc/services และการเชคจากการเปดบรการของโปรแกรม xinetd กอนวาไดมการเรยกใชหรอไม ดงน
$ cat /etc/services | grep 3333$ grep -r 3333 /etc/xinetd.d/*
เมอตรวจสอบแลว ปรากฏวายงไมมการเรยกใชหมายเลขพอรต 3333 และชอบรการ “hello” กสามารถเขาไปเพมชอบรการใหมในไฟล /etc/services ดงคำสงขางลางน
$ sudo vim /etc/services
ทำการเพมบรรทดดงขางลางน แลวบนทกไฟล /etc/services ใหเรยบรอย
hello 3333/tcp # sample hello service
หมายเหต:
- ใหลบบรรทดทเพมเขาไปใน /etc/services ออกเมอไดทดสอบ hello service แลว เพอไมใหเกดปญหากบการทำงานของโปรแกรม xinetd ในอนาคต
ขนตอนท 3 : ระบรายละเอยดของ hello service เพมเตมในไดเรกทอร /etc/xinetd.d/$ sudo vim /etc/xinetd.d/hello
เพมบรรทดดงขางลางน# default: on# description: Hello World socket serverservice hello{! port! = 3333! disable! = no! socket_type! = stream! protocol! = tcp! user! = root! wait! = no! server! = /home/student/hello_server.sh! log_on_success! += USERID! log_on_failure! += USERID}
ทำการเรยกโปรแกรม xinetd ใหม เพอใหอานการตงคาระบบใหม
$ sudo /etc/init.d/xinetd restart * Stopping internet superserver xinetd [ OK ] * Starting internet superserver xinetd [ OK ]
217
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 4 : ทดสอบการทำงานโดยการเรยกใชโปรแกรม telnet$ telnet 172.16.56.134 3333Trying 172.16.56.134...Connected to 172.16.56.134.Escape character is '^]'.Hello World:Mon Sep 30 02:30:39 PDT 2013Connection closed by foreign host.
การพฒนาโปรแกรมเกบขอมลดวย SQLITE
การเกบขอมลในระบบสมองกลฝงตวมดวยกนหลายวธ แตปญหาทเกดขนบอยในการพฒนาระบบเกบขอมลภายในบอรดสมองกลฝงตวทมระบบปฏบตการลนกซทำงานอย คอถาเกบขอมล log ในลกษณะ text file ธรรมดา ในกรณทตองการลบหรอแทรกขอมลในตำแหนงทระบไวในไฟล log จะมโอกาสทำใหไฟลเสยหายไดสง รวมทงการเขยนโปรแกรมเพอเขาไปจดการขอมลภายในไฟล log กจะมความซบซอนมากยงขน
ดงนนทางออกสำหรบการเกบขอมลใหมระบบ และสามารถเขาถงไดอยางมประสทธภาพ ควรจะตองใหอยในลกษณะการเกบขอมลแบบเดยวกนโครงสรางฐานขอมล (Database) โปรแกรมตวหนงทไดรบความนยมสง และเปนโปรแกรมทกลายเปนตวมาตราฐานในการเกบขอมลภายในอปกรณสมองกลฝงตวในปจจบนนไมวาจะเปนแอนดรอยด, iOS เปนตน กคอโปรแกรม SQLite ซงเปนโปรแกรมประเภท Open Source มขนาดเลก รองรบหลายสถาปตยกรรมโดยจะมสกลไฟลทเกบเปน .db, .sdb, หรอ .s3db เปนตน
ขนตอนขางลางนแสดงตวอยางการตดตงโปรแกรม SQLite ลงในเครอง Host เพอเตรยมสภาพแวดลอมในการพฒนาโปรแกรมภาษา C/C++ ทใชการเกบขอมลดวยไลบรารของ SQLite ภายในระบบปฏบตการ Embedded Linux ทจะถกนำไปใชในบอรดสมองฝงตวตอไป
ขนตอนท 1 : ดาวนโหลดโปรแกรม SQLite เวอรชนลาสดดาวนโหลดโปรแกรม SQLite (sqlite-autoconf-3080002.tar.gz) จากลงค http://www.sqlite.org/download.html
$ tar -xzvf sqlite-autoconf-3080002.tar.gz$ cd sqlite-autoconf-3080002/
ขนตอนท 2 : ตดตงตว cross compiler ลงใน Ubuntuในกรณทใช Ubuntu เวอรชน 10.10 ขนไป
218
Embedded Android Development สเสนทางนกพฒนา
$ sudo apt-get install gcc-arm-linux-gnueabi.
ในกรณทใช Ubuntu เวอรชนตำกวา 10.10
$ sudo add-apt-repository ppa:linaro-maintainers/toolchain$ sudo apt-get update$ sudo apt-get install gcc-arm-linux-gnueabi
ขนตอนท 3 : ทำการคอมไพลโปรแกรม SQLite เพอใหรองรบสถาปตยกรรม ARM$ mkdir ~/sqlite$ ./configure --host=arm CC=arm-linux-gnueabi-gcc AR=arm-linux--gnueabi-ar STRIP=arm-linux-gnueabi-strip RANLIB=arm-linux-gnueabi--ranlib CFLAGS=" -mfpu=vfp -Os -lpthread -lrt" LDFLAGS=${LDFLAGS}$ make$ make install DESTDIR=~/sqlite
ไดเรกทอรจากการคอมไพลจะถกตดตงอยภายใตไดเรกทอร ~/sqlite/ ดงนusr/local/binusr/local/includeusr/local/libusr/local/share
ขนตอนท 4 : สรางโปรแกรมทเรยกใชไลบราร SQLite และทำการคอมไพลดวย cross compiler เพอใหรองรบสถาปตยกรรม ARM$ vim my_sqlite.c
#include <stdio.h>#include <sqlite3.h>
int main(int argc, char* argv[]){ sqlite3 *db; char *zErrMsg = 0; int rc;
rc = sqlite3_open("test.db", &db);
if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stderr, "Opened database successfully\n"); } sqlite3_close(db);}
219
Embedded Android Development สเสนทางนกพฒนา
ทำการคอมไพลโปรแกรมดงคำสงขางลางน
$ arm-linux-gnueabi-gcc -o my_sqlite my_sqlite.c -I~/sqlite/usr/local/include e -L~/sqlite/usr/local/lib -lsqlite3 -lpthread -ldl
นกพฒนาสามารถใชตวเลอก "-lpthread" หรอ "-pthread" กได แตถาใช "-pthread" ตวคอมไพลเลอรกจะคนหาตวไลบราร Posix Thread ทเหมาะสมใหอตโนมตสำหรบตวเลอก "-ldl" เปนการระบวาใชไลบรารทบรรจฟงกชน dlsym, dlopen ทมใชอยในโปรแกรม
$ file my_sqlitemy_sqlite: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, not stripped
การดบกโปรแกรมภาษา C/C++การตรวจสอบการทำงานของโปรแกรมเพอหาความผดพลาดหรอแมกระทงตรวจสอบขนตอนการ
ทำงานของโปรแกรมวาเปนไปตามเงอนไขทไดออกแบบไวหรอไมนนกอนทจะปลอยโปรแกรมไปอยในระบบสมองกลฝงตวเพอใหทำงานตามทไดกำหนด จำเปนอยางยงทนกพฒนาจะตองตรวจสอบการทำงานของโปรแกรมและดคาภายในตวแปรหรอภายในหนวยความจำทเกดขนในระหวางโปรแกรมกำลงทำงานอย (run-time) ซงเรยกขบวนการนวาการดบก (Debugging)
สำหรบระบบปฏบตการลนกซนน กไดเตรยมเครองมอสำหรบการดบก ซงเรยกวา GNU debugger ถกพฒนาโดย Richard Stallman บดาแหง GPL ในป ค.ศ. 1986 ซงเปนสวนหนงในระบบ GNU ของ Richard Stallman โดยการใชกลมคำสง gdb kdb หรอ ddd เปนตน คำสง gdb สามารถชวยนกพฒนาในการดบกโปรแกรม ดงรายละเอยดขางลางน:
• เมอโปรแกรมเรมทำงานกสามารถสงใหทำงานตามคำสงบรรทดตอบรรทด (line by line) ดวย ชดคำสง gdb
• สามารถทำใหโปรแกรมหยดตามเงอนไขทระบไวได• แสดงคาของตวแปร ณ ขณะนนในระหวางททำงานอย (run-time)• กำหนดจดหยดโปรแกรม (breakpoints) แลวจงตรวจสอบการทำงานแตละขนตอนแบบ step-
by-step หรอสงใหโปรแกรมทำงานตามปกตตอไปไดโดยกอนทจะเรมการดบกโปรแกรมนกพฒนาจะตองระบตวเลอก “-g” ตองทายคำสง gcc ในขณะทกำลงคอมไพลโปรแกรม ดงตวอยางขางลาง
$ gcc –g –c main.c$ g++ -g –c function1.c$ g++ -g –o my_program main.o function1.o
220
Embedded Android Development สเสนทางนกพฒนา
คอมไพลเลอรจะเพมขอมลบางอยางทจำเปนตอการทำงานของ gdb ลงไปในออปเจคไฟล (.o) และโปรแกรมทไดจากการคอมไพล (executable file) ซง gdb จะใชขอมลเหลานนเพอคำนวณหาบรรทดของโคดโปรแกรมเพอแสดงขอมลตางๆออกมา คำสงพนฐานของ gdb ทนยมใชกนไดแก
ตาราง 4.4 ตวอยางคำสงการดบกโปรแกรมดวยโปรแกรม gdb
คำสงเตม คำสงยอ คำอธบายrun r เรมโปรแกรม
kill k หยดโปรแกรม
quit q ออกจาก GDB
continue c ทำงานตอโดยหยดท breakpoint ถดไป
disassemble disassแสดง assembly code ของ function ท EIP อย
disassemble ADDR disass ADDRแสดง assembly code ท address ADDR (ใชชอ function ได)
disassemble ADDR1 ADDR2 disass ADDR1 ADDR2แสดง assembly code ท address ADDR1 ถง ADDR2
info breakpoints i b แสดง breakpoint ทงหมด
info registers i r แสดงคาของ CPU registers ทงหมด
info frame i f แสดงขอมลเกยวกบ stack frame ปจจบน
backtrace bt แสดง call stack
break *ADDR b *ADDRset breakpoint ท address ADDR (ถาใชชอ function ไมตองม *)
enable [NUM] en [NUM] enable breakpoint หมายเลขท NUM
disable [NUM] dis [NUM] disable breakpoint หมายเลขท NUM
delete [NUM] d [NUM] delete breakpoint หมายเลขท NUM
delete d delete breakpoint ทงหมด
nexti [num] ni [num] ทำงานคำสงถดไป ไมเขาไปใน call
stepi [num] si [num] ทำงานคำสงถดไป เขาไปใน call
x/NFU ADDR
แสดงคาของ address ADDR โดยN คอจำนวนทจะแสดงผลF คอรปแบบทจะแสดงผล (ดตารางถดไป)U คอจำนวน byte ม b (byte), h (2 bytes), w (4 bytes), g (8 bytes)
display/F ADDR disp/F ADDRแสดงคาของ address ADDR ทกครงทถงหยดทำงานชวคราว
display disp แสดงคาทอยใน display list ทงหมด
221
Embedded Android Development สเสนทางนกพฒนา
คำสงเตม คำสงยอ คำอธบายundisplay [NUM] und [NUM] ลบ display ทเกบไวท NUM
set ADDR=VAL set คา VAL ไปท address ADDR
ตวอยางถดไปเปนการทดสอบการดบกโปรแกรม factorial โดยเรมตนใหทำการสรางโปรแกรมดงน
$ vim factorial.c# include <stdio.h>int main(){ int i=0, num=0, j=1; printf ("Enter the number: "); scanf ("%d", &num );
for (i=1; i<num; i++) j=j*i; printf("The factorial of %d is %d\n",num,j);}
ทำการคอมไพลโปรแกรม factorial โดยใสตวเลอก -g ดงแสดงในคำสงขางลางน
$ gcc -g factorial.c$ ./a.outEnter the number: 10The factorial of 10 is 362880
เรยกโปรแกรม gdb ดวยคำสง
$ gdb ./a.out GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11~ppa1) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/student/unix/a.out...done.
ทดสอบการใชคำสงเพอตงตำแหนง breakpoint และ clear breakpoint ซงมรปแบบการใชงานได 2 แบบคอแบบท 1 หยดในตำแหนงบรรทดทระบ
break [file_name]:line_number
222
Embedded Android Development สเสนทางนกพฒนา
clear [file_name]:line_number
แบบท 2 คอหยดในตำแหนงชอฟงกชนทระบbreak [file_name]:func_name
clear [file_name]:func_name
ตวอยางการใชคำสงดบกโปรแกรม
(gdb) break 3
Breakpoint 2 at 0x40059c: file factorial.c, line 3.
(gdb) break 7
Breakpoint 2 at 0x4005c3: file factorial.c, line 7.
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040059c in main at factorial.c:3
2 breakpoint keep y 0x00000000004005c3 in main at factorial.c:10
(gdb) run
Starting program: /home/student/unix/a.out
Breakpoint 2, main () at factorial.c:7
7! ! scanf ("%d", &num );
สามารถใชคำสง print [variables] เพอแสดงคาภายในตวแปรขณะทโปรแกรมกำลงทำงานอยได
(gdb) print j
$1 = 1
(gdb) sEnter the number: 39! ! for (i=1; i<num; i++)(gdb) s10! ! ! j=j*i; (gdb) s9! ! for (i=1; i<num; i++)(gdb) s10! ! ! j=j*i; (gdb) print j$2 = 1(gdb) print i$3 = 2
223
Embedded Android Development สเสนทางนกพฒนา
(gdb) break 10 if j==2Note: breakpoint 1 also set at pc 0x4005e5.Breakpoint 3 at 0x4005e5: file factorial.c, line 10.(gdb) info breakNum Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005e5 in main at factorial.c:10
2 breakpoint keep y 0x000000000040059c in main at factorial.c:3
3 breakpoint keep y 0x00000000004005e5 in main at factorial.c:10
! stop only if j==2
(gdb) watch j==3Hardware watchpoint 2: j == 3
(gdb) disass mainDump of assembler code for function main: 0x0000000000400594 <+0>:!push %rbp 0x0000000000400595 <+1>:!mov %rsp,%rbp 0x0000000000400598 <+4>:!sub $0x10,%rsp 0x000000000040059c <+8>:!movl$0x0,-0x4(%rbp) 0x00000000004005a3 <+15>:! movl$0x0,-0x8(%rbp) 0x00000000004005aa <+22>:! movl$0x1,-0xc(%rbp) 0x00000000004005b1 <+29>:! mov $0x40070c,%eax 0x00000000004005b6 <+34>:! mov %rax,%rdi 0x00000000004005b9 <+37>:! mov $0x0,%eax 0x00000000004005be <+42>:! callq 0x400478 <printf@plt> 0x00000000004005c3 <+47>:! mov $0x40071f,%eax 0x00000000004005c8 <+52>:! lea -0x8(%rbp),%rdx 0x00000000004005cc <+56>:! mov %rdx,%rsi 0x00000000004005cf <+59>:! mov %rax,%rdi 0x00000000004005d2 <+62>:! mov $0x0,%eax 0x00000000004005d7 <+67>:! callq 0x400498 <__isoc99_scanf@plt> 0x00000000004005dc <+72>:! movl$0x1,-0x4(%rbp) 0x00000000004005e3 <+79>:! jmp 0x4005f3 <main+95>=> 0x00000000004005e5 <+81>:" mov -0xc(%rbp),%eax 0x00000000004005e8 <+84>:! imul -0x4(%rbp),%eax 0x00000000004005ec <+88>:! mov %eax,-0xc(%rbp) 0x00000000004005ef <+91>:! addl$0x1,-0x4(%rbp)... 0x0000000000400608 <+116>:! mov %rax,%rdi 0x000000000040060b <+119>:! mov $0x0,%eax 0x0000000000400610 <+124>:! callq 0x400478 <printf@plt> 0x0000000000400615 <+129>:! leaveq 0x0000000000400616 <+130>:! retq End of assembler dump.
224
Embedded Android Development สเสนทางนกพฒนา
ในกรณทใชโปรแกรม ddd ซงเปนโปรแกรมดบกในรปแบบกราฟฟกซงงายตอการใชงาน เพราะมไอคอนทสามารถอางองถงคำสงตางๆภายใน gdb ไดทงหมดดงตวอยางหนาตาของโปรแกรมในรปขางลาง
รปท 4.13 หนาตาโปรแกรม DDD และองคประกอบเครองมอตางๆ
การตงตำแหนง breakpoint และดคาภายในตวแปร สามารถทำไดงาย ดงตวอยางขางลาง
225
Embedded Android Development สเสนทางนกพฒนา
รปท 4.14 ตวอยางการตงจด Break Point
นอกจากนนสามารถสงสญญาณ (Signal) แบบตางๆ และดโคดโปรแกรมในรปแบบภาษาแอสเซมบลไดเชนกน
รปท 4.15 หนาตางโปรแกรมในสวนของการตงคาในการสงสญญาณและดภาษาแอสเซมบล
226
Embedded Android Development สเสนทางนกพฒนา
การเขยนโปรแกรมภาษา C++ ดวย Qtโปรแกรม Qt ไดรบการยอมรบวาเปน cross-platform application framework ทดทสดตวหนง
ในปจจบนน ซงมการเตรยมไลบรารและฟงกชน API จำนวนมากสำหรบการเขยนโปรแกรมภาษาซพลสพลส ซงโปรแกรม Qt ไดมการปรบปรงการทำงานหลายๆดานภายในไลบรารของภาษาซพลสพลสเอง ตวอยางเชน การจดการหนวยความจำ การตดตอกบพอรตการสอสาร การจดการโปรเซสและเทรด ใหมความยดหยน มความเสถยรภาพ และมประสทธภาพสงมากขน เพอใหเหมาะกบสถาปตยกรรมทแตกตางกนไป
Qt จะชวยใหนกพฒนาสามารถออกแบบและเขยนโปรแกรมงายขนในการพฒนาโปรแกรมประยกตดานตางๆ ตวอยางเชน งานดานกราฟฟก งานดานระบบเครอขาย งานดานระบบฐานขอมล งานดานมลตมเดย การจดการไฟล XML หรองานดานเวปโปรแกรม เปนตน นอกจากนนโปรแกรมทพฒนาขนมาภายใต Qt จะสามารถคอมไพลและถกรองรบใหสามารถทำงานไดหลายสถาปตยกรรมและหลายแพลตฟอรม ไดแก ระบปฏบตการลนกซ ระบบปฏบตการ MacOS X ระบบปฏบตการวนโดส ระบบปฏบตการวนโดสซอ ระบบปฏบตการมโก และระบบปฏบตการลนกซสำหรบระบบสมองกลฝงตว
โคดภาษา C++
Core Libraries GUI LibrariesDatabaseNetwork
XML
OpenGLMultimedia
Web Kit
Windows Linux/X11 MacOS X Embedded Linux WinCE
รปท 4.16 โครงสรางสถาปตยกรรม Qt framework
จากรปขางบนแสดงโครงสรางของ Qt framework โดยชนบนสดคอโคดโปรแกรมภาษาซพลสพลส ชนรองลงมาจะเปนสวนของ Qt classes สำหรบสราง GUI, Webkit, Database และอนๆ และชนสดทายคอระบบปฏบตการทรองรบการทำงานของโปรแกรม
การตดตง QT สำหรบแตละระบบปฏบตการตดตง Qt สำหรบแตละระบบปฏบตการ จะมการเตรยมชดโปรแกรมสำหรบการพฒนาทเรยกวา
Qt Installer ซงไดรวม Qt Libraries และ Qt Creator สำหรบเปนโปรแกรมเพอใหพฒนาโคดโปรแกรมและกราฟฟกทใชในโปรแกรม โดยการเขาไปดาวนโหลดไดจาก http://qt-project.org/downloads หลงจากนนกสามารถตดตงไดทนท
227
Embedded Android Development สเสนทางนกพฒนา
สำหรบระบบปฏบตการ Embedded Linux
ทำการดาวนโหลด Qt source code ลงเครองคอมพวเตอร และแตกไฟล ดงคำสงขางลางน$ wget http://download.qt-project.org/official_releases/qt/4.8/4.8.5/qt-everywhere-opensource-src-4.8.5.tar.gz$ tar -xzvf qt-everywhere-opensource-src-4.8.5.tar.gz
กำหนดการตงคา เพอใหรองรบสถาปตยกรรมทตองการ เชน ARM แลวทำการคอมไพลตามลำดบ $ cd ~/qt-everywhere-opensource-src-4.8.5$ ./configure -embedded [architecture]
โดยท:[architecture] คอสถาปตยกรรมของบอรด target เชน สถาปตยกรรม arm, x86 หรอ mips
หรอสามารถระบรายละเอยดพเศษอนๆในระหวางการใชคำสง ./configure เพอใหเหมาะสมกบสภาพแวดลอมของสถาปตยกรรมทใชงาน ดงคำสงขางลางน$ sudo /usr/local/qt-embedded-4.8.5$ ./configure -prefix /usr/local/qt-embedded-4.8.5 \ -embedded -qt-gfx-linuxfb -qt-gfx-qvfb \ -qt-gfx-vnc -no-largefile -exceptions -no-accessibility \ -no-qt3support -qt-zlib -no-gif -no-libtiff \ -qt-libpng -no-libmng -qt-libjpeg \ -no-nis -no-cups -depths 8,16,18,32 \ -qt-kbd-tty -qt-kbd-qvfb -qt-kbd-linuxinput \ -qt-mouse-linuxinput -qt-mouse-qvfb -qt-mouse-pc$ make
หลงจากเสรจสนการคอมไพลแลว จะไดไฟลไลบรารทจำเปนสำหรบการนำไปตดตงเพมลงในบอรดสมองกลฝงตว ทใชระบบปฏบตการ Embedded Linux ดงน
-libQtCore.so <--- ไลบรารหลก-libQtGui.so <--- ในกรณทตองการแสดงสวนกราฟฟกตดตอผใช (GUI)-libQtNetwork.so <--- ในกรณทตองการใชงานทางดานระบบเครอขาย-libQtSql.so <--- ในกรณทตองการใชงานในการเกบขอมลดวย SQlite-libQtXml.so <--- ในกรณทตองการใชงานในการจดการไฟล XML
ซงนกพฒนาสามารถเลอกไฟลไลบรารทตองการ แลวทำการคดลอกไฟลไลบรารไปยงไดเรกทอร /lib ของ root file system ภายในบอรดสมองกลฝงตว
228
Embedded Android Development สเสนทางนกพฒนา
ในการเรมตนพนฐานการพฒนาโปรแกรมดวย Qt นน สามารถสรางโปรแกรม “Hello World” อยางงาย ไดดงน
$ vim main.cpp
// main.cpp
#include<QtCore>int main(){ qDebug() << "Hello World\n";}
กอนจะทำการคอมไพล จะตองมการสรางไฟลทง 2 ไฟลขนมา ไดแก ไฟลโปรเจค (.pro) และไฟล Makefile ดวยคำสงดงน
$ qmake -project
ไฟลโปรเจค (.pro) จะถกสรางขนมาโดยอตโนมต ดงรายละเอยดภายในไฟลขางลางน
####################################################################### Automatically generated by qmake ###################################################################### TEMPLATE = appTARGET =DEPENDPATH += .INCLUDEPATH += . # InputSOURCES += main.cpp
ถดไปเปนการสราง Makefile โดยรนคำสง qmake โดยทไมตองใสพารามเตอร
$ qmake
$ cat Makefile####### Compilemain.o: main.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp
####### Installinstall: FORCE
uninstall: FORCE
FORCE:
229
Embedded Android Development สเสนทางนกพฒนา
ทำการคอมไพลโปรแกรม
$ makeg++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp
g++ -Wl,-O1 -o qt main.o -L/usr/lib -lQtGui -lQtCore -lpthread
ทดสอบเรยกโปรแกรม
$ ./qt Hello World
ตวอยางโปรแกรม Qt ในรปแบบกราฟฟกทตดตอกบผใช (GUI program) สามารถพฒนาผานโปรแกรม Qt Creator หรอสามารถเขยนโคดโปรแกรมดวย Text editor ทวไป ดงแสดงขางลางน
$ vim qt_gui.cpp// qt_gui.cpp#include<QApplication>#include<QLabel>
int main(int argc, char *argv[]){ QApplication app(argc, argv); QLabel* hello = new QLabel("<h1>Hello, World</h1>"); hello->show(); hello->setWindowTitle("Welcome to Embedded System World"); return app.exec();}
ทำการสรางไฟลโปรเจค (.pro) และไฟล Makefile ดงคำสงขางลางน
$ qmake -project$ qmake
ไฟลทงสองจะถกสรางขนดงรายละเอยดดงน
$ lsgui.pro Makefile qt_gui.cpp
$ cat gui.pro ####################################################################### Automatically generated by qmake (2.01a) Mon Sep 30 23:09:58 2013######################################################################
TEMPLATE = app
230
Embedded Android Development สเสนทางนกพฒนา
TARGET = DEPENDPATH += .INCLUDEPATH += .
# InputSOURCES += qt_gui.cpp
$ cat Makefile ############################################################################## Makefile for building: gui# Generated by qmake (2.01a) (Qt 4.6.2) on: Mon Sep 30 23:10:00 2013# Project: gui.pro# Template: app# Command: /usr/bin/qmake -unix -o Makefile gui.pro#############################################################################
####### Compiler, tools and options
CC = gccCXX = g++DEFINES = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHAREDCFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)...compiler_uic_clean:compiler_yacc_decl_make_all:compiler_yacc_decl_clean:compiler_yacc_impl_make_all:compiler_yacc_impl_clean:compiler_lex_make_all:compiler_lex_clean:compiler_clean:
####### Compile
qt_gui.o: qt_gui.cpp ! $(CXX) -c $(CXXFLAGS) $(INCPATH) -o qt_gui.o qt_gui.cpp
####### Install
install: FORCE
uninstall: FORCE
FORCE:
ทำการคอมไพลโปรแกรม
$ makeg++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o qt_gui.o qt_gui.cppg++ -Wl,-O1 -o gui qt_gui.o -L/usr/lib -lQtGui -lQtCore -lpthread
231
Embedded Android Development สเสนทางนกพฒนา
ทดสอบเรยกโปรแกรม Hello World ดงขางลาง
$ ./gui
รปท 4.17 ผลลพธการรนโปรแกรม Hello World
กลไกการทำงานของ SIGNAL และ SLOT
Signals และ slots ใชสำหรบการสอสารระหวางวตถ (object) ซงเปนกลไกหลกในการนำไปพฒนาโปรแกรม Qt โดยเฉพาะทางดานกราฟฟกตดตอกบผใช (GUI) ดงแสดงในรปขางลาง
รปท 4.18 กลไกการเชอมระหวาง Signals และ Slots
ฟงกชนในการเชอมระหวาง signals กบ slots นนจะมรปแบบการเขยนโปรแกรมดงน
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
ตวอยางโปรแกรมประยกตการทำงานของ signals และ slots#include<QApplication>
232
Embedded Android Development สเสนทางนกพฒนา
#include<QPushButton>
int main(int argc, char *argv[]){ QApplication app(argc, argv); QPushButton* hello = new QPushButton("Quit"); hello->resize(150, 75); QObject::connect(hello, SIGNAL(clicked()), &app, SLOT(quit())); hello->show(); hello->setWindowTitle("Hi"); return app.exec();}
จากโคดโปรแกรมขางบนเปนการเชอม signal ของปมทเกดจากการถกกด (clicked()) ไปยงตว slot ทชอฟงกชน quit() ซงทำการออกจากโปรแกรม ดงนนการทำงานของโปรแกรมคอเมอมการกดปมกจะออกจากโปรแกรมทนท โดยขอสงเกตในการใช signal และ slot มดงน
1. หนง signal สามารถเชอมไดหลาย slots
2. หลาย signals สามารถเชอมกบ slot เดยวกนได
3. สามารถยกเลกการเชอมตอ (connection) ได
ตวอยางการพฒนาโปรแกรมดวย Qt Creator
เปดโปรแกรม Qt Creator แลวทำการสรางโปรเจคใหม โดยเลอกชนด Qt GUI Application แลวเลอก Base class ใหเปนแบบ QDialog ดงแสดงในรปขางลาง
รปท 4.19 หนาตางสวนการตงคารายละเอยดของคลาส
233
Embedded Android Development สเสนทางนกพฒนา
หลงจากกด Next แลว Qt Creator จะไดโคดโปรแกรมดงรปดานลาง
รปท 4.20 แสดงโคดเบองตนทถกสรางขนมาอตโนมต
เปดไฟล dialog.ui เพอสราง UI ใหกบโปรแกรม โดยการเพม QPushButton และ QLabel ดงแสดงในรปขางลาง
รปท 4.21 การสราง GUI ผานสวนของ Design
ขนตอนตอไปจะเปนการสรางการเชอมโยง โดยการคลกขวาทปม Count แลวเลอก “Go to Slot” จากนนเลอก signal ทตองการเชอมไปยง slot ในทนใหเลอก clicked() จากนนกด OK
234
Embedded Android Development สเสนทางนกพฒนา
รปท 4.22 การตงคา Signal เพอกำหนด Slot เปาหมาย
โปรแกรมจะทำการสรางฟงกชนสำหรบการเชอมตอระหวาง signals และ slots ใหอตโนมต โดยจะตงชอ slots ใหชอวา “on_pushButton_clicked” ดงแสดงในรปขางลาง
รปท 4.23 Method ทถกสรางขนเมอมการเลอก slot
เพมเตมโคดโปรแกรมเขาไปในฟงกชน on_pushButton_clicked() ดงน
void Dialog::on_pushButton_clicked(){ static int count;
235
Embedded Android Development สเสนทางนกพฒนา
count++; ui->label->setText(QString::number(count));}
ในขนตอนสดทายทำการคอมไพลและรนโปรแกรม โดยกดปมลด Ctrl+R จะไดผลลพธดงรปดานลาง ซงเมอผใชกดปม Count โปรแกรมกจะทำการบวกเลขเพมขนทละ 1
รปท 4.24 ผลลพธการรนโปรแกรมเมอกดปม Count
การพฒนาโปรแกรมตดตอพอรตอนกรมการพฒนาโปรแกรมดวย Qt นนเรมไดรบความนยมมากขน โดยเฉพาะในวงการการพฒนาบน
ระบบสมองกลฝงตว เนองจากการทำงานของโปรแกรมทรวดเรว และการแสดงผลทางดานกราฟฟกทดขน นอกจากนนการพฒนาโปรแกรมเพอตดตอสอสารกบพอรตอนกรม กบอปกรณภายนอก เชน บอรดไมโครคอลโทรเลอร เปนตน กยงจำเปนตองมอย ดงนนใน Qt เวอรชนใหม ตงแตเวอรชน 5 เปนตนไป ไดมการรวมเอาโมดล QtSerialPort เขาไปอยในไลบราร Qt5 เปนทเรยบรอยแลว เพอความสะดวกในการเรยกใชงาน ซงสามารถตดตอไดทง hardware serial ports และ virtual serial ports
ภายในโมดล QtSerialPort ประกอบไปดวย 2 คลาสหลกๆคอ SerialPort และ SerialPortInfo โดยคลาส SerialPort จะเปนคลาสพนฐานทมเมทธอดตางๆ ในการตงคาพนฐานสำหรบพอรตอนกรม
ตาราง 4.5 การรองรบการตงคาพอรมอนกรมดวย Qt ในแตละระบบปฏบตการ
ระบบปฏบตการ สนบสนน รายละเอยด
Windows NT/2K/XP/Vista/7/8 YES Full support
Windows CE YES เวอรชน 5 และ 6 บนตว WinCE Emulator
Gnu/Linux YES Full support
MacOS X YES Full support
236
Embedded Android Development สเสนทางนกพฒนา
ระบบปฏบตการ สนบสนน รายละเอยด
Unix อนๆ YES POSIX-compatible ทงหมด
สำหรบคลาส SerialPortInfo จะเปนคลาสตวชวย ทจะแสดงคาสถานะตางๆของพอรตอนกรมทสามารถเรยกใชไดในระบบคอมพวเตอร หรอบอรดสมองกลฝงตว
ตาราง 4.6 การรองรบของฟงกชน SerialPortInfo ในแตละระบบปฏบตการ
ระบบปฏบตการ สนบสนน รายละเอยด
Windows NT/2K/XP/Vista/7/8 YES Full support โดยเรยกใชฟงกชน SetupAPI
Windows CE YES เวอรชน 5 และ 6 บนตว WinCE Emulator
Gnu/Linux YESFull support โดยเรยกใช libudev หรอคนหาได
ในไดเรกทอร /dev/ โดยตรง
MacOS X YES Full support
Unix อนๆ YESPOSIX-compatible ทงหมด คนหาไดใน
ไดเรกทอร /dev/ โดยตรง
แตโมดล QtSerialPort ยงมขอจำกดบางอยางทยงไมรองรบไดแก-การทำงานแบบโหมด Terminal, control CR/LF-ตงคา timeouts และ delays ของการอาน-การแจงเตอนเมอการมเปลยนสถานะของ RS-232 ขาOUT
ดาวนโหลดโมดล QtSerialPort แลวทำการคอมไพลและตดตงเพมเขาไปใน Qt4/Qt5 ดวยคำสงดงน
$ git clone git://gitorious.org/qt/qtserialport.git
Initialized empty Git repository in
/home/student/Downloads/qtserialport/.git/
remote: Counting objects: 4482, done.
remote: Compressing objects: 100% (1737/1737), done.
remote: Total 4482 (delta 3158), reused 3764 (delta 2719)
Receiving objects: 100% (4482/4482), 1.22 MiB | 233 KiB/s, done.
Resolving deltas: 100% (3158/3158), done.
237
Embedded Android Development สเสนทางนกพฒนา
$ cd qtserialport/
$ qmake qtserialport.pro
$ make
$ sudo make install
ในการพฒนาโปรแกรม Qt เพอตดตอพอรตอนกรมนนในกรณทเปน Qt4 และ Qt5 นน จะตองมการระบการเรยกใชโมดล QtSerialPort ในไฟลโปรเจค (.pro) เพมเขาไปดวยหลงจากรนคำสง qmake -project เพอสรางไฟลโปรเจค (.pro) ดงนกรณทเปน Qt4
CONFIG += serialport
กรณทเปน Qt5QT += serialport
แตสำหรบการ include ในโคดโปรแกรมทง Qt4 และ Qt5 จะเหมอนกน
...#include <QtSerialPort/QSerialPort>#include <QtSerialPort/QSerialPortInfo>...
การเปดพอรตอนกรมสามารถเลอกระดบของการเขาถงไดดงน read-only (r/o), write-only (w/o), read/write (r/w) และเมอเปดพอรตไดสำเรจ โมดล QSerialPort จะใชคาทตงไวดงเดมของพอรตนน แตอยางไรกตามกสามารถทำการตงคาใหมได โดยเรยกใชฟงกชน setBaudRate(), setDataBits(), set-Parity(), setStopBits() และ setFlowControl() ตามลำดบ ตวอยางการเปดพอรตอนกรม /dev/ttyS0
QSerialPort serial;serial.setPortName("/dev/ttyS0");serial.setBaudRate(QSerialPort::Baud9600);if (serial.open(QIODevice::ReadWrite)) { // to do this}
ตวอยางโปรแกรมการใชคลาส QSerialPortInfo เพอทำการตรวจสอบพอรตทเรยกใชงานได แลวทำการสงรายละเอยดของพอรตนนตอไปใหคลาส QSerialPort เพอทำการเปดตอไป #include <QtCore/QCoreApplication>#include <QtCore/QDebug>
238
Embedded Android Development สเสนทางนกพฒนา
#include <QtSerialPort/QSerialPort>#include <QtSerialPort/QSerialPortInfo>
QT_USE_NAMESPACE
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Example use QSerialPortInfo foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){ qDebug() << "Name : " << info.portName(); qDebug() << "Description : " << info.description(); qDebug() << "Manufacturer: " << info.manufacturer(); // Example use QSerialPort QSerialPort serial; serial.setPort(info); if (serial.open(QIODevice::ReadWrite)) serial.close(); } return a.exec();}
สรางไฟลโปรเจค (.pro) แลวเพมใหรองรบการใชโมดล QtSerialPort และทำการคอมไพล ดงคำสงขางลางน
$ qmake -project$ echo “CONFIG += serialport” >> serial.pro$ qmake$ makeg++ -Wl,-O1 -Wl,-rpath,/usr/local/qt-embedded-4.8.5/lib -o serial main.o -L/usr/local/qt-embedded-4.8.5/lib -lQtSerialPort -lQtGui -L/usr/local/qt-embedded-4.8.5/lib -lQtNetwork -lQtCore -lpthread $ lsmain.cpp main.o Makefile serial serial.pro$ ./serial Name : "ttyS0" Description : "" Manufacturer: "" Name : "ttyS1" Description : "" Manufacturer: ""
239
Embedded Android Development สเสนทางนกพฒนา
การพฒนาโปรแกรมแบบ MULTI-THREADING
การเขยนโปรแกรมเพอใหเทรดหลายตวสามารถทำงานพรอมกนได (multi-threading) ดงทเคยอธบายการพฒนาดวยภาษา C ในบททผานมา สำหรบการพฒนาโปรแกรมในลกษณะเปนกราฟฟกทตดตอกบผใชดวยภาษา C++ กบตว Qt นน ถอวาเปนสงจำเปนอยางมาก เนองจากถางานไหนทมโอกาสจะมการประมวลผลนาน กควรเปลยนใหไปประมวลผลการทำงานอยเบองหลงแทน (background processing) เพอไมใหกระทบตอการใชงานสวนกราฟฟกกบผใช ซงการพฒนาโปรแกรมในลกษณะ multi-threading นนไดนำมาใชอยางแพรหลาย สำหรบการพฒนาใน Qt นนสามารถเรยกใชงานไดงายและยงรองรบการเชอมตอกบแบบ signal และ slot เพอใชสงขอมลระหวางกนไปมาของเทรดได Qt สามารถใชงาน Thread ได 2 แบบใหญ คอ1. แบบ Low Level ดวย QThread คลาส QThread นนจะใชสำหรบ 1 เทรด ตอ 1 QThread ซงจะเรมทำงานจากฟงกชน run() แตจะตองทำการ implement ฟงกชน run() นกอน (::run()) ดงตวอยางโปรแกรมขางลาง
สรางไฟล writer.h และ main.cpp ดงน
$ vim writer.h// writer.h#ifndef WRITER_H#define WRITER_H
#include <QThread>#include <QString>#include <iostream>class Writer: public QThread {public: explicit Writer(const QString& mark) : mark_(mark) { }
void run();private: QString mark_;};#endif // WRITER_H
void Writer::run() { for (int i = 0; i < 20; ++i) { std::cout << qPrintable(mark_); msleep(200); }}
240
Embedded Android Development สเสนทางนกพฒนา
ในไฟล main.cpp จะมการเขยนลงไปในฟงกชน run() และจะมการหยดไปชวขณะประมาณ 200 มลลวนาท หลงจากนนกจะแสดงขอความออกทางหนาจอ ดงโคดขางลางน
$ vim main.cpp// main.cpp#include <QtCore/QCoreApplication>#include <QTimer>#include "writer.h"
int main(int argc, char *argv[]){ QCoreApplication a(argc, argv);
Writer w1("One"); Writer w2("Two"); Writer w3("Three");
w1.start(); w2.start(); w3.start();
w1.wait(); w2.wait(); w3.wait();
QTimer::singleShot(12000, &a, SLOT(quit()));
return a.exec();}
สรางไฟลโปรเจค (.pro) และไฟล Makefile เพอคอมไพลโปรแกรม ดงคำสงขางลางน
$ qmake -project$ qmake$ make$ ./thread Two Three One Two Three One Two Three One Three Two One Two One Three Two One Three Three Two One Three One Two Two Three One Two Three One Two Three One Two One Three Two One Three Two One Three Two One Three One Three Two One Three Two One Three Two One Three Two One Three Two
2. แบบ High Level ดวย QConcurrentQtConcurrent เปนตว API ในระดบสง สำหรบการเขยนโปรแกรมแบบ multi-threading บน Qt
น จะสามารถใชงานไดงายยงขนโดยทไมตองลงลกในรายละเอยดของเทรดและการจดการจำนวนเทรดตางๆ โดย QtConcurrent ไดรวมเอาฟงกชนไวหลายรปแบบเพอใหเหมาะสำหรบการนำไปประยกตใช
241
Embedded Android Development สเสนทางนกพฒนา
กบงานแบบไมตรงจงหวะกน (asynchronous task) โดยเฉพาะในโปรแกรมแบบกราฟฟกตดตอกบผใช (GUI applications)QtConcurrent::run() จะทำการเรยกฟงกชนขนมาภายใน thread ทสรางขนมาใหม
extern void aFunction();extern void bFunction();
QFuture<void> future1 = QtConcurrent::run(aFunction);QFuture<void> future2 = QtConcurrent::run(bFunction);
สามารถใชคลาส QFuture และ QFutureWatcher ในการตรวจสอบสถานะของฟงกชนทถกเรยกเขาไปในเทรดไดตวอยางโปรแกรมขางลางน #include <QCoreApplication>#include <qtconcurrentrun.h>#include <QThread>
#ifndef QT_NO_CONCURRENT
void myRunFunction(QString name) { for (int i = 0; i <= 5; i++) { qDebug() << name << " " << i << "from" << QThread::currentThread(); }}
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QFuture<void> t1 = QtConcurrent::run(myRunFunction, QString("A")); QFuture<void> t2 = QtConcurrent::run(myRunFunction, QString("B")); QFuture<void> t3 = QtConcurrent::run(myRunFunction, QString("C"));
t1.waitForFinished(); t2.waitForFinished(); t3.waitForFinished();
return a.exec();}
#else
#include <QLabel>
int main(int argc, char *argv[]){ QApplication app(argc, argv); QString text("Qt Concurrent is not yet supported on this platform"); QLabel *label = new QLabel(text); label->setWordWrap(true); label->show();
242
Embedded Android Development สเสนทางนกพฒนา
qDebug() << text; app.exec();}#endif
ทำการสรางไฟลโปรเจค (.pro) แลวเพมไลบราร concurrent เขาไปในไฟลโปรเจค ดงคำสงขางลางน
$ qmake -project$ echo “CONFIG += concurrent” >> qtconcurrent.pro
ทำการสรางไฟล Makefile และคอมไพลโปรแกรม เพอทดสอบการทำงานของ multi-threading ดงคำสงขางลางน
$ qmake$ make$ lsmain.cpp main.o Makefile qtconcurrent qtconcurrent.pro$ ./qtconcurrent "B" 0 from QThread(0x128d1c0, name = "Thread (pooled)") "B" 1 from QThread(0x128d1c0, name = "Thread (pooled)") "B" 2 from QThread(0x128d1c0, name = "Thread (pooled)") "A" 0 from QThread(0x128cb10, name = "Thread (pooled)") "A" 1 from QThread(0x128cb10, name = "Thread (pooled)") "A" 2 from QThread(0x128cb10, name = "Thread (pooled)") "A" 3 from QThread(0x128cb10, name = "Thread (pooled)") "A" 4 from QThread(0x128cb10, name = "Thread (pooled)") "A" 5 from QThread(0x128cb10, name = "Thread (pooled)") "B" 3 from QThread(0x128d1c0, name = "Thread (pooled)") "B" 4 from QThread(0x128d1c0, name = "Thread (pooled)") "C" 0 from QThread(0x128cb10, name = "Thread (pooled)") "C" 1 from QThread(0x128cb10, name = "Thread (pooled)") "B" 5 from QThread(0x128d1c0, name = "Thread (pooled)") "C" 2 from QThread(0x128cb10, name = "Thread (pooled)") "C" 3 from QThread(0x128cb10, name = "Thread (pooled)") "C" 4 from QThread(0x128cb10, name = "Thread (pooled)") "C" 5 from QThread(0x128cb10, name = "Thread (pooled)")
243
Embedded Android Development สเสนทางนกพฒนา
บทท 5 พนฐานระบบปฏบตการแอนดรอยดสำหรบนก พฒนา
ระบบปฏบตการแอนดรอยดประวตศาสตรของระบบปฏบตการแอนดรอยดเรมตนตงแตป ค.ศ. 2002 โดยเมอผกอตงบรษทก
เกลทงสองคอ Larry Page และ Sergey Brin ไดเขารวมฟงสมนา ณ มหาวทยาลยสแตนฟอรด (Stan-ford University) ในหวขอการพฒนาโทรศพทมอถอรนใหมชอ “SideKick Phone” นำเสนอโดยนาย Andy Rubin ซงขณะนนดำรงตำแหนงซอโอ (CEO) ของบรษท Danger Inc. เขาไดแสดงความสามารถของตวโทรศพทชนดพกพาชอวา SideKick Phone ซงเปนโทรศพทชนดพกพาตวแรกทสามารถเชอมตอผานระบบอนเทอรเนต (Internet) และทำงานไดหลากหลายตวอยางเชน การสงขอความ (Instant Messenger), อเมล (Mail), ตารางปฏทน (Calendar), และการทองเวปไซต (Browser) โดยเฉพาะการตงหนาการคนหาหลก (Search Engine default) ใหเปน Google search กยงทำให Larry Page เกดความประทบใจและไดกลายเปนหนงในผใช Sidekick Phone
แมวาตว Sidekick Phone จะเปนมอถอรนใหมทโดดเดนและทำใหผใชตางรสกตนเตนไดไมนอยกตามท แตกยงไมสามารถสรางใหเกดผลสำเรจในทางธรกจไดเทาทควรจะเปน จงทำให Andy Rubin ถกบบใหออกจากบรษท Danger Inc. ในชวงตนป ค.ศ. 2003 หลงจากหนงปผานไป Andy Rubin พรอมกบเงนกอนหนง เขากยงคงมความมงมนทตองการสรางธรกจทางดานระบบปฏบตการแนวคดใหมสำหรบโทรศพทเคลอนท (Mobile Operating System) เขาจงทำการจดโดเมนใหมในชอวา Android.com พรอมกบกอตงบรษทใหมในชอเดยวกนวา Android Inc. และไดเรมทำการพฒนา Open Mobile handset platform เพอใหกลายเปนระบบปฏบตการแบบเปด (Open Operating System) สำหรบผผลตโทรศพทเพอใหสามารถนำไปใชเปนระบบปฏบตการพนฐานภายในเครองของตนได
จนกระทงประมาณเดอนสงหาคม ป ค.ศ. 2005 ทางบรษทกเกลไดขอเจรจากบ Andy Rubin เพอขอเขาซอกจการบรษทของเขาจนในทสดกไดบรรลขอตกลงรวมกนดวยมลคาทไมไดถกเปดเผยตอสาธารณะชน และหลงจากนนเปนตนมาในชวงปลายป ค.ศ. 2007 บรษทกเกลไดประกาศเขารวมเปนสมาชกใน Open Handset Alliance (OHA) เพอทจะสรางระบบปฏบตการแบบเปดสำหรบโทรศพทเคลอนทในชอระบบปฏบตการแอนดรอยด (Android Operating System) อยางเปนทางการ และตอมาในเดอนกนยายน ป ค.ศ. 2008 บรษทกเกลจงไดปลอยระบบปฏบตการแอนดรอยด เวอรชน 1.0 โดยใชชอรหส (Codename) วา Astro ตอสาธารณะชนเปนครงแรก และกไดปลอยรนตางๆอยางตอเนองจนกระทงปจจบนดงแสดงในตารางขางลาง
244
Embedded Android Development สเสนทางนกพฒนา
1.5Cupcake
1.6Donut
2.0/2.1Eclair
2.2Froyo
2.3Gingerbread
3.0/3.1Honeycomb
4.0Icecream Sandwich
4.1/4.2/4.3Jelly Bean
4.4KitKat
รปท 5.1 รนของระบบปฏบตการแอนดรอยด
ตาราง 5.1 รายละเอยดการเปลยนแปลงทสำคญของแตละรนของแอนดรอยด
ชอโคด เวอรชน ออกเมอ การเปลยนแปลงสำคญ KERNEL SDK API NDK API
ไมระบ 1.0 กนยายน 2551 2.6.25 1 N/A
Petit Four 1.1 กมภาพนธ 2552 2.6.25 2 N/A
Cupcake 1.5 เมษายน 2552- Onscreen soft keyboard- หนาจอหมนอตโนมต
2.6.27 3 1
Donut 1.6 กนยายน 2552- มสถานะการใชแบตเตอร- สนบสนนการเชอมตอ VPN
2.6.27 4 2
Eclair
2.0 ตลาคม 2552- ม Live Wallpaper- รองรบระบบ Exchange
2.6.29 5 2
Eclair 2.0.1 ธนวาคม 2552- ม Live Wallpaper- รองรบระบบ Exchange
2.6.29 6 2Eclair
2.1 มกราคม 2553
- ม Live Wallpaper- รองรบระบบ Exchange
2.6.29 7 3
Froyo 2.2 พฤษภาคม 2553- มฟงกชน WiFi Hotspot- Just In Time Compile- กำเนด Nexus One
2.6.32 8 4
Ginger-
bread
2.3 - 2.3.2 พฤศจกายน 2553- รองรบ NFC และ SIP- มตว Download Manager- กำเนด Nexus S
2.6.35 9 5Ginger-
bread2.3.3 - 2.3.7 กมภาพนธ 2554 - รองรบ ADK 2.6.35 10 5
Honey-
comb
3.0 กมภาพนธ 2554- รองรบการแสดงผลบนแทปเลต- รองรบ Multi-core CPU
2.6.36 11 6Honey-
comb 3.1.x พฤษภาคม 2554 - รองรบ USB Host และม APIs 2.6.36 12 6
Honey-
comb
3.2.x มถนายน 2554 2.6.36 13 6
245
Embedded Android Development สเสนทางนกพฒนา
ชอโคด เวอรชน ออกเมอ การเปลยนแปลงสำคญ KERNEL SDK API NDK API
Ice-Cream
Sandwich
4.0 - 4.0.2 ตลาคม 2554- รองรบการแสดงผลบนมอถอและแทปเลต- กำเนด Galaxy Nexus
3.0.1 14 7Ice-Cream
Sandwich4.0.3 - 4.0.4 ธนวาคม 2554
- กำเนด WiFi Direct และ Android Beam- มความสามารถ Face Unlock
3.0.1 15 7
Jelly Bean
4.1.1 - 4.1.2 มถนายน 2555 - มการปรบปรงประสทธภาพโดยรวมมากขน 3.0.31 16 8
Jelly Bean 4.2 พฤศจกายน 2555 - รองรบการใชงานแบบ Multi-user 3.0.31 17 8
Jelly Bean
4.3 กรกฏาคม 2556- รองรบเทคโนโลย Low Power Bluetooth- รองรบการแสดงผลระดบ 4K
3.4.5 18 9
KitKat 4.4 พฤศจกายน 2556- รองรบเครองรนเกา (RAM >512MB)- รองรบเซนเซอรนบกาวเดน- รองรบระบบสง Infrared Remote
3.4.5 19 9
ดวยความรวมมอระหวางทมดแลลนกซคอรเนลและทมนกพฒนาของกเกล กไดทำใหในชวงป ค.ศ. 2011 ถง ค.ศ. 2012 เกดโครงการ Android Mainlining Project ขนโดยมวตถประสงคหลกคอการรวมไดรเวอรของแอนดรอยด (Android drivers) และความสามารถตางๆเขาไปอยในลนกซคอรเนลหลกตงแตเคอรเนล เวอรชน 3.3 เปนตนมาจนกระทงปจจบนโครงการนกสามารถรวมกนไดอยางสมบรณในเคอรเนลเวอรชน 3.5
ภายในระบบปฏบตการแอนดรอยดเองกไดมการปรบปรงการทำงานภายในระบบปฏบตการลนกซทเปนแกนกลางเพอใหเหมาะสมและสามารถรองรบการใชงานในสภาพแวดลอมของอปกรณชนดพกพา (Mobile Environment) ทตองใชพลงงานไฟฟาจากแบตเตอร รวมทงการปรบปรงความเรวของการสอสารระหวางโปรเซส (InterProcess Communication - IPC) ปรบปรงระบบการจดการหนวยความจำในระหวางโหลดโปรแกรมใชงาน และแกปญหาการจดการหนวยความจำ เปนตน ซงสวนรายละเอยดหลกๆทระบบปฏบตการแอนดรอยดไดปรบปรงและเพมเตมเขาไปในลนกซคอรเนล ดงแสดงในตารางขางลาง
ตาราง 5.2 การปรบเปลยนลนกซคอรเนลของระบบปฏบตการแอนดรอยด
เรอง คำอธบาย
Binderกลไกการตดตอสอสารระหวางโปรเซสภายในระบบปฏบตการแอนดรอยด (An-droid's IPC mechanism) ซงไดแรงบนดาลใจมาจากโปรเจค Open Binder
Ashmem ยอมาจาก Anonymous Shared Memory ทำหนาทเปนตวจดสรรพนท ทตองใชรวมกนภายในหนวยความจำกลาง (Shared memory allocator) โดยจะถอดสวนพนททถกแชรไว ในกรณทหนวยความจำเรมวกฤต
Logger สวนโปรแกรมไดรเวอรทบนทกขอมลตางๆจากการใชงานของผใช (user space)
246
Embedded Android Development สเสนทางนกพฒนา
เรอง คำอธบาย
Wakelocks
สวนควบคมไมใหเครองเขาสโหมดพก (suspend) ในกรณทพลงงานไฟฟานอย หรอมการพบปดหนาจอเหมอนเครองคอมพวเตอรทวไปทระบบปฏบตการจะปดเครองแลวเขาสโหมด suspend แต Wakelocks จะทำงานเพยงแคดบหนาจอ (Screen Turn-Off) เมอผใชตองการใชงานตอกเพยงเปดหนาจอกลบมา (Screen Turn-On) โดยทเครองไมไดดบ
OOMยอมาจาก Out Of Memory handler คอการจดการปญหาในกรณทหนวยความจำเตมโดยจะมการสงสญาณ Triggers กอนจะสงตอให Kernel ดำเนนการจดการ
Alarmตวนบหนวยเวลาเพอแจงเตอน (Android's alarm timer) ซงพฒนาตอยอดมาจากตวนาฬกา RTC (Real-time Clock) ของลนกซคอรเนลเดม
RAM consoleตวแสดงบนทกขอมลการทำงานของ Kernel ภายใน โดยการเรยกผานไฟล /proc/last_kmsg
สถาปตยกรรมของระบบปฏบตการแอนดรอยด
โครงสรางสถาปตยกรรมของระบบปฏบตการแอนดรอยดโดยเปรยบเทยบกบระบบปฏบตการลนกซทวไปนนจะมความคลายคลงกนหลายสวน แตกยงมอกหลายๆสวนทแตกตางกนออกไปเนองจากการปรบแตงใหเหมาะสมกบการนำไปใชในอปกรณชนดพกพาทมทรพยากรภายในทกำจดและพฤตกรรมการใชของผใชทแตกตางจากคอมพวเตอรแบบตงโตะ ดงรปเปรยบเทยบสถาปตยกรรมทงสอง
Application Application ApplicationApplication Application Application
Library
Framework & VM
middleware & Library
Kernel Kernelscheduler scheduler
Linux Android
รปท 5.2 เปรยบเทยบสถาปตยกรรมระบบปฏบตการลนกซ และปฏบตการแอนดรอยด
รายละเอยดภายในโครงสรางสถาปตยกรรมของระบบปฏบตการแอนดรอยดดงแสดงในรปขางลาง
247
Embedded Android Development สเสนทางนกพฒนา
โปรแกรมพนฐานแอนดรอยด
Launcher2 Phone AlarmClockEmail Settings CameraGallery Calendar BrowserBluetooth Contacts ...
โปรแกรมพนฐานแอนดรอยด
Power Manager Mount ServiceActivity Manager Notification ManagerPackage Manager Location ManagerBattery Service Search Service ....
android.*
LibsBionic / OpenGL / WebKit / ... Init / Toolbox Native Daenons Hardware Support
โปรแกรมประยกต (พฒนา/จาก Play Store)
java.*(Apache Harmony)
Android Runtime / Dalvik / Zygote
Linux KernelWakelocks / lowmem / binder / ashmem / ...
App API
Java NativeInterface
Bin
der
รปท 5.3 รายละเอยดภายในสถาปตยกรรมแอนดรอยด
จากโครงสรางสถาปตยกรรมของระบบปฏบตการแอนดรอยดจะสงเกตไดวามการแบงออกเปนสวนๆทมความเกยวเนองกน โดยสวนบนสดจะเปนสวนทผใชงานทำการตดตอโดยตรงซงเรยกวาโปรแกรมประยกต (Applications) และลำดบชนลงมากจะเปนองคประกอบของโปรแกรมระบบ ไลบรารตางๆ จนถงชนลางสดกจะเปนสวนทตดตอกบอปกรณโดยผานลนกซคอรเนล ซงในรายละเอยดของโครงสรางสถาปตยกรรมจะอธบายดงน
• Applications สวนของโปรแกรมทมมากบระบบปฏบตการหรอเปนกลมของโปรแกรมทผใชงานไดทำการตดตงไว โดยผใชงานสามารถเรยกใชโปรแกรมตางๆไดโดยตรงซงการทำงานของแตละโปรแกรมจะเปนไปตามทนกพฒนาโปรแกรมไดออกแบบและเขยนโคดโปรแกรมเอาไว
• Application Framework เปนสวนทมการพฒนาขนเพอใหนกพฒนาสามารถพฒนาโปรแกรมไดสะดวกและมประสทธภาพมากยงขน ดงนนนกพฒนาเพยงแคทำการศกษาวธการเรยกใชงาน Ap-plication Framework ในสวนทตองการใชงานแลวนำมาใชงานซงมหลายกลมดวยกน ตวอยางเชน
o Activities Manager เปนกลมของชดคำสงทจดการเกยวกบวงจรการทำงานของหนาตางโปรแกรม (Activity)
o Content Providers เปนกลมของชดคำสงทใชในการเขาถงขอมลของโปรแกรมอนและสามารถแบงปนขอมลใหโปรแกรมอนเขาถงได
o View System เปนกลมของชดคำสงทเกยวกบการจดการโครงสรางของหนาจอทแสดงผลในสวนทตดตอกบผใชงาน (User Interface)
248
Embedded Android Development สเสนทางนกพฒนา
o Telephony Manager เปนกลมของชดคำสงทใชในการเขาถงขอมลดานโทรศพท เชนหมายเลขโทรศพท เปนตน
o Resource Manager เปนกลมของชดคำสงในการเขาถงขอมลทเปนขอความ, รปภาพ เปนตน
o Location Manager เปนกลมของชดคำสงทเกยวกบตำแหนงทางภมศาตร ทระบบปฏบตการไดรบคาจากอปกรณ
o Notification Manager เปนกลมของชดคำสงทจะถกเรยกใชเมอโปรแกรม ตองการแสดงผลใหกบผใชงาน ผานทางแถบสถานะ(Status Bar) ของหนาจอ
• Libraries เปนสวนของชดคำสงทพฒนาดวยภาษา C/C++ โดยแบงชดคำสงออกเปนกลมตามวตถประสงคของการใชงาน เชน Surface Manage จดการเกยวกบการแสดงผล, Media Frame-work จดการเกยวกบการการแสดงภาพและเสยง, Open GL | ES และ SGL จดการเกยวกบภาพ 3มต และ 2มต, SQLite จดการเกยวกบระบบฐานขอมล เปนตน
• Android Runtime จะม Dalvik Virtual Machine ทถกออกแบบมา เพอใหทำงานบนอปกรณทมหนวยความจำ (Memory), หนวยประมวลผลกลาง (CPU) และพลงงาน (Battery)ทจำกด ซงการทำงานของ Dalvik Virtual Machine จะทำการแปลงไฟลทตองการทำงาน ไปเปนไฟล .DEX กอนการทำงาน เหตผลกเพอใหมประสทธภาพเพมขนเมอใชงานกบหนวยประมวลผลกลางทมความเรวไมมาก สวนตอมาคอ Core Libraries ทเปนสวนรวบรวมคำสงและชดคำสงสำคญๆซงถกเขยนดวยภาษาจาวา (Java Language)
• Linux Kernel เปนสวนหวใจสำคญในการจดการกบบรการหลกของระบบปฏบตการ เชน เรองหนวยความจำ พลงงาน ตดตอกบอปกรณตางๆ ความปลอดภย ระบบเครอขาย โดยแอนดรอยดไดนำเอาสวนนมาจากระบบปฏบตการลนกซ 2.6 (Kernel 2.6.24) ทไดถกออกแบบมาเปนอยางด ถาจะนำ vanilla kernel ใหสามารถทำงานบนระบบปฏบตการแอนดรอยดไดนน เปนเรองไมงายนกสำหรบนกพฒนาระบบสมองกลฝงตว ดงนนทางกเกลจงไดเตรยมซอรสโคดและเคอรเนลพนฐานภายใตโปรเจคชอวา AOSP (Android Open Source Project) เพอเปนแนวทางใหนกพฒนาสามารถพฒนาไดสะดวกยงขน
249
Embedded Android Development สเสนทางนกพฒนา
แนวทางการพฒนา Embedded Android
เมอวเคราะหแนวการพฒนาในเชงลกของนกพฒนาทางดานระบบสมองกลฝงตว โดยเฉพาะทางดานระบบสมองกลฝงตว ทใชระบบปฏบตการแอนดรอยด สามารถแยกได 4 กลมไดแก
นกพฒนาโปรแกรม (Application Developers)
Application Framework
Linux Kernel
Applications
Surface Manager Dalvik VM
Media Manager
Shared Libraries
พฒนาโปรแกรม
System Image
เนนการพฒนาโปรแกรมประยกตดวยภาษาจาวา
(Android JAVA) และ ภาษาซ (Native C lan-
guage) ในระดบ Application Layer เชน
โปรแกรมทางดานการศกษา เกมส อเนกประสงค
การสอสาร ธรกจการเงน เปนตน
นกพฒนาโปรแกรม (Platform Developers)
Application Framework
Linux Kernel
Applications
Surface Manager Dalvik VM
Media Manager
Shared Libraries
Rebuild ระบบปฏบตการแอน
ดรอยด
เปนการปรบแตง Android Application
Framework เชน โปรแกรมระบบ โปรแกรม
ประยกตพนฐานทมากบเครอง ปรบแตงการ
แสดง UI พเศษ การแสดงผลแบบสองหนาพรอม
กน เปนตน ซงจะเปนกลมทเนนปรบแตง ROMs
เชน CyanogenMod เปนตน
250
Embedded Android Development สเสนทางนกพฒนา
นกปรบแตงระบบปฏบตการ (Android Porting)
Application Framework
Linux Kernel
Applications
Surface Manager Dalvik VM
Media Manager
Shared Libraries
การ Porting ระบบปฏบตการแอนดรอยด
เนนงานทางดานการ Porting แอนดรอยดรน
ตางๆ ใหสามารถทำงานอยบนสถาปตยกรรมอน
เชน MIPS, Intel x86 เปนตน หรอไปอยบน
เครอง Netbook (EeePC) หรอ Virtual Ma-
chine (VMWare, Virtual Box, GenyMotion
เปนตน)
นกระบบฮารดแวร (Hardware Developers)
Application Framework
Linux Kernel
Applications
Surface Manager Dalvik VM
Media Manager
Shared Libraries
ปรบแตงระบบปฏบตการ แอนดรอยด
ปรบแตง Kernel
เนนการออกแบบบอรดสมองกลฝงตว สำหรบ
งานประยกตดานตางๆ เชน อปกรณ Set-top-
box, Android USB Stick, ต Kiosk เปนตน
โดยจะตองมการปรบแตงลนกซคอรเนลเพอให
รองรบอปกรณพวงรอบขางตามทตองการ และ
ปรบแตงโปรแกรมระบบ, Launcher UI หรอ
การเลนมลตมเดยแบบพเศษ เปนตน
251
Embedded Android Development สเสนทางนกพฒนา
เตรยมสภาพแวดลอมสำหรบการพฒนา Embedded Android
โปรแกรมพนฐานและบรการระบบPower Manager Mount ServiceActivity Manager Notification ManagerPackage Manager Location ManagerBattery Service Search Service ....
Media Server
Media WebKit Fresstype SQLite
Home Dialer Camera Media Player Settings ...
Service Manager
Network Manager
...
Skia Input ALSA ...
Core Libraries
Dalvik VM
Audio Camera Radio (RIL) GPS ...Sensors NFS
Audio WiFi Camera Display ...Bimder Logger
Applications
ApplicationFrameworks
Libraries & Runtimes
Hardware Abstraction
Layer
LinuxKernel
รปท 5.4 รายละเอยดภายในแตละชนของระบบปฏบตการแอนดรอยด
เตรยมสภาพแวดลอมบนเครอง HOST
ระบบปฏบตการลนกซตวทเหมาะสำหรบการศกษาและทดสอบระบบปฏบตการแอนดรอยดคอ Ubuntu LTS (Long Term Support) รน 10.04 หรอ Ubuntu LTS รน 12.04 ซงทางกเกลไดใชเปนตวหลกในการทดสอบระบบปฏบตการแอนดรอยดรนตางๆโดยเฉพาะรน Android Gingerbread (2.3.x) ขนไปนนจะตองใชสภาพแวดลอมทเปนระบบปฏบตการแบบ 64 บตเทานน นอกจากนนทรพยากรพนฐานของเครอง Host กควรจะมหนวยความจำไมนอยกวา 8GB (แนะนำอยท 16GB) และมพนทความจวางไมนอยกวา 30GB ตวอยางเชน Android IceScream Sandwich (ICS) จะใชพนทประมาณ 25GB สำหรบหนงแพลตฟอรม ในกรณตองการสรางทกรนของ AOSP จะตองมพนทไมนอยกวา 80GB สำหรบโปรแกรมและไลบรารทตองตดตงลงไป สำหรบโปรแกรมและเครองมอพนฐานทตองมอยในเครอง Host ตวอยางเชน
• โปรแกรม Python รน 2.6 - 2.7• เครองมอในการคอมไพล GNU Make รน 3.81 - 3.82• โปรแกรม JDK รน 6 สำหรบ Android Gingerbread ขนไป แตถาตองการ Android Froyo ตำลงมา จะตองลง JDK รน 5 (fromjava.sun.com)
• โปรแกรม Git รน 1.7 ขนไป (git-scm.com)ตวอยางการตดตง JDK รน 6 สำหรบ Gingerbread ขนไป และ JDK รน 5 สำหรบ Froyo ตำลงมา
252
Embedded Android Development สเสนทางนกพฒนา
$ sudo add-apt-repository "deb http://archive.canonical.com/ lucid part-ner"$ sudo apt-get update$ sudo apt-get install openjdk-6-jre
หรอ
$ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu hardy main multiverse"$ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu hardy-updates main multiverse"$ sudo apt-get update$ sudo apt-get install openjdk-6-jre
ตดตงโปรแกรม และไลบรารทเกยวของสำหรบระบบปฏบตการ 64-bit Ubuntu LTS 10.04 $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs \ x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev \ libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown \ libxml2-utils xsltproc
ในกรณทใชระบบปฏบตการ 64-bit Ubuntu LTS 12.04
$ sudo apt-get install git gnupg flex bison gperf build-essential \zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \libgl1-mesa-dev g++-multilib mingw32 tofrodos \python-markdown libxml2-utils xsltproc zlib1g-dev:i386
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
253
Embedded Android Development สเสนทางนกพฒนา
Android Open Source Project (AOSP)
ดาวนโหลดซอรส AOSPในการดาวนโหลดซอรสโคดของระบบปฏบตการแอนดรอยดนนจะใชโปรแกรม repo ซงเปน Git
Wrapper script เพอระบรนของแอนดรอยดทตองการและดาวนโหลดโคดทเกยวของทงหมด โดยปกตแลวจะใชพนทในการเกบโคดทงหมดไมตำกวา 20GB และอาจจะตองใชเวลาในการดาวนโหลดประมาณ 3-6 ชวโมง ขนอยกบความเรวของอนเตอรเนตของเครอขายนนๆ
ดงตวอยางขนตอนการดาวนโหลด AOSP
$ mkdir ~/bin$ export PATH=$PATH:~/bin$ sudo apt-get install curl$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 22889 100 22889 0 0 50164 0 --:--:-- --:--:-- --:--:-- 111k
$ chmod a+x ~/bin/repo
ไฟล manifest จะเกบลงคและขอมลทจำเปนสำหรบดาวนโหลดโปรแกรมทเกยวของทงหมด ดงตวอยางแสดงภายในไฟล XML ขางลาง
ตาราง 5.3 รายละเอยดภายใน XML ไฟลของ AOSP
ชอ รายละเอยด
name ชอโปรเจค ทบรรจโคดทงหมด
fetch Server URL
revision git branch
remote รายละเอยด server
path ไดเรกทอรทจะเกบจากการ unpack
project รายละเอยดของโปรเจค
254
Embedded Android Development สเสนทางนกพฒนา
ดาวนโหลด AOSP รนลาสด สามารถใชคำสง
$ repo init -u https://android.googlesource.com/platform/manifest
ในกรณทตองการระบรน เชน รน 4.0.1_r1 กสามารถทำโดยการเพม option -b ดงคำสงขางลาง
$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1
จากรปขางลาง แสดงใหเหนแนวคดของ AOSP ในการจดการและปลอยโคดแตละรน
รปท 5.5 แสดงแนวทางการออกเวอรชนของแตละรน
เรมตนการดาวนโหลดโคด AOSP ลงในไดเรกทอร ~/aosp ซงใชเวลาในการดาวนโหลดไมนอยกวา 3-5 ขวโมง
$ mkdir ~/aosp$ cd ~/aosp$ repo sync
255
Embedded Android Development สเสนทางนกพฒนา
โครงสรางภายใน AOSPเมอดาวนโหลดไฟลทงหมดเสรจสน ภายในไดเรกทอร ~/aosp จะมไดเรกทอรยอยๆไมนอยกวา
35,000 ไดเรกทอร สำหรบไดเรกทอรสำคญๆทนกพฒนาควรจะทำความเขาใจ ไดแกตาราง 5.4 รายละเอยดไดเรกทอรของ AOSP
ไดเรกทอร รายละเอยดabi บรรจ Minimal C++ Run-time Type information
bionic ไลบรารภาษา C ของแอนดรอยด
bootable บรรจโคดสำหรบ Bootloader และ Recovery
build บรรจโครงสราง framework สำหรบสราง AOSP
cts ชด Test Suite สำหรบแอนดรอยด
dalvik บรรจตว Dalvik Virtual Machine
development ชดเครองมอสำหรบพฒนาตางๆ
device บรรจไฟล configuration ตางๆของแตละผขายตว System-on-Chip
external โปรเจคภายนอกทถกนำมาใชใน AOSP
frameworks Android core application framework
hardware ไลบรารและโมดลตางๆสำหรบระบบฮารดแวร (HAL)
kernel Linux Kernel
libcoreบรรจโปรเจค Apache Harmony และไลบรารพนฐานของจาวาทถกใชใน Dalvik
ndk Native Development Kit
packages โปรแกรมประยกตตางๆภายใน AOSP
prebuilt เครองมอ Toolchain สำเรจรป
sdk Android's Software Development Kit
systemไลบรารและไฟลไบนารหลกๆของระบบแอนดรอยด เชน init, toolbox, adb
tools เครองมอตางๆสำหรบการตงคาและใชงาน
เมอคดเปนสดสวนเปอรเซนตเปรยบเทยบขนาดแตละไดเรกทอร สามารถแสดงเปนกราฟวงกลมไดดงรปขางลางน
256
Embedded Android Development สเสนทางนกพฒนา
รปท 5.6 แสดงขนาดพนทของแตละไดเรกทอรของ AOSP
Stock Android Apps
packages/
android.*frameworks/base/core/
System Servicesframeworks/base/services/,frameworks/base/media/,
java.*(Apache Harmony)
libcore/
Linux Kernelไมม เนองจาก Kernel ไมไดเปนสวนหนงในไดเรกทอร AOSP
Librariesbionic/, external/, frameworks/base/
App API
โปรแกรมประยกตจาก Play Store
HALhardware/, device/
Native Daemonssystem/, external,
frameworks/base/cmds/
Init / Toolboxsystem/core/
Binder
JNI
รปท 5.7 ไดเรกทอรทเกยวของของแตละชนของระบบปฏบตการแอนดรอยด
bionic0.3%
cts2.3%
dalvik0.7%
development1.5%
device0.7%
external26.9%
frameworks19.4%
hardware0.9%libcore0.7%
ndk0.5%
packages4.7%
prebuilts40.2%
sdk0.9%others0.3%
257
Embedded Android Development สเสนทางนกพฒนา
สทธอนญาต (License) ของแตละสวนภายใน AOSP สามารถแยกประเภทของลขสทธทคมครองอยได 4 กลม ไดแก
• สวน Kernel จะม GNU GPLv2/GPLv3 license คมครอง• สวน external libraries จะม LGPL และ GPL license คมครอง• สวน bionic และ toolbox จะม BSD license คมครอง• สวน framework จะม Apache 2.0 license คมครอง
Android Kernel โคดของ Android Kernel patches ไมไดถกนำเขาไปไวในระบบกลางของลนกซคอรเนลหลก
เนองจากทางบรษทกเกลเปนผดแลเองทงหมดเรยกในสวนนวา “android-common” โดยสวน An-droid Kernel patches จะวางอยในตำแหนงระดบบนของพนฐานระบบปฏบตการตามขอกำหนดของ Linus Torvalds
สวนเคอรเนลทบรษทกเกลไดพฒนาขนเองนน กเพอตองการเพมความสามารถทขาดอยและปรบปรงการทำงานของลนกซคอรเนลเดมบางสวนใหเหมาะสมกบทรพยากรทมอยจำกด สภาพแวดลอม และพฤตกรรมการใชงานอปกรณชนดพกพา (Portable device) จนเรยกวาเปนแอนดรอยดเคอรเนล (Android Kernel) เฉพาะขนมา โดยมรายละเอยดดงน
• Binder - กลไกการตดตอสอสารระหวางโปรเซสภายในระบบปฏบตการแอนดรอยด (Android's IPC mechanism) ซงไดแรงบนดาลใจมาจากโปรเจค Open Binder
โปรแกรม A โปรแกรม BBinder
Function(Object)- Marshalling (assembling)- Relaying
Thread
รปท 5.8 แสดงขนตอนการรบสงขอมลระหวางโปรแกรมผาน Binder
• Ashmem (Anonymous Shared Memory) - ทำหนาทเปนตวจดสรรพนททตองใชรวมกนภายในหนวยความจำกลาง (Shared memory allocator) โดยจะถอดสวนพนททถกแชรไวในกรณทหนวยความจำเรมวกฤต
• Logger - สวนโปรแกรมไดรเวอรทบนทกขอมลตางๆจากการใชงานของผใช (user space)• Wakelocks - สวนควบคมไมใหเครองเขาสโหมดพก (suspend) ในกรณทพลงงานไฟฟานอยหรอมการพบปดหนาจอเหมอนเครองคอมพวเตอรทวไปทระบบปฏบตการจะปดเครองแลวเขาสโหลด suspend แต Wakelocks จะทำงานเพยงแคดบหนาจอ (Screen Turn-Off) เมอผใชตองการใชงานตอกเพยงเปดหนาจอกลบมา (Screen Turn-On) โดยทเครองไมไดดบ
258
Embedded Android Development สเสนทางนกพฒนา
CPU Screen KeyboardWakelock บางสวน
Wakelock เตมรปแบบ
รปท 5.9 ระดบการควบคมไมใหเครองเขาสโหมดพก
• OOM (Out Of Memory handler) - ตวจดการปญหาในกรณหนวยความจำเตม โดยจะมการสงสญาณ Triggers กอนจะสงตอใหเคอรเนลดำเนนการจดการ
• Alarm - ตวนบหนวยเวลาเพอแจงเตอน (Android's alarm timer) ซงพฒนาตอยอดมาจากตวนาฬกา RTC (Real-time Clock) ของลนกซคอรเนลเดม
• RAM console - ตวแสดงบนทกขอมลการทำงานของเคอรเนลภายในโดยการเรยกผานไฟล /proc/last_kmsg
• Paranoid network - ตวดแลจดการระบบเครอขายผาน uid (user id) และ pid (process id) เชน การกำหนดให uid หรอ pid มสทธในการเขาถง (access permission) ระบบเครอขายอนเทอรเนตดวยการตงคาภายในไฟล manifest.xml ดงตวอยางขางลางน
<permission name=”android.permission.INTERNET”> <group gid=”inet” /> </permission>
ขนตอนการคอมไพล AOSP มาเปนระบบปฏบตการแอนดรอยดตงคาพนฐานสำหรบเตรยมพรอมสภาพแวดลอมในการคอมไพล AOSP
$ cd ~/aosp$ source build/envsetup.sh
จากคำสงดานบนเปนคำสงใชในการตงคาสภาพแวดลอมใหกบระบบเพอจำเปนตอการคอมไพล และเพมคำสง shell script เพอใชในการเลอกแพลมฟอรตทตองการ เชน
• hmm() - สำหรบแสดงมนชวยเหลอ
• lunch() - สำหรบแสดง lunch เมนเพอเลอกแพลมฟอรตทตองการ (target board)
• add_lunch_combo() - สำหรบเพมชอผลตภณฑใหมทนกพฒนากำหนดขนเอง
• mm() - สำหรบสรางโมดลทงหมดทอยในไดเรกทอรปจจบน
259
Embedded Android Development สเสนทางนกพฒนา
นอกจากนนในระหวางเรยก envsetup.sh กจะมการรนคำสง source vendorsetup.sh, vendor/*/vendorsetup.sh, vendor/*/*/vendorsetup.sh และ device/*/*/vendorsetup.sh เพออนญาตใหเพมรายชอผลตภณฑทนกพฒนากำหนดขนเองอกดวย ตวอยางเชน Samsung Maguro product ทอยในไดเรกทอร device/samsung/maguro## Copyright (C) 2011 The Android Open Source Project## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-‐2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.# add_lunch_combo full_maguro-‐userdebug
ทดสอบเรยกคำสง shell script ทถกตงคาจากไฟล envsetup.sh
$ hmm
Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:- croot: Changes directory to the top of the tree.- m: Makes from the top of the tree.- mm: Builds all of the modules in the current directory.- mmm: Builds all of the modules in the supplied directories.- cgrep: Greps on all local C/C++ files.- jgrep: Greps on all local Java files.- resgrep: Greps on all local res/*.xml files.- godir: Go to the directory containing a file.
Look at the source to view more functions. The complete list is:addcompletions add_lunch_combo cgrep check_product check_variant choosecombo choose-product choosetype choosevariant cproj croot findmakefile gdbclient get_abs_build_var getbugreports get_build_var getprebuilt gettop godir hmm is-viewserverstarted jgrep key_back key_home key_menu lunch _lunch m mm mmm pid print-config print_lunch_menu resgrep runhat runtest set_java_home setpaths set_se-quence_number set_stuff_for_environment settitle smoketest startviewserver stopviewserver systemstack tapas tracedmdump
ขนตอนถดไปเปนการเลอกบอรด target (ซงในทนจะเลอกสถาปตยกรรม x86) ดวยคำสง
$ lunch
You're building on LinuxLunch menu... pick a combo:
260
Embedded Android Development สเสนทางนกพฒนา
1. full-eng 2. full_x86-eng 3. vbox_x86-eng 4. full_grouper-userdebug 5. mini_armv7a_neon-userdebug 6. mini_armv7a-userdebug 7. full_wingray-userdebug 8. full_crespo-userdebug 9. full_maguro-userdebug 10. full_panda-userdebug
Which would you like? [full-eng] full_x86-eng
============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.1.1TARGET_PRODUCT=full_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86-atomHOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-3.0.0-burapha-x86_64-with-Ubuntu-10.04-lucidHOST_BUILD_TYPE=releaseBUILD_ID=JRO03LOUT_DIR=out============================================
หลงจากเรยกคำสงขางตน การตงคาผลตภณฑทนกพฒนาเลอกไว จะถกตงเปนทเรยบรอยแลว รวมทงคาตวแปรสำคญตางๆ ไดแก
•ANDROID_BUILD_TOP•ANDROID_TOOLCHAIN•ANDROID_PRODUCT_OUT•ANDROID_HOST_OUT
สามารถตรวจสอบคาตวแปรสภาพแวดลอมของระบบดวยคำสง
$ echo $ANDROID_BUILD_TOP
กอนเขาสขนตอนคอมไพล AOSP ทใชเวลาอยางนอย 3-4 ชวโมงซงขนอยกบความเรวอนเทอรเนตนน จะมอยอก 2 คำสงทนกพฒนาควรรไดแก คำสงการเกบแคสซ (cache) ออฟเจคไฟลทไดมาจากการคอมไพลโดยเผอไวสำหรบครงถดไปทตองมการคอมไพลใหมอกรอบ โดยการตงคาดงน
$ export USE_CCACHE=1
261
Embedded Android Development สเสนทางนกพฒนา
และการตงคาจำนวนคอรของหนวยประมวลผลทจะนำมาใชระหวางการคอมไพล เพอเพมความเรวยงขนโดยการระบ option -jX โดยท X จะแทนจำนวนของคอร (Core) หนวยประมวลผลกลางบวก 1 ดงตวอยางการใชงานขางลาง
$ make -j3
============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.1.1TARGET_PRODUCT=full_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86-atomHOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-2.6.32-42-server-x86_64-with-Ubuntu-10.04-lucidHOST_BUILD_TYPE=releaseBUILD_ID=JRO03LOUT_DIR=out============================================find: `src': No such file or directoryPRODUCT_COPY_FILES frameworks/base/data/sounds/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg ignored.PRODUCT_COPY_FILES frameworks/base/data/sounds/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg ignored....PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg ignored.
ผลลพธของไฟลทไดจากการคอมไพลมอยางนอย 6 ไฟลไดแก
1. boot.img – Native system boot image2. ramdisk.img – Ramdisk rootfs3. recovery.img – Recovery image4. ramdisk-recovery.img – Ramdisk rootfs สำหรบการกคน (recovery)5. system.img – System data (ไดเรกทอร /system)6. userdata.img – User data (ไดเรกทอร /data)
ไฟลขางตนเหลานเปนเพยงสวนหนงของระบบปฏบตการแอนดรอยด ทไดมาจาก AOSP แตยงไมไดรวมถง Android Kernel ซงจะตองดาวนโหลดและคอมไพลแยกออกไปจาก AOSP ซงจะกลาวถงในบทถดไป จากรปขางลางแสดงตำแหนงไฟลทจะถกนำไปใสไวในบอรด target ตามตำแหนงไดเรกทอรดงอธบายไวในรป
262
Embedded Android Development สเสนทางนกพฒนา
Stack
เครอง Host
PRJROOT (glibc)
sysapps/rootfs/build-tools/...
AOSP (bionic)
build/system/frameworks/packages/external/
Kernel
บอรด TargetRoot (/) RAM disk
/acct/cache/d/data/dev/etc/mnt/proc/root/sbin/sdcard/sys/system/vendor/config/storage/charger
/cache Image /data Image
/amr/app/app-private/backup/dalvik-cache/data/dontpanic/local/misc/property/secure/system
SD Card(/mnt/sdcard)
/system Image
/app/bin/etc/fonts/framework/lib/usr/xbin
Live Kernel
procfssysfstmpfscgroupconfigfs
รปท 5.10 แสดงรายละเอยดของแตละไดเรกทอรภายในระบบไฟลของแอนดรอยด
ตาราง 5.5 แสดงตำแหนงการถก mount ของแตละไฟล image ในแอนดรอยด
IMAGE FILE MTD PARTITION MOUNT POINT
ramdisk.img N/A /
system.img /dev/mtdblock0 /system
userdata.img /dev/mtdblock1 /data
N/A /dev/mtdblock2 /cache
รายละเอยดระบบไฟลภายในระบบปฏบตการแอนดรอยด ซงประกอบไปดวยไดเรกทอรและไฟลทสำคญตางๆ ดงอธบายอยในตารางขางลางน
ตาราง 5.6 รายละเอยดไดเรกทอรภายในระบบปฏบตการแอนดรอยด
ชอไฟล ประเภท รายละเอยด/acct ไดเรกทอร จด mount-point ไปยง cgroup
/cache ไดเรกทอร สวนเกบขอมลชวคราวตางๆ เชนการดาวนโหลด เปนตน
/d symlinkชไปยง /sys/kernel/debug ซงเปนจด mount-point สำหรบ de-
bugfs
/data ไดเรกทอรจด mount-point ไปยงพารทชน data ซงเปนจด mount ของไฟล
userdata.img
263
Embedded Android Development สเสนทางนกพฒนา
ชอไฟล ประเภท รายละเอยด/dev ไดเรกทอร จด mount-point ไปยง tmpfs ซงบรรจ device node ตางๆ
/etc symlink ชไปยง /system/etc
/mnt ไดเรกทอร จดสำหรบ mount ระบบไฟลชวคราว
/proc ไดเรกทอร จด mount-point ไปยง procfs
/root ไดเรกทอรไดเรกทอรของผดแลระบบ root เดมของ Linux แตใน Android จะไมม
บรรจไฟลใดๆ
/sbin ไดเรกทอรโดยปกตใน Linux จะเกบโปรแกรมสำหรบผดแลระบบ แตใน Android
จะเกบเพยง ueventd และ adbd
/sdcard ไดเรกทอร จดสำหรบ mount ระบบไฟลบน SD Card
/sys ไดเรกทอร จด mount-point ไปยง sysfs
/system ไดเรกทอรจด mount-point ไปยงพารทชน system ซงเปนจด mount ของไฟล
system.img
/vendor symlink ชไปยง /system/vendor ซงอาจจะพบเจอไดในบางเครอง
/config ไดเรกทอร (ตงแต Jelly Bean 4.2) จด mount-point ไปยง configfs
/storage ไดเรกทอร(ตงแต Jelly Bean 4.1) สำหรบ mount ตวเกบขอมลภายนอก (Ex-
ternal Storage)
/charger ไฟล (ตงแต Jelly Bean 4.2) เปนโปรแกรมแสดงสถานะของแบตเตอร
/res ไดเรกทอร (ตงแต Jelly Bean 4.2) ไฟล resources สำหรบโปรแกรม charger
/init ไดเรกทอรโปรแกรม init ทจะถกเรยกโดย Kernel หลงจากสนสดการเรมตนระบบ
ครงแรก
/init.rc ไฟล ไฟล configuration สำหรบโปรแกรม init
/init<device_name>.rc
ไฟล ไฟล configuration ของบอรด target รนนนๆ สำหรบโปรแกรม init
/ueventd.rc ไฟล ไฟล configuration สำหรบโปรแกรม uventd
/uventd<device_name>.rc
ไฟลไฟล configuration ของบอรด target รนนนๆ สำหรบโปรแกรม
ueventd
/default.prop ไฟลคาคณสมบตทวไปของระบบ (global properties) ซงจะอานโดย
โปรแกรม init
264
Embedded Android Development สเสนทางนกพฒนา
ระบบปฏบตการแอนดรอยดบน Android Emulator ไฟลระบบปฏบตการแอนดรอยด จะถกเกบไวในไดเรกทอรดงแสดงขางลางน
$ ls ~/aosp/out/target/product/generic_x86/android-info.txt grub previous_build_config.mk system userdata-qemu.img clean_steps.mk hardware-qemu.ini ramdisk.img system.img data installed-files.txt root test dex_bootjars obj symbols userdata.img
ดงนนผใชกสามารถเปดโปรแกรม Android Emulator ดวยคำสงขางลางน กจะขนหนาตางโปรแกรมดงแสดงในรปขางลาง
$ emulator &
265
Embedded Android Development สเสนทางนกพฒนา
266
Embedded Android Development สเสนทางนกพฒนา
พนฐานการใช ANDROID DEBUG BRIDGE (ADB)การเรยนรหลกการทำงานของ Android Emulator ถอวาเปนพนฐานการเรมตนทดสำหรบนก
พฒนาทางดานสมองกลฝงตวน เนองจากมองคประกอบทงดานกราฟฟก ดานระบบปฏบตการพนฐาน และ Android Kernel รวมถงการพฒนาโปรแกรมประยกต ดงนนเพอใหสามารถเขาใจโครงสราง root filesystem ไดโดยละเอยด รวมทงสามารถตดตงหรอถอนโปรแกรมในระบบปฏบตการแอนดรอยดได จะตองใชโปรแกรมเครองมอชอวา “adb” (Android Debug Bridge) ในการตดตอและเขาสระบบภายใน Android Emulator ดงแสดงรายละเอยดการทำงานของ adb ดงรปขางลาง
รปท 5.11 แสดงกลไกการทำงานของ adb
ตวอยางคำสงแสดงรายการอปกรณแอนดรอยดทตออยกบเครอง Host
$ adb devices* daemon not running. starting it now on port 5037 ** daemon started successfully *List of devices attached emulator-5554 device
การตดตอเขาสระบบภายในระบบปฏบตการแอนดรอยดของ Android Emulator
$ adb shell# ls -aldrwxr-xr-x root root 2013-08-17 15:11 acctdrwxrwx--- system cache 2013-08-17 15:11 cachedr-x------ root root 2013-08-17 15:11 configlrwxrwxrwx root root 2013-08-17 15:11 d -> /sys/kernel/debug
267
Embedded Android Development สเสนทางนกพฒนา
drwxrwx--x system system 2013-08-05 02:01 data-rw-r--r-- root root 116 1970-01-01 00:00 default.propdrwxr-xr-x root root 2013-08-17 15:11 devlrwxrwxrwx root root 2013-08-17 15:11 etc -> /system/etc-rwxr-x--- root root 234929 1970-01-01 00:00 init-rwxr-x--- root root 2344 1970-01-01 00:00 init.goldfish.rc-rwxr-x--- root root 17057 1970-01-01 00:00 init.rc-rwxr-x--- root root 1637 1970-01-01 00:00 init.trace.rc-rwxr-x--- root root 3915 1970-01-01 00:00 init.usb.rcdrwxrwxr-x root system 2013-08-17 15:11 mntdr-xr-xr-x root root 2013-08-17 15:11 procdrwx------ root root 2011-11-14 19:00 rootdrwxr-x--- root root 1970-01-01 00:00 sbinlrwxrwxrwx root root 2013-08-17 15:11 sdcard -> /mnt/sdcarddrwxr-xr-x root root 2013-08-17 15:11 sysdrwxr-xr-x root root 2013-08-04 18:33 system-rw-r--r-- root root 272 1970-01-01 00:00 ueventd.goldfish.rc-rw-r--r-- root root 3879 1970-01-01 00:00 ueventd.rclrwxrwxrwx root root 2013-08-17 15:11 vendor -> /system/vendor
# cat /proc/cpuinfoprocessor : 0vendor_id : GenuineIntelcpu family : 6model : 3model name : Pentium II (Klamath)stepping : 3cpu MHz : 2293.936cache size : 2048 KBfdiv_bug : nohlt_bug : nof00f_bug : nocoma_bug : nofpu : yesfpu_exception : yescpuid level : 2wp : yesflags : fpu de pse tsc msr pae mce cx8 apic sep pge cmov pat mmx fxsr sse sse2 pni ssse3bogomips : 4587.87clflush size: 32
แสดงพนทภายใน MTD Device ของระบบไฟลภายในระบบปฏบตการแอนดรอยดแตละพารทชนดวยคำสงดงน
# cat /proc/mtddev: size erasesize namemtd0: 0f180000 00020000 "system"mtd1: 0c200000 00020000 "userdata"mtd2: 04000000 00020000 "cache"
# cat /proc/mountsrootfs / rootfs ro 0 0tmpfs /dev tmpfs rw,nosuid,mode=755 0 0devpts /dev/pts devpts rw,mode=600 0 0proc /proc proc rw 0 0sysfs /sys sysfs rw 0 0tmpfs /mnt/asec tmpfs rw,mode=755,gid=1000 0 0
268
Embedded Android Development สเสนทางนกพฒนา
tmpfs /mnt/obb tmpfs rw,mode=755,gid=1000 0 0/dev/block/mtdblock0 /system yaffs2 ro 0 0/dev/block/mtdblock1 /data yaffs2 rw,nosuid,nodev 0 0/dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0
Android Emulator
Android Emulator หรอเรยกอกชอหนงวา Goldfish ถกพฒนาบนพนฐานจากโปรแกรม QEMU รวมทงซอรสของ Android Kernel ซงเหมาะในการทดสอบการปรบแตงหรอเพมเตมโปรแกรมระบบและโปรแกรมประยกตอนๆเขาไปภายในระบบปฏบตการแอนดรอยด ซงการปรบแตงตวจำลองเสมอนจรง Goldfish ตวนม แนวทางการเรยนรออกมาไดเปน 4 ขนตอนดงน
1. การตงคา cross-compiling toolchain สำหรบสราง Android kernel2. ดาวนโหลดซอรสโคดของ Android Kernel โดยระบรนของ Kernel ทตองการ3. การคอมไพล Android Kernel4. การตงคาเมนใหรองรบ loadable kernel module (LKM)
$ cd ~/aosp$ source build/envsetup.sh$ lunch full_x86-eng$ emulator -helpAndroid Emulator usage: emulator [options] [-qemu args]options:-sysdir <dir> search for system disk images in <dir>-system <file> read initial system image from <file>-datadir <dir> write user data into <dir>....-help-build-images about disk images when building Android-help-all prints all help content
ตวอยางการระบตวเลอก -show-kernel เพอแสดงผลการทำงานของ Android Kernel สามารถทำไดดงน
$ emulator -kernel ~/aosp/goldfish/arch/x86/boot/bzImage -wipe-data -show-kernel
emulator: WARNING: system partition size adjusted to match image file (249 MB > 200 MB)serial0 consolestudent@marabuntu:~/aosp$ [ 0.000000] Linux version 3.4.0+ (student@marabuntu) (gcc version 4.4.3 (GCC) ) #1 PREEMPT Tue Aug 6 12:14:53 PDT 2013[ 0.000000] BIOS-provided physical RAM map:[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f000 (usable)[ 0.000000] BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved)[ 0.000000] BIOS-e820: 00000000000e8000 - 0000000000100000 (reserved)[ 0.000000] BIOS-e820: 0000000000100000 - 000000001fff0000 (usable)[ 0.000000] BIOS-e820: 000000001fff0000 - 0000000020000000 (ACPI data)[ 0.000000] BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
269
Embedded Android Development สเสนทางนกพฒนา
[ 0.000000] Notice: NX (Execute Disable) protection missing in CPU![ 0.000000] DMI 2.4 present.[ 0.000000] last_pfn = 0x1fff0 max_arch_pfn = 0x100000[ 0.000000] init_memory_mapping: 0000000000000000-000000001fff0000[ 0.000000] RAMDISK: 1ffb4000 - 1fff0000
.....for 1f700000-1f796000, got write-back[ 4.816692] Clocksource tsc unstable (delta = 70001460 ns)[ 35.829113] warning: `zygote' uses 32-bit capabilities (legacy support in use)[ 86.091553] binder: 1208: binder_alloc_buf, no vma[ 86.091710] binder: 1115:1126 transaction failed 29201, size 4-0[ 86.091868] binder: send failed reply for transaction 3147 to 1208:1208[ 99.262724] init: sys_prop: permission denied uid:1003 name:service.bootanim.exit
270
Embedded Android Development สเสนทางนกพฒนา
ขนตอนการอพเกรดและปรบแตง Android Kernel สำหรบ Emulator
จากรปดานลางจะเหนไดวา Android Emulator ของ Android รน 4.1.1 (ICS) พนฐานทมากบ AOSP นนยงใช Android Kernel รน 2.6.29 เดมอยดงแสดงในรปขางลาง
ขนตอนการอพเกรด ANDROID KERNEL สำหรบ ANDROID EMULATOR (GOLDFISH) เรมตนดวยการดาวนโหลด Android Kernel รนใหมดงคำสงขางลาง
$ cd ~/aosp$ git clone http://android.googlesource.com/kernel/goldfish.git
ใชคำสง git branch -r เพอตรวจสอบวาม Kernel รนไหนอยบาง
$ cd goldfish$ git branch -rorigin/HEAD -> origin/masterorigin/android-goldfish-2.6.29
271
Embedded Android Development สเสนทางนกพฒนา
origin/android-goldfish-3.4origin/linux-goldfish-3.0-wiporigin/master
เลอกใช Kernel รนทตองการ ซงในทนจะเลอกรน 3.4
$ git checkout -b 3.4 origin/android-goldfish-3.4Checking out files: 100% (38868/38868), done.Branch 3.4 set up to track remote branch android-goldfish-3.4 from origin.Switched to a new branch '3.4'
ตงคา Kernel พนฐานสำหรบ Goldfish
โดยเรมตนจะอางองจากคาทเลอกพนฐานไวสำหรบ Goldfish Emulator ซงถกเกบอยภายใตไดเรกทอร arch/x86/configs/$ ls -al arch/x86/configs/total 80drwxr-xr-x 2 student student 4096 2013-08-17 18:46 .drwxr-xr-x 25 student student 4096 2013-08-17 18:46 ..-rw-r--r-- 1 student student 55883 2013-08-17 18:46 goldfish_defconfig-rw-r--r-- 1 student student 7511 2013-08-17 18:46 i386_defconfig-rw-r--r-- 1 student student 7528 2013-08-17 18:46 x86_64_defconfig
$ make goldfish_defconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf## configuration written to .config#
ในกรณทตองการใชการตงคาทมากบบอรด target และอปกรณมอถอ/แทปเลตนน โดยปกตจะมไฟล .config เดมอยแลวซงจะถกบบอดและเกบในชอไฟลวา config.gz และจะถกเกบอยในไดเรกทอร /proc/ ของเครองนนๆ ดงนนนกพฒนาสามารถใชคำสง adb pull เพอดงไฟล config.gz ออกมา แลวเปลยนชอไฟลเปน .config ดงคำสงขางลาง แตอยางไรกตามนกพฒนากยงสามารถดาวนโหลดเพมเตมและตงคาเคอรเนลพเศษเพมเตมได$ adb pull /proc/config.gz .$ gunzip config.gz $ cp config .config
272
Embedded Android Development สเสนทางนกพฒนา
ขนตอนสดทายกอนทจะคอมไพลเพอสราง Kernel image ใหม นกพฒนาสามารถปรบแตงคาตางๆ ทมอยใน เคอรเนลไดตามตองการ ตวอยางเชน Networking support, Device Drivers, Firmware Driv-ers, File systems, Security options, Cryptographic API, Virtualization, Library routines เปนตน
$ make menuconfig
ทดลองเพมการรองรบการใชงาน Bluetooth และ NFC เพมเตม โดยการเขาไปเลอกจากเมน Network-ing support
273
Embedded Android Development สเสนทางนกพฒนา
เลอกใหรองรบ Kernel Loading Module (KLM) โดยการเลอกในเมน enable loadable module support ดงแสดงในรปขางลาง
274
Embedded Android Development สเสนทางนกพฒนา
คอมไพลเคอรเนลรนใหมสำหรบ Goldfish
เรมตนโดยการตงคาสภาพแวดลอมสำหรบ cross-compiling และสถาปตยกรรมของ Goldfish Emula-tor ซงในทนคอสถาปตยกรรม x86 $ export CROSS_COMPILE=~/aosp/external/qemu/distrib/kernel-toolchain/android-kernel-toolchain-
$ export REAL_CROSS_COMPILE=~/aosp/prebuilts/gcc/linux-x86/x86/i686-android-linux-4.4.3/bin/i686-android-linux-
$ export ARCH=x86
$ export SUBARCH=x86
$ make -j3
หลงจากคอมไพลสนสดลงกจะไดไฟล kernel image ชอวา “bzImage” เกดขนอยในไดเรกทอร arch/x86/boot/ ดงรายการคำสงขางลาง$ ls arch/x86/boot/a20.c cpustr.h mtools.conf.in version.oa20.o ctype.h pm.c vesa.hapm.c early_serial_console.c pmjump.o video-bios.cbioscall.o early_serial_console.o pmjump.S video-bios.obioscall.S edd.c pm.o video.cbitops.h edd.o printf.c video.hboot.h header.o printf.o video-mode.cbzImage header.S regs.c video-mode.ocmdline.c install.sh regs.o video.ocmdline.o main.c setup.bin video-vesa.ccode16gcc.h main.o setup.elf video-vesa.ocompressed Makefile setup.ld video-vga.ccopy.o mca.c string.c video-vga.ocopy.S mca.o string.o vmlinux.bincpu.c memory.c tools voffset.hcpucheck.c memory.o tty.c zoffset.hcpucheck.o mkcpustr tty.ocpu.o mkcpustr.c version.c
ทำการเรยกโปรแกรม Android Emulator ขนมาใหมอกครงโดยระบตำแหนงทเกบไฟล kernel image ตวใหม โดยใช option -kernel ดงคำสงขางลางน$ cd ~/aosp$ source build/envsetup.sh$ lunch full_x86-eng$ emulator -kernel ~/aosp/goldfish/arch/x86/boot/bzImage -wipe-data &
275
Embedded Android Development สเสนทางนกพฒนา
การพฒนา Kernel Module สำหรบระบบปฏบตการแอนดรอยด ในตอนนตว Android Emulator สามารถใชงานกบเคอรเนลตวใหม (รน 3.4) ซงขนตอนหลงจากน
นกพฒนาจะสามารถศกษาและทดสอบการปรบแตงคาตางๆภายใน Android Kernel ไดแลว นอกจากนนกยงสามารถพฒนาโปรแกรม kernel module หรอ kernel device driver ในระดบ kernel space เพอปรบปรงระบบปฏบตการแอนดรอยดหรอรองรบการตดตอกบอปกรณภายในไดยดหยนมากขน
ตวอยางการพฒนา kernel module อยางงาย ดงแสดงในขนตอนขางลางน
$ mkdir ~/aosp/goldfish/my_modules$ cd ~/aosp/goldfish/my_modules/
การเขยนโมดลสามารถเขยนไดหลายแบบ ดงตวอยางโปรแกรม hello.c และ hello1.c ขางลาง
// hello.c#include <linux/module.h> /* Needed by all modules */#include <linux/kernel.h> /* Needed for KERN_ALERT */MODULE_LICENSE("GPL");MODULE_AUTHOR("Wiroon Sriborrirux EE-Burapha, 2013");MODULE_DESCRIPTION("Demo module");
int init_module(void)
276
Embedded Android Development สเสนทางนกพฒนา
{ printk(KERN_INFO "Hello world! 1\n"); return 0;}
void cleanup_module(void){ printk(KERN_ALERT "Cleaning up module 1\n");}
ตวอยางโปรแกรม hello1.c// hello1.c// Defining __KERNEL__ and MODULE allows us to access kernel-level code not usually available to userspace programs.#undef __KERNEL__#define __KERNEL__
#undef MODULE#define MODULE
// Linux Kernel/LKM headers: module.h is needed by all modules and kernel.h is needed for KERN_INFO.#include <linux/module.h> // included for all kernel modules#include <linux/kernel.h> // included for KERN_INFO#include <linux/init.h> // included for __init and __exit macros
MODULE_LICENSE("GPL");MODULE_AUTHOR("Wiroon Sriborrirux EE-Burapha, 2013");MODULE_DESCRIPTION("Demo module");
static int __init hello_init(void){ printk(KERN_INFO "Hello world! 2\n"); return 0; // Non-zero return means that the module couldn't be loaded.}
static void __exit hello_cleanup(void){ printk(KERN_INFO "Cleaning up module 2\n");}module_init(hello_init);module_exit(hello_cleanup);
ทำการสรางไฟล Makefile เพอใชในการคอมไพลโปรแกรมทสรางขน ดงน
$ vim Makefile
VERSION = 3PATCHLEVEL = 4
277
Embedded Android Development สเสนทางนกพฒนา
SUBLEVEL = 0EXTRAVERSION=
obj-m += hello.o hello1.o
all: make -C /home/student/aosp/goldfish/ M=$(PWD) modulesclean: make -C /home/student/aosp/goldfish/ M=$(PWD) clean
กอนจะทำการคอมไพลโมดล hello จำเปนจะตองคอมไพล Kernel เพอใหพรอมสำหรบการใชงานโมดลดวยคำสง
$ cd ~/aosp/goldfish/$ make ARCH=x86 CROSS_COMPILE=~/aosp/prebuilts/gcc/linux-x86/x86/i686-android-linux-4.4.3/bin/i686-android-linux- modules_prepare
make[1]: Nothing to be done for `all'.make[1]: Nothing to be done for `relocs'. CHK include/linux/version.h CHK include/generated/utsrelease.h CC kernel/bounds.s GEN include/generated/bounds.h CC arch/x86/kernel/asm-offsets.s GEN include/generated/asm-offsets.h CALL scripts/checksyscalls.sh CC scripts/mod/empty.o MKELF scripts/mod/elfconfig.h HOSTCC scripts/mod/file2alias.o HOSTCC scripts/mod/modpost.o HOSTCC scripts/mod/sumversion.o HOSTLD scripts/mod/modpost
เรมการคอมไพล kernel module ทไดสรางไว (hello.c)
$ cd ~/aosp/goldfish/my_modules/$ makemake -C /home/student/aosp/goldfish/ M=/home/student/aosp/goldfish-/custom_modules modulesmake[1]: Entering directory `/home/student/aosp/goldfish' CC [M] /home/student/aosp/goldfish/custom_modules/hello.o CC [M] /home/student/aosp/goldfish/custom_modules/hello1.o Building modules, stage 2. MODPOST 2 modules CC /home/student/aosp/goldfish/custom_modules/hello.mod.o LD [M] /home/student/aosp/goldfish/custom_modules/hello.ko CC /home/student/aosp/goldfish/custom_modules/hello1.mod.o LD [M] /home/student/aosp/goldfish/custom_modules/hello1.komake[1]: Leaving directory `/home/student/aosp/goldfish'
$ ls
278
Embedded Android Development สเสนทางนกพฒนา
hello1.c hello1.mod.o hello.ko hello.o Makefile_oldhello1.ko hello1.o hello.mod.c Makefile modules.orderhello1.mod.c hello.c hello.mod.o Makefile1 Module.symvers
หลงจากการคอมไพลเสรจสมบรณกจะไดไฟลโมดลชอวา hello.ko ใหทำการคดลอกโดยสงผาน adb push ไปยง Android Emulator ดวยคำสงดงน
$ adb push hello.ko /data/local52 KB/s (2203 bytes in 0.040s)$ adb push hello1.ko /data/local54 KB/s (2238 bytes in 0.040s)$ adb shell# cd /data/local# lshello.kohello1.kotmp
ทดสอบโหลดโมดล hello และ hello1 ภายใตระบบปฏบตการแอนดรอยด ซงใช Kernel รนใหม (3.4.0) และตรวจสอบผลการทำงานของโมดล ดวยคำสง dmesg
# insmod hello.ko# insmod hello1.ko# lsmodhello1 506 0 - Live 0x00000000 (PO)hello 540 0 - Live 0x00000000 (O)# rmmod hello# rmmod hello1# dmesg...<3>[ 79.016988] init: sys_prop: permission denied uid:1003 name:service.bootanim.exit<4>[ 4000.418990] hello: module license 'unspecified' taints kernel.<4>[ 4000.419343] Disabling lock debugging due to kernel taint<6>[ 4064.182198] Hello world! 1<6>[ 4068.910892] Hello world! 2<6>[ 4086.416483] Cleaning up module 1<6>[ 4089.112969] Cleaning up module 2
279
Embedded Android Development สเสนทางนกพฒนา
การสรางโปรแกรมประยกตเพอฝงลงในแอนดรอยด
เมอตองการตดตงโปรแกรมประยกตสำหรบระบบปฏบตการแอนดรอยด (.APK) โดยทวไปแลวจะมวธการดวยกน 2 วธคอการนำขน Google PlayStore แลวดาวนโหลดเพอตดตง และวธทสองคอการนำไฟลตดตง (นามสกล .APK) มาตดตงลงในเครองโดยตรง แตอยางไรกตามถาตองการตดตงโปรแกรมประยกตทไดพฒนาขนมาฝงลงไปอยในระบบปฏบตการแอนดรอยดเพอใหเปนหนงในชดโปรแกรมพนฐานของอปกรณยหอนนตงแตแรกนกพฒนาจำเปนจะตองจดเตรยมตงแตการสรางระบบปฏบตการแอนดรอยดตงแตเรมตนโดยจะมขนตอนการทำดงตอไปน
1. เปดโปรแกรม Eclipse เพอสรางแอพพลเคชนอยางงาย โดยตงชอวา MyApp
280
Embedded Android Development สเสนทางนกพฒนา
281
Embedded Android Development สเสนทางนกพฒนา
// MainActivity.javapackage com.example.myapp;
import android.os.Bundle;import android.app.Activity;import android.view.Menu;
public class MainActivity extends Activity {
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }}
// activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" />
</RelativeLayout>
282
Embedded Android Development สเสนทางนกพฒนา
2. สรางไฟล Android.mk
283
Embedded Android Development สเสนทางนกพฒนา
3. สราง symbolic link เพอชไปยงไดเรกทอรโปรแกรม MyApp
$ cd ~/aosp/packages/apps$ ln -s /home/student/android/workspace/MyApp MyApp$ ls -altotal 148drwxr-xr-x 37 student student 4096 2013-08-19 02:27 .drwxr-xr-x 7 student student 4096 2012-09-04 04:30 ..drwxr-xr-x 5 student student 4096 2012-09-04 22:50 BasicSmsReceiverdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 Bluetoothdrwxr-xr-x 7 student student 4096 2012-09-04 22:50 Browserdrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Calculatordrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Calendardrwxr-xr-x 7 student student 4096 2012-09-04 22:50 Cameradrwxr-xr-x 5 student student 4096 2012-09-04 22:50 CellBroadcastReceiverdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 CertInstallerdrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Contactsdrwxr-xr-x 6 student student 4096 2012-09-04 22:50 DeskClockdrwxr-xr-x 7 student student 4096 2012-09-04 22:50 Emaildrwxr-xr-x 6 student student 4096 2012-09-04 22:50 Exchangedrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Gallerydrwxr-xr-x 8 student student 4096 2012-09-04 22:50 Gallery2drwxr-xr-x 4 student student 4096 2012-09-04 22:50 HTMLViewerdrwxr-xr-x 6 student student 4096 2012-09-04 22:50 KeyChaindrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Launcher2drwxr-xr-x 6 student student 4096 2012-09-04 22:50 LegacyCameradrwxr-xr-x 6 student student 4096 2012-09-04 22:50 Mmsdrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Musicdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 MusicFXlrwxrwxrwx 1 student student 37 2013-08-19 02:27 MyApp -> /home/student/android/workspace/MyAppdrwxr-xr-x 8 student student 4096 2012-09-04 22:50 Nfcdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 PackageInstallerdrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Phonedrwxr-xr-x 4 student student 4096 2012-09-04 22:50 Protipsdrwxr-xr-x 3 student student 4096 2012-09-04 22:50 Provisiondrwxr-xr-x 6 student student 4096 2012-09-04 22:50 QuickSearchBoxdrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Settingsdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 SoundRecorderdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 SparePartsdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 SpeechRecorderdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 Stkdrwxr-xr-x 5 student student 4096 2012-09-04 22:50 Tagdrwxr-xr-x 4 student student 4096 2012-09-04 22:50 VideoEditordrwxr-xr-x 5 student student 4096 2012-09-04 22:50 VoiceDialer
4. ลบไดเรกทอร gen/ และ bin/ ทอยภายใตไดเรกทอรของโปรแกรม MyApp
$ cd MyApp $ rm -rf gen bin
5. เพมชอแอพพลเคชนเขาไปในไฟล ~/aosp/build/target/product/core.mk ในสวนของ PRODUCT_PACKAGES
284
Embedded Android Development สเสนทางนกพฒนา
$ cd /home/student/aosp/build/target/product/
$ gedit core.mk
6. ตงคาสภาพแวดลอมสำหรบ AOSP ใหมอกครง
$ cd ~/aosp $ source build/envsetup.sh $ lunch 2============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.1.1TARGET_PRODUCT=full_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86-atomHOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-2.6.32-42-server-x86_64-with-Ubuntu-10.04-lucidHOST_BUILD_TYPE=releaseBUILD_ID=JRO03LOUT_DIR=out============================================
7. คอมไพลและสรางโปรแกรม MyApp
$ cd package/apps/MyApp$ make$ mm============================================PLATFORM_VERSION_CODENAME=REL
285
Embedded Android Development สเสนทางนกพฒนา
PLATFORM_VERSION=4.1.1TARGET_PRODUCT=full_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86-atom....Processing target/product/generic_x86/obj/APPS/MyAppAndroid_intermediates/package.apkDone!Install: out/target/product/generic_x86/system/app/MyAppAndroid.odexInstall: out/target/product/generic_x86/system/app/MyAppAndroid.apkmake: Leaving directory `/home/student/aosp'
8.ลบไฟล system.img ทอยในไดเรกทอร ~/aosp/out/target/product/generic_x86 และแฟมทงหมดภายในไดเรกทอร ~/aosp/out/target/product/generic_x86/obj/PACKAGING/systemimage_intermediates/
$ cd ~/aosp/out/target/product/generic_x86$ rm -rf system.img obj/PACKAGING/systemimage_intermediates/
9. คอมไพล AOSP ใหมอกครง
$ cd ~/aosp$ make -j3ringtones/Rigel.ogg ignored.PRODUCT_COPY_FILES frameworks/base/data/sounds/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg ignored.PRODUCT_COPY_FILES frameworks/base/data/sounds/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg ignored.PRODUCT_COPY_FILES frameworks/base/data/sounds/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg ignored.PRODUCT_COPY_FILES frameworks/base/data/sounds/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg ignored.PRODUCT_COPY_FILES frameworks/base/data/sounds/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg ignored.Target system fs image: out/target/product/generic_x86/obj/PACKAGING/systemimage_intermediates/system.imgRunning: mkyaffs2image -f out/target/product/generic_x86/system out/target/product/generic_x86/obj/PACKAGING/systemimage_intermediates/system.imgInstall system fs image: out/target/product/generic_x86/system.img
286
Embedded Android Development สเสนทางนกพฒนา
10. ขนตอนสดทายทำการเรยกโปรแกรม Android Emulator ขนมาใหมอกครง
$ emulator -kernel ~/aosp/goldfish/arch/x86/boot/bzImage -system out/target/product/generic_x86/system.img -ramdisk out/target/product/generic_x86/ramdisk.img &
287
Embedded Android Development สเสนทางนกพฒนา
ชดเครองมอและคำสงภายใน Android Emulator
เพอศกษากลไกการทำงานภายใน และสามารถจดการตว Android Emulator ไดเปนอยางด นกพฒนาจะตองเรยนรชดคำสงอยางนอย ดงแสดงในตารางขางลางน
ตาราง 5.7 ตวอยางคำสงทนาสนใจภายใน Android Emulator
คำสง รายละเอยด
services เปนคำสงททำหนาทเรยกด Service ทอย Android ทงหมด
dumpsysเปนคำสงททำหนาทเรยกดขอมลระบบทเราตองการเชนระดบแบตเตอรการทำงานของCPU
dumpstate เปนคำสงททำหนาทเรยกสถานะการทำงานของแตละโปรแกรมใน Android
rawbu เปนคำสงทใชในการ backup และ restore ขอมลทอย /data
am ตวจดการ Activity
pm ตวจดการ Package
dalvikvm เปนคำสงทใชในการรนไฟล Java Class ในรปแบบ DEX format
288
Embedded Android Development สเสนทางนกพฒนา
คำสง รายละเอยด
getpropเปนคำสงแสดงขอมลการระบบ เชน DNS servers, gateways, GSM, serv-ices ทกำลงทำงาน, build parameters, เวอรชน เปนตน
เราจะเรมตนจากการเรยกโปรแกรม Android Emulator ดวยคำสง
$ cd ~/aosp/$ source build/envsetup.sh including device/asus/grouper/vendorsetup.shincluding device/generic/armv7-a-neon/vendorsetup.shincluding device/generic/armv7-a/vendorsetup.shincluding device/moto/wingray/vendorsetup.shincluding device/samsung/crespo/vendorsetup.shincluding device/samsung/maguro/vendorsetup.shincluding device/ti/panda/vendorsetup.shincluding sdk/bash_completion/adb.bash
$ lunch
You're building on LinuxLunch menu... pick a combo: 1. full-eng 2. full_x86-eng 3. vbox_x86-eng 4. full_grouper-userdebug 5. mini_armv7a_neon-userdebug 6. mini_armv7a-userdebug 7. full_wingray-userdebug 8. full_crespo-userdebug 9. full_maguro-userdebug 10. full_panda-userdebug
Which would you like? [full-eng] 2
============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.1.1TARGET_PRODUCT=full_x86TARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=x86TARGET_ARCH_VARIANT=x86-atomHOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-3.2.17-x86_64-with-Ubuntu-10.04-lucidHOST_BUILD_TYPE=releaseBUILD_ID=JRO03LOUT_DIR=out============================================
$ emulator &
289
Embedded Android Development สเสนทางนกพฒนา
การกำหนดสทธใหกบพารทชน (Mounting)รปแบบการใชงานคำสง:
mount -o rw,remount -t "filesystem" "Device" "Mount Point"
$ adb shell
การตงให root file system สามารถเขยนได
# mount -o rw,remount -t rootfs /
การตงใหพารทชน /system สามารถเขยนได
# mount -o rw,remount -t yaffs2 /dev/block/mtdblock4 /system$ adb shell
การเรยกใชโปรแกรมบรการภายใน Android Emulator
# serviceUsage: service [-h|-?] service list service check SERVICE service call SERVICE CODE [i32 INT | s16 STR] ...Options: i32: Write the integer INT into the send parcel. s16: Write the UTF-16 string STR into the send parcel.
# service listFound 65 services:0! phone: [com.android.internal.telephony.ITelephony]1! iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo]2! simphonebook: [com.android.internal.telephony.IIccPhoneBook]3! isms: [com.android.internal.telephony.ISms]4! commontime_management: []5! samplingprofiler: []6! diskstats: []7! appwidget: [com.android.internal.appwidget.IAppWidgetService]8! backup: [android.app.backup.IBackupManager]9! uimode: [android.app.IUiModeManager]10! serial: [android.hardware.ISerialManager]11! usb: [android.hardware.usb.IUsbManager]12! audio: [android.media.IAudioService]13! wallpaper: [android.app.IWallpaperManager]14! dropbox: [com.android.internal.os.IDropBoxManagerService]15! search: [android.app.ISearchManager]16! country_detector: [android.location.ICountryDetector]17! location: [android.location.ILocationManager]18! devicestoragemonitor: []19! notification: [android.app.INotificationManager]20! updatelock: [android.os.IUpdateLock]21! throttle: [android.net.IThrottleManager]
290
Embedded Android Development สเสนทางนกพฒนา
22! servicediscovery: [android.net.nsd.INsdManager]23! connectivity: [android.net.IConnectivityManager]24! wifi: [android.net.wifi.IWifiManager]25! wifip2p: [android.net.wifi.p2p.IWifiP2pManager]26! netpolicy: [android.net.INetworkPolicyManager]27! netstats: [android.net.INetworkStatsService]28! textservices: [com.android.internal.textservice.ITextServicesManager]29! network_management: [android.os.INetworkManagementService]30! clipboard: [android.content.IClipboard]31! statusbar: [com.android.internal.statusbar.IStatusBarService]32! device_policy: [android.app.admin.IDevicePolicyManager]33! lock_settings: [com.android.internal.widget.ILockSettings]34! mount: [IMountService]35! accessibility: [android.view.accessibility.IAccessibilityManager]36! input_method: [com.android.internal.view.IInputMethodManager]37! input: [android.hardware.input.IInputManager]38! window: [android.view.IWindowManager]39! alarm: [android.app.IAlarmManager]40! vibrator: [android.os.IVibratorService]41! battery: []42! hardware: [android.os.IHardwareService]43! content: [android.content.IContentService]44! account: [android.accounts.IAccountManager]45! permission: [android.os.IPermissionController]46! cpuinfo: []47! dbinfo: []48! gfxinfo: []49! meminfo: []50! activity: [android.app.IActivityManager]51! package: [android.content.pm.IPackageManager]52! scheduling_policy: [android.os.ISchedulingPolicyService]53! telephony.registry: [com.android.internal.telephony.ITelephonyRegistry]54! usagestats: [com.android.internal.app.IUsageStats]55! batteryinfo: [com.android.internal.app.IBatteryStats]56! power: [android.os.IPowerManager]57! entropy: []58! sensorservice: [android.gui.SensorServer]59! media.audio_policy: [android.media.IAudioPolicyService]60! media.camera: [android.hardware.ICameraService]61! SurfaceFlinger: [android.ui.ISurfaceComposer]62! media.player: [android.media.IMediaPlayerService]63! media.audio_flinger: [android.media.IAudioFlinger]64! drm.drmManager: [drm.IDrmManagerService]
ตวอยางการเรยกใชงาน
# service call statusbar 1Result: Parcel(00000000 '....')
291
Embedded Android Development สเสนทางนกพฒนา
# service call statusbar 2Result: Parcel(00000000 '....')
292
Embedded Android Development สเสนทางนกพฒนา
คำสง dumpsys คอเครองมอทใชสำหรบเรยกดขอมลภายในสถานะตางๆ ของตวใหบรการของระบบ (system service) ตวอยางเชน หนวยประมวลผลกลาง หนวยความจำ แบตเตอร ตวเกบขอมล เปนตน
$ adb shell dumpsys | grep "DUMP OF SERVICE"Output CommandDUMP OF SERVICE SurfaceFlinger:DUMP OF SERVICE accessibility:DUMP OF SERVICE account:DUMP OF SERVICE activity:DUMP OF SERVICE alarm:DUMP OF SERVICE appwidget:DUMP OF SERVICE audio:DUMP OF SERVICE backup:DUMP OF SERVICE battery:DUMP OF SERVICE batteryinfo:DUMP OF SERVICE clipboard:DUMP OF SERVICE commontime_management:DUMP OF SERVICE connectivity:DUMP OF SERVICE content:DUMP OF SERVICE country_detector:DUMP OF SERVICE cpuinfo:DUMP OF SERVICE dbinfo:DUMP OF SERVICE device_policy:DUMP OF SERVICE devicestoragemonitor:DUMP OF SERVICE diskstats:DUMP OF SERVICE drm.drmManager:DUMP OF SERVICE dropbox:DUMP OF SERVICE entropy:DUMP OF SERVICE gfxinfo:DUMP OF SERVICE hardware:DUMP OF SERVICE input:DUMP OF SERVICE input_method:DUMP OF SERVICE iphonesubinfo:DUMP OF SERVICE isms:DUMP OF SERVICE location:DUMP OF SERVICE lock_settings:DUMP OF SERVICE media.audio_flinger:DUMP OF SERVICE media.audio_policy:DUMP OF SERVICE media.camera:DUMP OF SERVICE media.player:DUMP OF SERVICE meminfo:DUMP OF SERVICE mount:DUMP OF SERVICE netpolicy:DUMP OF SERVICE netstats:DUMP OF SERVICE network_management:DUMP OF SERVICE notification:DUMP OF SERVICE package:DUMP OF SERVICE permission:DUMP OF SERVICE phone:DUMP OF SERVICE power:DUMP OF SERVICE samplingprofiler:DUMP OF SERVICE scheduling_policy:DUMP OF SERVICE search:DUMP OF SERVICE sensorservice:DUMP OF SERVICE serial:DUMP OF SERVICE servicediscovery:DUMP OF SERVICE simphonebook:DUMP OF SERVICE statusbar:DUMP OF SERVICE telephony.registry:DUMP OF SERVICE textservices:
293
Embedded Android Development สเสนทางนกพฒนา
DUMP OF SERVICE throttle:DUMP OF SERVICE uimode:DUMP OF SERVICE updatelock:DUMP OF SERVICE usagestats:DUMP OF SERVICE usb:DUMP OF SERVICE vibrator:DUMP OF SERVICE wallpaper:DUMP OF SERVICE wifi:DUMP OF SERVICE wifip2p:DUMP OF SERVICE window:
$ adb shell dumpsys batteryCurrent Battery Service state: AC powered: true USB powered: false status: 2 health: 2 present: true level: 50 scale: 100 voltage:0 temperature: 0 technology: Li-ion
$ adb shell dumpsys wifiWi-Fi is disabledStay-awake conditions: 1Internal state:current HSM state: DriverUnloadedStatemLinkProperties LinkAddresses: [] Routes: [] DnsAddresses: [] mWifiInfo SSID: <none>, BSSID: <none>, MAC: <none>, Supplicant state: UNINITIALIZED, RSSI: -9999, Link speed: -1, Net ID: -1, Metered hint: falsemDhcขาfoInternal addr: null/0 mRoutes: dns: null,null dhcpServer: null leaseDura-tion: 0mNetworkInfo NetworkInfo: type: WIFI[], state: UNKNOWN/IDLE, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: falsemLastSignalLevel -1mLastBssid nullmLastNetworkId -1mReconnectCount 0mIsScanMode falseSupplicant statusnullmLastPriority -1Configured networks Latest scan results:Locks acquired: 0 full, 0 full high perf, 0 scanLocks released: 0 full, 0 full high perf, 0 scanLocks held:Scan count since last plugged inWifiWatchdogStateMachine dumpWatchdogStatus: State: android.net.wifi.WifiWatchdogStateMachine$NotConnectedState@b444f100mWifiInfo: [null]mLinkProperties: [null]mCurrentSignalLevel: [0]mArpCheckIntervalMs: [120000]mRssiFetchIntervalMs: [1000]mWalledGardenIntervalMs: [1800000]
294
Embedded Android Development สเสนทางนกพฒนา
mNumArppings: [5]mMinArpResponses: [1]mArppingTimeoutMs: [100]mPoorNetworkDetectionEnabled: [true]mWalledGardenTestEnabled: [true]mWalledGardenUrl: [http://clients3.google.com/generate_204]WifiStateMachine dumpWifiStateMachine: total messages=3 msg[0]: time=09-21 16:03:00.308 state=DefaultState orgState=DriverUnloadedState what=69632(0x11000) msg[1]: time=09-21 16:03:00.389 state=DefaultState orgState=DriverUnloadedState what=131085(0x2000d) msg[2]: time=09-21 16:03:00.408 state=DefaultState orgState=DriverUnloadedState what=131147(0x2004b)curState=DriverUnloadedState
$ adb shell dumpsys cpuinfoLoad: 3.24 / 1.4 / 0.51CPU usage from 533936ms to 513149ms ago: 23% 2477/system_server: 22% user + 0.7% kernel / faults: 625 minor 4.8% 2445/surfaceflinger: 4.6% user + 0.1% kernel / faults: 592 minor 1.5% 2634/android.process.acore: 1.4% user + 0% kernel / faults: 252 minor 1.9% 2782/android.process.media: 1.7% user + 0.1% kernel / faults: 125 minor 1.7% 2619/com.android.launcher: 1.4% user + 0.2% kernel / faults: 145 minor 1.5% 2570/com.android.inputmethod.latin: 1.3% user + 0.1% kernel / faults: 141 mi-nor 1.4% 2708/com.android.deskclock: 1.3% user + 0% kernel / faults: 150 minor 1.3% 2765/com.android.email: 1.3% user + 0% kernel / faults: 106 minor 1.3% 2851/com.android.providers.calendar: 1.3% user + 0% kernel / faults: 148 mi-nor 1.3% 2552/com.android.systemui: 1.2% user + 0% kernel / faults: 60 minor 0.9% 2731/com.android.contacts: 0.8% user + 0% kernel / faults: 160 minor 1% 2589/com.android.phone: 0.8% user + 0.1% kernel / faults: 55 minor 0.7% 2681/zygote: 0.6% user + 0% kernel / faults: 160 minor 0.9% 2805/com.android.exchange: 0.9% user + 0% kernel / faults: 120 minor 0.5% 2659/com.android.smspush: 0.4% user + 0% kernel / faults: 165 minor 0.8% 2878/com.android.calendar: 0.8% user + 0% kernel / faults: 99 minor 0.5% 806/adbd: 0% user + 0.5% kernel / faults: 11 minor 0.1% 2428/mediaserver: 0% user + 0% kernel / faults: 27 minor 0% 4/events/0: 0% user + 0% kernel 0% 783/servicemanager: 0% user + 0% kernel +0% 2900/sh: 0% user + 0% kernel +0% 2902/dumpsys: 0% user + 0% kernel48% TOTAL: 45% user + 3.3% kernel
$ adb shell dumpsys meminfoApplications Memory Usage (kB):Uptime: 9118113 Realtime: 9118113Total PSS by process: 22980 kB: system (pid 2477) 19899 kB: com.android.settings (pid 2681) 19648 kB: com.android.launcher (pid 2619) 12665 kB: com.android.systemui (pid 2552) 8792 kB: com.android.phone (pid 2589) 7504 kB: com.android.contacts (pid 2731) 7085 kB: com.android.inputmethod.latin (pid 2570) 6619 kB: android.process.acore (pid 2634) 5815 kB: com.android.email (pid 2765) 5402 kB: android.process.media (pid 2782)
295
Embedded Android Development สเสนทางนกพฒนา
5328 kB: com.android.calendar (pid 2878) 4603 kB: com.android.providers.calendar (pid 2851) 4287 kB: com.android.deskclock (pid 2708) 4282 kB: com.android.exchange (pid 2805) 2824 kB: com.android.smspush (pid 2659) 2686 kB: com.android.defcontainer (pid 2965)
Total PSS by OOM adjustment: 22980 kB: System 22980 kB: system (pid 2477) 21457 kB: Persistent 12665 kB: com.android.systemui (pid 2552) 8792 kB: com.android.phone (pid 2589) 19648 kB: Foreground 19648 kB: com.android.launcher (pid 2619) 2824 kB: Visible 2824 kB: com.android.smspush (pid 2659) 7085 kB: Perceptible 7085 kB: com.android.inputmethod.latin (pid 2570) 22585 kB: Previous 19899 kB: com.android.settings (pid 2681) 2686 kB: com.android.defcontainer (pid 2965) 43840 kB: Background 7504 kB: com.android.contacts (pid 2731) 6619 kB: android.process.acore (pid 2634) 5815 kB: com.android.email (pid 2765) 5402 kB: android.process.media (pid 2782) 5328 kB: com.android.calendar (pid 2878) 4603 kB: com.android.providers.calendar (pid 2851) 4287 kB: com.android.deskclock (pid 2708) 4282 kB: com.android.exchange (pid 2805)
Total PSS by category: 53374 kB: Dalvik 23817 kB: Unknown 19418 kB: Other mmap 18091 kB: Native 11556 kB: .apk mmap 11425 kB: .so mmap 1936 kB: Ashmem 718 kB: .ttf mmap 68 kB: Other dev 12 kB: Cursor 4 kB: .jar mmap 0 kB: .dex mmap
Total PSS: 140419 kB KSM: 0 kB saved from shared 0 kB 0 kB unshared; 0 kB volatile
$ adb shell dumpsys meminfo com.android.providers.calendarApplications Memory Usage (kB):Uptime: 8961566 Realtime: 8961566** MEMINFO in pid 2851 [com.android.providers.calendar] ** Shared Private Heap Heap Heap Pss Dirty Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ Native 806 684 760 1908 1692 143 Dalvik 2145 8904 1608 6407 6093 314 Cursor 0 0 0 Ashmem 0 0 0
296
Embedded Android Development สเสนทางนกพฒนา
Other dev 4 0 0 .so mmap 522 1828 216 .jar mmap 4 0 0 .apk mmap 95 0 0 .ttf mmap 0 0 0 .dex mmap 0 0 0 Other mmap 912 24 24 Unknown 177 36 176 TOTAL 4665 11476 2784 8315 7785 457 Objects Views: 0 ViewRootImpl: 0 AppContexts: 1 Activities: 0 Assets: 2 AssetManagers: 2 Local Binders: 10 Proxy Binders: 8 Death Recipients: 0 OpenSSL Sockets: 0 SQL MEMORY_USED: 171 PAGECACHE_OVERFLOW: 53 MALLOC_SIZE: 62 DATABASES pgsz dbsz Lookaside(b) cache Dbname 4 120 117 24/36/11 /data/data/com.android.providers.calendar/databases/calendar.db Asset Allocations zip:/system/app/CalendarProvider.apk:/resources.arsc: 57K
เพอใหสามารถเรยกใชคำสง dumpsys ไดจะตองเพมบรรทด <uses-permission android:name="android.permission.DUMP" /> เขาไปในไฟล AndroidManifest.xmlคำสง dumpstate ใชสำหรบดสถานะการทำงานของแอนดรอยดทงหมด
$ adb shell# dumpstate......PROVIDER ContentProviderRecord{b4669e98 com.android.email/.provider.AttachmentProvider} pid=1306 Client: nothing to dumpPROVIDER ContentProviderRecord{b470bc88 com.android.providers.contacts/.CallLogProvider} pid=1151 Client: nothing to dumpPROVIDER ContentProviderRecord{b462a2a0 com.android.providers.downloads/.DownloadProvider} pid=1324 Client: nothing to dumpPROVIDER ContentProviderRecord{b46e1b68 com.android.providers.userdictionary/.UserDictionaryProvider} pid=1151 Client: nothing to dump[dumpsys: 0.4s elapsed]========================================================== dumpstate: done========================================================
297
Embedded Android Development สเสนทางนกพฒนา
คำสง dalvikvm (Dalvik VM) เปนคำสงทอนญาตใหผใชสามารถเรยกโปรแกรม Dalvik VM เพอรนไฟล Java class ทเปนรปแบบ DEX ดงตวอยางขางลาง
$ mkdir dalvik$ cd dalvik/
สรางโปรแกรมอยางงาย
$ cat hello.javapackage org.apache;
public class Hello { public static void main(String[] args) { System.out.println("Hello World!"); }}
ทำการคอมไพลโปรแกรมดวย JAVA Compiler
$ javac -d . -g Hello.java
ทำการรวมไฟลทไดจากการคอมไพลทงหมดมาเปนไฟล .jar
$ jar -cvf Temp.jar *
added manifestadding: Hello.java(in = 139) (out= 115)(deflated 17%)adding: org/(in = 0) (out= 0)(stored 0%)adding: org/apache/(in = 0) (out= 0)(stored 0%)adding: org/apache/Hello.class(in = 541) (out= 336)(deflated 37%)
ใชโปรแกรม “dx” เพอสรางไฟล classes.dex จากไฟล Temp.jar
$ dx --dex --output=./classes.dex Temp.jar $ lsclasses.dex Hello.java org Temp.jar
ถดไปใชโปรแกรม “aapt” เพอสรางไฟล .jar ตวใหม เพอใหสามารถทำงานภายใต Dalvik VM ได
$ aapt add CmdLine.jar classes.dex 'classes.dex'...
นำไฟล CmdLine.jar ทบรรจไฟล classes.dex เขาสตว Android Emulator แลวทำการทดสอบเรยกโปรแกรมดวย Dalvikvm ดงคำสงขางลางน
$ adb push CmdLine.jar /data
298
Embedded Android Development สเสนทางนกพฒนา
10 KB/s (547 bytes in 0.050s)
$ adb shell
# /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -versionDalvikVM version 1.6.0Copyright (C) 2007 The Android Open Source ProjectThis software is built from source code licensed under the Apache Licen-se,Version 2.0 (the "License"). You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0See the associated NOTICE file for this software for further details.Dalvik VM init failed (check log file)
# /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /data/CmdLine.jar org.apache.HelloHello World!
am (Activity Manager)
คำสง am จะสามารถใชในการจดการแอคทวต (activities) เชน เรยกใหทำงาน สงหยดการทำงาน และเฝาดสถานะการทำงาน เปนตน
# amusage: am [subcommand] [options]usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>] [--R COUNT] [-S] [--opengl-trace] <INTENT> am startservice <INTENT> am force-stop <PACKAGE> am kill <PACKAGE> am kill-all am broadcast <INTENT>.... [--activity-single-top] [--activity-clear-task] [--activity-task-on-home] [--receiver-registered-only] [--receiver-replace-pending] [--selector] [<URI> | <PACKAGE> | <COMPONENT>]
# am start com.android.deskclock .ClockStarting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] pkg=com.android.deskclock }Warning: Activity not started, its current task has been brought to the front
299
Embedded Android Development สเสนทางนกพฒนา
# am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivityStarting: Intent { action=android.intent.action.MAIN comp={com.android.browser/com.android.browser.BrowserActivity} }Warning: Activity not started, its current task has been brought to the front
# am start -a android.intent.action.MAIN -n com.android.settings/.SettingsStarting: Intent { action=android.intent.action.MAIN comp={com.android.settings/com.android.settings.Settings} }
คำสงในการจดการแพกเกต (package manager)
# pm list packagepackage:android
package:com.android.backupconfirm
package:com.android.bluetooth
package:com.android.browser
package:com.android.calculator2
....
package:com.android.wallpaper.holospiral
package:com.android.wallpaper.livepicker
package:com.example.myapp
package:com.svox.pico
package:jp.co.omronsoft.openwnn
300
Embedded Android Development สเสนทางนกพฒนา
เมอตองการตดตงโปรแกรม (.apk) เพม สามารถใชคำสง pm install ไดดงตวอยางขางลาง
# pm install /sdcard/com.twitter.android-1.apk
ตรวจสอบโปรแกรมทไดตดตงไปกอนหนาน
# pm list packages | grep twitter
แสดงไดเรกทอร ทเกบโปรแกรมทไดตดตงไป
# pm path com.twitter.android
คำสง svc (service control) ใชสำหรบดสถานะการทำงานและควบคมการทำงานของบรการภายใน
# svc helpAvailable commands: help Show information about the subcommands power Control the power manager data Control mobile data connectivity wifi Control the Wi-Fi manager usb Control Usb state
# svc powerControl the power managerusage: svc power stayon [true|false|usb|ac] Set the 'keep awake while plugged in' setting.
# svc dataControl mobile data connectivityusage: svc data [enable|disable] Turn mobile data on or off. svc data prefer Set mobile as the preferred data network# svc wifiControl the Wi-Fi managerusage: svc wifi [enable|disable] Turn Wi-Fi on or off.
svc wifi prefer Set Wi-Fi as the preferred data network
# svc usbControl Usb stateusage: svc usb setFunction [function] Set the current usb function.
svc usb getFunction Gets the list of currently enabled functions
301
Embedded Android Development สเสนทางนกพฒนา
บทท 6 พนฐานการเขยนโปรแกรมภาษาจาวาบน แอนดรอยดสำหรบนกพฒนา
ระบบปฏบตการแอนดรอยดถอไดวาเปนหนงในระบบปฏบตการสำหรบอปกรณชนดพกพาทประสบความสำเรจสงสดเทาทเคยมมาและยงเปนตวแทนสำคญของวงการระบบสมองกลฝงตวทพสจนใหเหนถงศกยภาพของระบบสมองกลฝงตวและบทบาททมความสำคญตอมวลมนษยชาต ทงในโลกของการสอสาร โปรแกรมประยกตทหลากหลายและมอบโอกาสทสำคญทางดานระบบสมองกลฝงตวแกเหลานกพฒนาทวทกมมโลกรวมทงบรษทผผลตในอตสาหกรรมอปกรณอเลกทรอนกสไดมโอกาสสรางสรรผลตภณฑทรวมเทคโนโลยดานตางๆของระบบสมองกลฝงตวไมวาจะเปนระบบปฏบตการ ระบบโปรแกรมระบบ โปรแกรมประยกต และบอรดสมองกลใหสามารถทำงานไดรวมกนไดอยางลงตว และสามารถตอบสนองการใชงานของผคนในปจจบน สามารถตอบโจทยระดบภาคอตสาหกรรม รวมถงสามารถทำใหเกดผลตภณฑทยกระดบการแขงขนใหกบประเทศเหลานนไดอยางทไมเคยมมากอนและเปนททราบกนดวาตนนำเทคโนโลยสวนใหญจะเกดขนจากประเทศทพฒนาแลว ดงนนประเทศทกำลงพฒนาสวนใหญจะตองอยในฐานะผใชมาโดยตลอดรวมทงคนทตองซอเทคโนโลยมาเพอพฒนาประเทศของตน แตอยางไรกตามเมอยคของซอฟทแวรเสร (Open Source) ระบบปฏบตการแบบเปด (Open Operating System) แหลงความรอนมหาศาลในโลกอนเตอรเนต รวมถงการออกแบบพฒนาฮารดแวรแบบเปด (Open Hardware) ไดมาถงจดลงตวในชวงไมกปทผานมา กทำใหเกดโอกาสทสำคญในการนำองคความรเหลานมาประยกตเพอเปนพนฐานในการตอยอดการพฒนาตางๆไดอกมากมายหลงจากน
ดงนนถานกพฒนาคนไทยพยายามทำความเขาใจในศาสตรดานระบบสมองกลฝงตวอยางจรงจงและนานเพยงพอทงยงสามารถมองเหนถงความสำคญของการนำระบบสมองกลผงตวทมระบบปฏบตการแอนดรอยดเพอมาแกปญหาระบบโครงสรางพนฐานทางดานอตสาหกรรมในเมองไทยอยางแทจรง รวมทงถาไดรบการสนบสนนทางดานผลตภณฑทเกดจากการพฒนาของคนไทยหนวยงานองคกรภาครฐหรอภาคเอกชนดวยแลว ผเขยนกมความเชอมนวาในอกไมกปขางหนาประเทศไทยกอาจมโอกาสสรางผลตภณฑทสามารถตอบโจทยความตองการพนฐานของประเทศโดยไมตองพงพาเทคโนโลยจากประเทศอนๆมากเกนไป ทงยงสามารถแขงขนไดในระดบนานาชาตไดอยางภาคภมใจได
302
Embedded Android Development สเสนทางนกพฒนา
ดงนนนกพฒนาทางดานระบบสมองกลฝงตวจงถอไดวาเปนกลไกสำคญของการขบเคลอนการพฒนาเทคโนโลยพนฐานของประเทศเพอใหเกดการนำไปสการประยกตใชในดานการเกษตรกรรมและอตสาหกรรมในดานตางๆไดอยางทวถง ดงนนนกพฒนาจะตองเขาใจหลกการหลายๆอยางโดยเฉพาะอยางยงพนฐานตางๆของระบบปฏบตการลนกซไมวาจะเปนการใชคำสงตงแตระดบพนฐานจนถงระดบสง พนฐานการเขยนโปรแกรม พนฐานการเชอมตอระหวางระบบฮารดแวรและระบบโปรแกรมใหเปนอยางด รวมถงรแนวทางวธการแกไขปรบแตงระบบปฏบตการลนกซและระบบปฏบตการแอนดรอยดจากทไดกลาวในบททผานมา เพอใหนกพฒนาสามารถเชอมโยงศาสตรความรทเกยวของตางๆ (เชนคอมพวเตอร อเลกทรอนกส และระบบสอสารเครอขาย) เขาดวยกน
เครองมอพฒนา Android Studio IDEในงาน Google I/O 2013 ทผานมาทางบรษทกเกลกไดเปดตวเครองมอตวใหมชอวา Android
Studio IDE ทถกพฒนาอยบนพนฐานของ IntelliJ IDEA เพอมาแทนทเครองมอพฒนาตวเดมทใชโปรแกรม Eclipse IDE โดยขอดของ Android Studio IDE คอทำงานไดเรวขน เปนโปรแกรมลกษณะ Live Layout, Live Coding (WYSIWYG Editor) ซงจะทำใหนกพฒนาสามารถเหนภาพรวมของโปรแกรมทกำลงพฒนาอยบนอปกรณแอนดรอยดทมขนาดหนาจอแตกตางกน สามารถดรปภาพและขอความทเราอางองจากไฟลอน (Preview) และมเครองมอตรวจสอบโคดโปรแกรม (Lint tools) ครบถวน เชนสามารถดประสทธภาพการทำงานของโปรแกรม การรองรบเวอรชนรนกอนๆ เปนตน
รปท 6.1 หนาตาโปรแกรม Android Studio
303
Embedded Android Development สเสนทางนกพฒนา
วธการตดตง ANDROID STUDIO IDE
สำหรบระบบปฏบตการ Windows: ดาวนโหลดไฟล EXE android-studio-bundle-<version>.exe ในกรณทกำลงตดตงอยมการ
รองขอใหตดตง JAVA เพมเตมหรออาจจะทำการตงคาตวแปรสภาพแวดลอม (environment variables) โดยการเลอก Start menu > Computer > System Properties > Advanced System Properties เลอกแทบ Advanced > Environment Variables กดปม “add a new system variable” จากนนใหใส path ของ JAVA_HOME เชน C:\Program Files\Java\jdk1.7.0_21.สำหรบระบบปฏบตการ MacOS X:
ดาวนโหลดไฟล dmg android-studio-bundle-<version>.dmg ซงปญหาทพบเจอบอยครงคอการขอสทธอนญาต (Permissions) ใหทำการตงคาดงน เลอกท System Preferences > Security & Privacy ทแทบของ Allow applications downloaded ใหทำการเลอก Anywhereสำหรบระบบปฏบตการลนกซ:
ดาวนโหลดไฟล android-studio-bundle-<version>.tgz เมอดาวนโหลดเสรจเรยบรอยกใหแตกไฟล แลวรนคำสง ./studio.sh เมอตดตงโปรแกรมเสรจแลวใหตงคาตวแปรระบบในไฟล ~/.bashrc เชน PATH เพอชไปยงไดเรกทอร android-studio/bin/
เรมตนการใชงานโปรแกรม เมอเขาโปรแกรม Android Studio ครงแรกกจะแสดงหนาตางดงรปขางลาง
รปท 6.2 หนาตาสำหรบสรางหรอนำเขาโปรแกรม
304
Embedded Android Development สเสนทางนกพฒนา
ทดสอบสราง Project ใหม (New Project...) ซงเมอเขาไปแลวจะมการตงคาพนฐานตางๆ ดงแสดงในรปขางลาง เชน Application name: ชอของโปรแกรม Module name:
Package name: ชอของ Package ทใชงาน Project location: ทอยของโปรเจค
Minimum required SDK: เวอรชนของ SDK ตำสดทสามารถใชงานได Target SDK: เวอรชนของ SDK ทตองการใขงาน
Compile with: เวอรชนของ SDK ททำการรนโปรแกรม Theme: ลกษณะธมของโปรแกรม
รปท 6.3 ตงคารายละเอยดของโปรแกรม
ขนตอนถดไปโปรแกรมจะใหผใชทำการเลอกไอคอน ทใชเปนไอคอนของโปรแกรม
305
Embedded Android Development สเสนทางนกพฒนา
รปท 6.4 กำหนดรปไอคอนโปรแกรมและคาทางกราฟฟกตางๆ
สำหรบในขนตอนนนกพฒนาสามารถเลอกชนดของโปรแกรมเบองตนไดหลายแบบ ตวอยางเชน Blank Activity, Fullscreen Activity, Login Activity, Master/Detail Flow หรอ Settings Activity โดยในทนจะขอเลอก Blank Activity และตงชอ Activity หลกของโปรแกรมวา MainActivity จากนนกดปม Finish เพอสรางโคดโปรแกรม
รปท 6.5 เลอก template ของโปรแกรมและตงคา Activity
306
Embedded Android Development สเสนทางนกพฒนา
โปรแกรม Android Studio จะทำการสรางโปรเจค และจดเตรยมไฟลทสำคญสำหรบโปรเจคตามทตงไว
รปท 6.6 ดาวนโหลดองคประกอบผาน Gradle และสรางโครงสรางโปรเจค
รายการโคดโปรแกรมและไฟลตางๆ ดงแสดงในรปขางลางน
รปท 6.7 แสดงโครงสรางภายในโปรเจค
307
Embedded Android Development สเสนทางนกพฒนา
ขอมลภายในไดเรกทอร res (Resource) ของโปรแกรมจะประกอบดวยไฟลประเภท XML ซงไฟลทเกบขอมลของ Layout ทงหมดทใชในโปรแกรม และในไดเรกทอร res จะเปนทเกบไฟลมลตมเดยตางๆ เชน ไฟลภาพ ไฟลเสยง เมอทำการคอมไพลไฟลโปรแกรม ขอมลทงหมดในไดเรกทอร res กจะถกอางองรวมกบไฟลทถกสรางขนมาในระหวางการคอมไพลทชอวา R.java
การกำหนดคณลกษณะในไฟล AndroidMainfest.xml
ไฟลสำคญไฟลหนงคอไฟล AndroidManifest.xml ซงเปนไฟลทกำหนดคณลกษณะตางๆภายในโปรแกรมประยกตนนๆ ซงประกอบไปดวย Activities, Services, Broadcast Receivers และ Con-tent Providers ดงรปขางลาง
AndroidManifest.xml
Activ
ities
Serv
ices
Broa
dcas
t Rec
eivi
ers
Con
tent
Pro
vide
rs
รปท 6.8 องคประกอบภายในไฟล AndroidManifest.xml
นอกจากนนการพฒนาโปรแกรมแอนดรอยดบอยครงทจะมการขอเขาถงทรพยากรตางๆในระบบ ดงนนโปรแกรมเหลานจะตองมการประกาศการรองขอสทธ ไวภายในไฟลชอวา AndroidManifest.xml ดวย
ตวอยางไฟล AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidaudiostream" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity
308
Embedded Android Development สเสนทางนกพฒนา
android:name="com.example.androidaudiostream.ActivityAudioDecode" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
จากตวอยางของ XML ดานบนเปนตวอยางของไฟล AndroidManifest.xml ทมอลเมนตชอวา manifest โดยหลกจะมการตงคาไวในสองตวแปรคอ android:versionCode ซงเปนคาทใชในการตรวจสอบขณะททำการตดตงเพอใหทราบวาเปนการตดตงแบบปรบปรงรนใหม (upgrade) หรอลดรนลง (downgrade) สวนของตวแปร android:versionName จะเปนคาระบเวอรชนทจะใชแสดงในโปรแกรม
อลเมนต <application> จะระบการตงคาเกยวกบฉลาก (label) และไอคอน (Icon) ของโปรแกรม
อลเมนต <activity> เปนการกำหนดชอแอคทวตทจะสามารถใชงานไดภายในโปรแกรม ซงจะตองกำหนดตว android:name เปนชอของแพคเกจทแอคทวตนนอย
อลเมนต <intent-filter> จะเปนการระบใหระบบปฏบตการแอนดรอยดรวามการเรยกใชงานคอมโพเน นต ต ว ไหนบ าง การประกาศอ ล เมนต < a c t i o n > เป นช อ android.intent.action.MAIN เปนการบอกวาแอคทวตนทำงานเปนแอคทวตหลกของโปรแกรม
การตดตงและเรยกใชโปรแกรมบนอปกรณแอนดรอยดเมอผเขยนโปรแกรมทำการเขยนโปรแกรมเรยบรอยแลวตองการทดสอบโปรแกรมทเขยนบนอป-
กรณแอนดรอยดซงจะมวธการทดสอบได 2 ทางคอ
การรนโปรแกรมผาน Emulator ในการทดสอบโปรแกรมผาน Emulator กอนอนผใชจะตองทำการสราง Emulator เขาไปอยใน
รายการอปกรณกอน หลงจากนนเมอผใชกดรนโปรแกรมกจะปรากฏหนาตางแสดงรายชอของอปกรณ แลวทำการเลอกอปกรณทตองการรนโปรแกรมทดสอบ ดงตวอยางในรปขางลาง
309
Embedded Android Development สเสนทางนกพฒนา
รปท 6.9 แสดงการเรยกใช Android Emulator
การรนโปรแกรมบนอปกรณจรงผาน ADBในการทดสอบโปรแกรมอกวธหนงคอการรนโปรแกรมผาน ADB เพอทำการตดตงโปรแกรมลง
อปกรณจรงดงรปขางลาง วธการนจะทำใหผเขยนโปรแกรมสามารถดความสมบรณของโปรแกรมไดดกวาการรนโปรแกรมบน Emulator
รปท 6.10 แสดงอปกรณ Android ทเชอมตออยกบเครองคอมพวเตอร
310
Embedded Android Development สเสนทางนกพฒนา
การยายโคดโปรแกรมเดม ECLIPSE IDE มาส ANDROID STUDIO
เนองจากนกพฒนาในยคแรกๆจะมความคนเคยกบการเขยนโปรแกรมดวยเครองมอพฒนา Eclipse IDE ดงนนเมอตองการยายโคดโปรเจคเดมทเคยพฒนาอยบน Eclipse IDE มาส Android Studio IDE จะมขนตอนการยายโคดโปรเจคดงน
ขนตอนท 1: Export โปรแกรมเดมจาก Eclipse IDE 1. ทำการเปดโปรเจคและอพเดต ADT Plugin (เวอรชน 22.0 หรอสงกวา) 2. เลอกเมน File > Export 3. โปรแกรมจะแสดงหนาตางขนมา ใหเลอก Generate Gradle build files ภายใน Android จากนน กดปม Finish
รปท 6.11 แสดงหนาตางการสราง Gradle build files
ขนตอนท 2: Import โปรแกรมเขาส Android Studio 1. เปดโปรแกรม Android Studio เลอกเมน File > Import Project 2. จากนนเลอกไปยงทอยโปรเจค เลอก build.gradle จากนนกดปม Finish 3. ใหเลอกตาม Dialog ทแสดงจากนนกด OK
311
Embedded Android Development สเสนทางนกพฒนา
APACHE ANT สำหรบการพฒนาแอนดรอยดApache Ant คอเครองมอสำหรบใชในการคอมไพลและสรางโปรแกรม JAVA โดยนกพฒนา
โปรแกรมสามารถสรางสครปท (Script) ในรปแบบ XML ทมการระบ packages ทเกยวของเพอสงใหโปรแกรม ant ทำการคอมไพลและสรางออกมาเปนโปรแกรม .APK (Android Package) ไดเหมอนกบการสรางไฟล Makefile และใชคำสง “make” ในระบปฏบตการลนกซ
เมอไดทำการตดตงโปรแกรม Ant (http://ant.apache.org) สามารถทดสอบเขยนโปรแกรมพนฐาน (src\ant\Test.java) ดงตวอยางขางลาง
package ant;class Test { public static void main(String args[]) { System.out.println("Hello World from ANT"); }}
สครปทไฟล src\ant\build.xml
<project basedir="." default="make"> <property name="root" value="../.." /> <property name="classes" value="${root}/classes" /> <property name="srcroot" value="${root}/src" /> <path id="project.class.path"> <pathelement location="${classes}" /> </path> <target name="make"> <javac debug="true" srcdir="${srcroot}" includes="ant/**/*.java" destdir="${classes}"> </javac> </target> <target name="run" depends="make" description="Run Test"> <java classname="ant.Test" classpathref="project.class.path" fork="true"> </java> </target> <target name="clean" description="clean all classes"> <delete dir="${classes}/ant"/> </target></project><?xml version="1.0" encoding="UTF-8"?>
คอมไพลและสรางโปรแกรมออกมาเปน .APK
C:\...\src\ant>ant makeBuildfile: build.xmlmake:
312
Embedded Android Development สเสนทางนกพฒนา
BUILD SUCCESSFULTotal time: 0 seconds
C:\...\src\ant>ant runBuildfile: build.xmlmake:run: [java] test ANTBUILD SUCCESSFULTotal time: 0 seconds
C:\...\src\ant>ant cleanBuildfile: build.xmlclean: [delete] Deleting directory C:\...\classes\antBUILD SUCCESSFULTotal time: 0 seconds
ไฟลโปรแกรม (.APK) จะถกสรางเกบไวในไดเรกทอร bin ผใชสามารถนำไฟล .APK ไปตดตงลงใน An-droid Emulator หรออปกรณแอนดรอยด โดยใชคำสง adb install <ชอโปรแกรม>.apk
ANDROID ACTIVITY
การพฒนาโปรแกรมประยกตแอนดรอยด : แอคทวต (Activity)
แอคทวต (Activity) มความสำคญมากสำหรบโปรแกรมประยกต เพราะเปนสวนทใชตดตอกบผใชผาน UI ดงแสดงในรปขางลาง
UI Activity
Service
OperatingSystem
สง broadcast Intent
การ Intent โดยตรง
รปท 6.12 แสดงกลไกการทำงานของโปรแกรมภายในแอนดรอยด
แตละ activity จะแทนหนงหนาตางทจะแสดงขนบนหนาจอในขณะนนดงแสดงในรปขางลาง
313
Embedded Android Development สเสนทางนกพฒนา
รปท 6.13 การแสดงผลของแตละ activity
ซงในแตละโปรแกรมประยกตสามารถสรางแอคทวตไดหลายตวแตจะตองกำหนดแอคทวตเพยงตวใดตวหนงเทานนทจะใหทำงานเปนแอคทวตหลกของโปรแกรมประยกตนน ซงแตละแอคทวตสามารถทจะเรยกใหตวแอคทวตอนขนมาทำงานไดโดยทแอคทวตกอนหนาจะถกเกบไวในสแตก (Stack) ของระบบตามลำดบไปดงรปขางลาง
ActivityActivity
Activity
Activity ททางานอยเบองหนา (foreground)(visible และ focused)
Task (stack of activity)
Activity ททางานอยเบองหลง (background)
รปท 6.14 ขบวนการจดการของ activities แตละตวในขณะททำงานอย
ภายในโปรแกรมประยกตจะม 4 องคประกอบหลกไดแก1) Activity2) Service3) Intent4) Broadcast Receiver
314
Embedded Android Development สเสนทางนกพฒนา
ตาราง 6.1 แสดงลกษณะการทำงานของ 4 องคประกอบหลกในโปรแกรม Android
ประเภท ลกษณะการทำงาน ตวอยางการทำงาน
Activityโปรเซสททำงานรวมกบ User
Interfaceแสดงขอความ, รปภาพ, เลนเกมส ฯลฯ
Service โปรแกรมททำงานอยเบองหลง เลนเพลง, ระบบซงคขอมล
Intent
Intent ชนด Directed Intent การแจงไปยงโปรเซสทระบไว
IntentIntent ชนด Broadcast Intent การแจงแบบกระจายไปยงทกโปรเซส
IntentIntent Filter รายการของ Intents ใน Activity หรอ
Services
Broadcast Receiver การขอเรยกใชขอมล GPS, Internet, สมดโทรศพท ฯลฯ
วงจรชวต (lifecycle) ของแอคทวต
Starting
Running
Stopped Stopped
Destroyed
1. onCreate()2. onStart()3. onResume()
onPause()onResume()
onStop()
onDestroy()
รปท 6.15 วงจรชวตของแอคทวต (Activity)
315
Embedded Android Development สเสนทางนกพฒนา
ชวงวงจรชวตของแอคทวตนนสามารถแบงออกไดเปน 3 ชวงการทำงาน ดงรปขางบน คอ1. Entire Lifetime คอการเรมตนและการปดตวของแอคทวต ในชวงการทำงานนจะมการเรยกใชฟงกชนคอ onCreate() และเมอแอคทวตถกสงปดจะมการเรยกใชฟงกชนคอ onDestroy()
2. Visible Lifetime คอชวงเวลาทแอคทวตนน กำลงทำงานอยโดยหลงจากทแอคทวตถกสรางขนมาแลว แอคทวตนน กำลงจะเรมตนการทำงานจะมการเรยกใชฟงกชน onStart() และเมอแอคทวตนนถกสงปดจะตองมการปดการทำงานแอคทวตกอนจะมการเรยกใชฟงกชน onStop()
3. Foreground Lifetime คอชวงเวลาทแอคทวตนน กำลงทำงานอยเบองหนาเชน เมอแอคทวตนนเรมตนการทำงานจะถกดนขนมาดานบนเพอตดตอกบผใชงานโดยจะเรยกฟงกชน onResume() และถาแอคทวตนนกำลงจะหยดการทำงานชวคราวหรอถาวร กจะเรยกใชฟงกชน onPause() หรอ onDestroy()
รปท 6.16 รายละเอยดของวงจรชวตของแอคทวต
316
Embedded Android Development สเสนทางนกพฒนา
ตวอยางโคดการทำงานของแอคทวตจากโคดตวอยางดงตอไปนจะเปนการอธบายหลกการทำงานของแอคทวตใหเขาใจไดงายขน โดยจะ
มการทำงานตาม Lifecycle ทไดอธบายแลวขางตน
public class ActivityA extends Activity {
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); Log.d("Embedded Debug”, onCreate - Called when the Activity is first created”); }
@Override protected void onStart() { Log.d("Embedded Debug”, onStart - Called when the Activity is becoming visible to the User”); super.onStart(); }
@Override protected void onRestart() { Log.d("Embedded Debug”, onRestart - Called after your activity has been stopped, prior to it being started again”); super.onRestart(); }
@Override protected void onResume() { Log.d("Embedded Debug”, onResume - Called when the Activity will start in-teracting with the User”); super.onResume(); }
@Override protected void onPause() { Log.d("Embedded Debug”, onPause - Called when the system is about to start resuming a previous activity”); super.onPause(); }
@Override protected void onStop() { Log.d("Embedded Debug”, onStop - Called when the Activity is no longer visi-ble to the User because another activity has been resumed and is covering this one”); super.onStop(); }
@Override protected void onDestroy() {
317
Embedded Android Development สเสนทางนกพฒนา
Log.d("Embedded Debug”, onDestroy - the final call you receive before your activity is destroyed”); super.onDestroy(); }
public void startActivityB(View v) { Intent intent = new Intent(ActivityA.this, ActivityB.class); startActivity(intent); }
public void startActivityC(View v) { Intent intent = new Intent(ActivityA.this, ActivityC.class); startActivity(intent); }
public void finishActivityA(View v) { ActivityA.this.finish(); }
}
ไฟล AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/dark_blue" android:padding="8dip" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" > <Button android:id="@+id/btn_start_b" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/btn_start_b_label" android:onClick="startActivityB" />
<Button android:id="@+id/btn_start_c" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/btn_start_c_label"
318
Embedded Android Development สเสนทางนกพฒนา
android:layout_toRightOf="@id/btn_start_b" android:onClick="startActivityC" /> <Button android:id="@+id/btn_finish_a" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/btn_finish_a_label" android:layout_toRightOf="@id/btn_start_c" android:onClick="finishActivityA" /> <Button android:id="@+id/btn_start_dialog" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/btn_start_dialog_label" android:layout_toRightOf="@id/btn_finish_a" android:onClick="startDialog" /> </RelativeLayout></LinearLayout>
จากตวอยางโคดโปรแกรมขางตน เปนการแสดงตวอยางการเรยกใชงานแอคทวต โดยจะแสดงใหเหนถงวงจรชวตของแอคทวต จากโคดโปรแกรมไดแสดงตวอยางของแอคทวต A เมอรนโปรแกรม โปรแกรมจะทำการเรมตนดวยกนเรยกใชงานแอคทวต A ขนมา จากนนจะทำการแสดง layout ทไดออกแบบไวซงภายใน layout ไดมการตงคาใหเรยกใชงานฟงกชนตางๆ เชนการเรยกแอคทวต B เรยกแอคทวต C เปนตน ดงตวอยางโคดและผลการทำการของโปรแกรมในรปขางลาง
android:onClick="startActivityB"
319
Embedded Android Development สเสนทางนกพฒนา
รปท 6.17 ผลลพธการรนโปรแกรม
USER INTERFACE
เมอเขาใจหลกการทำการของแอคทวตแลว ในสวนการตดตอระหวางแอคทวตกบผใชกมสวนสำคญไมนอยเนองจากเปนกราฟฟกสำหรบใชในการตดตอกบผใชทวไป ซงจะเรยกกนโดยทวไปวา User Inter-face (UI) การสรางหนาตาของโปรแกรมหรอ UI ขนมาไดนนมเครองมออยตางๆมากมาย แตอยางไรกตามการออกแบบและพฒนาโปรแกรมเพอตอบสนองความตองการของผใชงานใหไดดทสดนนกยงตองใหความสนใจในการสรางประสบการณการใชงานโปรแกรมทเรยกวา User Experience (UX) ควบคไปดวย ดงนนนกพฒนาจะตองมการศกษาวเคราะหพฤตกรรมการใชงานกบอปกรณไฮเทคโนโลยเหลานไมวาจะเปนเทคโนโลยหนาจอสมผสและแสดงผล หนวยประมวลผลกลาง หนวยความจำ และการพฒนาปรบปรงระบบปฏบตการทางดานระบบสมองกลฝงตวควบคกนไปดวยตวอยางเชนการทำความเขาใจหนวยคาการแสดงผลกราฟฟกทจะถกขนอยกบเทคโนโลยหนาจอสมผสและแสดงผล การออกแบบโปรแกรมทางดานกราฟฟกเพอรบคาจากผใชโดยตองใหเหมาะสมกบขนาดของหนาจออปกรณทใชงาน โดยจะกลาวถงในรายละเอยดตอไปน
หนวยคาการแสดงผลกราฟฟก
การทำความเขาใจหลกการทางดานการออกแบบกราฟฟก นกพฒนาสวนใหญจะคอนขางมปญหาในเรองนพอสมควรเนองจากมรายละเอยดอยไมนอย ปจจบนอปกรณทใชระบบปฏบตการแอนดรอยดนนมอยมากมายหลากหลายรนและมความหลากหลายของสดสวนหนาจอแสดงผล เชนขนาดหนาจอ 480x320, 800x480, 960x540, 1280x720 ซงจะมผลตอการออกแบบหนาตาของโปรแกรม ดงนนการกำหนดตำแหนงการวางกราฟฟกหรอองคประกอบตางๆจะไมสามารถกำหนดจดส (Pixel) แบบตายตวไดเพราะหากมการกำหนดคาจดสตายตวเมอเปดโปรแกรมบนเครองหนาจอทมความละเอยดแตกตางกนกจะทำใหการแสดงผลกราฟฟกผดเพยนไปจากเดมทกำหนดไวได
320
Embedded Android Development สเสนทางนกพฒนา
ดงนนทางผพฒนาของบรษทกเกลจงไดคดคนหนวยจดสใหมขนมาเพอใหความละเอยดหนาจอทแตกตางกนเกดความคลาดเคลอนนอยทสดเรยกหนวยนวาหนวย “dp” (Density Independent Pixel) หรอจดสเสมอน (Virtual Pixel) ซงเปนหนวยของความละเอยดหนาจอทสมมตขนมาโดยองจากความละเอยด (Resolution), ขนาด (Size) และความหนาแนนจดส (Pixel) (Density) ของหนาจอบนอปกรณนนซงนกพฒนาจะตองใชคา dp ในการกำหนดขนาดของขอความ (Text) ขนาดของรปภาพหรอขนาดของปมตางๆ โดยมหลกการคำนวณคา dp ดงน
1 dp = (ความหนาแนนของจอ) / 160
แอนดรอยดไดแบงหนาจอเปนหลายขนาดโดยมคาความละเอยดของแตละหนาจอ ดงแสดงในรปขางลาง
3" 5" 7" 11" 13"
120 160 240 320 480 640
ldpi mdpi hdpi xdpi xxdpi xxxdpi
Actual size (inches)
Actual density (dpi)
small normal large xlarge xxlarge xxxlarge
รปท 6.18 เปรยบเทยบรายละเอยดของขนาดหนาจอและคา dpi
ลาสดบนระบบปฏบตการแอนดรอยด เวอรชน 4.3 ไดประกาศออกมาอยางเปนทางการแลววาพรอมจะรองรบคาความละเอยดหนาจอระดบ extra extra high dpi (xxhdpi) ขนาด 640 dpi ดงรปขางบน และในอนาคตอนใกลนคาความละเอยดของหนาจอบนอปกรณแอนดรอยดกจะเทยบเทากบคาความละเอยดหนาจอโทรทศนท 4K ไดอยางแนนอน
• ldpi (low dpi) คอ หนาจอทมขนาดของความหนาแนน ไมเกน 120 dpi • mdpi (medium dpi) คอ หนาจอทมความหนาแนน ตงแต 120 - 160 dpi เชนรน T-Mobile G1• hdpi (high dpi) คอ หนาจอทมความหนาแนน ตงแต 160 - 240 dpi เชนรน Nexus S• xdpi (extra high dpi) คอ หนาจอทมความหนาแนน 240 dpi ขนไป (320 dpi บนรน Galaxy Nexus/N4 หรอ 480 dpi บนรน HTC One)
321
Embedded Android Development สเสนทางนกพฒนา
• xxdpi (extra extra high dpi) คอ หนาจอทมความหนาแนน 480 dpi ขนไป• xxxdpi (extra extra extra high dpi) คอ หนาจอทมความหนาแนน 640 dpi ขนไป
ซงคา dpi (Dot Per Inch) หมายถง จำนวนจดสทมไดทงหมดในพนทขนาด 1 ตารางนว ดงแสดงในรปดานขวา ยกตวอยางเชน จำนวนจดในพนทขนาด 1 ตารางนว จะมจดสเรยงกนอยจำนวนทงสน 300 x 300 Pixel ซงคา dpi ยงสงกจะมผลตอการแสดงผลโดยเฉพาะกบการใชในโปรแกรมเกมสในลกษณะ FPS หรอเกมสลกษณะ Shootingทตองการใชการแสดงผลกราฟฟกทเปลยนแปลงอยางรวดเรว เปนตน
สตรการคำนวณคา dp จากคา dpi คอ
dp = pixel * (160 / dpi)
ตวอยางการคำนวณคา dp ของเครองยหอ Samsung Galaxy Note 10.1 ทมขนาดหนาจอแบบ mdpi ซงเทยบคา dpi เทากบ 160 (ตามรปท 6.8) และเครองนมคาความละเอยดหนาจออยท 1280 x 800 Pixel คา dp จะมคาเทากบ
1280 * (160 / 160) = 1280 dp 800 * (160 / 160) = 800 dp
ดงนนเครอง Samsung Galaxy Note 10.1 นจะมคาขนาดหนาจอแบบ dp เทากบ 1280 x 800 dp
ซงเมอนำเครอง Samsung Nexus 10 ทมขนาดหนาจอแบบ xhdpi ทคา dpi เทากบ 320 dpi (ตามรปท 6.8) และความละเอยดหนาจอสงถง 2560 x 1600 Pixel ซงจะเหนวามคาสงกวาเครอง Samsung Galaxy Note 10.1 แตเมอคำนวณคา dp จะมคาเทากบ
2560 * (160 / 320) = 1280 dp 1600 * (160 / 320) = 800 dp
จะเหนไดวาคา dp ของทง 2 เครองมคา 1280 x 800 dp เทากน ดงนนนกพฒนากควรยดคา dp เปนหลกในการวางรปแบบกราฟฟกทจะเปนหนาตาโปรแกรม โดยทยงคงแสดงในสดสวนทถกตองเชนเดม
อางองสวนหนงมาจาก: http://www.akexorcist.com/2013/03/android-design-dp.html
322
Embedded Android Development สเสนทางนกพฒนา
1 นว
5 จด
ส
5 จดส
1 จดส (pixel)
ความละเอยด เทากบ 5 dpi(5 จดสตอ 1 นว)
รปท 6.19 แสดงการคดคาความละเอยด (dpi) ของหนาจอ
View และ ViewGroup
View คอสวนตดตอกบผใชพนฐานเนองจากเปนองคประกอบพนฐานการของสราง UI ตางๆภายในโปรแกรมตวอยางเชน TextView, ImageView, SurfaceView, ViewGroup เปนตน สำหรบคลาส ViewGroup เปนสวนขยายของ View ทสามารถม View ไดหลายตวโดยสามารถสรางการควบคมเชอมตอไปยง View ทงหมดได
ViewGroup
View
ViewGroup
View
View
รปท 6.20 แสดงความสมพนธของ ViewGroup และ View
Input Controls
คอสวนวตถ (Object) ทใชตดตอกบผใช ซงสามารถโตตอบกบผใชได ยกตวอยางเชน ปม (Button), ชองใสขอความ (text fields), บารตงคา (seek bars), ปมเลอก (checkboxes), ปมขยาย (zoom but-tons), ปมกลบคา (toggle buttons) เปนตน
รปท 6.21 ตวอยาง Input Controls
Layout Containers
ถาเปรยบเทยบกบการเขยนโปรแกรมดวย JAVA AWT หรอ JAVA Swing ตว layout กเปรยบเสมอน JAVA Containers สวน View กจะเปรยบเสมอน JAVA Components หรอ Widgets นนเอง โดยความสมพนธระหวาง layout และ view แสดงดงรปขางลาง
323
Embedded Android Development สเสนทางนกพฒนา
Parent Layout
Button
Another Layout View (aka Widget)
TextView EditView
รปท 6.22 แสดงความสมพนธของ Layout และ components ตางๆ
โดย layout แตละตวจะสามารถบรรจ View และ layout อนๆเขาไปไดหลายๆตว ไดแก1. RelativeLayout ซงเปน layout ทกำหนดไวเปนตวพนฐานตงแตเรมสรางโปรเจค ซงเปน layout
ทมการจดเรยงตววตถ (object) โดยมการอางองตำแหนงของวตถนนกบวตถอนภายใน layout หรออางองกบตว layout ทวตถนนอยภายใน โดยการอางองผานหมายเลข (android:id) ของวตถหรอ layout
รปท 6.23 การตงคาแบบ RelativeLayout
2. FrameLayout เปน layout ทมการจดวางวตถเปนชนๆ โดยจะเรมวางวตถเรมตนจากมมซายบน (top-left) ของ layout เสมอและจะนำวตถทวางทหลงมาไวชนบนสดของ layout
324
Embedded Android Development สเสนทางนกพฒนา
รปท 6.24 การตงคาแบบ FrameLayout
3. LinearLayout เปน layout ทมการจดเรยงวตถเปนแนวเสนตรง ซงอาจจะเปนแนวตงหรอแนวนอนกได โดยการกำหนดคาใน android:orientation (horizontal/vertical)
รปท 6.25 การตงคาแบบ LinearLayout แนวตง
325
Embedded Android Development สเสนทางนกพฒนา
รปท 6.26 การตงคาแบบ LinearLayout แนวนอน 4. TableLayout เปน layout ทมการจดวางวตถในแบบตาราง โดยวตถแตละตวจะถอเปน 1 คอลมน ซงสามารถเพมแถวไดโดยเพม XML tag ของ TableRow
รปท 6.27 การตงคาแบบ TableLayout ไมมแถว
326
Embedded Android Development สเสนทางนกพฒนา
รปท 6.28 การตงคาแบบ TableLayout มแถว
5. AbsoluteLayout เปน layout ทมการจดวางวตถตามตำแหนงจรงบนหนาจอ โดยจะกำหนดตำแหนงของวตถไดผานคา android:layout_x และ android:layout_y
รปท 6.29 การตงคาแบบ AbsoluteLayout
327
Embedded Android Development สเสนทางนกพฒนา
6. ListView เปนคลาสทสบทอดจากคลาส ViewGroup ทมมมมองการแสดงแบบรายการ (list) ของไอเทม (item) โดยทสามารถเลอนขนลง (Scrolling) เพอดเนอหาทงหมดได ซงเนอหาของรายการแตละรายการจะถกแทรกลงอตโนมตผานทางอะแดปเตอร (Adapter)
รปท 6.30 การตงคา ListView
7. GridView เปนอกคลาสทสบทอดจากคลาส ViewGroup ทมมมมองการแสดงแบบสองมต (แถว-คอลมน) ในลกษณะตาราง สามารถทำการเลอนขนลงเพอดขอมลทงหมดได ซงรายการจะถกแทรกลงอตโนมตผานทางอะแดปเตอรเชนเดยวกนแบบ ListView
รปท 6.31 การตงคา GridView
หนาตาง Dialog และ Alert
คอหนาตางตอบโต (Dialog) ทใชในการแจงเตอนหรอรบคาจากผใช ดงรปขางลาง
328
Embedded Android Development สเสนทางนกพฒนา
รปท 6.32 แสดง Dialog พนฐาน
การแจงเตอนอกแบบหนงคอการแจงเตอนในลกษณะแสดงเปนขอความสนๆชวระยะเวลาหนง ใหปรากฏบนหนาจอ เรยกวา Toast แตจะไมมการโตตอบกบผใชแตอยางใด โดยใชคำสง Toast.makeText(this, “text”, Toast.LENGTH_SHORT).show() ดงรปขางลาง
รปท 6.33 แสดงการแสดงขอความแบบ toast
ANDROID ADAPTER
อะแดปเตอร (Adapter) ทำหนาทตดตอระหวาง AdapterView กบขอมลทตองการใหแสดงใน ListView, GridView, spinner หรอ Gallery นอกจากน Adapter ยงใชในการจดการ View กบชดขอมลโดยท AdapterView จะสามารถแสดงขอมลบางสวนซงถกกำหนดโดย Adapter เชนในกรณมขอมลมากและไมสามารถแสดงไดในครงเดยว
329
Embedded Android Development สเสนทางนกพฒนา
Adapter Adapter ViewDataSource
CursorArrayList
List ViewGrid ViewSpinner
รปท 6.34 แสดงความสมพนธของ Adapter
ตวอยางการใชงาน Adapter
1. ArrayAdapterตวอยางนจะแสดงการเพมคาเขาไปแสดงบน listview และลบคาเมอมการกดทตำแหนง list
โคดภายในไฟล device_list.xml<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="wrap_content" />
รปท 6.35 แสดงรายละเอยดภายในไฟล device_list.xml
โคดภายในไฟล device_name.xml<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:textSize="18sp" />
330
Embedded Android Development สเสนทางนกพฒนา
รปท 6.36 แสดงรายละเอยดภายในไฟล device_name.xml
ซงภายในไฟล MainActivity.java มรายละเอยดดงนpackage com.example.basicarrayadapter;
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.ListView;
public class MainActivity extends Activity {
ListView listview; private ArrayAdapter<String> mNewDevicesArrayAdapter; String[] values = new String[] { "Android", "iPhone", "WindowsMobile", "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", "Android", "iPhone", "WindowsMobile" };
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.device_list);
listview = (ListView) findViewById(R.id.listview); mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
331
Embedded Android Development สเสนทางนกพฒนา
for (int i = 0; i < values.length; ++i) { mNewDevicesArrayAdapter.add(values[i]); }
listview.setAdapter(mNewDevicesArrayAdapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = (String) parent.getItemAtPosition(position); mNewDevicesArrayAdapter.remove(item); mNewDevicesArrayAdapter.notifyDataSetChanged(); } }); }}
สำหรบการแสดงขอมลโดยใช ArrayAdapter จะมขนตอนดงน
• ทำการอางอง ID ของตว ListView ทเปน xml เขากบโคดโปรแกรม • ทำการอางอง Layout ของ xml ทจะแสดงคาใน ListView • ทำการเพมขอมลลงใน ArrayAdapter • ทำการเชอม ArrayAdapter เขากบ listview เพอแสดงขอมล
รปท 6.37 แสดงการทำงานของโปรแกรม
332
Embedded Android Development สเสนทางนกพฒนา
ANDROID INTENT
Intent เปนรปแบบการสงขอมลระหวางโปรแกรมภายในระบบปฏบตการแอนดรอยด ซงจะพบบอยในการใชเพอเรยก Activity ตวอน โดยสามารถสงขอมลไดหลายรปแบบ ทงยงเปนชองทางการสงขอมลทนยมใชมากในการเขยนโปรแกรมเชนกน ดงรปขางลาง
รปท 6.38 แสดงการใช intent แยกการทำงานของ Activity แตละตว
ประเภทของ Intents
Intent แบงไดเปน 2 ประเภทหลกดงน
1. Implicit Intent เปน Intent ทระบบปฏบตการแอนดรอยดไดเตรยมไวใหแลว สามารถเรยกใชงานไดในทนท ตวอยางเชน เวบเบราวเซอร เครองมอการคนหา รายชอผตดตอในโทรศพท การโทรออก และ แผนท เปนตน ตวอยางการประกาศ Intent เพอเรยกเวปไซตคนหาขอมล ดงตวอยางขางลาง
Intent i = new Intent(Intent.ACTION_WEB_SEARCH);
2. Explicit Intent เปน intent ทตองสรางขนเองเพอกำหนดการทำงานเฉพาะอยางตามทตองการ ตวอยางการประกาศ Intent เพอเรยก activity ทตองการเชน ActivityTwo.class ดงตวอยางขางลาง
Intent i = new Intent(this, ActivityTwo.class);
333
Embedded Android Development สเสนทางนกพฒนา
BROADCAST RECEIVER
Broadcast receivers เปนสวนทจะทำงานกตอเมอไดรบการตอบสนองหรอเกดเหตการณตามทโปรแกรมไดกำหนดเอาไวลวงหนาดวยการลงทะเบยนเพอรบการแจงของระบบดงแสดงในรปขางลาง โดยเงอนไขเหลานจะสามารถตอบสนองในขณะทผใชกำลงเปดโปรแกรมอยหรอแมจะปดโปรแกรมไปแลวกตามท ตวอยางการทำงานเชน ในขณะทผใชกำลงขบรถหรอไมสะดวกในการรบสายแตเมอมคนโทรศพทเขามาตวโปรแกรมกทำการตดสายทกำลงโทรฯเขามาทนทและจะทำการสงขอความ (SMS) กลบไปหาคนทกำลงโทรเขามาโดยอตโนมต หรออกตวอยางเชนในกรณทตงคาไววาเมอเครองบทเสรจเรยบรอย (AC-TION_BOOT_COMPLETED) กใหระบบปฏบตการทำการเปดโปรแกรมทไดลงทะเบยนใน Broadcast receiver ใหทำขนมาทนท
AndroidSystem
BroadcastReceiver
ลงทะเบยน Intent
ไดรบการแจงเตอนวามการขอใช Intent
รปท 6.39 แสดงการใชทำงานของ intent
ขนตอนการพฒนาโปรแกรม Broadcast receivers•ทำการตงคาใน AndroidManifest.xml ตามทไดลงทะเบยนไว หรอสามารถตงคาแบบตามสถานการณทเปลยนแปลงผานฟงกชน Context.registerReceiver()
• เขยนคลาสขนมาโดยสบทอดตอมาจากคลาส BroadcastReceiver •ภายในจะมฟงกชน onReceive() สำหรบกำหนดการทำงานของโปรแกรมเมอเกดเหตการณ (event) ตามทไดตงคาไว
System broadcastsเหตการณของระบบ (system events) ทไดถกกำหนดเปนคาคงทไวภายในระบบปฏบตการแอน
ดรอยด ดงแสดงในตารางขางลางน
334
Embedded Android Development สเสนทางนกพฒนา
ตาราง 6.2 แสดงรายการเหตการณของระบบ
Event Usage
Intent.ACTION_BATTERY_LOW ระดบแบตเตอรอยในระดบตำ
Intent.ACTION_BATTERY_OKAY ระดบแบตเตอรอยในระดบด
Intent.ACTION_BOOT_COMPLETED แอนดรอยดบทเสรจเรยบรอย
Intent.ACTION_DEVICE_STORAGE_LOW ระดบหนวยความจำอยในระดบตำ
Intent.ACTION_DEVICE_STORAGE_OK ระดบหนวยความจำอยในระดบด
Intent.ACTION_HEADSET_PLUG ตรวจสอบหฟงวาตออยหรอไม
Intent.ACTION_LOCALE_CHANGED เมอมการเปลยนแปลงภาษาของอปกรณ
Intent.ACTION_MY_PACKAGE_REPLACED อพเดทแทนโปรแกรมเดม
Intent.ACTION_PACKAGE_ADDED ตดตงโปรแกรมใหม
Intent.ACTION_POWER_CONNECTED ตอสายไฟเขากบอปกรณ
Intent.ACTION_POWER_DISCONNECTED ถอดสายไฟออกจากอปกรณ
KeyChain.ACTION_STORAGE_CHANGED เกดการเปลยนแปลง keystore
BluetoothDevice.ACTION_ACL_CONNECTED Bluetooth ACL เกดการเชอมตอ
AudioManager.ACTION_AUDIO_BECOMING_NOISY เลอก audio output ทมสญญาณรบวนนอย
ตวอยางโปรแกรมตรวจสอบการเชอมตอกบหฟงโดยใชเหตการณของระบบชอวา ACTION_HEAD-SET_PLUG ซงใชในการตรวจสอบการเชอมตอชดหฟง ซงถาตอหฟงอยกจะสงคาเปน “1” ถาไมกจะสงคา “0” แทนตวอยางโปรแกรมทดสอบการบรอดทแคสท เมอมการเสยบหฟงเขาอปกรณแอนดรอยด// MainActivity.java
package com.example.demoeebuubroadcastreceiver;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity { @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter intentfilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
335
Embedded Android Development สเสนทางนกพฒนา
MyBroadCast mybroadcast = new MyBroadCast(); registerReceiver(myboradcast,intentfilter); }
@Overridepublic boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }}
// MyBroadCast..java
package com.example.demoeebuubroadcastreceiver;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;
public class MyBroadCast extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1); switch (state) { case 0: Toast.makeText(context, "Headset is unplugged", Toast.LENGTH_LONG).show(); break; case 1: Toast.makeText(context, "Headset is plugged", Toast.LENGTH_LONG).show(); break; default: Toast.makeText(context, "Unknow", Toast.LENGTH_LONG).show(); } } }}
การแสดงผล (ดานซายไมไดตอหฟง ดานขวาตอหฟง)
336
Embedded Android Development สเสนทางนกพฒนา
รปท 6.40 แสดงการตรวจจบของโปรแกรมในการตรวจสอบการเสยบห
การพฒนาโปรแกรมดวย Android Native Development Kit
พนฐาน ANDROID NDK
โปรแกรมแอนดรอยดสามารถแยกออกไดเปน 2 ประเภท ดงแสดงในรปขางลาง ไดแก • โปรแกรมดารวค (Dalvik applications) คอโปรแกรมทรวมโปรแกรมภาษาจาวา และ SDK API ตามมาตราฐานของแอนดรอยด รวมทงการรวมเอาไฟลประกอบตางๆ (resource files) ตวอยางเชน ไฟล XML ไฟลรปชนด PNG รวมเขาดวยกนจนกลายเปนไฟล APK
• โปรแกรมแอนดรอยด NDK (Android NDK applications) ซงรวมโคดโปรแกรมภาษาจาวา ไฟลประกอบตางๆ (resource files) รวมทงโคดโปรแกรมภาษา C/C++ (หรออาจมโคดโปรแกรมภาษาแอสเซมบล (Assembly) โดยทโคดโปรแกรมภาษา C/C++ จะถกคอมไพลเปนไลบราร (Dynamic linked library) ซงมนามสกลไฟลเปน “.so” แลวจะถกเรยกโดยโคดโปรแกรมภาษาจาวา ตามกลไกของ JNI (JAVA Native Interface) และสดทายทงหมดกจะถกรวมกลายมาเปนไฟล APK
337
Embedded Android Development สเสนทางนกพฒนา
Android NDK Application Dalvik Application
Java* NativeLibrary
โคดโปรแกรมภาษา Java
ทาการ Compileดวยคาสง Javac
Compilewith Javac
Dynamic Library
Java NativeLibrary Class
Android App Class
โคดโปรแกรมภาษา C Head File
ทาการ Compileและ Link โคด C
สรางไฟล C header ดวยคาสง Javah -jni
Application File
Makefile
รปท 6.41 แสดงกลไกการสรางโปรแกรม NDK และ โปรแกรมแอนดรอยดทวไป
Android NDK เปนอกชดเครองมอในการพฒนาโปรแกรมประเภท Android NDK โดยนกพฒนาจะเขยนโปรแกรมทงในสวนของโปรแกรมภาษา C/C++ หรอ ภาษา Assembly (Native Language) และสวนโปรแกรมภาษาจาวา ซงทำใหสามารถเพมประสทธภาพการทำงานโดยรวมของโปรแกรมประยกต เหมาะในการพฒนาโปรแกรมประยกตประเภทการเขา-ถอดรหสสญญาณวดโอ (Video en-coding and decoding) การประมวลภาพ (Image processing) หรอการคำนวณทางคณตศาสตรทซบซอนและตองการความเรวในการคำนวณโดยตรงจากหนวยประมวลผลกลาง เปนตน เหตผลหลกททำใหการเขยนโปรแกรมดวย Native language (C/C++, Assembly) สามารถเพมประสทธภาพการทำงานของโปรแกรมประยกตใหสามารถตอบสนองการทำงาน และการประมวลผลขอมล หรอการคำนวณทางคณตศาสตรไดดกวาการเขยนโปรแกรมดวยภาษาจาวา เพยงอยาง ไดแก
• โคดโปรแกรม (C/C++ หรอ Assembly) จะถกคอมไพลจนมาเปนรหสไบนาร (binary code) เรยบรอยแลว ซงสามารถทำงานไดทนทในระดบระบบปฏบตการ แตในขณะทโคดโปรแกรม JAVA เรมตนจะถกแปลใหกลายเปน JAVA byte-code โดยตว DVM (Dalvik Virtual Machine) ถงแมวาแอนดรอยดตงแตรน 2.2 หลงจากนนจะมการเพมการวเคราะหและปรบแตงประสทธภาพใหกบ JAVA byte-code ดวยเทคนคการแปลงบางสวนใหเปนรหสไบนาร (binary code) ดวย JIT Com-piler (Just-In-Time Compiler) แลวกตาม แตกยงทำงานไดชากวาโคดโปรแกรม C/C++ อยด
•การพฒนาโปรแกรมดวย Android NDK จะชวยใหนกพฒนาสามารถเขาถงและเรยกใชความสามารถพเศษบางอยางของหนวยประมวลผลกลางทมอยในบางตว ซงไมสามารถเรยกผาน Android SDK ได
338
Embedded Android Development สเสนทางนกพฒนา
ตวอยางเชน ตว NEON ซงเปนหนวยประมวลผลรวมของ ARM CPU เปนเทคโนโลยแบบ SIMD (Single Instruction Multiple Data) ทมการยอมใหมการประมวลผลสวนของขอมลไดแบบขนาน (Parallel processing) ซงเทคโนโลยตวนสามารถเพมความเรวในการประมวลผลทางดานมลตมเดย เชน การทำ Video encoding/decoding การแสดงผลในดานกราฟฟกทงแบบสองมตและสามมต การประมวลผลสญญาณเสยงพด เปนตน ดงตวอยางการใชงานดงน
ไฟล Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := neon_utilsLOCAL_SRC_FILES := neon_add.cLOCAL_CFLAGS += -mfloat-abi=softfp -mfpu=neon -march=armv7include $(BUILD_STATIC_LIBRARY)
NDK_PATH:=$(call my-dir)/../..
include $(CLEAR_VARS)LOCAL_MODULE := test_conditional_loadLOCAL_C_INCLUDES := $(NDK_PATH)/sources/cpufeaturesLOCAL_SRC_FILES := main.cLOCAL_STATIC_LIBRARIES := neon_utils cpufeatures
include $(BUILD_EXECUTABLE)include $(NDK_PATH)/sources/cpufeatures/Android.mk
ตวอยางไฟลโปรแกรม main.c
#include <stdio.h>#include <cpu-features.h>
int main(){ int32_t int32_4[] = {2,3,4,5};
if (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON)
339
Embedded Android Development สเสนทางนกพฒนา
{ neon_add(int32_4); printf("NEON supported\n"); } else { printf("NEON Not Supported\n"); } printf("values = %d, %d, %d, %d\n", int32_4[0], int32_4[1], int32_4[2], int32_4[3]); return 0;}
ตวอยางไฟลโปรแกรม neon_add.c
#include <arm_neon.h>void neon_add(int32_t * ptr){ int32x4_t vin = vld1q_s32(ptr); int32x4_t vout = vaddq_s32(vin, vin); vst1q_s32(ptr, vout);}
ความสามารถในการนำโคดโปรแกรม native มาใชใหม (Code Reusability) โดยเฉพาะโปรแกรมแบบเปด (Open source) และไลบรารตางๆ ซงถกพฒนาดวยโปรแกรมภาษา C/C++ ซงถกใชอยแลวภายในระบบปฏบตการลนกซในงานประยกตอน นกพฒนาเพยงทำความเขาใจและปฏบตตามเงอนไขขอตกลงทางลขสทธการใชงานโคดโปรแกรม กสามารถนำมาใชรวมในการพฒนา Android NDK ไดทนท เชน ไลบราร zlib ทใชสำหรบการบบอดขอมล หรอ ไลบราร OpenMAX ทสามารถนำมาใชในการพฒนาโปรแกรมดานมลตมเดย สำหรบเลนและจดการไฟลวดโอหรอไฟลเสยง เปนตน
เรมตนการพฒนาโปรแกรม ANDROID NDK
ขนตอนการตดตง Android NDKดาวนโหลดโปรแกรมเครองมอ Android NDK เวอรชนลาสดไดจาก Android NDK และทำการตดตงและตงคาตามคำแนะนำจากเวปไซต ทขนอยกบระบบปฏบตการทนกพฒนาใชงานอย เชน ระบบปฏบตการลนกซ หลงจากแตกไฟลแลวใหตงคาตำแหนงของไดเรกทอร Android NDK เปนตวแปรระบบ ภายในไฟล ~/.bashrc ดงตวอยางขางลาง
$ cat ~/.bashrc
340
Embedded Android Development สเสนทางนกพฒนา
...export USE_CCACHE=0export CCACHE_DIR=~/ccacheexport JAVA_HOME=/usr/lib/jvm/jdkexport ANT_HOME=~/android/antexport ANDROID_SDK_HOME=~/android/sdkexport ANDROID_NDK_HOME=~/android/ndkexport AOSP_HOME=~/aospexport PATH=$HOME/bin:$JAVA_HOME/bin:$ANT_HOME/bin:$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform-tools:$ANDROID_NDK_HOME:$PATH
ขนตอนการพฒนาโปรแกรมขนตอนการพฒนาโปรแกรม Android NDK มดวยกน 2 สวนใหญๆคอ
1.การเขยนโปรแกรม native ดวยภาษา C/C++ เพอสรางเปนไลบราร (Dynamic link library)2.การเขยนโปรแกรมประยกตเพอเรยกใชงานไลบราร ดวยภาษาจาวา
ตวอยางการพฒนาโปรแกรม native ในขนตอนนจะใช Android NDK รน r7b และ GNU make รน 3.81 ดงขนตอนขางลางน$ ls -al ~/android-ndk-r7b/total 320drwxr-xr-x@ 19 sriborrirux staff 646 Mar 17 2012 .drwxr-xr-x+ 94 sriborrirux staff 3196 Oct 6 02:12 ..-rw-r--r--@ 1 sriborrirux staff 6148 Mar 17 2012 .DS_Store-rw-r-----@ 1 sriborrirux staff 1306 Dec 19 2011 GNUmakefile-rw-r-----@ 1 sriborrirux staff 1360 Dec 19 2011 README.TXT-rw-r--r--@ 1 sriborrirux staff 4 Jan 25 2012 RELEASE.TXTdrwxr-xr-x@ 6 sriborrirux staff 204 Jan 25 2012 builddrwxr-xr-x@ 29 sriborrirux staff 986 Jan 25 2012 docs-rw-r-----@ 1 sriborrirux staff 201 Dec 19 2011 documentation.html-rwxr-x---@ 1 sriborrirux staff 2985 Dec 19 2011 ndk-build-rw-r-----@ 1 sriborrirux staff 279 Dec 19 2011 ndk-build.cmd-rwxr-x---@ 1 sriborrirux staff 21832 Dec 19 2011 ndk-gdb-rwxr-xr-x@ 1 sriborrirux staff 103928 Jan 25 2012 ndk-stackdrwxr-x---@ 8 sriborrirux staff 272 Jan 25 2012 platformsdrwxr-xr-x@ 3 sriborrirux staff 102 Jan 25 2012 prebuiltdrwxr-x---@ 17 sriborrirux staff 578 Oct 6 02:09 samplesdrwxr-xr-x@ 5 sriborrirux staff 170 Dec 18 2010 sourcesdrwxr-xr-x@ 10 sriborrirux staff 340 Jan 25 2012 testsdrwxr-xr-x@ 4 sriborrirux staff 136 Jan 25 2012 toolchains
$ ndk-build --versionGNU Make 3.81Copyright (C) 2006 Free Software Foundation, Inc.This is free software; see the source for copying conditions.There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE.This program built for i386-apple-darwin11.3.0
341
Embedded Android Development สเสนทางนกพฒนา
สวนการพฒนาโปรแกรมประยกตในขนตอนท 2 นนจะทำการพฒนาดวยโปรแกรม Android Studio ททางบรษทกเกล ไดพฒนาตอยอดมาจาก InteliJ IDEA เพอมาแทนทโปรแกรม Eclipse IDE (ทตองตดตง Android ADT Plugin เพมเตม) ซงตวโปรแกรม Android Studio กไดรวมเครองมอสำหรบการพฒนาและเครองมอจดการตางๆสำหรบโปรแกรมแอนดรอยดไวครบถวนดงแสดงในรปขางลาง
รปท 6.42 หนาตาง Android SDK Manager
ทางบรษทกเกลจะมการปรบปรงใหโปรแกรม Android Studio สามารถรองรบการพฒนาโปรแกรม Android NDK ไดประมาณตนป พ.ศ. 2557 เปนตนไป แตอยางไรกตามเนอหาตอไปน จะเปน
342
Embedded Android Development สเสนทางนกพฒนา
ขนตอนการปรบแตงบางอยางซงไดทำในชวงปลายป พ.ศ. 2556 เพอทำใหโปรแกรมประยกตทเขยนบน Android Studio สามารถตดตอกบโปรแกรม native C/C++ ได
ตวอยางโปรแกรม HELLO WORLD ดวย ANDROID NDK
นกพฒนาสามารถเรยนรโปรแกรมตวอยางไดจากไดเรกทอร ~/android-ndk-r7b/samples/
$ ls -altotal 0drwxr-x---@ 17 sriborrirux staff 578 Oct 6 02:09 .drwxr-xr-x@ 19 sriborrirux staff 646 Mar 17 2012 ..drwxr-x---@ 7 sriborrirux staff 238 Oct 1 2011 bitmap-plasmadrwxr-x---@ 7 sriborrirux staff 238 Jan 25 2012 hello-gl2drwxr-x---@ 10 sriborrirux staff 340 Oct 5 21:26 hello-jnidrwxr-x---@ 8 sriborrirux staff 272 Jul 14 2011 hello-neondrwxr-x---@ 4 sriborrirux staff 136 Jul 14 2011 module-exportsdrwxr-x---@ 6 sriborrirux staff 204 Jan 25 2012 native-activitydrwxr-x---@ 8 sriborrirux staff 272 Oct 1 2011 native-audiodrwxr-x---@ 10 sriborrirux staff 340 Nov 3 2011 native-mediadrwxr-x---@ 7 sriborrirux staff 238 Oct 1 2011 native-plasmadrwxr-x---@ 7 sriborrirux staff 238 Oct 1 2011 san-angelesdrwxr-x---@ 3 sriborrirux staff 102 Dec 18 2010 test-libstdc++drwxr-x---@ 8 sriborrirux staff 272 Jul 14 2011 two-libs
ในทนจะหยบยกตวอยางโปรแกรมในไดเรกทอร hello-jni มาปรบใชกบโปรแกรม Android Studio โดยใหทำตามขนตอนดงนขนตอนท 1: คอมไพลโปรแกรม hello-jni.c
$ cd samples/hello-jni/$ lsAndroidManifest.xml default.properties jni res src tests$ cd jni/
เปดไฟล hello-jni.c เพอแกไขชอฟงกชนใหมจาก Java_com_example_hellojni_HelloJni_stringFromJNI เปนJava_com_example_hellondk_MainActivity_stringFromJNI
$ vim hello-jni.c
#include <string.h>#include <jni.h>
Java_com_example_hellondk_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz ) {
343
Embedded Android Development สเสนทางนกพฒนา
return (*env)->NewStringUTF(env, "Hello from JNI !");}
ทำการคอมไพลโดยใชคำสง ndk-build
$ ndk-build Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserverGdbsetup : libs/armeabi/gdb.setupCompile thumb : hello-jni <= hello-jni.cSharedLibrary : libhello-jni.soInstall : libhello-jni.so => libs/armeabi/libhello-jni.so$ cd ..
เมอถอยออกมาจากไดเรกทอร jni/ จะเหนไดเรกทอรทถกสรางใหมจากการคอมไพลชอ libs ดงแสดงในคำสง ls ขางลางน
$ lsAndroidManifest.xml! res default.propertieslibs! src jni! obj! tests
ขนตอนท 2: การเตรยมไลบราร เพอใหใชไดกบ Android Studioในขนตอนนจะแตกตางจากการพฒนาดวยโปรแกรม Eclipse IDE คอจะตองมการปรบเปลยนบาง
อยางพเศษ ไดแก การเตรยมไลบรารในรปแบบ .jar แทนทจะเปน .so เพอให Android Studio อางองผานการตงคาในไฟล build.gradle ได การเตรยมไลบรารจะม 5 ขนตอนยอยดงน
$ mv libs lib <---- 1. เปลยนชอไดเรกทอร libs ใหเปน lib$ zip -r native-libs.zip lib/ <---- 2. ทำการแพกไดเรกทอร lib ใหเปนไฟลไลบาร adding: lib/ (stored 0%) adding: lib/armeabi/ (stored 0%) adding: lib/armeabi/gdb.setup (deflated 54%) adding: lib/armeabi/gdbserver (deflated 39%) adding: lib/armeabi/libhello-jni.so (deflated 48%)(reverse-i-search)`mv': mv libs lib
$ mv native-libs.zip native-libs.jar <---- 3. เปลยนชอนามสกลไฟลใหเปน .jar$ lsAndroidManifest.xml! lib! res default.properties!src jni! obj! tests native-libs.jar
$ mv lib libs <---- 4. เปลยนชอไดเรกทอรกลบมาเปน libs เชนเดม$ mv native-libs.jar libs/ <---- 5. ยายไฟลไลบรารกลบไปอยในไดเรกทอร libs
สำหรบการสรางโปรแกรมภาษาจาวา ดวย Android Studio เพอเรยกใชไลบราร hello-jni นน สามารถทำตามขนตอนดงน
344
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 1: สรางโปรเจคใหมดวย Android Studio เปดโปรแกรม Android Studio แลวเลอกเมน File -> New Project แลวตงชอ Application
name วา “HelloNDK” และตงชอ Package name วา “com.example.hellondk”
รปท 6.43 ตงคารายละเอยดของโปรแกรม NDK
เลอกชนดโปรแกรมเปน Blank Activity แลวตงชอ Activity วา “MainActivity”
รปท 6.44 กำหนด template ใหโปรแกรมและตงคา Activity
345
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 2: นำเขาไลบราร hello-jni มาวางไวในโปรเจค โดยการใชเมาสลากไดเรกทอร libs/ ทอยภายใตไดเรกทอร ~/android-ndk-r7b/
samples/hello-jni/ แลวมาวางไวในโปรเจคภายใต src/main
รปท 6.45 การนำเขาไดเรกทอร libs
ขนตอนท 3: แกไขไฟล build.gradle ภายในโปรเจคจะปรากฏไฟลชอวา build.gradle ซงเปนไฟลทใชในการตงคาเพมเตมสำหรบคอม
ไพล ใหเพม task nativeLibsToJar, tasks.withType (Compile) และ dependencies เขาไปในไฟล build.gradle ใหเหมอนขางลางน
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.5.+' }}apply plugin: 'android'repositories { mavenCentral()}
android { compileSdkVersion 17 buildToolsVersion "17.0.0" defaultConfig { minSdkVersion 7
346
Embedded Android Development สเสนทางนกพฒนา
targetSdkVersion 16 }}
task nativeLibsToJar( type: Zip, description: 'create a jar archive of the native libs') { destinationDir file("src/main/libs/native-libs") baseName 'native-libs' extension 'jar' from fileTree(dir: 'src/main/libs', include: '**/*.so') into 'lib/'}
tasks.withType (Compile) { compileTask -> compileTask.dependsOn (nativeLibsToJar)}
dependencies { compile fileTree(dir: "src/main/libs/native-libs", include: 'native-libs.jar')}
ขนตอนท 4: เขยนโปรแกรมภาษาจาวา เพอใหทำงานตามทตองการใหแกไขไฟล MainActivity.java และไฟล activity_main.xml ใหมรายละเอยดดงน
// MainActivity.javapackage com.example.hellondk;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.widget.TextView;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = new TextView(this); tv =(TextView)findViewById(R.id.hello); tv.setText(stringFromJNI()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; }
347
Embedded Android Development สเสนทางนกพฒนา
public native String stringFromJNI(); static { System.loadLibrary("hello-jni"); }}
แกไขไฟล activity_main.xml โดยการเพม android:id="@+id/text" และ
android:textSize="40dp" android:text="No Message..."
รปท 6.46 แสดงรายละเอยดภายในไฟล activity_main.xml
// activity_main.xml<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="40dp" android:text="No Message..."/></RelativeLayout>
ขนตอนท 5: รนโปรแกรมประยกตเพอเรยกใชไลบราร ทำการสราง Android Virtual Device และรนโปรแกรม HelloNDK ดงแสดงในรปขางลางน
348
Embedded Android Development สเสนทางนกพฒนา
รปท 6.47 ผลลพธการรนโปรแกรม
พนฐานการพฒนา JAVA NATIVE INTERFACE (JNI)Java Native Interface หรอเรยกยอๆวา JNI เปนสวนหนงทอยในชดเครองมอพฒนา JDK (Java
Software Development Kit) ซง JNI นจะทำหนาทเปนสวนเชอมตอระหวางโปรแกรม native (C/C++) และโปรแกรม JAVA ทำใหโปรแกรม JAVA สามารถเรยกโคดโปรแกรม หรอฟงกชนของโปรแกรมทถกพฒนาดวยโปรแกรมภาษา C/C++ หรอแมแตภาษาอนๆได นอกจากนนโปรแกรมภาษาอนกยงสามารถเรยกฟงกชนภายในโปรแกรมภาษาจาวาไดเชนกน โดยเรยกผาน Invocation API ทอยภายใน JVM (Java virtual machine)
สำหรบระบบปฏบตการแอนดรอยดโคดโปรแกรม JAVA (JAVA Code) กจะถกรนบน Dalvik ซงเปนเครองเสมอน (Virtual Machine) คลายกบ (แตไมเหมอน) JVM ของบรษท Oracle แตตว Dalvik นนไดถกพฒนาใหมทงหมดโดยนกพฒนาของกเกลเอง ในขณะทโคดโปรแกรม native (Native Code) จะถกคอมไพลเปนโคดไบนาร ซงพรอมถกเรยกไดทนทในระดบระบบปฏบตการ ดงนน JNI จงทำตวเองเหมอนสะพานเชอมกนระหวางโลกสองโลกน ดงรปแสดงความสมพนธระหวาง JAVA code, Dalvik VM, native code, และ ระบบปฏบตการแอนดรอยด ขางลางน
JAVA Code
Android System
Dalvik VM JNI Native Code
รปท 6.48 แสดงการสอสารระหวางโปรแกรม Java และ Native C
349
Embedded Android Development สเสนทางนกพฒนา
จากรปขางบนทง Dalvik VM และ Native Code ตางกทำงานอยบนระบบปฏบตการแอนดรอยด ดงนนระบบปฏบตการจะตองเตรยมสภาพแวดลอมสำหรบการเรยกคำสงระหวางกน (execution environ-ment) และจะเหนวา JNI เปนสวนหนงทอยใน Dalvik VM ซงจะอำนวยความสะดวกให Native Code ใหสามารถเขาถงตวแปรภายในคลาส (Data fields) และสมาชกฟงกชนภายในคลาส (Member func-tions) ไดจากการกำหนดสทธการเขาถง (Access Permissions) คลาสภายในโคด JAVA
ดงนนการแลกเปลยนขอมลระหวางโปรแกรม JAVA และโปรแกรม native (C/C++) นนจงเปนประเดนสำคญทนกพฒนาควรทำความเขาใจ ซงใน JNI นนกไดมการกำหนดตวแปรทสามารถรองรบตวแปรมาตราฐานของแตละภาษา ดงแสดงในตารางขางลางน
ตาราง 6.3 แสดงประเภทของตวแปรในภาษาจาวา เทยบกบตวแปรใน JNI
J A V A T Y P E J N I J A V A A R R A Y T Y P E
J N I
byte jbyte byte[] jbyteArray
short jshort short[] jshortArray
int jint int[] jintArray
long jlong long[] jlongArray
float jfloat float[] jfloatArray
double jdouble double[] jdoubleArray
char jchar char[] jcharArray
boolean jboolean boolean[] jbooleanArray
void jvoid Object[] jobjectArray
Object jobject
Class jclass
String jstring
array jarray
Throwable jthrowable
นอกจากนน JNI ยงมการกำหนดคา (definition) ทจำเปนพนฐานไวใหเบองตน เพอความสะดวกในการใชงาน เชน
#define JNI_FALSE 0 #define JNI_TRUE 1
typedef jint jsize;
350
Embedded Android Development สเสนทางนกพฒนา
เมอนกพฒนาไดสรางฟงกชนภายในโคดโปรแกรม native จะมขบวนการหนงทสำคญไมนอยไปกวากน คอการลงทะเบยน native ฟงกชน (Native Method Registration) ซงโดยทวไป JNI เองจะสามารถคนหาสำรวจชอฟงกชนภายในโปรแกรม native โดยอตโนมตอยแลวดงตวอยางโปรแกรม HelloNDK กอนหนาน แตการพฒนาโปรแกรมใหมระบบและทำให JNI ไมตองเสยเวลาเพอทำการคนหาสำรวจชอฟงกชนทงหมดของโปรแกรม native กอนจะเรมทำการเรยกใช นกพฒนาสามารถสรางโปรแกรม native โดยใหทำการลงทะเบยนชอฟงกชนภายในทงหมดใหกบ JNI ทอยภายใน Dalvik VM โดยการเรยกใชฟงกชนของ JNI ชอ RegisterNatives(JNIEnv *env, jclass clazz, const
JNINativeMethod *methods, jint nMethods); ดงตวอยางขางลาง
...JNINativeMethod nm[2];nm[0].name = "NativePlus";nm[0].signature = "(II)I";nm[0].fnPtr = NativePlus;nm[1].name = "NativeMultiply";nm[1].signature = "(II)I";nm[1].fnPtr = NativeMultiply;
jclass cls = (*env)->FindClass(env, "com/example/NativeApp/Activity");// Register methods with env->RegisterNatives.(*env)->RegisterNatives(env, cls, nm, 2);
อารกวเมนต cls (clazz) ในฟงกชน RegisterNatives(..) จะถกอางองไปยงคลาสทเกบรายการฟงกชนของโปรแกรม native ทไดถกลงทะเบยนแลว และตวแปรแบบโครงสราง (data struc-ture) nm (JNINativeMethod) จะเกบรายละเอยดของฟงกชนในโปรแกรม native ทลงทะเบยนทงหมด โดยมรายละเอยดดงน
typedef struct {
char *name; <--- ชอฟงกชน (method name)
char *signature; <--- ตวอธบายคณลกษณะของฟงกชน (descriptor) void *fnPtr; <--- ตวชไฟลยงตำแหนงของฟงกชน (function pointer) } JNINativeMethod;
รปแบบทวไปของการกำหนด method signature คอ
method-name(argument-types)return-type
JVM จะใชอกขระเพอเปนตวแทนประเภทของตวแปรในภาษาจาวา ดงแสดงในตารางขางลางน
ตาราง 6.4 อกขระเพอแทนสญลกษณใหกบตวแปรของภาษาจาวา
351
Embedded Android Development สเสนทางนกพฒนา
JVM SIGNATURE JAVA TYPE
Z boolean
B byte
C char
S short
I int
J long
F float
D double
V void
Lclass ชอคลาส[type ชนดตวแปร
(arg-type)ret-type ชนดตวแปรของอากวเมนต และการคนคากลบ
ตวอยางการใชงาน
ฟงกชน SIGNATURE
void fun1() fun1()V
int fun2(int n, long l) fun2(IJ)I
long fun3(int n, String s, int[] arr) fun3(ILjava/lang/String;[I)J
boolean fun4(int[] arr) fun4([I)Z
double fun5(String s, int n) fun5(Ljava/lang/String;I)D
void fun6(int n, String[] arr, char c) fun6(I[Ljava/lang/String;C)V
long fun7(int n, String s, int[] arr) fun7(ILjava/lang/String;[I)J
ตวอยางการสรางและเรยกใช JNI METHODS
การพฒนาโปรแกรม native (C/C++) โดยทมการสรางฟงกชนแลวทำการลงทะเบยนไปยง Dalvik VM ดวยฟงกชน RegisterNatives ของ JNI เพอใหโปรแกรมประยกตภาษาจาวา บนแอนดรอยดสามารถเรยกใชงานได มขนตอนการพฒนาดงน
352
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 1: สรางโปรแกรม native และสรางฟงกชนสำหรบการคำนวณทางคณตศาสตรสรางไดเรกทอรชอ NativeCalculation และไดเรกทอรยอยชอ jni/ ซงใชในการเกบโคดโปรแกรม
(.c, .h) และ Android.mk โดยใชคำสงดงน
$ mkdir NativeCalculation$ mkdir NativeCalculation/jni$ cd NativeCalculation/jni
$ vim Android.mk LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := NativeCalculationLOCAL_SRC_FILES := NativeCalculation.cLOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)
$ vim NativeCalculation.h#include <jni.h>#ifndef _Included_foo_Sqrt#define _Included_foo_Sqrt#ifdef __cplusplusextern "C" {#endif#undef foo_Sqrt_EPSILON#define foo_Sqrt_EPSILON 0.05
#ifdef __cplusplus}#endif#endif
$ vim NativeCalculation.c#include <jni.h>#include <android/log.h>#include <stdio.h>#include <stdlib.h>#include "NativeCalculation.h"
jint NativePlus(JNIEnv *pEnv, jobject pObj, jint pa, jint pb) { return pa+pb;}
jint NativeMultiply(JNIEnv *pEnv, jobject pObj, jint pa, jint pb) { return pa*pb;}
jdouble NativeSqrt(JNIEnv *pEnv, jobject pObj, jdouble pa) { jdouble x0 = 10.0, x1 = pa, diff; do {
353
Embedded Android Development สเสนทางนกพฒนา
x1 = x0 - (((x0 * x0) - pa) / (x0 * 2)); diff = x1 - x0; x0 = x1; } while (labs(diff) > 0.05);
return x1;}
jdoubleArray NativeArraySumAndAverage(JNIEnv *pEnv, jobject pObj, jintArray rets) { jboolean isCopy; // Convert rets to C's jint[] jint *intArr = (*pEnv)->GetIntArrayElements(pEnv, rets, &isCopy); __android_log_print(ANDROID_LOG_INFO, "NativeArraySumAndAverage", "a new copy is created: %d", isCopy); if (NULL == intArr) return NULL;
jsize len = (*pEnv)->GetArrayLength(pEnv, rets); int i; jint sum = 0; jdouble average = 0.0;
for (i = 0; i < len; ++i) { __android_log_print(ANDROID_LOG_INFO, "NativeArraySumAndAverage of ", "%d = %d", i, intArr[i]); sum += intArr[i]; } average = (jdouble)sum / len; (*pEnv)->ReleaseIntArrayElements(pEnv, rets, intArr, 0);
jdouble outCArray[] = {sum, average};
// Convert the C's Native jdouble[] to JNI jdoublearray, and then return // allocate array[2] jdoubleArray returnJNIArray = (*pEnv)->NewDoubleArray(pEnv, 2); if (NULL == returnJNIArray) return NULL; // copy outCArray to returnJNIArray (*pEnv)->SetDoubleArrayRegion(pEnv, returnJNIArray, 0 , 2, outCArray);
return returnJNIArray;}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* pVm, void* reserved){ JNIEnv* env; if ((*pVm)->GetEnv(pVm, (void **)&env, JNI_VERSION_1_6)) { return -1; } JNINativeMethod nm[4]; nm[0].name = "NativePlus"; nm[0].signature = "(II)I";
354
Embedded Android Development สเสนทางนกพฒนา
nm[0].fnPtr = NativePlus; nm[1].name = "NativeMultiply"; nm[1].signature = "(II)I"; nm[1].fnPtr = NativeMultiply; nm[2].name = "NativeSqrt"; nm[2].signature = "(D)D"; nm[2].fnPtr = NativeSqrt; nm[3].name = "NativeArraySumAndAverage"; nm[3].signature = "([I)[D"; nm[3].fnPtr = NativeArraySumAndAverage;
jclass cls = (*env)->FindClass(env, "com/example/NativeCalculation/MainActivity"); // Register methods with env->RegisterNatives. (*env)->RegisterNatives(env, cls, nm, 4); return JNI_VERSION_1_6;}
ขนตอนท 2: คอมไพลโปรแกรม native และเตรยมไลบราร เพอใหใชไดกบ Android Studio
$ ndk-buildCompile thumb : NativeCalculation <= NativeCalculation.cSharedLibrary : libNativeCalculation.soInstall : libNativeCalculation.so => libs/armeabi/libNativeCalculation.so
$ lsAndroid.mk!! NativeCalculation.c! NativeCalculation.h$ cd ..$ mv libs lib$ zip -r NativeCalculation.zip lib/ adding: lib/ (stored 0%) adding: lib/android-support-v4.jar (deflated 14%) adding: lib/armeabi/ (stored 0%) adding: lib/armeabi/libNativeCalculation.so (deflated 47%)$ mv NativeCalculation.zip NativeCalculation.jar$ mn lib libs$ mv NativeCalculation.jar libs/
สำหรบการสรางโปรแกรมภาษาจาวา ดวย Android Studio เพอเรยกใชไลบราร NativeCalcula-tion นน สามารถทำตามขนตอนดงน
ขนตอนท 1: สรางโปรเจคใหมดวย Android Studio เลอกเมน File -> New Project แลวตงชอ Application name วา “NativeCalculation” และ
ตงชอ Package name วา “com.example.NativeCalculation” ดงรป
355
Embedded Android Development สเสนทางนกพฒนา
รปท 6.49 การตงคาโปรแกรม Calculation NDK
ขนตอนท 2: นำเขาไลบราร NativeCalculation มาวางไวในโปรเจค โดยการใชเมาสลากไดเรกทอร libs/ แลวนำมาวางไวในโปรเจคภายใตไดเรกทอร src/main ดง
แสดงในรปขางลาง
รปท 6.50 การนำเขาไดเรกทอร lib และระบรายละเอยดในไฟล MainActivity.java
356
Embedded Android Development สเสนทางนกพฒนา
ขนตอนท 3: แกไขไฟล build.gradle ภายในโปรเจค จะปรากฏไฟลชอวา build.gradle ซงเปนไฟลใชในการตงคาเพมเตมสำหรบคอม
ไพล ใหเพม task nativeLibsToJar, tasks.withType (Compile) และ dependencies เขาไปในไฟล build.gradle ใหเหมอนขางลางน
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.5.+' }}apply plugin: 'android'
repositories { mavenCentral()}
android { compileSdkVersion 18 buildToolsVersion "18.1.0"
defaultConfig { minSdkVersion 7 targetSdkVersion 16 }}
task nativeLibsToJar( type: Zip, description: 'create a jar archive of the native libs') { destinationDir file("src/main/libs/NativeCaculation") baseName 'NativeCaculation' extension 'jar' from fileTree(dir: 'src/main/libs', include: '**/*.so') into 'lib/'}
tasks.withType (Compile) { compileTask -> compileTask.dependsOn (nativeLibsToJar)}
dependencies { compile fileTree(dir: "src/main/libs/NativeCaculation", include: 'NativeCaculation.jar')}
ขนตอนท 4: เขยนโปรแกรมภาษาจาวา เพอใหทำงานตามทตองการ
357
Embedded Android Development สเสนทางนกพฒนา
ใหแกไขไฟล MainActivity.java และไฟล activity_main.xml ใหมรายละเอยดงน
package com.example.NativeCalculation;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.widget.TextView;
public class MainActivity extends Activity { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.tv = new TextView(this); this.tv =(TextView)findViewById(R.id.calculation_text); callingNative(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } private void callingNative() { int a = 2342, b = 452; double c = 2353.0; int d = NativePlus(a, b); this.tv.setText(a + "+" + b + "=" + d); d = NativeMultiply(a, b); this.tv.append("\n" + a + "x" + b + "=" + d); double e = NativeSqrt(c); this.tv.append("\nSqrt(" + c + ")" + "=" + e); int numbers[] = new int[10000]; for (int i=0; i < numbers.length ; ++i) { numbers[i] = i; } double[] results = this.NativeArraySumAndAverage(numbers); this.tv.append("\nSummation of Numbers (1-" + numbers.length + ") = " + re-sults[0]); this.tv.append("\nAverage of Numbers (1-" + numbers.length + ") = " + re-sults[1]); } private native int NativePlus(int a, int b); private native int NativeMultiply(int a, int b); private native double NativeSqrt(double a); private native double[] NativeArraySumAndAverage(int[] numbers); static { System.loadLibrary("NativeCalculation"); }}
358
Embedded Android Development สเสนทางนกพฒนา
แกไขไฟล activity_main.xml โดยการเพม android:id="@+id/calculation_text" และ android:textSize="40dp" android:text="No Message..."
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/calculation_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30dp" android:text="No Message..." /></RelativeLayout>
ขนตอนท 5: รนโปรแกรมประยกตเพอเรยกใชไลบรารผลการรนโปรแกรม NativeCalculation ซงเปนการเรยกใชฟงกชนในการบวกเลข คณเลข หาราก
ทสอง บวกเลขในอาเรย และหาคาเฉลยของเลขในอาเรย แสดงผลลพธดงรปขางลางน
รปท 6.51 แสดงผลลพธการรนโปรแกรมคำนวณทางคณตศาสตร
ตวอยางการพฒนา ANDROID NDK MULTI-THREADING
เพอใหการทำงานในระดบ Native code สามารถดงศกยภาพทางดาน multi-processing tech-nique ทเปนพนฐานสำคญทมากบระบบปฏบตการลนกซตงแตแรกดวยการนำ Posix Thread ททำใหโปรเซสสามารถแบงงานออกเปนงานยอยๆ (thread) แลวแยกกนประมวลผล ซงเรยกวา multi-
359
Embedded Android Development สเสนทางนกพฒนา
threading programming เพอใหโปรแกรมประยกตภาษาจาวา สามารถเรยกใชงาน posix thread ได โดยตวอยางขางลางนจะแสดงใหเหนถงการใช mutex เพอทำใหเทรดแตละตวทำงานไดสอดประสานไมขดแยงหรอแยงใชทรพยากรในเวลาเดยวกน ดงตวอยางการพฒนาในบทท 4 โดยการนำฟงกชน pthread_mutex ทเกยวของมาใช ตวอยางเชน
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);int pthread_mutex_destroy(pthread_mutex_t *mutex);
ซงการเรยกใช mutex เพอใหเทรดนำไปเปนเงอนไขในการขอเขาใชทรพยากรของระบบนน โดยมฟงกชนใหเรยกใชไดดงน int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_lock_timeout_np(pthread_mutex_t *mutex, unsigned msecs);
ขนตอนการพฒนาโปรแกรม native และโปรแกรมประยกต มขนตอนดงน
ขนตอนท 1: สรางโปรแกรม native และสรางฟงกชนเทรดสรางไดเรกทอรชอ NativeThreadMutex และไดเรกทอรยอยชอ jni/ ซงใชในการเกบโคด
โปรแกรม (.c, .h) และ Android.mk โดยใชคำสงดงน
$ mkdir NativeThreadsMutex$ mkdir NativeThreadsMutex/jni$ cd NativeThreadsMutex/jni
$ vim NativeThreadsMutex.cpp #include <jni.h>#include <unistd.h>#include <pthread.h>#include "mylog.h"
void jni_start_threads();void *run_by_thread1(void *arg);void *run_by_thread2(void *arg);
void jni_start_threads_dead();void *run_by_thread1dead(void *arg);void *run_by_thread2dead(void *arg);
jint JNI_OnLoad(JavaVM* pVm, void* reserved){ JNIEnv* env; if (pVm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) {
360
Embedded Android Development สเสนทางนกพฒนา
return -1; } JNINativeMethod nm[2]; nm[0].name = "jni_start_threads"; nm[0].signature = "()V"; nm[0].fnPtr = (void*)jni_start_threads; nm[1].name = "jni_start_threads_dead"; nm[1].signature = "()V"; nm[1].fnPtr = (void*)jni_start_threads_dead; jclass cls = env->FindClass("com/example/NativeThreadsMutex/MainActivity"); // Register methods with env->RegisterNatives. env->RegisterNatives(cls, nm, 2); return JNI_VERSION_1_6;}
//pthread_mutex_t mux1 = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mux1;pthread_mutex_t mux2;void jni_start_threads() { pthread_t th1, th2; int threadNum1 = 1, threadNum2 = 2; int ret; pthread_mutex_init(&mux1, NULL); pthread_mutex_init(&mux2, NULL); ret = pthread_create(&th1, NULL, run_by_thread1, (void*)&threadNum1); if(ret) { LOGE(1, "cannot create the thread %d thread: %d", threadNum1, ret); } LOGI(1, "thread 1 started"); ret = pthread_create(&th2, NULL, run_by_thread2, (void*)&threadNum2); if(ret) { LOGE(1, "cannot create the thread %d: %d", threadNum2, ret); } LOGI(1, "thread 2 started"); ret = pthread_join(th1, NULL); LOGI(1, "thread 1 end %d", ret); ret = pthread_join(th2, NULL); LOGI(1, "thread 2 end %d", ret); pthread_mutex_destroy(&mux1); pthread_mutex_destroy(&mux2);}
int cnt = 0;int THR = 10;void *run_by_thread1(void *arg) { int* threadNum = (int*)arg; while (cnt < THR) { pthread_mutex_lock(&mux1); while ( pthread_mutex_trylock(&mux2) ) { pthread_mutex_unlock(&mux1); //avoid deadlock usleep(50000); //if failed to get mux2, release mux1 first
361
Embedded Android Development สเสนทางนกพฒนา
pthread_mutex_lock(&mux1); } ++cnt; LOGI(1, "thread %d: cnt = %d", *threadNum, cnt); pthread_mutex_unlock(&mux1); pthread_mutex_unlock(&mux2); sleep(1); }}
void *run_by_thread2(void *arg) { int* threadNum = (int*)arg; while (cnt < THR) { pthread_mutex_lock(&mux2); while ( pthread_mutex_trylock(&mux1) ) { pthread_mutex_unlock(&mux2); //avoid deadlock usleep(50000); //if failed to get mux2, release mux1 first pthread_mutex_lock(&mux2); } ++cnt; LOGI(1, "thread %d: cnt = %d", *threadNum, cnt); pthread_mutex_unlock(&mux2); pthread_mutex_unlock(&mux1); sleep(1); }}
void jni_start_threads_dead() { pthread_t th1, th2; int threadNum1 = 1, threadNum2 = 2; int ret; pthread_mutex_init(&mux1, NULL); pthread_mutex_init(&mux2, NULL); ret = pthread_create(&th1, NULL, run_by_thread1dead, (void*)&threadNum1); if(ret) { LOGE(1, "cannot create the thread %d thread: %d", threadNum1, ret); } LOGI(1, "thread 1 started"); ret = pthread_create(&th2, NULL, run_by_thread2dead, (void*)&threadNum2); if(ret) { LOGE(1, "cannot create the thread %d: %d", threadNum2, ret); } LOGI(1, "thread 2 started"); ret = pthread_join(th1, NULL); LOGI(1, "thread 1 end %d", ret); ret = pthread_join(th2, NULL); LOGI(1, "thread 2 end %d", ret); pthread_mutex_destroy(&mux1); pthread_mutex_destroy(&mux2);}
362
Embedded Android Development สเสนทางนกพฒนา
void *run_by_thread1dead(void *arg) { int* threadNum = (int*)arg; while (cnt < THR) { pthread_mutex_lock(&mux1); usleep(50); pthread_mutex_lock(&mux2); ++cnt; LOGI(1, "thread %d: cnt = %d", *threadNum, cnt); pthread_mutex_unlock(&mux2); pthread_mutex_unlock(&mux1); sleep(1); }}
void *run_by_thread2dead(void *arg) { int* threadNum = (int*)arg; while (cnt < THR) { pthread_mutex_lock(&mux2); usleep(50); pthread_mutex_lock(&mux1); ++cnt; LOGI(1, "thread %d: cnt = %d", *threadNum, cnt); pthread_mutex_unlock(&mux1); pthread_mutex_unlock(&mux2); sleep(1); }}
$ vim mylog.h
#ifndef COOKBOOK_LOG_H#define COOKBOOK_LOG_H
#include <android/log.h>
#define LOG_LEVEL 4#define LOG_TAG "NativeThreadsMutex"
#define LOGU(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_UNKNOWN, LOG_TAG, __VA_ARGS__);}#define LOGD(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_DEFAULT, LOG_TAG, __VA_ARGS__);}#define LOGV(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);}#define LOGDE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);}#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}#define LOGW(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);}#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}#define LOGF(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__);}
363
Embedded Android Development สเสนทางนกพฒนา
#define LOGS(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__);}
#endif
$ vim Android.mkLOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := NativeThreadsMutexLOCAL_SRC_FILES := NativeThreadsMutex.cppLOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)
ขนตอนท 2: คอมไพลโปรแกรม native และเตรยมไลบราร เพอใหใชไดกบ Android Studio
$ ndk-build Compile++ thumb : NativeThreadsMutex <= NativeThreadsMutex.cppSharedLibrary : libNativeThreadsMutex.soInstall : libNativeThreadsMutex.so => libs/armeabi/libNativeThreadsMutex.so$ cd ..$ mv libs lib$ zip -r NativeThreadsMutex.zip lib/ adding: lib/ (stored 0%) adding: lib/android-support-v4.jar (deflated 14%) adding: lib/armeabi/ (stored 0%) adding: lib/armeabi/libNativeThreadsMutex.so (deflated 49%)$ mv NativeThreadsMutex.zip NativeThreadsMutex.jar$ mv lib libs$ mv NativeThreadsMutex.jar libs/
สำหรบการสรางโปรแกรมภาษาจาวา ดวย Android Studio เพอเรยกใชไลบราร NativeThreads-Mutex นน สามารถทำตามขนตอนดงน
ขนตอนท 1: สรางโปรเจคใหมดวย Android Studio เลอกเมน File -> New Project แลวตงชอ Application name วา “NativeThreadsMutex”
และตงชอ Package name วา “com.example.NativeThreadsMutex”
364
Embedded Android Development สเสนทางนกพฒนา
รปท 6.52 การตงคาโปรแกรม NativeThreadsMutex NDK
ขนตอนท 2: ทำการรนโปรแกรม และตรวจสอบการทำงานผานโปรแกรม adb เมอรนโปรแกรม ผลลพธจะแสดงอยใน logcat ดงนนเพอดผลลพธ จะใชคำสง adb logcat ดง
แสดงขางลางน
$ adb logcat -v time NativeThreadsMutex:I *:S10-05 19:19:45.469 I/NativeThreadsMutex( 2836): thread 1 started10-05 19:19:45.469 I/NativeThreadsMutex( 2836): thread 2 started10-05 19:19:45.479 I/NativeThreadsMutex( 2836): thread 2: cnt = 110-05 19:19:45.479 I/NativeThreadsMutex( 2836): thread 1: cnt = 210-05 19:19:46.488 I/NativeThreadsMutex( 2836): thread 2: cnt = 310-05 19:19:46.492 I/NativeThreadsMutex( 2836): thread 1: cnt = 410-05 19:19:47.489 I/NativeThreadsMutex( 2836): thread 2: cnt = 510-05 19:19:47.499 I/NativeThreadsMutex( 2836): thread 1: cnt = 610-05 19:19:48.490 I/NativeThreadsMutex( 2836): thread 2: cnt = 710-05 19:19:48.499 I/NativeThreadsMutex( 2836): thread 1: cnt = 810-05 19:19:49.489 I/NativeThreadsMutex( 2836): thread 2: cnt = 910-05 19:19:49.499 I/NativeThreadsMutex( 2836): thread 1: cnt = 1010-05 19:19:50.499 I/NativeThreadsMutex( 2836): thread 1 end 010-05 19:19:50.499 I/NativeThreadsMutex( 2836): thread 2 end 0
365
Embedded Android Development สเสนทางนกพฒนา
บทท 7 การพฒนาโปรแกรมเพองานประยกตบนระบบสมองกลฝงตว
ตวอยางการพฒนาโปรแกรมบนบอรด Raspberry Piในบทนจะแสดงตวอยางการประยกตทางดานระบบสมองกลฝงตว โดยเนอหาในสวนแรกจะเปน
ตวอยางการพฒนาโปรแกรมสำหรบบอรดสมองกลฝงตวซงเปนบอรดทไดรบความนยมมากในปจจบนชอวาบอรด Raspberry Pi ซงเปนบอรดสมองกลฝงตวททำหนาทเหมอนคอมพวเตอรขนาดเลก (Single-board computer) ทพฒนาโดยนาย Eben Upton ซงทำงานอยบรษท Broadcom และเปนนกพฒนาหลกภายใตองคกรไมแสวงหากำไรชอวา Raspberry Pi Foundation ในประเทศองกฤษ โดยมวตถประสงคหลกคอตองการสรางบอรดตวนขนมาเพอสงเสรมการเรยนการสอนทางดานวทยาศาตรและคอมพวเตอรในโรงเรยน
ซงความตงใจเดมของโครงการ Raspberry Pi คอเพอตองการเพยงจะทำเปนบอรดไมโครคอนโทรลเลอรทมความสามารถคลายกบบอรด Arduino แตในทสดกไดตดสนใจออกแบบพฒนาใหเปนระดบบอรดคอมพวเตอรขนาดเลกแทน เพอตองการใหครและนกเรยนสามารถพฒนาโปรแกรมภายในบอรด Raspberry Pi ไดทนท โดยไมตองใชเครองคอมพวเตอรเปนเครอง Host สำหรบพฒนาโปรแกรมเหมอนบอรดสมองกลฝงตวทวไป ทางองคกร Raspberry Pi ไดทำขอตกลงความรวมมอทางลขสทธรวมกบบรษท Element14 และบรษท RS Components ซงเปนบรษทยกษใหญดานการสงซออปกรณอเลกทรอนกสแบบออนไลน เพอใหเปนผผลตและผแทนจำหนายบอรด Raspberry Pi รายละเอยดทางดานเทคนคดงน
1. ใช System-on-Chip จากคาย Broadcom รน BCM2835 ซงมหนวยประมวลผลกลาง ARM1176JZF-S ความเรวสญญาณนาฬกา 700 MHz สามารถถก Over Clock ไดถง 1 GHz
2. หนวยความจำ SDRAM ขนาด 256 MB ในรน A และ SDRAM 512 MB ในรน B
3. สามารถเกบขอมลและบต Image file ระบบปฏบตการไดจาก SD Card
4. มUSB 2.0 ใหใชงาน
5. มชองเสยบ Video แบบ Composite RCA และ HDMI
6. มหวแจก Audio ขนาด 3.5 มลลเมตร
7. ม Ethernet 10/100
8. ม GPIO 17 พนใหใชงาน
9. มแหลงจายไฟเลยง +3.3 V และ +5V
10. ขนาดของบอรด 85.60 มลลเมตร x 53.98 มลลเมตร
11. นำหนก 45 กรม
366
Embedded Android Development สเสนทางนกพฒนา
รปท 7.1 แสดงความสามารถในการเชอมตอกบอปกรณภายนอกตางๆกบบอรด Raspberry Pi
บอรด Raspberry Pi สามารถเชอมตอกบอปกรณตางไดหลายหลากดงแสดงในรปขางบน ซงเหมาะสำหรบนกพฒนาระบบสมองกลฝงตวทไมตองการเครอง Host เพอใชในการพฒนาโปรแกรมแตจะสามารถพฒนาโปรแกรมดวยโปรแกรม Arduino IDE เพอใชในการโปรแกรมภาษา C เพอเปนโปรแกรมเฟรมแวร (firmware) สำหรบไมโครคอนโทรเลอร ATMEL ทใชในบอรด Arduino หรอโปรแกรมภาษาอนๆ เชน ภาษาPython ดวยโปรแกรม Python IDE ภาษาเพรล (Perl) ภาษาเบสก (Basic) หรอ ภาษา C++ เปนตน
บอรด Raspberry Pi ยงรองรบระบบปฏบตการทเปนทนยมอยในปจจบน ตวอยางเชน ระบบปฏบตการ Debian GNU/Linux, Fedora, FreeBSD, NetBSD, Plan 9, Raspbian OS, RISC OS และ Slackware Linux นอกจากนนบอรดนกยงเหมาะกบการนำไปประยกตทำเปนเครอง Media server หรอ Set-top-box สำหรบงานทางดานมลตมเดย ดงตวอยางโปรเจค OpenELEC (Open Embedded
367
Embedded Android Development สเสนทางนกพฒนา
Linux Entertainment Center) ทมการนำระบบปฏบตการลนกซ มาปรบแตงใสโปรแกรม XBMC media center แลวนำมาตดตงในบอรด Raspberry Pi
การประยกตใชงานบอรด RaspBerry Pi
ในดานการศกษา บอรด Raspberry Pi สามารถใชเปนบอรดสรางแรงบนดาลใจใหกบเดก หรอนกศกษา ทมความสนใจในการนำไปสรางเปนของเลน หรอใชในการควบคมอปกรณภายนอกตางได
รปท 7.2 การนำ Raspberry Pi ไปใชในการสอนภายในโรงเรยน
สำหรบการประยกตในงานดานอตสาหกรรม บอรด Raspberry Pi เองกไดรบความนยมไมนอยจากเหลานกพฒนา เนองจากมความยดหยนในการเลอกใชภาษาโปรแกรมทจะนำมาพฒนาโปรแกรมลงภายในบอรดและสามารถตดตงไลบรารพเศษเพมเตมลงไปได ตวอยางเชน บอรด Data Acquisition (DAQ), Mini Super Computer ดงรปขางลาง
รปท 7.3 การนำ Raspberry Pi ไปประยกตในการประมวลผลขนาน
368
Embedded Android Development สเสนทางนกพฒนา
แนวทางการพฒนาบนบอรด Raspberry Pi
ต งแตในอดตจนถงปจจบนมบอรดสมองกลฝงตวสำหรบการเรยนร และเปนบอรดประยกต (Evaluation Kit) ออกมาจำนวนมากมาย ซงสวนใหญจะตองมการเตรยมเครองคอมพวเตอร (Host) ไวอกเครองสำหรบตดตง เครองมอพฒนา cross-compiling toolchains และชดโปรแกรมสำหรบใชในการพฒนาภาษาโปรแกรมตางๆ นอกจากนนจะตองเตรยมสายเคเบลแบบสายอนกรม (Serial cable) เพอเชอมตอกบบอรดสมองกลฝงตวผานพอรทคอนโซล (console) เพอใหสามารถเขาถงระบบปฏบตการภายในบอรดผานหนาจอเทอรมนลและสามารถพมพชดคำสงการตงคาตางๆ หรอเพอดบกโคดโปรแกรมได
แตดวยวธการดงทกลาวมาขางตนกยงสรางความยงยากไมนอยใหกบนกพฒนามอใหมทงหลาย แตเมอมาถงยคการมาของบอรด Raspberry Pi ทำใหนกพฒนาสามารถพฒนาโปรแกรมและทำการคอมไพลโปรแกรมอยบนบอรดสมองกลไดทนท โดยเพยงนำบอรด Raspberry Pi มาตอกบจอมอนเตอร คยบอรด และเมาส เทานน นอกจากนนนกพฒนากยงสามารถทำการ remote หนาจอ (Remote Desktop) ผานเครองคอมพวเตอร (Host) โดยใชโปรแกรม VNC (หรอ ssh ในกรณ text mode) เขาไปยงบอรด Raspberry Pi ไดเชนกน ดงแสดงในรปขางลาง
เครอง Host
Ethernet Hub
บอรดสมองกลฝงตว (Target)
สาย RS-232
สาย LAN
ARM, PowerPC, MIPS(Linux OS)
x86, x86_64 (Desktp OS)
สาย LAN
รปท 7.4 การเชอมตออปกรณสำหรบการพฒนาระบบสมองกลฝงตวแบบทวไป
Ethernet Hub
บอรด RaspBerry Pi (Target)
สาย LAN สาย LAN
Remote Desktop (vnc)Remote Login (ssh)
เครองคอมพวเตอร
สาย RS-232
HDMI
รปท 7.5 การเชอมตออปกรณสำหรบการพฒนาระบบสมองกลฝงตวของ Raspberry Pi
369
Embedded Android Development สเสนทางนกพฒนา
การเขาสระบบฏบตการภายใน Raspberry Pi ผานโปรแกรม Secure Shell (ssh)
การตดตงและเปดการใชงาน ssh (secure shell) เปนการสรางการเชอมตอ command line ระยะไกล ผานทางโปรโตคอล ssh ระหวางเครองคอมพวเตอร และบอรด Raspberry Pi วธการตดตงมดงน $ sudo raspi-config
รปท 7.6 แสดงการตงคาของ Raspberry Pi ผานคำสง raspi-config
แลวเลอกเมน SSH แลวตงคาใหเปน ENABLE ถดไป
ทดสอบเปดการเชอมตอระยะไกลจากเครองอนผาน ssh client ไปยงบอรด Raspberry Pi (IP Ad-dress: 10.20.4.222 ดวยชอผใช pi)
(จากเครอง Mac)$ ssh 10.20.4.222 -l pi
370
Embedded Android Development สเสนทางนกพฒนา
เปดการเชอมตอระยะไกลจากเครองอนผาน ssh client ไปยงบอรด Raspberry Pi ดวยโปรแกรม Putty บนระบบปฏบตการ Windows
รปท 7.7 หนาตาโปรแกรม PuTTY ในสวนหนาแสดงการตงคาตางๆ
ทำการใสไอพแอดเดลสของบอรด Raspberry PI แลวเลอก Open จากนนจะเขาไปทหนา terminal ใหทำการ login : pi และ password : raspberry ตอจากนนกจะเขาสหนา terminal ของ Raspbian โดยสมบรณ
รปท 7.8 หนาตางโปรแกรม Terminal ในระหวางการลอกอนเขาสระบบ
371
Embedded Android Development สเสนทางนกพฒนา
การเขาสระบบฏบตการภายใน Raspberry Pi ผานโปรแกรม VNC (Remote Desktop)
เรมตนดวยการตดตงโปรแกรม VNC server ชอวา tightvncserver ลงเขาไปในบอรด Raspberry Pi ดวยคำสงดงน
$ sudo apt-get install tightvncserver
ทำการเปดบรการโปรแกรม VNC server พรอมระบขนาดของหนาจอ Raspberry Pi $ vncserver :1 -geometry 1024x786 -depth 16 -pixelformat rgb565
สำหรบเครองคอมพวเตอร ใหทำการตดตงโปรแกรม VNC viewer (รองรบหลายระบบปฏบตการ) แลวระบ IP ของเครอง Raspberry Pi ดงแสดงในรปขางลางน
รปท 7.9 แสดงการ Remote Desktop เขาไปยงบอรด Raspberry Pi
372
Embedded Android Development สเสนทางนกพฒนา
GPIOs ภายในบอรด Raspberry PI
GPIO เปนหนงในคณสมบตพเศษทบอรด Raspberry Pi เปดใหนกพฒนาสามารถใชงานได แมวาคณสมบตบางอยางมไมครบเหมอนบอรดไมโครคอนโทรลเลอรทวไปแตกเพยงพอทจะสรางโปรแกรมประยกตไดมากมาย เพราะตวบอรด Raspberry Pi เองนนดวยคณสมบตทสามารถเขยนโปรแกรมไดบนบอรดเหมอนเครองคอมพวเตอร Host เมอบวกกบการใหสามารถเขาถง GPIOs ตางๆไดงาย กยงทำใหนกพฒนามอใหมจนถงระดบกลางสะดวกและงายตอการตดตงโปรแกรมหรอเขยนโปรแกรมเปนอยางด จงทำใหบอรด Raspberry Pi เปนอกหนงบอรดทไดรบความนยมเปนอยางสง
รปท 7.10 ตำแหนง GPIO บนบอรด Raspberry Pi
โดยทวไป GPIO (General purpose I/O) ของบอรด Raspberry Pi จะอยตรงสวนขา (ขา) P1 ซงมจำนวนของขา 2x13 หรอ 26 ขา โดยขาทงหมดไมไดมแค GPIO เพยงอยางเดยว แตประกอบไปดวย SPI, I2C, serial UART, ไฟเลยง 3.3 V, ไฟเลยง 5 V และ GND
รายละเอยด GPIO ของบอรด Raspberry Pi-P1 มจำนวน 26 ขา มระยะหางระหวางขา 2.54 มม. (100 mil) -เอาพตทของแตละขา จะอยในชวง 0-3.3V และอนพตไมควรมากกวา 3.3 V ถา มอนพตทเปน 5 V ควรผานวงจรปรบแรงดนใหเปน 3.3V กอนทเขามาทขาอนพต -ไฟเลยง 3.3 V สามารถจายกระแสไดไมเกน 50 mA-ไฟเลยง 5V สามารถจายกระแสไดไมเกน 100 mA-มดจตอล อนพต/เอาพต 8 ขา-ม I2C 2 ขา-ม SPI 5 ขา
373
Embedded Android Development สเสนทางนกพฒนา
-ม UART 2 ขา-มขาทยงไมใชอกอยางนอย 6 ขา
พนฐานการพฒนาโปรแกรมภาษาPython (Python)
การใชงานและพฒนา GPIO บนบอรด Raspberry Pi สวนใหญเปนการสงคาให GPIO ทอยบนบอรดสามารถใชงานได ไมวาจะเปนการสงงานจากเทอรมนล หรอจะเปนการเขยนโคดสงงาน โดยทสวนใหญระบบปฏบตการทอยบนบอรด Raspberry Pi อยางเชน ระบบปฏบตการ Raspbian ไดเตรยมเครองมอ Python IDE พรอมทง Python Cross complier และ C/C++ Cross complier ไวใหแลว ซงนกพฒนาสามารถใชงานไดทนทโดยไมตองตดตงโปรแกรม toolchains เพมเตม
ตวอยางการสงเอาพตขา GPIO ผาน command lineเขาสระบบปฏบตการภายใน Raspberry Pi ในสทธ super user เพอสามารถเขาถงขา GPIO ได
$ sudo su
export GPIO ขา จากไฟล /sys/class/gpio/export
# echo “4” > /sys/class/gpio/export
กำหนดชนดของ GPIO4 ใหเปนแบบเอาพท
# echo “out” > /sys/class/gpio/gpio4/direction
สามารถสงให GPIO4 ตดหรอดบได ดวยคำสง
# echo “1” > /sys/class/gpio/gpio4/value <--- (สงให LED ตด)
หรอ
# echo “0” > /sys/class/gpio/gpio4/value <--- (สงให LED ดบ)
เมอตองการยกเลกใชงาน GPIO ใหใชคำสง unexport ไฟล /sys/class/gpio/unexport
# echo “4” > /sys/class/gpio/unexport
374
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการรบคาจากขา GPIO ทเปน Push button ผาน command line
รปท 7.11 การตอวงจรเพอรบการกดสวทซกบบอรด Raspberry Pi
เขาสระบบปฏบตการภายใน Raspberry Pi ในสทธ super user เพอสามารถเขาถงขา GPIO ได
$ sudo su
export GPIO ขา จากไฟล /sys/class/gpio/export
# echo “4” > /sys/class/gpio/export
กำหนดชนดของ GPIO4 ใหเปนแบบเอาพท
# echo “in” > /sys/class/gpio/gpio4/direction
อานคาของอนพท ดวยคำสง cat
# cat /sys/class/gpio/gpio4/value
เมอตองการยกเลกใชงาน GPIO ใหใชคำสง unexport ไฟล /sys/class/gpio/unexport
# echo “4” > /sys/class/gpio/unexport
375
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการสงเอาพตขา GPIO เพอขบ LED
รปท 7.12 การตอวงจรเพอควบคม LED ดวยบอรด Raspberry Pi
สรางไฟล gpio_out_LED.py โดยมรายละเอยดโคดดงนimport RPi.GPIO as GPIOimport timeGPIO.setmode(GPIO.BOARD)GPIO.setup(12,GPIO.OUT)while (1): GPIO.output(12,GPIO.HIGH) time.sleep(1) GPIO.output(12,GPIO.LOW) time.sleep(1)
ในการตงคารปแบบการนบหมายเลขขานน มดวยกน 2 แบบคอ แบบท 1: GPIO.BOARD เปนการอางองหมายเลขขา GPIO ทอยบนบอรด Raspberry Pi แบบท 2: GPIO.BCM เปนการอางองหมายเลขขา GPIO หนวยประมวลผล Broadcom BCM2835 CPU
ตวอยางเชน GPIO.BOARD เทากบตำแหนงขาหมายเลข 12 แตถาเปน GPIO.BCM จะเปนตำแหนงขาหมายเลข 18
376
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการสงเอาพตขา GPIO โดยการรบจากการกดปม push button
รปท 7.13 การตอวงจรเพอรบการกดสวทซผานขา 18
สรางไฟล gpio_button.py โดยมรายละเอยดโคดดงนimport RPi.GPIO as GPIOimport timeGPIO.setmode(GPIO.BOARD)GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP)channel = 12def check_button(): if(GPIO.input(channel) == GPIO.LOW): print ('Button Pressed.')while (1): check_button() time.sleep(1)
จากรปดานบน ถาผใชงานไมตองการทจะตอตวตานทานเพอทำการ pull-up หรอ pull-down สามารถเพมพารามเตอร pull_up_down ใน GPIO.setup ได เชน
GPIO.setup(12,GPIO.IN, pull_up_down=GPIO.PUD_UP) (ตอตวตานทาน pull-up )
หรอ
GPIO.setup(12,GPIO.IN, pull_up_down=GPIO.PUD_DOWN) (ตอตวตานทาน pull-down )
การตงคาการตรวจจบการกดปม มอยดวยกน 2 สถานะ คอ วงจรอนพตแบบศกยตำ (Active Low) และ วงจรอนพตแบบศกยสง (Active High) ซงสามารถเขยนโปรแกรม python เพอตรวจจบได ดงน
377
Embedded Android Development สเสนทางนกพฒนา
if(GPIO.input(channel) == GPIO.LOW): (ตอวงจรอนพตแบบศกยตำ - Active low) print ('Button Pressed.')
หรอ
if(GPIO.input(channel) == GPIO.HIGH): (ตอวงจรอนพตแบบศกยสง - Active high) print ('Button Pressed.')
ตวอยางโคดโปรแกรม gpio_button.py ขางตนจะเปนการอานคาสถานะการกดปมโดยการวนรอบเขามาอานคาสถานะทกๆ 1 วนาทดวยเทคนคโพลลง (polling technique) แตอยางไรกตามอาจจะไมเหมาะกบการนำไปใชงานจรง เนองจากอาจมงานอยางอนทโปรแกรมตองทำดวย ไมเพยงแตวนรอบเพออานสถานะของการกดปมเพยงอยางเดยว ดงนนการนำเทคนคอนเตอรรพท (Interrupt technique) ทนยมเขยนกนบนไมโครคอลโทรเลอรทวไป จงเหมาะสมมากกวาแบบเทคนคโพลลง
ซงภาษา Python สามารถสรางฟงกชนในลกษณะ threaded callback เพอตรวจจบสญญาณของอนพต โดยการเขยนโคดโปรแกรมดงตวอยางขางลาง
def my_callback(channel): print('Button on press...') GPIO.add_event_detect(12, GPIO.FALLING, callback=my_callback, bounce-time=200)
ตวอยางโคดโปรแกรมตวใหมimport RPi.GPIO as GPIOimport timeGPIO.setmode(GPIO.BOARD)GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP)channel = 12def my_callback(channel): print('Button on press...') GPIO.add_event_detect(12, GPIO.FALLING, callback=my_callback, bounceti-me=200)
while (1):
378
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการประยกตบอรด Raspberry Pi ใหเปน Web Server
นอกจากเขยนโคดโปรแกรมหรอใชคำสงเพอเขาถง GPIO ของบอรด Raspberry Pi แลว นกพฒนายงสามารถสงงาน GPIO ผานหนาบราวเซอร (Web Browser) ซงจะสะดวกตอผใชงานเนองจากสามารถสงงานหรอเฝาตดตามดสถานะของอปกรณทตอกบ GPIO ของบอรด Raspberry Pi จากระยะไกลได ตวอยางการนำไปประยกตเชน การนำบอรด Raspberry Pi เชอมตอกบอปกรณไฟฟาภายในบาน แลวสามารถสงงานเครองใชไฟฟาหรอดสถานะเครองใชไฟฟาผานบราวเซอรจากททำงาน เปนตน
ตวอยางการตดตง Web server ลงบอรด Raspberry Pi
ตดตงโปรแกรมจดการแพกเกต (pip) และ โปรแกรม Flask ซงเปน web application frame-work ขนาดเลกทถกพฒนาดวยภาษา Python รวมกบ Werkzeug WSGI toolkit และ Jinja2 engine$ sudo apt-get install python-pip$ sudo pip install Flask
จากนนทดลองเขยนโปรแกรม Hello world$ mkdir hello$ cd hello/$ nano hello.py from flask import Flask app = Flask(__name__) @app.route(“/”) def hello(): return “Hello world!” if __name__ == “__main__”: app.run(‘0.0.0.0’)$ python hello.py * Running on http://0.0.0.0:5000/
จากนนเปดหนาบราวเซอรบนเครองคอมพวเตอร แลวพมพ raspberrypi:5000 ชอง URL
รปท 7.14 ผลลพธการเรยกไฟล hello.py ผานหนาบราวเซอร ทพอรตหมายเลข 5000
379
Embedded Android Development สเสนทางนกพฒนา
ตวอยางการเพมไฟล HTML และ CSS เขาไปในโปรแกรม hello.pyสรางไดเรกทอรชอ “templates/” อยภายในไดเรกทอร hello/ เพอเกบไฟล HTML ชอวา
home.html เนองจากฟงกชน home() นนจะคนหาไฟล home.html ทอยภายในไดเรกทอร tem-plates/ นอกจากนนถาตองการใช CSS กตองสรางไดเรกทอรเพมเตมชอวา static/css/ ไวภายในไดเรกทอร hello/ เพอเกบไฟล CSS
$ cd hello/$ mkdir templates$ mkdir static$ mkdir static/css$ cd static/css
$ nano main.cssbody { margin: 0; padding: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #444;}/* * Create dark grey header with a white logo */header { background-color: #2B2B2B; height: 35px; width: 100%; opacity: .9; margin-bottom: 10px;}header h1.logo { margin: 0; font-size: 1.7em; color: #fff; text-transform: uppercase; float: left;}header h1.logo:hover { color: #fff; text-decoration: none;}/* * Center the body content */ .container { width: 940px; margin: 0 auto;}
380
Embedded Android Development สเสนทางนกพฒนา
div.jumbo { padding: 10px 0 30px 0; background-color: #eeeeee; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px;}h2 { font-size: 3em; margin-top: 40px; text-align: center; letter-spacing: -2px;}h3 { font-size: 1.7em; font-weight: 100; margin-top: 30px; text-align: center; letter-spacing: -1px; color: #999;}
สรางไฟล layout.html เพอกำหนดรปแบบการแสดงของหนาเวป
$ nano layout.html<!DOCTYPE html><html> <head> <title>Flask</title> <strong><link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"></strong> </head> <body> <header> <div class="container"> <h1 class="logo">Flask App</h1> </div> </header> <div class="container"> {% block content %} {% endblock %} </div> </body></html>
แกไขไฟล home.html เพอเรยกใชรปแบบในไฟล layout.html
381
Embedded Android Development สเสนทางนกพฒนา
$ nano home.html{% extends "layout.html" %}{% block content %} <div class="jumbo"> <h2>Welcome to the Embedded System<h2> <h3>This is the home page for the Home Automation<h3> </div>{% endblock %}
ขนตอนสดทาย ทำการทดดสอบเปดหนาบราวเซอรทตำแหนง localhost:5000 อกครง
รปท 7.15 ผลลพธการเขาหนาบราวเซอร ทมการกำหนด CSS Style ไว
เครองมอพฒนาพนฐานสำหรบ Android และ Arduino Accessory Development Kit (ADK) คอการพฒนาตอยอดของฮารแวรสำหรบนกพฒนามอ
สมครเลน ทใชเปนจดเรมตนในการเรยนรในการพฒนาโปรแกรมสรางสรรคตางๆ ใหสามารถเชอมตอกบอปกรณเสรมสำหรบเครองโทรศพทและแทปเลตทมระบบปฏบตการแอนดรอยดได นบเปนจดเรมตนสำคญในวงการอปกรณชนดพกพาทสามารถจะเกดการสรางสรรคสงใหมมากยงขน
ซงภายในงาน Google I/O 2011 ทางบรษทกเกลกไดเปดตว ADK รนแรก และตอมาบรษทในญ ป นช อ RT Corporation ไดพ ฒนาบอรด RT-ADK ซ งถ อว าเปนบอรด Arduino (http://www.arduino.cc) ทถกผลตออกมา โดยภายในใชไมโครคอนโทรลเลอร ATMega 2560 พรอมกบชดเซนเซอรตางๆ เพอรองรบเทคโนโลยนโดยเฉพาะ นอกจากนนจดเดนของ Arduino คอไดถกออกแบบใหสามารถขยายการเชอมตอกบบอรดโมดลอนๆ ทเรยกวาบอรด Shield เชนบอรด Ethernet Shield บอรด WIFI Shield บอรด Bluetooth Shield เปนตน
382
Embedded Android Development สเสนทางนกพฒนา
รปท 7.16 สามารถในการเชอมตออปกรณภายนอกผาน ADK และบอรด RT-ADK รนแรก
รปแบบในการตดตอสอสารจะเปนแบบ Android Open Accessory (AOA Protocol) เพอทำการตดตอสอสารกนไดกบอปกรณแอนดรอยด (Android Devices) ผานสายการเชอมตอ USB
Android Open AccessoryAndroid Open Accessory ไดถกพฒนาขนมาเพอใหอปกรณแอนดรอยดสามารถเชอมตอกบ
อปกรณภายนอกผานทาง USB ไปยง USB Host ของอปกรณภายนอก แตอปกรณภายนอกจะไมสามารถใชพลงงานไฟฟาจากอปกรณแอนดรอยดได ดงนนอปกรณภายนอกจะตองมแหลงจายพลงงานไฟฟาของตวเองและตองมระดบกระแสไมนอยกวา 500mA ทความตางศกยไฟฟา 5V เพอใหสามารถสอสารกบอปกรณแอนดรอยดได สำหรบบอรด Arduino นนนกพฒนาสามารถเขยนโปรแกรมโดยใชโปรแกรม Arduino IDE (www.arduino.cc) หรอโปรแกรม ADK2012 IDE (บรษทกเกล)
โปรแกรม ADK2012 IDEหลกจากดาวนโหลดโปรแกรม ADK2012 IDE จาก Android ADK แลวทำการตดตงลงเครอง
คอมพวเตอรเรยบรอย หนาตาของโปรแกรมจะคลาย Arduino IDE แตจะมสวนของไลบารทางดาน Us-bAccessory ทกเกลไดพฒนาเพมเตมเขามาดงแสดงในรปขางลาง ในกรณทนกพฒนาตองการลงไลบรารเพมเตมกทำไดโดยการแตกไฟลไลบรารแลวคดลอกไปใวในไดเรกทอรชอวา libraries
383
Embedded Android Development สเสนทางนกพฒนา
รปท 7.17 หนาตาโปรแกรม ADK2012 IDE
ปจจบนไดมการพฒนาบอรด Arduino ออกมาดวยกนหลายรนดงแสดงในตารางขางลาง ดงนนนกพฒนาควรทำความเขาใจรายละเอยดความสามารถของบอรดแตละรนและพฒนาโปรแกรมเพอดงเอาความสามารถมาใชงานไดอยางเตมทเพอใหเหมาะสมกบงานประยกต
ตาราง 7.1 แสดงรนตางๆของ Arduino
รนบอรด Arduinoรนบอรด Arduino
Arduino Uno Arduino BT w/ ATmega328
Arduino Duemilanove w/ ATmega328 Arduino BT w/ ATmega168
Arduino Diecimila or Duemilanove w/ ATmega 168 LilyPad Arduino USB
Arduino Nano w/ ATmega328 LilyPad Arduino w/ ATmega328
Arduino Nano w/ ATmega168 LilyPad Arduino w/ ATmega168
Arduino Mega 2560 or Mega ADK Arduino Pro or Pro Mini (5V, 16MHz) w/ ATmega328
Arduino Mega (ATmega1280) Arduino Pro or Pro Mini (5V, 16MHz) w/ ATmega168
Arduino Leonardo Arduino Pro or Pro Mini (3.3V, 8MHz) w/ ATmega328
Arduino Esplora Arduino Pro or Pro Mini (3.3V, 8MHz) w/ ATmega168
Arduino Micro Arduino NG or older w/ ATmega168
Arduino Mini w/ ATmega328 Arduino NG or older w/ ATmega8
384
Embedded Android Development สเสนทางนกพฒนา
Arduino Mini w/ ATmega168 Arduino Robot Control
Arduino Ethernet Arduino Robot Motor
Arduino Fio
รปท 7.18 ตวอยางบอรด Arduino แตละรน
หลกการทำงานของโปรแกรมภายในบอรด Arduino ดงแสดงในรปขางลาง โดยเมอบอรด Arduino เรมทำงาน ขน โคดโปรแกรมภายในฟงกชนตงคา Setup() กจะถกเรยกในครงแรก ซงสวนจะเปนการตงคาการทำงานใหกบบอรด และการกำหนดรายละเอยดการทำงานใหกบพอรตตางๆ หลงจากนน
385
Embedded Android Development สเสนทางนกพฒนา
โปรแกรมจะเขาสฟงกชนลป loop() ในขนตอนนโปรแกรมจะวนทำงานอยภายในฟงกชน loop() นไปเรอยๆจนกวาจะมคำสงใหรเซตการทำงานของบอรดใหมอกครง (Arduino Reset)
รปท 7.19 แสดงขนตอนการทำงานภายในโปรแกรม Arduino
ตวอยางการเชอมตอระหวาง Android กบ Arduino ผาน ADKคลาสสำคญภายใน ADK2012 IDE สำหรบใชในการสอสารผาน ADK ระหวางแอนดรอยดและ Ar-
duino นนไดแกคลาส AndroidAccessory ซงมรายละเอยดภายในดงนclass AndroidAccessory { private: const char *manufacturer; const char *model; const char *description; const char *version; const char *uri; const char *serial; ... int getProtocol(byte addr); void sendString(byte addr, int index, const char *str); bool switchDevice(byte addr); bool findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp); bool configureAndroid(void); public: AndroidAccessory(const char *manufacturer, const char *model, const char *description, const char *version, const char *uri, const char *serial); void powerOn(void);
386
Embedded Android Development สเสนทางนกพฒนา
bool isConnected(void); int read(void *buff, int len, unsigned int nakLimit = USB_NAK_LIMIT); int write(void *buff, int len); };
ฟงกชนหลกทจะเรยกใชภายในฟงกชน setup() เพอใชในการเปด Android Accessory คอ pow-erOn(), read() และ write() โดยทตวแปร buff นนจะใชในการเกบขอมลทตองการจะสงออกหรอรบเขามาจากฝงโปรแกรมแอนดรอยดผานทาง USB ตามขนาดความยาวของขอมล (len) ในกรณทเปนการรบสงขอมลแบบเตมความเรว (Full Speed USB) ในฟงกชน read() นนสวนของคา NAK จะเปนการบอกคาสถานะวาอปกรณทจะสงขอมลใหนนยงไมพรอมทจะสงกลบหรอยงไมมขอมลทจะสงใหในเวลาน นอกจากนนกยงถกใชในการแจงเตอนระหวางถายโอนขอมลไปยงเครองรบวาไมมขอมลทจะสงใหแลว
ตวอยางขางลางเปนการเขยนโปรแกรมเพอทำการเชอมตอ ADK แลวรบขอมลทถกสงมาจากแอนดรอยด
#include <AndroidAccessory.h> AndroidAccessory acc("Google, Inc.", "DemoKit", "DemoKit Arduino Board", "1.0", "http://www.android.com", "0000000012345678");
void Setup(){ acc.powerOn(); // สงเปดใชงาน Android Accessory } void loop(){ if (acc.isConnected()) { // อานคาทถกสงออกมาจาก Android int len = acc.read(msg, sizeof(msg), 1); } }
การเขยนโปรแกรมสวนแอนดรอยด
ในฝงของแอนดรอยดจะใชคลาสหลกไดแกคลาส UsbManager และคลาส UsbAccessory ทกเกลไดจดเตรยมไวใหเบองตนแลว โดยขนตอนแรกนกพฒนาจะตองสรางโปรเจคของแอนดรอยดขนมาแลวทำการระบการเรยกใช UsbAccessory เขาไปในไฟล AndroidManifest.xml ดงแสดงดานลาง
<application android:icon="@drawable/icon" android:label="@string/app_name" > <uses-library android:name="com.android.future.usb.accessory" /> ...
387
Embedded Android Development สเสนทางนกพฒนา
... ... </application>
โคดสวนหนงภายในโปรแกรมแอนดรอยดเพอขอเปดและเขาถงการรบสงขอมลผาน USB
// เปนการกาหนด Intent เบองตนสาหรบการดกอเวนทกรณทมการเชอมตอ ADKprivate PendingIntent mPermissionIntent;private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private UsbManager mUsbManager;private UsbAccessory mAccessory;
@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mUsbManager = UsbManager.getInstance(this); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent( ACTION_USB_PERMISSION), 0);// กาหนด filter IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);// register ใหสามารถรบ intent ได registerReceiver(mUsbReceiver, filter); setContentView(R.layout.main); textView = (TextView) findViewById(R.id.textView);}
/** Called when the activity is resumed from its paused state andimmediately after onCreate(). */@Overridepublic void onResume() { super.onResume(); if (mInputStream != null && mOutputStream != null) { return; } UsbAccessory[] accessories = mUsbManager.getAccessoryList(); UsbAccessory accessory = (accessories == null ? null : accessories[0]); if (accessory != null) {// ตรวจสอบสทธในการเรยกใชงาน Accessory if (mUsbManager.hasPermission(accessory)) { openAccessory(accessory); // สงเปดการใชงาน accessory } else { synchronized (mUsbReceiver) { if (!mPermissionRequestPending) { mUsbManager.requestPermission(accessory, mPermissionIntent); mPermissionRequestPending = true; } }}} else {
388
Embedded Android Development สเสนทางนกพฒนา
Log.d(TAG, "mAccessory is null"); }}/** เมอ Application ถกปดโปรแกรมจะทาการปด Accessory */@Overridepublic void onPause() { super.onPause(); closeAccessory();}
/** เมอปด Application จะทาการ unregister Intent */@Overridepublic void onDestroy() { super.onDestroy(); unregisterReceiver(mUsbReceiver);}
จากโคดตวอยางขางตนเปนการตรวจสอบและสงเปดโหมดการเชอมตอผาน USB ซงหากมการ
เชอมตอเขามาของบอรด Arduino ผานสาย USB กจะทำในฟงกชน openAccessory(accessory) เมอสงเปดการทำงานแลวภายในจะมการสราง Thread ขนมา เพอทำการอานขอมลทถกสงออกมาจากบอรด Arduino ดงรปขางลาง
รปท 7.20 ผลลพธการรบขอมลจากบอรด Arduino ผานพอรต USB
ตวอยางการอานและแสดงสญญาณไฟฟากลามเนอ (EMG)
รปท 7.21 แสดงภาพรวมของระบบ
สำหรบตวอยางนเปนการตรวจวดสญญาณกลามเนอทไดรบจากเซนเซอร EMG ทเชอมตอกบบอรด Ar-duino แลวถกสงขอมลตอไปยงอปกรณแอนดรอยดผานสาย USB ดวยมาตราฐาน AOA Protocol หลงจากนนจงนำมาแสดงผลในลกษณะกราฟเสน ซงมแนวทางการพฒนาดวยกน 2 สวนดงน
389
Embedded Android Development สเสนทางนกพฒนา
พฒนาสวนโปรแกรมภาษาซบนบอรด Arduino และการตอกบเซนเซอร EMG
รปท 7.22 แสดงการเชอมตอเซนเซอร EMG กบบอรด Arduino
หลกการทำงานของเซนเซอร EMG คอแผน EMG จะทำหนาทเปนสอนำไฟฟาเมอผใชขยบรางกายจะเกดสญญาณทางไฟฟาเคลอนทไปตามกลามเนอของรางกาย ดงนนแผน EMG จะทำการขยายสญญาณทางไฟฟานน ใหอยในชวงทบอรด Arduino สามารถตรวจวดไดโดยคาสญญาณทไดออกมาจะเปนคาระดบแรงดนกระแสตรงขนาดชวง 0-5 โวลท
ในสวนของบอรด Arduino จะประกอบไปดวย มสองสวนททำงานรวมกนคอ สวนแรกเปนสวนของการอานคา Analog Read Voltage (จากตวอยาง) สวนทสองเปนการเชอมตอ ADK กบอปกรณ An-droid จากนนจะทำการอานคา Analog เพอสงขอมลทอานไดผาน ADK ไปยงอปกรณ Android เพอนำขอมลไปวเคราะหตอไป
รปท 7.23 แสดงการเชอมตอเซนเซอร EMG กบบอรด Arduino
ในสวนนจะเปนการเขยนโปรแกรมบนบอรด Arduino เพอทำการเปด accessory mode แลวอานคาแรงดนทไดจากเซนเซอร EMG เมอไดขอมลกจะทำการจดขอมลในรปแบบ “E<คาทอานได>” เพอสงผาน USB ไปยงแอนดรอยดตอไป ดงตวอยางโปรแกรมขางลางน#include <Wire.h>#include <Servo.h>#include <Max3421e.h>#include <Usb.h>#include <AndroidAccessory.h>#define LED3_RED 2
390
Embedded Android Development สเสนทางนกพฒนา
#define LED3_GREEN 4#define LED3_BLUE 3#define LED2_RED 5#define LED2_GREEN 7#define LED2_BLUE 6#define LED1_RED 8#define LED1_GREEN 10#define LED1_BLUE 9
AndroidAccessory acc("Google, Inc.", "DemoKit", "DemoKit Arduino Board", "1.0", "http://www.android.com", "0000000012345678");
boolean sendData=false;void setup();void loop();
void init_leds(){ digitalWrite(LED1_RED, 1); digitalWrite(LED1_GREEN, 1); digitalWrite(LED1_BLUE, 1);
pinMode(LED1_RED, OUTPUT); pinMode(LED1_GREEN, OUTPUT); pinMode(LED1_BLUE, OUTPUT);
digitalWrite(LED2_RED, 1); digitalWrite(LED2_GREEN, 1); digitalWrite(LED2_BLUE, 1);
pinMode(LED2_RED, OUTPUT); pinMode(LED2_GREEN, OUTPUT); pinMode(LED2_BLUE, OUTPUT);
digitalWrite(LED3_RED, 1); digitalWrite(LED3_GREEN, 1); digitalWrite(LED3_BLUE, 1);
pinMode(LED3_RED, OUTPUT); pinMode(LED3_GREEN, OUTPUT); pinMode(LED3_BLUE, OUTPUT);}
byte b1, b2, b3, b4, c;int value=0;void setup(){ pinMode(0, INPUT);
391
Embedded Android Development สเสนทางนกพฒนา
Serial.begin(115200); Serial.print("\r\nStart"); init_leds(); c = 0; acc.powerOn();}
void loop(){ byte err; byte idle; static byte count = 0; byte msg[5]; long touchcount; if (acc.isConnected()) { value = analogRead(0); msg[0] = 'E'; msg[1] = value; acc.write(msg, sizeof(msg)); Serial.println("\f"); Serial.println(msg[0]); Serial.println(msg[1]); }}
พฒนาสวนโปรแกรมแอนดรอยด
สวนนเปนการเขยนโปรแกรมประยกตแอนดรอยด เพอทำการเชอมตอ ADK กบบอรด Arduino จากนนกนำขอมลมาแสดงเปนกราฟแบบเวลาจรง ในทนจะอธบายเกยวกบการสรางกราฟเบองตนเพอนำมาแสดงผลทนททรบไดขอมลจากบอรด Arduino โดยการประยกตใชไลบรารชอวา GraphView ซงสามารถสรางกราฟไดทงแบบชนดกราฟเสน และกราฟแทง
int num = 150; // จานวนของขอมลGraphViewData[] data = new GraphViewData[num];double v = 0;for (int i = 0; i < num; i++) { v += 0.2; // คานวณคาในแตละจดทจะทาการ plot กราฟ data[i] = new GraphViewData(i, Math.sin(v)); }GraphView graphView = new LineGraphView(this, "AndroidGraph");graphView.addSeries(new GraphViewSeries(data));// ตงคาของกราฟใหเรมตนทจดท 2 ใหมขนาดเทากบ 40 ชองgraphView.setViewPort(2, 40);// ตงคาใหสามารถ Scroll ไดgraphView.setScrollable(true);
392
Embedded Android Development สเสนทางนกพฒนา
graphView.setScalable(true);LinearLayout layout = (LinearLayout) findViewById(R.id.lay1);layout.addView(graphView);
// ตงคาใหกบแกน XgraphView.setHorizontalLabels(new String[] {"2 days ago", "yesterday", "today", "to-morrow"}); // ตงคาใหกบแกน YgraphView.setVerticalLabels(new String[] {"high", "middle", "low"});
ในกรณทตองการเพมเสนขอมลใหมใหทำการสราง GrapViewSeries ใหมจากนนใหทำการเพมเขาไปในการ Graph-View ทไดสรางไวแลกอนหนาเชน
// draw sin curveint num = 150;GraphViewData[] data = new GraphViewData[num];double v = 0;for (int i = 0; i < num; i++) { v += 0.2; data[i] = new GraphViewData(i, Math.sin(v));}GraphViewSeries seriesSin = new GraphViewSeries(data);// draw cos curvedata = new GraphViewData[num]; v=0; for (int i=0; i<num; i++) { v += 0.2; data[i] = new GraphViewData(i, Math.cos(v)); } GraphViewSeries seriesCos = new GraphViewSeries( data);
จากขางตนเปนตวอยางการสรางกราฟจากขอมลทม แตเนองจากการนำคา EMG มาแสดงนน
เปนการแสดงแบบเวลาจรง (Real-time) จงจำเปนจะตองใชเทคนคของแอนดรอยด เกยวกบการวนรอบเพอทำการแสดงผลกราฟทนทเมอไดรบขอมลใหมเพมเขามา โดยใช Handler และ Runnable ดงตวอยางโคดขางลาง
// โคดตวอยางดานลางจะเปนการสราง Runnable ขนมาเพอทาการสรางตวสงคาขนไปเพอทาการ plot กราฟ จากนนจะใช Handler เพอสรางลปในการวนทก 1 มลลวนาท Handler mHandler = new Handler();Runnable mTimer1;mTimer1 = new Runnable() { @Override public void run() { graph2LastXValue += 1d; exampleSeries2.appendData(new GraphViewData(graph2LastXValue, getRandom()), true); mHandler.postDelayed(this, 1); }};
393
Embedded Android Development สเสนทางนกพฒนา
เมอถงจดนจะสามารถสรางการทำงานของกราฟทมการ plot แบบ Real-time ไดตอมาจะเปนการสรางฟงกชนททำงานแบบ Async Task เพอทำการอานคาทถกสงผานมาทาง ADK ดงตวอยาง
// ฟงกชนเปดใชงาน ADK และสราง InputStream เพอเตรยมการอานขอมลprivate void openAccessory(UsbAccessory accessory) { mFileDescriptor = mUsbManager.openAccessory(accessory); if (mFileDescriptor != null) { mAccessory = accessory; FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); new receiveData().execute(); enableControls(true); } }
public class receiveData extends AsyncTask<Object, Void, Void> { @Override protected Void doInBackground(Object... params) { while (true) { // ทาการอานขอมลและเกบไวใน array Buffer ret = mInputStream.read(buffer); /* ทาการอานขอมลและเกบไว จากนนใหดงคาตวแปรดงกลาวนาไป plot กราฟ */ } }}
รปท 7.24 แสดงการเชอมตอเซนเซอร EMG กบบอรด Arduino
394
Embedded Android Development สเสนทางนกพฒนา
บทสรปและกาวตอไป...
เนอหาทงหมดของหนงสอเลมนลวนแลวไดมาจากประสบการณของผเขยนทพยายามเกบรวบรวมองคความรพนฐานทสำคญตางๆในตลอดระยะเวลาหลายสบป รวมทงยงไดแรงบนดาลใจมาจากหนงสอ Textbook เหลาน ซงไดแก Embedded Linux Primer A Practical Real World Approach, Pro Linux Embedded Systems, Building Embedded Linux Systems, Embedded Android, An-droid Native Development Kit Cookbook ททำใหผเขยนมความตงใจอยากจะทำการถายทอดออกมาใหเปนหนงสอภาษาไทยเพอนกพฒนาคนไทย ซงอยางนอยนาจะพอทจะสามารถชวยจดประกายความฝนใหกบนกพฒนาไทยใหหนมาใหความสำคญในเทคโนโลยระบบสมองกลฝงตวไดไมมากกนอย
โดยผเขยนไดรวบรวมองคความรพนฐานตงแตระบบปฏบตการลนกซ ชดเครองมอสำหรบนกพฒนา การพฒนาโปรแกรมภาษาตางๆทเกยวของ (C, C++, JAVA, Python) มมมองแตละสวนของเทคโนโลยระบบสมองกลฝงตวและรายละเอยดทางดานเทคนคทนกพฒนาควรร ซงอาจจะยงไมไดลงในรายละเอยดเชงลกมากสกเทาใด เนองจากผเขยนตองการเชอมโยงองคความรจากศาสตรดานตางๆแลวนำมาเรยบเรยงอยไวในบทแตละบทใหครบถวนมากทสดเพอใหผอานสามารถทำความเขาใจในแตละสวนไดวามสวนใดบางทเกยวของกบระบบสมองกลฝงตวและสำหรบผอานทตองการจะกาวเปนนกพฒนาทางดานระบบสมองกลฝงตวอยางจรงจงไดมโอกาสทดลองใชชดคำสงตางๆทงบนระบบปฏบตการลนกซและระบบปฏบตการแอนดรอยด รวมทงทำความเขาใจในการออกแบบพฒนาภาษาโปรแกรมใหคนเคยมากยงขน
แตกยงคงมเนอหาและรายละเอยดทางดานเทคนคสำหรบการออกแบบพฒนาระบบสมองกลฝงตวทนาสนใจอกมากโดยเฉพาะการพฒนาภายใตระบบปฏบตการลนกซแบบฝงตวและระบบปฏบตการแอนดรอยด รวมทงแนวทางการออกแบบบอรดสมองกลฝงตวสำหรบงานประยกต ทผเขยนตงใจไววาจะพยายามเรยบเรยงเพอเขยนลงในเลมถดๆไป ซงไดแก
• การพฒนาโปรแกรมเชลลสครปทขนสง• การปรบแตงลนกซเคอรเนลและตดตงโปรแกรม Open Sources• การตดตงโปรแกรมใหบรการสำหรบระบบเครอขาย เชน Web Server, File Server เปนตน• การพฒนาโปรแกรมระดบลางเพอตดตอกบระบบฮารดแวร• การพฒนาโปรแกรม Linux Kernel Module สำหรบงานประยกต• การพฒนาโปรแกรมเพอเรยกใชไลบราร Native C/C++• การพฒนาโปรแกรม Qt 5.2 สำหรบอนาคตของอปกรณชนดพกพา• การใชงานและปรบแตง Android Framework• กลไกการทำงานในระดบลางภายในระบบปฏบตการแอนดรอยดเชน Android IPC/Binder
Framework, Android Hardware Abstract Layer (HAL) เปนตน• การพฒนา Android NDK Application • การพฒนาโปรแกรมประยกตดวยบอรดสมองกลฝงตว เชน BeagleBone, BeagleBoard xM,
iMX53 QSB, PandaBoard ES, AM335x Starter Kit, ODROID-X2, RaspBerry Pi, Intel Galileo เปนตน
395
Embedded Android Development สเสนทางนกพฒนา
ประวตผเขยนผชวยศาสตราจารยวรฬห ศรบรรกษอาจารยประจำภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา
ประวตการทำงาน
2553 - ปจจบน รองคณบดฝายพฒนานสต คณะวศวกรรมศาสตร มหาวทยาลยบรพา
2553 - ปจจบน กรรมการบรหารสมาคมสมองกลฝงตวแหงประเทศไทย (TESA)
2550 - ปจจบนหวหนาหองปฏบตการวจยและพฒนาระบบสมองกลฝงตวและทฤษฏขอมลชนสง (ESTIA) ภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา
2548 - ปจจบนรองประธานหนวยวจยโลจสตกสและวศวกรรมสมองกลฝงตว (หวหนาทมวศวกรรมสมองกลฝงตว) BAL-LABS มหาวทยาลยบรพา
2550 - 2551หวหนาทมวจยและผคดคนออกแบบระบบสอสารขอมลแบบไรสายระหวางรถและสถาน RFID Sensor Network และโปรโตคอลสอสารระหวางสถาน RFID Sensor Network
และ ศนยควบคมกลาง
2549 - 2550หวหนาทมออกแบบและพฒนาระบบฮารดแวรและซอฟตแวรใหกบบรษท Endemol ผเปนเจาของรายการ Fear Factor, Survivor และ 1 versus 100
2549 - 2551 หวหนาภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา
2549 - 2552 คณะกรรมการผเชยวชาญสมาคมสมองกลฝงตวแหงประเทศไทย
2547 - 2548 รองคณบดฝายกจการพเศษ คณะวศวกรรมศาสตร มหาวทยาลยบรพา
2546 - 2547รกษาราชการแทนผชวยคณบดฝายเทคโนโลยสารสนเทศ คณะวศวกรรมศาสตร มหาวทยาลยบรพา
2544 - 2546หวหนาทม Wireless Sensor Network Team โครงการ Korea Brain Project, Korea University, Seoul, Republic of South Korea
396
Embedded Android Development สเสนทางนกพฒนา
!
รางวลทไดรบ
2555 รางวลรตนบรพา สาขาการสรางสรรคและประดษฐคดคน มหาวทยาลยบรพา
2553รางวลสงประดษฐทางวทยาศาสตรทมศกยภาพสงในการลงทน โดยสำนกงานพฒนาวทยาศาสตรและเทคโนโลยแหงชาต (NSTDA) กระทรวงวทยาศาสตร
2552รางวลนวตกรรมแหงชาตทางดานเศรษฐกจ ในชอ “ระบบเครอขายเซนเซอรไรสาย” เพอใชในการตดตามยานพาหนะแบบเรยลไทม สำนกงานนวตกรรมแหงชาต (NIA)
2552รางวลชนะเลศ การออกแบบและพฒนาผลตภณฑสมองกลฝงตวแหงประเทศไทย ประเภท Intel-ligent Transport System (ITS) and Automotive “Vehicle Identification ITS Solution” สมาคมสมองกลฝงตวแหงประเทศไทย
2549รางวลยอดเยยมในการนำเสนอแนวทางการนำสอ E-Learning มาใชทางดานการศกษา ท TIT University, ญปน
2545 Best Paper Award in Wireless Sensor Network, Korea University, Seoul, South Korea
2543 Republic of South Korea Government Scholarship Grantee
สถานททำงาน
หองปฏบตการวจยและพฒนาระบบสมองกลฝงตวและทฤษฏขอมลชนสง (ESITA) ภาควชาวศวกรรมไฟฟา คณะวศวกรรมศาสตร มหาวทยาลยบรพา ถนนลงหาดบางแสน ตาบลแสนสข อาเภอเมองชลบร จงหวดชลบร
โทรศพท 038-10-2222 ตอ 3380 โทรสาร 038-74-5806E-mail [email protected]
397
Embedded Android Development สเสนทางนกพฒนา
EMBEDDED ANDROID DEVELOPMENT
ขอแสดงความยนดในความสำเรจดานการเขยนหนงสอแลวผมจะนำความรในหนงสอไปใชใหเกดประโยชนตอศษยและตนเอง...
ขอบคณครบทไดเขยนหนงสอเลมนออกมา เพราะตอนนผมกทำทางดานนอย แตกยงไมเขาใจถองแท และในเมองไทยกยงไมคอยม ถาไดหนงสอเลมนมานำทางและผมกอยากมาประสบการณทสามารถไปถายทอดใหนองๆๆไดอกดวย ขอบคณครบ...
ขอบคณมากครบ ผมเปนคนนอกสายงานดานน (เดกชางกล) อาศยศกษาจากผรมง หนงสอมง จาก google มง หนงสอของอาจารยเลมน คงชวยใหคนนอกวงการอยางผมมโอกาศเขาใจและนำไปใชไดมากขน แนๆ ขอบคณมากๆครบ อาจารย อยากใหประเทศนมคนแบบนเยอะๆครบ
ขอบคณครบ...อยากใหอาจารยทำหนงสอด ๆ แบบนออกมาเรอย ๆ ครบ จากความคดหนงสอกความคด
หนง มนจะแตกกงออกไปเหมอนกบตนไม...สดทายแลวตนไมตนนนกจะเตบโตและใหประโยชนตอ ๆ ไป แลวผมจะนำความรในหนงสอไปใชใหเกดประโยชนตอศษยและตนเอง...
อยากใหหลายๆ คนเปนแบบนนะคะ แบงบนประสบการณการณและความรแบบทอดๆ มนทำใหรสกวา .. นอกจากจะนาชนชมในความเกงและความสำเรจของเคาแลว
ยงรสกซาบซงใจททำใหคนอกหลายๆ คนไดรบความรนน ขอบคณมากนะคะ ;) ....
ผมเคยเปนเดกใน HyperCamp และ TESA TopGun ขอชอชมผลงานของ อาจารย และ จะเดนสาย Embedded ตอครบ ...
ผมคลงไคลอาจารยตงแตแขง TopGun แลวครบ (โอเวอรมากๆๆ (>.<)) ขอบคณอาจารยมากๆครบทเขยนหนงสอดๆอยางนมาแบงปนใหไดอานครบผม ~(^_^)~ ...
ผมมความสนใจในดานนแตยงขาดความรประสบการและออนแอในดานภาษา นบเปนการเรมตนทดมากเลยครบสำหรบหนงสอเลมน หนงสอเลมเปนเหมอน
แรงบนดาลใจเลยครบ ขอบคณครบ :) ...
タイ語の Embedded Android があった、よかった。^_^
อาจารยจอมครบ ผมขอขอบคณสำหรบการเผยแพรความรทเปนประโยชนอยางมากมายนะครบ และผมจะนำความรทไดมาใชใหเกดประโยชนใหมากทสดนะครบ ^__^
ขอเปนกำลงใจใหเผยแพรบทความหรอหนงสอดๆตอไปครบ เพราะคนเราไมมใครรทกเรอง สงทคณรไมวาจะมาจากประสบการณตรงจากการทำงานหรอการขวนขวานเรยนรนนผมคดวามนตองมประโยชนกบผอนอยางแนนอนไมมากกนอย สดทายอยากจะบอกวาถาเรายงทำกยงได
ยงใหกยงม ขอบคณครบ...
ขอขอบคณสำหรบหนงสอคณภาพของผเขยน ผมมความสนใจในระบบปฏบตการณแอนดรอยดเปนอยางมาก อกทงเพอเปนการพฒนาความรดานความเขาใจในระบบสมองกลฝงตว เพอพฒนาศกยภาพของตวผมเองใหเปนนกพฒนาทดในอนาคต ขอขอบคณผเขยนเปนอยางมากครบ...
ผมพยายามจะศกษามานาน ดวยอายเยอะ และภาษาองกฤษไมคอยด มหนงสอภาษาไทยมาใหอานนบวาเปนความกรณาตอผมมากๆ ขอใหทานผจดทำไดรบการตอบแทนสงดๆ จากพระผเปนเจา...
หนงในหลายๆกำลงใจถงนกเขยน จากผอาน 1,500 ทานแรก