The current directory mainly contains some common tool implementations provided by the framework.
Tool | Brief description of tool |
---|---|
kvdb |
Key-value pair data access interface based on local database. |
log |
Provides an Log API interface compatible with the Android platform.Used to directly use the Android LOG API in openvela . |
trace |
Provides a dotting tool for user-space programs. |
kvdb
provides a set of local database read and write interfaces. The API
design refers to the properties
access specification of Android
, and also provides command line tools to facilitate local quick debugging.
kvdb
in openvela
supports local persistent storage and cross-core calls (requires Unix domain socket and rpmsg socket support respectively). The key value that needs to be permanently stored in the file needs to start with "persist."
.
kvdb
underlying implementation includes three mechanisms:
-
Based on the open source
UnQLite
database, dependent on the database. -
Based on
MTD CONFIG
(currently only used for nor flash). -
The last one is based on
file
files.
kvdb
interface description: frameworks/utils/include/kvdb.h
kvdb configuration | Description |
---|---|
CONFIG_KVDB_PRIORITY | KVDB task priority, defaults to system default |
CONFIG_KVDB_STACKSIZE | KVDB stack space allocation, defaults to system default |
CONFIG_KVDB_SERVER | KVDB SERVER mode: indicates whether the current CPU is the main CPU for reading and writing files, if it is n, only KVDB on other CPUs is called |
CONFIG_KVDB_DIRECT | KVDB DIRECT mode: This mode can be used in scenarios where rpmsg socket is not required (no need for cross-core) CONFIG_KVDB_DIRECT and CONFIG_KVDB_SERVER can only be selected from the two modes |
CONFIG_KVDB_COMMIT_INTERVAL | KVDB commit interval (seconds), default is 5 KVDB has internal cache, and the data is actually written to the file only after committing. If the power is turned off before CONFIG_KVDB_COMMIT_INTERVAL time after committing the persist type kv, the data will not be actually written to the persist.db file. The shorter the CONFIG_KVDB_COMMIT_INTERVAL time is set, the more frequently kvdb writes the internal cache to the file, which will affect the system performance to a certain extent. |
CONFIG_KVDB_SOURCE_PATH | KVDB default value loading path, the default is "/etc/build.prop" , supports multiple paths, separated by ; , and the KV value will be automatically loaded from this file every time the computer starts. |
CONFIG_KVDB_UNQLITE | Configure to use unqlite database to store kv |
CONFIG_KVDB_NVS | Configure to use nvs to store kv |
CONFIG_KVDB_FILE | Configure to use file to store kv |
Only one of the three data storage
backend
sCONFIG_KVDB_UNQLITE
,CONFIG_KVDB_NVS
, andCONFIG_KVDB_FILE
can be selected.
The log module itself is a wrapper layer, which encapsulates the openvela log
system at the bottom layer. The encapsulated API is consistent with the log API
in Android. When we port the Android
application or framework to openvela
, we do not need to provide our own log
connection, and can directly use the current module.
The following is the structure of the log module:
android log api
|
\|/
log wrapper
|
\|/
vela log impl
This module mainly contains the dot analysis tool for user space programs. We can implement dot analysis by manually inserting stubs in user programs. The atrace tool provided in trace is mainly used in conjunction with the dot analysis tool provided by the openvela system.
kvdb
itself has multiple usage forms. We can integrate it directly in the code, or use it directly in nsh
as a command line program.
The following is a demo of the interface provided by kvdb
to monitor key/value
changes. Two sets of APIs are provided for simple and complex scenarios:
-
Simple scenario: Only one
key
can be monitored.int main(void) { char newkey[PROPERTY_KEY_MAX]; char newvalue[PROPERTY_VALUE_MAX]; int ret = property_wait("tsetkey", newkey, newvalue, -1); if (ret < 0) { printf("property_wait failed, ret=%d\n", ret); goto out; } printf("the new key: %s\n", newkey); printf("the new value: %s\n", newvalue); out: return ret; }
-
Complex scenarios: Supports
poll
, allowing users to freely monitor multiplekeys
.int main(void) { struct pollfd fds[2]; char newkey[PROPERTY_KEY_MAX]; char newvalue[PROPERTY_VALUE_MAX]; int fd1 = property_monitor_open("monitorkey*"); int fd2 = property_monitor_open("testkey"); fds[0].fd = fd1; fds[0].events = POLLIN; fds[1].fd = fd2; fds[1].events = POLLIN; int ret= poll(fds, 2, -1); if (ret <= 0) goto out; for (int i = 0; i < 2; i++) { if ((fds[i].revents & POLLIN) == 0) continue; ret = property_monitor_read(fds[i].fd, newkey, newvalue); if (ret < 0) goto out; printf("the new key: %s\n", newkey); printf("the new value: %s\n", newvalue); } out: property_monitor_close(fd1); property_monitor_close(fd2); return ret; }
KVDB provides two command line programs, getprop
and setprop
, for users to use. Users can use getprop
and setprop
to easily view existing KVs or set new KVs.
These two command lines are enabled by default after KVDB is enabled.
- getprop: print out the set property
- nsh> getprop: list all current
props
- nsh> getprop
key
: print out theprop
corresponding tokey
- setprop: set or delete property
- nsh> setprop
key
: delete theprop
corresponding tokey
- nsh> setprop
key
value
: savekey
:value
to the database
Here are specific usage examples:
nsh> setprop name peter # add a key-value pair named name with a value of peter, which disappears when the power is off
nsh> setprop persist.name1 peter1 # add a key-value pair named name1 with a value of peter1, which does not disappear when the power is off
nsh> getprop # view all key-value pairs
name: peter
nsh> setprop name # delete a key-value pair named name
nsh> getprop name
-
Enable
CONFIG_ANDROID_LIBBASE
. -
Use the standard Android log API to collect and print logs directly in the program.
#include <log/log.h> // the tag for the ALOGI #define LOG_TAG "MyAppTag" int main() { // print log with custom priority level __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Formatted number: %d", 42); // Using ALOGI macro to print info level log ALOGI("ALOGI: A log message from my app."); return 0; }
-
To enable the
CONFIG_SCHED_INSTRUMENTATION_DUMP
andCONFIG_ATRACE
build options -
Add the instrumentation point in the program:
// define the tag for tracing #define ATRACE_TAG ATRACE_TAG_ALWAYS #include <cutils/trace.h> int main(int argc, char *argv[]) { // instrument the current function ATRACE_BEGIN("hello_main"); sleep(1); ATRACE_INSTANT("printf"); printf("hello world!"); // end instrumentation ATRACE_END(); return 0; }
-
Show the instrumentation result with
trace dump
tool:hello-7 [0] 3.187400000: sched_wakeup_new: comm=hello pid=7 target_cpu=0 hello-7 [0] 3.187400000: tracing_mark_write: B|7|hello_main hello-7 [0] 4.197700000: tracing_mark_write: I|7|printf hello-7 [0] 4.187700000: tracing_mark_write: E|7|hello_main
In addition, the output result of atrace can also directly use the perfetto tool to view the timing diagram of the trace in a visual form.