Saturday, December 6, 2014

[Book Review] Embedded Android

Embedded Android by Karim Yaghmour

The book starts with introduction chapter about the Android ecosystem and code licenses that are useful to know when developing a product that is going to be shipped.
The second chapter starts to explore the tools and the requirements you need to build the Android Open Source Project (AOSP) on your machine. The book then explains the Android concept from an app developer point of view describing also the lifecycle of the applications. The discussion then moves to the Android SDK and NDK as well as the linux kernel used by android and the related discussions about porting the modifications to the streamline kernel. Those paragraphs are really small and can be used as a starting point for reference and further investigation. From the linux kernel the author goes into deeper detail about the changes that Android introduced into the kernel and how to access the hardware APIs for each component of the system. It's worth mentioning that the author also describes differences for the various version of Android and the current edition covers up to Jelly Bean (Android 4.2). The boot process is then described together with the services that the kernel will start at boot time and the toolbox available on the target platform; the chapter is concluded with a discussion about the JNI and how the applications interacts with the services and system functions. Through this chapter you can find lots of tables and pictures explaining the relations within the components, libraries present on the system, services and so on.
The third chapter starts to get more practical. It will begin explaining how to obtain the AOSP source code and the tools needed to build it. The source code is decomposed in its main components and described before actually explain how to build it. At the end of the build process the created image is used to run on the android emulator. A paragraph explains how to run it and described all the options to master the emulator. Concluding this chapter there is a paragraph about the ADB (Android Debugger Bridge) tool that allows to retrieve information about the running system, execute commands, debugging and so on.
The forth chapter is about the build system. In this chapter the author explains in great detail how the build system works and how to modify it to do what you need. The chapter explores both the how to build and how to add your own modification such as libraries, tools, devices, etc to the produced AOSP image.
The fifth chapter moves to the hardware part of an embedded system. This chapter is more a description of what an embedded system and SOCs are and what are the main components of it.
The sixth chapter starts describing the native user-space system. The initial part of the chapter gives a overview of the filesystem and how it is structured. Most of the folders are described focusing on the ones mainly used by the applications. The chapter continues with some more commands for the ADB tool with attention to logging, remote debugging, filesystem operation and root access. After showing and exploring all the commands that are available from the adb shell,the init process for the user space application is described and explored to allow modification to it.
The seventh chapter talks about the Android Framework. The Android framework is the set of libraries and functionalities that are provided by AOSP after it has been built. The zygote and System services such as SurfaceFlinger. The discussion continues describing the apps that start to execute after the initialization process is near is end. A list of useful utility commands is also provided and a description of daemons supporting the system services is then provided.

Overall I found this book a really good reference for building and debugging android on an embedded system. Clear language and a lot of figures and tables to look complete the text providing a single reference for most of the questions related to the Android runtime and how to debug it. It also provides a lot of references to cover the topics that are not part of the book such as the SDK and NDK. 

Friday, July 12, 2013

Tip: enter the mindset of tracking bugs

Having a good tracking of bugs helps a lot. People can easily search for previous bugs, help other people commenting the possible causes and have a clear understanding of the support workforce needed to solve the issues.

Tip: TEST YOUR CODE!!!

Unfortunately, not everybody tests his/her code. Testing is fundamental to facilitate debugging and quality check of you software. No matter what is the dimension of the companies, there are simple step you should always have in your workflow:

-Precommit test: small subset of test that check the main functionalities of your software. It has to compile your code with all the possible configuration allowed to be used but the complete execution should not be longer than 30 minutes.
-Nightly test: bigger subset to run it in the night
-Weekendly test: typically an huge set of tests are run here to stress your code.

It's important also that all the main branches that are going to be released are covered by this tests.

Tip: Compare different branches

If you work in a company with a structured workflow and source control, you can really helpful to compare different branches of the same project between them. Happen to me that I spent 3-4 days working on a test issue that turn out to be solved in the main branch of development. So compare the failing code with another one, or previous revision if the failure appeared only recently, can be a good starting point.

Tip: Don't trust your assumptions

Everybody have assumptions and most of the time we think that those are satisfied. But sometimes that's not true and double-check them is always a good step if the problem seems to rely on magic (but magic doesn't exists)

Wednesday, July 3, 2013

Tip: we are not alone

This is a technical tip that can help when we join a project and something goes wrong but all the code seems clear. Happen to me ones that I was executing two print of the same variable within a distance of few lines and no line was modifing this variable. While I was expecting the print to be the same, I was continuosly get two different values. I spent a lot of time trying to find if was a memory corruption but in the end the issue was due to thread scheduling that overwrites the variable. When we debug, we can have the impression that a single thread is present, but most of the time is not. Even worse if when (as in this example), debugging the program will make the issue disappear due to changing in timing. So basically, if you suspect that multiple threads can run because you don't know perfectly the code, it's always a good idea to instrument your debugging printf with the thread id of the process. In this way you will see more clearly which thread is writing on the console making you understand better how the threads are scheduled.

Tip: Explain to others your finding

The first tip is a general tip that applies to mostly every field where you need to solve a problem. Basically sometime you really need to explain the ideas of a possible solution to someone to really understand it yourself. This can also work using writing but of course the colleague can give you also useful input and ideas. This helps mostly people that like me have a general picture of the whole system but with a not clear knowledge of the specific code we are working on due to inexperience with that code. People that like me prefer a picture rather then a text explaination tend to use more the side of the brain typically used for artistic and visual skills. Unfortunately programming is not a visual rappresentation of an algorithm but a sequence of logic steps. Forcing yourself to explain or write down what's happening in the system helps to convert the wide but opaque visual image you have in your brain to a more specific logical view where all the connection between elements gets explained. It will be like seeing a painting from the distance and discover that is actually a mosaic when we move near to it, where small pieces are connected together to form a single shape.