提交 47eaee0f 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 8c2a54a2
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
- [Exception Debugging](kernel-mini-memory-exception.md) - [Exception Debugging](kernel-mini-memory-exception.md)
- [Trace](kernel-mini-memory-trace.md) - [Trace](kernel-mini-memory-trace.md)
- [LMS](kernel-mini-memory-lms.md) - [LMS](kernel-mini-memory-lms.md)
- [Shell](kernel-mini-debug-shell.md)
- Appendix - Appendix
- [Kernel Coding Specification](kernel-mini-appx-code.md) - [Kernel Coding Specification](kernel-mini-appx-code.md)
- [Standard Libraries](kernel-mini-appx-lib.md) - [Standard Libraries](kernel-mini-appx-lib.md)
...@@ -135,7 +136,7 @@ ...@@ -135,7 +136,7 @@
- [Magic Key](kernel-small-debug-shell-magickey.md) - [Magic Key](kernel-small-debug-shell-magickey.md)
- [User-Space Exception Information](kernel-small-debug-shell-error.md) - [User-Space Exception Information](kernel-small-debug-shell-error.md)
- [Trace](kernel-small-debug-trace.md) - [Trace](kernel-small-debug-trace.md)
- [Perf](kernel-mini-memory-perf.md) - [Perf](kernel-small-debug-perf.md)
- [LMS](kernel-small-memory-lms.md) - [LMS](kernel-small-memory-lms.md)
- [Process Debugging](kernel-small-debug-process-cpu.md) - [Process Debugging](kernel-small-debug-process-cpu.md)
- Kernel-Mode Memory Debugging - Kernel-Mode Memory Debugging
......
...@@ -196,14 +196,14 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -196,14 +196,14 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
#### Available APIs #### Available APIs
**Table 1** APIs for process management **Table 11** APIs for process management
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| \#include &lt;stdlib.h&gt; | void abort(void); | Terminates the thread.| | \#include &lt;stdlib.h&gt; | void abort(void); | Terminates the thread.|
| \#include &lt;assert.h&gt; | void assert(scalar expression); | Terminates the thread if the assertion is false.| | \#include &lt;assert.h&gt; | void assert(scalar expression); | Terminates the thread if the assertion is false.|
| \#include &lt;pthread.h&gt; | int pthread_cond_destroy(pthread_cond_t *cond); | Destroys a condition variable.| | \#include &lt;pthread.h&gt; | int pthread_cond_destroy(pthread_cond_t \*cond); | Destroys a condition variable.|
| \#include &lt;pthread.h&gt; | int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t \*restrict attr); | Initializes a condition variable.| | \#include &lt;pthread.h&gt; | int pthread_cond_init(pthread_cond_t \*restrict cond, const pthread_condattr_t \*restrict attr); | Initializes a condition variable.|
| \#include &lt;pthread.h&gt; | int pthread_cond_timedwait(pthread_cond_t \*restrict cond, pthread_mutex_t \*restrict mutex, const struct timespec \*restrict abstime); | Waits for the condition.| | \#include &lt;pthread.h&gt; | int pthread_cond_timedwait(pthread_cond_t \*restrict cond, pthread_mutex_t \*restrict mutex, const struct timespec \*restrict abstime); | Waits for the condition.|
| \#include &lt;pthread.h&gt; | int pthread_condattr_init(pthread_condattr_t \*attr); | Initializes the condition variable attribute.| | \#include &lt;pthread.h&gt; | int pthread_condattr_init(pthread_condattr_t \*attr); | Initializes the condition variable attribute.|
| \#include &lt;pthread.h&gt; | int pthread_mutex_unlock(pthread_mutex_t \*mutex); | Unlocks a mutex.| | \#include &lt;pthread.h&gt; | int pthread_mutex_unlock(pthread_mutex_t \*mutex); | Unlocks a mutex.|
...@@ -212,13 +212,13 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -212,13 +212,13 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;pthread.h&gt; | pthread_t pthread_self(void); | Obtains the ID of the current thread.| | \#include &lt;pthread.h&gt; | pthread_t pthread_self(void); | Obtains the ID of the current thread.|
| \#include &lt;pthread.h&gt; | int pthread_getschedparam(pthread_t thread, int \*policy, struct sched_param \*param); | Obtains the scheduling policy and parameters of a thread.| | \#include &lt;pthread.h&gt; | int pthread_getschedparam(pthread_t thread, int \*policy, struct sched_param \*param); | Obtains the scheduling policy and parameters of a thread.|
| \#include &lt;pthread.h&gt; | int pthread_setschedparam(pthread_t thread, intpolicy, const struct sched_param \*param); | Sets a scheduling policy and parameters for a thread.| | \#include &lt;pthread.h&gt; | int pthread_setschedparam(pthread_t thread, intpolicy, const struct sched_param \*param); | Sets a scheduling policy and parameters for a thread.|
| \#include &lt;pthread.h&gt; | int pthread_mutex_init(pthread_mutex_t \* &#95;&#95;restrict m, const pthread_mutexattr_t \*__restrict a); | Initializes a mutex.| | \#include &lt;pthread.h&gt; | int pthread_mutex_init(pthread_mutex_t *\_restrict m, const pthread_mutexattr_t \*__restrict a); | Initializes a mutex.|
| \#include &lt;pthread.h&gt; | int pthread_mutex_lock(pthread_mutex_t \*m); | Locks a mutex.| | \#include &lt;pthread.h&gt; | int pthread_mutex_lock(pthread_mutex_t \*m); | Locks a mutex.|
| \#include &lt;pthread.h&gt; | int pthread_mutex_trylock(pthread_mutex_t \*m); | Attempts to lock a mutex.| | \#include &lt;pthread.h&gt; | int pthread_mutex_trylock(pthread_mutex_t \*m); | Attempts to lock a mutex.|
| \#include &lt;pthread.h&gt; | int pthread_mutex_destroy(pthread_mutex_t \*m); | Destroys a mutex.| | \#include &lt;pthread.h&gt; | int pthread_mutex_destroy(pthread_mutex_t \*m); | Destroys a mutex.|
| \#include &lt;pthread.h&gt; | int pthread_attr_init(pthread_attr_t \*attr); | Initializes a thread attribute object.| | \#include &lt;pthread.h&gt; | int pthread_attr_init(pthread_attr_t \*attr); | Initializes a thread attribute object.|
| \#include &lt;pthread.h&gt; | int pthread_attr_destroy(pthread_attr_t \*attr); | Destroys a thread attribute object.| | \#include &lt;pthread.h&gt; | int pthread_attr_destroy(pthread_attr_t \*attr); | Destroys a thread attribute object.|
| \#include &lt;pthread.h&gt; | int pthread_attr_getstacksize(const&nbsp;pthread_attr_t&nbsp;\*attr,&nbsp;size_t&nbsp;\*stacksize); | Obtains the stack size of a thread attribute object.| | \#include &lt;pthread.h&gt; | int pthread_attr_getstacksize(const pthread_attr*t \*attr, size*t \*stacksize); | Obtains the stack size of a thread attribute object.|
| \#include &lt;pthread.h&gt; | int pthread_attr_setstacksize(pthread_attr_t \*attr, size_t stacksize); | Sets the stack size for a thread attribute object.| | \#include &lt;pthread.h&gt; | int pthread_attr_setstacksize(pthread_attr_t \*attr, size_t stacksize); | Sets the stack size for a thread attribute object.|
| \#include &lt;pthread.h&gt; | int pthread_attr_getschedparam(const pthread_attr_t \*attr, struct sched_param \*param); | Obtains scheduling parameter attributes of a thread attribute object.| | \#include &lt;pthread.h&gt; | int pthread_attr_getschedparam(const pthread_attr_t \*attr, struct sched_param \*param); | Obtains scheduling parameter attributes of a thread attribute object.|
| \#include &lt;pthread.h&gt; | int pthread_attr_setschedparam(pthread_attr_t \*attr, const struct sched_param \*param); | Sets scheduling parameter attributes for a thread attribute object.| | \#include &lt;pthread.h&gt; | int pthread_attr_setschedparam(pthread_attr_t \*attr, const struct sched_param \*param); | Sets scheduling parameter attributes for a thread attribute object.|
...@@ -226,9 +226,9 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -226,9 +226,9 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;pthread.h&gt; | int pthread_setname_np(pthread_t pthread, constchar \*name); | Sets the thread name.| | \#include &lt;pthread.h&gt; | int pthread_setname_np(pthread_t pthread, constchar \*name); | Sets the thread name.|
| \#include &lt;pthread.h&gt; | int pthread_cond_broadcast(pthread_cond_t \*c); | Unblocks all threads that are currently blocked on the condition variable **cond**.| | \#include &lt;pthread.h&gt; | int pthread_cond_broadcast(pthread_cond_t \*c); | Unblocks all threads that are currently blocked on the condition variable **cond**.|
| \#include &lt;pthread.h&gt; | int pthread_cond_signal(pthread_cond_t \*c); | Unblocks a thread.| | \#include &lt;pthread.h&gt; | int pthread_cond_signal(pthread_cond_t \*c); | Unblocks a thread.|
| \#include &lt;pthread.h&gt; | int pthread_cond_wait(pthread_cond_t \*__restrictc, pthread_mutex_t \*__restrict m); | Waits for the condition.| | \#include &lt;pthread.h&gt; | int pthread_cond_wait(pthread_cond_t *\__restrictc, pthread_mutex_t \*__restrict m); | Waits for the condition.|
**Table 2** APIs for file system management **Table 12** APIs for file system management
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -250,7 +250,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -250,7 +250,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;sys/stat.h&gt; | int fstat(int fd, struct stat \*buf); | Obtains file status.| | \#include &lt;sys/stat.h&gt; | int fstat(int fd, struct stat \*buf); | Obtains file status.|
| \#include &lt;sys/statfs.h&gt; | int statfs(const char \*path, struct statfs \*buf); | Obtains the file system information for a file in a specified path.| | \#include &lt;sys/statfs.h&gt; | int statfs(const char \*path, struct statfs \*buf); | Obtains the file system information for a file in a specified path.|
**Table 3** APIs for time management **Table 13** APIs for time management
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -265,19 +265,19 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -265,19 +265,19 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;unistd.h&gt; | int usleep(useconds_t usec); | Goes to hibernation, in microseconds.| | \#include &lt;unistd.h&gt; | int usleep(useconds_t usec); | Goes to hibernation, in microseconds.|
| \#include &lt;time.h&gt; | int nanosleep(const struct timespec \*tspec1, structtimespec \*tspec2); | Suspends the current thread till the specified time.| | \#include &lt;time.h&gt; | int nanosleep(const struct timespec \*tspec1, structtimespec \*tspec2); | Suspends the current thread till the specified time.|
| \#include &lt;time.h&gt; | int clock_gettime(clockid_t id, struct timespec \*tspec); | Obtains the clock time.| | \#include &lt;time.h&gt; | int clock_gettime(clockid_t id, struct timespec \*tspec); | Obtains the clock time.|
| \#include &lt;time.h&gt; | int timer_create(clockid_t id, struct sigevent \*__restrict evp, timer_t \*__restrict t); | Creates a timer for a thread.| | \#include &lt;time.h&gt; | int timer_create(clockid_t id, struct sigevent *\__restrict evp, timer_t \*__restrict t); | Creates a timer for a thread.|
| \#include &lt;time.h&gt; | int timer_delete(timer_t t); | Deletes the timer for a thread.| | \#include &lt;time.h&gt; | int timer_delete(timer_t t); | Deletes the timer for a thread.|
| \#include &lt;time.h&gt; | int timer_settime(timer_t t, int flags, const structitimerspec \*__restrict val, struct itimerspec \*__restrict old); | Sets a timer for a thread.| | \#include &lt;time.h&gt; | int timer_settime(timer_t t, int flags, const struct itimerspec *\__restrict val, struct itimerspec \*_restrict old); | Sets a timer for a thread.|
| \#include &lt;time.h&gt; | time_t time (time_t \*t); | Obtains the time.| | \#include &lt;time.h&gt; | time_t time (time_t \*t); | Obtains the time.|
| \#include &lt;time.h&gt; | char \*strptime(const char \*s, const char \*format, struct tm \*tm); | Converts the time string into the time **tm** structure.| | \#include &lt;time.h&gt; | char \*strptime(const char \*s, const char \*format, struct tm \*tm); | Converts the time string into the time **tm** structure.|
**Table 4** APIs for util **Table 14** APIs for util
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| \#include &lt;stdlib.h&gt; | int atoi(const char \*nptr); | Converts the string pointed to by **nptr** into an integer (**int** type).| | \#include &lt;stdlib.h&gt; | int atoi(const char \*nptr); | Converts a string into an integer (**int** type).|
| \#include &lt;stdlib.h&gt; | long atol(const char \*nptr); | Converts the string pointed to by **nptr** into a long Integer (long type).| | \#include &lt;stdlib.h&gt; | long atol(const char \*nptr); | Converts the string into a long Integer (**long** type).|
| \#include &lt;stdlib.h&gt; | long long atoll(const char \*nptr); | Converts the string pointed to by **nptr** into a long long Integer (long long type).| | \#include &lt;stdlib.h&gt; | long long atoll(const char \*nptr); | Converts a string into a long longer integer (**long long** type).|
| \#include &lt;ctype.h&gt; | int isalnum(int c); | Checks whether the passed character is alphanumeric.| | \#include &lt;ctype.h&gt; | int isalnum(int c); | Checks whether the passed character is alphanumeric.|
| \#include &lt;ctype.h&gt; | int isascii(int c); | Checks whether the passed character is an ASCII character.| | \#include &lt;ctype.h&gt; | int isascii(int c); | Checks whether the passed character is an ASCII character.|
| \#include &lt;ctype.h&gt; | int isdigit(int c); | Checks whether the passed character is a digit.| | \#include &lt;ctype.h&gt; | int isdigit(int c); | Checks whether the passed character is a digit.|
...@@ -302,17 +302,17 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -302,17 +302,17 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;strings.h&gt; | int strncasecmp(const char \*s1, const char \*s2, size_t n); | Compares the bytes of the specified length in two strings, ignoring case.| | \#include &lt;strings.h&gt; | int strncasecmp(const char \*s1, const char \*s2, size_t n); | Compares the bytes of the specified length in two strings, ignoring case.|
| \#include &lt;strings.h&gt; | int strcasecmp(const char \*s1, const char \*s2); | Compares two strings, ignoring case.| | \#include &lt;strings.h&gt; | int strcasecmp(const char \*s1, const char \*s2); | Compares two strings, ignoring case.|
| \#include &lt;string.h&gt; | int strncmp(const char \*s1, const char \*s2, size_t n); | Compares the bytes of the specified length in two strings.| | \#include &lt;string.h&gt; | int strncmp(const char \*s1, const char \*s2, size_t n); | Compares the bytes of the specified length in two strings.|
| \#include &lt;string.h&gt; | char \*strrchr(const char \*s, int c); | Searches for the last occurrence of a character in a string.| | \#include &lt;string.h&gt; | char \*strrchr(const char \*s, int c); | Searches for a character in a string.|
| \#include &lt;string.h&gt; | char \*strstr(const char \*haystack, const char \*needle); | Searches for the specified substring in a string.| | \#include &lt;string.h&gt; | char \*strstr(const char \*haystack, const char \*needle); | Searches for the specified substring in a string.|
| \#include &lt;stdlib.h&gt; | long int strtol(const char \*nptr, char \*\*endptr, int base); | Converts the string pointed to by **nptr** into a **long int** value according to the given **base**.| | \#include &lt;stdlib.h&gt; | long int strtol(const char \*nptr, char \*\*endptr, int base); | Converts the string pointed to by **nptr** into a **long int** value according to the given **base**.|
| \#include &lt;stdlib.h&gt; | unsigned long int strtoul(const char \*nptr, char\*\*endptr, int base); | Converts the string pointed to by **nptr** into an unsigned long integer.| | \#include &lt;stdlib.h&gt; | unsigned long int strtoul(const char \*nptr, char\*\*endptr, int base); | Converts a string into an unsigned long integer.|
| \#include &lt;stdlib.h&gt; | unsigned long long int strtoull(const char \*nptr,char \*\*endptr, int base); | Converts the string pointed to by **nptr** into an unsigned long long integer.| | \#include &lt;stdlib.h&gt; | unsigned long long int strtoull(const char \*nptr,char \*\*endptr,int base); | Converts a string into an unsigned long long integer.|
| \#include &lt;regex.h&gt; | int regcomp(regex_t \*preg, const char \*regex,int cflags); | Compiles a regular expression.| | \#include &lt;regex.h&gt; | int regcomp(regex_t \*preg, const char \*regex,int cflags); | Compiles a regular expression.|
| \#include &lt;regex.h&gt; | int regexec(const regex_t \*preg, const char \*string, size_t nmatch, regmatch_t pmatch[], int eflags); | Executes the compiled regular expression.| | \#include &lt;regex.h&gt; | int regexec(const regex_t \*preg, const char \*string, size_t nmatch, regmatch_t pmatch[], int eflags); | Executes the compiled regular expression.|
| \#include &lt;regex.h&gt; | void regfree(regex_t \*preg); | Releases the regular expression.| | \#include &lt;regex.h&gt; | void regfree(regex_t \*preg); | Releases the regular expression.|
| \#include &lt;string.h&gt; | char \*strerror(int errnum); | Obtains an error message string of the specified error code.| | \#include &lt;string.h&gt; | char \*strerror(int errnum); | Obtains an error message string of the specified error code.|
**Table 5** APIs for math operations **Table 15** APIs for math operations
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -322,7 +322,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -322,7 +322,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;math.h&gt; | double round(double x); | Rounds off the value from zero to the nearest integer.| | \#include &lt;math.h&gt; | double round(double x); | Rounds off the value from zero to the nearest integer.|
| \#include &lt;math.h&gt; | double sqrt(double x); | Obtains the square root of **x**.| | \#include &lt;math.h&gt; | double sqrt(double x); | Obtains the square root of **x**.|
**Table 6** APIs for I/O operations **Table 16** APIs for I/O operations
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -335,16 +335,16 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -335,16 +335,16 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;stdio.h&gt; | int fileno(FILE \*stream); | Obtains the file descriptor for a stream.| | \#include &lt;stdio.h&gt; | int fileno(FILE \*stream); | Obtains the file descriptor for a stream.|
| \#include &lt;stdio.h&gt; | FILE \*fopen(const char \*path, const char \*mode); | Opens a stream.| | \#include &lt;stdio.h&gt; | FILE \*fopen(const char \*path, const char \*mode); | Opens a stream.|
| \#include &lt;stdio.h&gt; | int fputs(const char \*s, FILE \*stream); | Writes a line to the specified stream.| | \#include &lt;stdio.h&gt; | int fputs(const char \*s, FILE \*stream); | Writes a line to the specified stream.|
| \#include &lt;stdio.h&gt; | size_t fread(void \*ptr, size_t size, size_t nmemb,FILE \*stream); | Reads a stream.| | \#include &lt;stdio.h&gt; | size_t fread(void \*ptr, size_t size, size_t nmemb, FILE \*stream); | Reads a stream.|
| \#include &lt;stdio.h&gt; | int fseek(FILE \*stream, long offset, int whence); | Sets the position of the stream pointer.| | \#include &lt;stdio.h&gt; | int fseek(FILE \*stream, long offset, int whence); | Sets the position of the stream pointer.|
| \#include &lt;stdio.h&gt; | long ftell(FILE \*stream); | Obtains the position of the stream pointer.| | \#include &lt;stdio.h&gt; | long ftell(FILE \*stream); | Obtains the position of the stream pointer.|
| \#include &lt;stdio.h&gt; | size_t fwrite(const void \*ptr, size_t size, size_tnmemb,FILE \*stream); | Writes data to a stream.| | \#include &lt;stdio.h&gt; | size_t fwrite(const void \*ptr, size_t size, size_tnmemb, FILE \*stream); | Writes data to a stream.|
| \#include &lt;stdio.h&gt; | void perror(const char \*s); | Prints system error information.| | \#include &lt;stdio.h&gt; | void perror(const char \*s); | Prints system error information.|
| \#include &lt;stdio.h&gt; | void rewind(FILE \*stream); | Sets the position to the beginning of the file of the specified stream.| | \#include &lt;stdio.h&gt; | void rewind(FILE \*stream); | Sets the position to the beginning of the file of the specified stream.|
| \#include &lt;unistd.h&gt; | ssize_t write(int fd, const void \*buf, size_t size); | Writes data a file.| | \#include &lt;unistd.h&gt; | ssize_t write(int fd, const void \*buf, size_t size); | Writes data a file.|
| \#include &lt;unistd.h&gt; | ssize_t read(int fd, void \*buf, size_t size); | Reads data from a file.| | \#include &lt;unistd.h&gt; | ssize_t read(int fd, void \*buf, size_t size); | Reads data from a file.|
**Table 7** APIs for network **Table 17** APIs for network
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -363,7 +363,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -363,7 +363,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;sys/socket.h&gt; | ssize_t sendto(int sockfd, const void \*buf, size_t len, intflags,const struct sockaddr \*dest_addr, socklen_t addrlen); | Sends a message on a socket.| | \#include &lt;sys/socket.h&gt; | ssize_t sendto(int sockfd, const void \*buf, size_t len, intflags,const struct sockaddr \*dest_addr, socklen_t addrlen); | Sends a message on a socket.|
| \#include &lt;sys/socket.h&gt; | int setsockopt(int sockfd, int level, int optname,constvoid \*optval, socklen_t optlen); | Sets options associated with a socket.| | \#include &lt;sys/socket.h&gt; | int setsockopt(int sockfd, int level, int optname,constvoid \*optval, socklen_t optlen); | Sets options associated with a socket.|
**Table 8** APIs for memory management **Table 18** APIs for memory management
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -374,7 +374,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -374,7 +374,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;stdlib.h&gt; | void \*malloc(size_t size); | Dynamically allocates memory blocks.| | \#include &lt;stdlib.h&gt; | void \*malloc(size_t size); | Dynamically allocates memory blocks.|
| \#include &lt;stdlib.h&gt; | void free(void \*ptr); | Release the memory space pointed to by **ptr**.| | \#include &lt;stdlib.h&gt; | void free(void \*ptr); | Release the memory space pointed to by **ptr**.|
**Table 9** APIs for IPC **Table 19** APIs for IPC
| Header File| API| Description| | Header File| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
...@@ -386,11 +386,11 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an ...@@ -386,11 +386,11 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs an
| \#include &lt;mqueue.h&gt; | mqd_t mq_open(const char \*mqName, int openFlag, ...); | Opens an existing message queue with the specified name or creates a message queue.| | \#include &lt;mqueue.h&gt; | mqd_t mq_open(const char \*mqName, int openFlag, ...); | Opens an existing message queue with the specified name or creates a message queue.|
| \#include &lt;mqueue.h&gt; | int mq_close(mqd_t personal); | Closes a message queue with the specified descriptor.| | \#include &lt;mqueue.h&gt; | int mq_close(mqd_t personal); | Closes a message queue with the specified descriptor.|
| \#include &lt;mqueue.h&gt; | int mq_unlink(const char \*mqName); | Deletes the message queue of the specified name.| | \#include &lt;mqueue.h&gt; | int mq_unlink(const char \*mqName); | Deletes the message queue of the specified name.|
| \#include &lt;mqueue.h&gt; | int mq_send(mqd_t personal, const char \*msg,size_t msgLen, unsigned int msgPrio); | Puts a message with the specified content and length into a message queue.| | \#include &lt;mqueue.h&gt; | int mq_send(mqd_t personal, const char \*msg, size_t msgLen, unsigned int msgPrio); | Puts a message with the specified content and length into a message queue.|
| \#include &lt;mqueue.h&gt; | ssize_t mq_receive(mqd_t personal, char \*msg,size_t msgLen, unsigned int \*msgPrio); | Deletes the oldest message from a message queue and puts it in the buffer pointed to by **msg_ptr**.| | \#include &lt;mqueue.h&gt; | ssize_t mq_receive(mqd_t personal, char \*msg, size_t msgLen, unsigned int \*msgPrio); | Deletes the oldest message from a message queue and puts it in the buffer pointed to by **msg_ptr**.|
| \#include &lt;mqueue.h&gt; | int mq_timedsend(mqd_t personal, const char\*msg, size_t msgLen, unsigned int msgPrio, const struct timespec \*absTimeout) | Puts a message with the specified content and length into a message queue at the specified time.| | \#include &lt;mqueue.h&gt; | int mq_timedsend(mqd_t personal, const char\*msg, size_t msgLen, unsigned int msgPrio, const struct timespec \*absTimeout) | Puts a message with the specified content and length into a message queue at the specified time.|
| \#include &lt;mqueue.h&gt; | ssize_t mq_timedreceive(mqd_t personal, char\*msg, size_t msgLen, unsigned int \*msgPrio, const struct timespec \*absTimeout); | Obtains a message with the specified content and length from a message queue.| | \#include &lt;mqueue.h&gt; | ssize_t mq_timedreceive(mqd_t personal, char\*msg, size_t msgLen, unsigned int \*msgPrio, const struct timespec \*absTimeout); | Obtains a message with the specified content and length from a message queue.|
| \#include &lt;mqueue.h&gt; | int mq_setattr(mqd_t mqdes, const struct mq_attr \*__restrict newattr, struct mq_attr \*__restrict oldattr); | Sets the message queue attributes specified by the descriptor.| | \#include &lt;mqueue.h&gt; | int mq_setattr(mqd_t mqdes, const struct mq_attr \*\_\_restrict newattr, struct mq_attr *\__restrict oldattr); | Sets the message queue attributes specified by the descriptor.|
| \#include &lt;libc.h&gt; | const char \*libc_get_version_string(void); | Obtains the libc version string.| | \#include &lt;libc.h&gt; | const char \*libc_get_version_string(void); | Obtains the libc version string.|
| \#include &lt;libc.h&gt; | int libc_get_version(void); | Obtains the libc version.| | \#include &lt;libc.h&gt; | int libc_get_version(void); | Obtains the libc version.|
...@@ -459,6 +459,8 @@ Example: ...@@ -459,6 +459,8 @@ Example:
Creates a thread, transfers the information in the parent thread to the child thread, and prints the transferred information and the thread ID in the child thread. Creates a thread, transfers the information in the parent thread to the child thread, and prints the transferred information and the thread ID in the child thread.
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **DemoForTest** function is called in **TestTaskEntry**.
``` ```
#include <stdio.h> #include <stdio.h>
......
# Events # Event
## Basic Concepts ## Basic Concepts
An event is a mechanism for communication between tasks. It can be used to synchronize tasks. The events have the following features: An event is a communication mechanism used to synchronize tasks. Events have the following features:
- Events can be synchronized in one-to-many or many-to-many mode. In one-to-many mode, a task can wait for multiple events. In many-to-many mode, multiple tasks can wait for multiple events. However, a write event wakes up only one task from the block. - Events can be synchronized in one-to-many or many-to-many mode. In one-to-many mode, a task can wait for multiple events. In many-to-many mode, multiple tasks can wait for multiple events. However, a write event wakes up only one task from the block.
- Event read timeout mechanism is used. - Event read timeout mechanism is used.
- Events are used only for task synchronization, but not for data transmission. - Events are used for task synchronization, but not for data transmission.
APIs are provided to initialize, read/write, clear, and destroy events. APIs are provided to initialize, read/write, clear, and destroy events.
...@@ -18,7 +18,7 @@ APIs are provided to initialize, read/write, clear, and destroy events. ...@@ -18,7 +18,7 @@ APIs are provided to initialize, read/write, clear, and destroy events.
### Event Control Block ### Event Control Block
The event control block is a struct configured in the event initialization function. It is passed in as an input parameter to identify the event for operations such as event read and write. The data structure of the event control block is as follows: The event control block is a structure in the event initialization function. It passes in event identifies for operations such as event read and write. The data structure of the event control block is as follows:
``` ```
...@@ -31,23 +31,33 @@ typedef struct tagEvent { ...@@ -31,23 +31,33 @@ typedef struct tagEvent {
### Working Principles ### Working Principles
**Initializing an event**: An event control block is created to maintain a collection of processed events and a linked list of tasks waiting for specific events. **Initializing an Event**
**Writing an event**: When a specified event is written to the event control block, the event control block updates the event set, traverses the task linked list, and determines whether to wake up related task based on the task conditions. An event control block is created to maintain a set of processed events and a linked list of tasks waiting for specific events.
**Reading an event**: If the read event already exists, it is returned synchronously. In other cases, the return time is determined based on the timeout period and event triggering status. If the wait event condition is met before the timeout period expires, the blocked task will be directly woken up. Otherwise, the blocked task will be woken up only after the timeout period has expired. **Writing an Event**
The input parameters **eventMask** and **mode** determine whether the condition for reading an event is met. **eventMask** indicates the mask of the event. **mode** indicates the handling mode, which can be any of the following: When an event is written to the event control block, the event control block updates the event set, traverses the task linked list, and determines whether to wake up related tasks based on the task conditions.
- **LOS_WAITMODE_AND**: Event reading is successful only when all the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned. **Reading an Event**
- **LOS_WAITMODE_OR**: Event reading is successful when any of the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned. If the event to read already exists, it is returned synchronously. In other cases, the event is returned based on the timeout period and event triggering conditions. If the wait condition is met before the timeout period expires, the blocked task will be directly woken up. Otherwise, the blocked task will be woken up only after the timeout period has expired.
The parameters **eventMask** and **mode** determine whether the condition for reading an event is met. **eventMask** specifies the event mask. **mode** specifies the handling mode, which can be any of the following:
- **LOS_WAITMODE_AND**: Read the event only when all the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned.
- **LOS_WAITMODE_OR**: Read the event only when any of the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned.
- **LOS_WAITMODE_CLR**: This mode must be used with one or all of the event modes (LOS_WAITMODE_AND | LOS_WAITMODE_CLR or LOS_WAITMODE_OR | LOS_WAITMODE_CLR). In this mode, if all event modes or any event mode is successful, the corresponding event type bit in the event control block will be automatically cleared. - **LOS_WAITMODE_CLR**: This mode must be used with one or all of the event modes (LOS_WAITMODE_AND | LOS_WAITMODE_CLR or LOS_WAITMODE_OR | LOS_WAITMODE_CLR). In this mode, if all event modes or any event mode is successful, the corresponding event type bit in the event control block will be automatically cleared.
**Clearing events**: Clear the event set of the event control block based on the specified mask. If the mask is **0**, the event set will be cleared. If the mask is **0xffff**, no event will be cleared, and the event set remains unchanged. **Clearing Events**
The events in the event set of the event control block can be cleared based on the specified mask. The mask **0** means to clear the event set; the mask **0xffff** means the opposite.
**Destroying Events**
**Destroying an event**: Destroy the specified event control block. The event control block can be destroyed to release resources.
**Figure 1** Event working mechanism for a mini system **Figure 1** Event working mechanism for a mini system
...@@ -58,12 +68,12 @@ The input parameters **eventMask** and **mode** determine whether the condition ...@@ -58,12 +68,12 @@ The input parameters **eventMask** and **mode** determine whether the condition
| Category| API| Description| | Category| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| Event check| LOS_EventPoll | Checks whether the expected event occurs based on **eventID**, **eventMask**, and **mode**.<br>**NOTICE**<br><br>If **mode** contains **LOS_WAITMODE_CLR** and the expected event occurs, the event that meets the requirements in **eventID** will be cleared. In this case, **eventID** is an input parameter and an output parameter. In other cases, **eventID** is used only as an input parameter.| | Checking an event | LOS_EventPoll | Checks whether the expected event occurs based on **eventID**, **eventMask**, and **mode**.<br>**NOTE**<br>If **mode** contains **LOS_WAITMODE_CLR** and the expected event occurs, the event that meets the requirements in **eventID** will be cleared. In this case, **eventID** is an input parameter and an output parameter. In other cases, **eventID** is used only as an input parameter. |
| Initialization| LOS_EventInit | Initializes an event control block.| | Initializing an event control block | LOS_EventInit | Initializes an event control block.|
| Event read| LOS_EventRead | Reads an event (wait event). The task will be blocked to wait based on the timeout period (in ticks).<br>If no event is read, **0** is returned.<br>If an event is successfully read, a positive value (event set) is returned.<br>In other cases, an error code is returned.| | Reading an event | LOS_EventRead | Reads an event (wait event). The task will be blocked to wait based on the timeout period (in ticks).<br>If no event is read, **0** is returned.<br>If an event is successfully read, a positive value (event set) is returned.<br>In other cases, an error code is returned.|
| Event write| LOS_EventWrite | Writes an event to the event control block.| | Writing an event | LOS_EventWrite | Writes an event to the event control block.|
| Event clearance| LOS_EventClear | Clears an event in the event control block based on the event mask.| | Clearing events | LOS_EventClear | Clears events in the event control block based on the event mask. |
| Event destruction| LOS_EventDestroy | Destroys an event control block.| | Destroying events | LOS_EventDestroy | Destroys an event control block.|
## How to Develop ## How to Develop
...@@ -72,11 +82,11 @@ The typical event development process is as follows: ...@@ -72,11 +82,11 @@ The typical event development process is as follows:
1. Initialize an event control block. 1. Initialize an event control block.
2. Block a read event control block. 2. Block a read event.
3. Write related events. 3. Write events.
4. Wake up a blocked task, read the event, and check whether the event meets conditions. 4. Wake up the blocked task, read the event, and check whether the event meets conditions.
5. Handle the event control block. 5. Handle the event control block.
...@@ -84,7 +94,7 @@ The typical event development process is as follows: ...@@ -84,7 +94,7 @@ The typical event development process is as follows:
> **NOTE** > **NOTE**
> - When an event is read or written, the 25th bit of the event is reserved and cannot be set. > - For event read and write operations, the 25th bit (`0x02U << 24`) of the event is reserved and cannot be set.
> >
> - Repeated writes of the same event are treated as one write. > - Repeated writes of the same event are treated as one write.
...@@ -111,7 +121,7 @@ In the **ExampleEvent** task, create an **EventReadTask** task with a timout per ...@@ -111,7 +121,7 @@ In the **ExampleEvent** task, create an **EventReadTask** task with a timout per
The sample code is as follows: The sample code is as follows:
The sample code is compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. Call **ExampleEvent()** in **TestTaskEntry**. The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleEvent()** function is called in **TestTaskEntry**.
``` ```
......
...@@ -77,7 +77,7 @@ The preceding figure illustrates how to write data to the tail node only. Writin ...@@ -77,7 +77,7 @@ The preceding figure illustrates how to write data to the tail node only. Writin
## Available APIs ## Available APIs
| Category| Description| | Category| API Description |
| -------- | -------- | | -------- | -------- |
| Creating or deleting a message queue| **LOS_QueueCreate**: creates a message queue. The system dynamically allocates the queue space.<br>**LOS_QueueCreateStatic**: creates a static message queue. You need to pass in the queue space.<br>**LOS_QueueDelete**: deletes a message queue. After a static message queue is deleted, you need to release the queue space.| | Creating or deleting a message queue| **LOS_QueueCreate**: creates a message queue. The system dynamically allocates the queue space.<br>**LOS_QueueCreateStatic**: creates a static message queue. You need to pass in the queue space.<br>**LOS_QueueDelete**: deletes a message queue. After a static message queue is deleted, you need to release the queue space.|
| Reading or writing data (address without the content) in a queue| **LOS_QueueRead**: reads data in the head node of the specified queue. The data in the queue node is an address.<br>**LOS_QueueWrite**: writes the **bufferAddr** (buffer address) to the tail node of the specified queue.<br>**LOS_QueueWriteHead**: writes the **bufferAddr** (buffer address) to the head node of the specified queue.| | Reading or writing data (address without the content) in a queue| **LOS_QueueRead**: reads data in the head node of the specified queue. The data in the queue node is an address.<br>**LOS_QueueWrite**: writes the **bufferAddr** (buffer address) to the tail node of the specified queue.<br>**LOS_QueueWriteHead**: writes the **bufferAddr** (buffer address) to the head node of the specified queue.|
...@@ -136,7 +136,7 @@ Create a queue and two tasks. Enable task 1 to write data to the queue, and task ...@@ -136,7 +136,7 @@ Create a queue and two tasks. Enable task 1 to write data to the queue, and task
The sample code is as follows: The sample code is as follows:
The sample code is compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. Call **ExampleQueue** in **TestTaskEntry**. The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleQueue** function is called in **TestTaskEntry**.
``` ```
......
# Shell
The shell provided by the OpenHarmony kernel supports basic debugging functions and provides commands related to the system, files, and network. It also supports commands customized based on service requirements.
The shell function is used for debugging only. Currently, it does not support the functions such as tab completion and undo with a key.
Some commands can be used only after the corresponding options are enabled by using **make menuconfig**.
## Common Shell Commands
### cat
Displays the content of a text file. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
cat [FILE]
#### Parameters
| Parameter| Description | Value Range |
| ---- | ---------- | -------------- |
| FILE | File path.| An existing file.|
### cd
Changes the current directory. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
cd [path]
#### Parameters
| Parameter| Description | Value Range |
| ---- | ---------- | -------------- |
| path | File path.| Path of the new directory.|
### cp
Copies a file. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
cp [SOURCEFILE] [DESTFILE]
#### Parameters
| Parameter | Description | Value Range |
| ---------- | -------------- | ----------------------------------------- |
| SOURCEFILE | Path of the file to copy. | Currently, only files are supported. Directories are not supported. The file cannot be empty.|
| DESTFILE | Path of the file created.| Directory and file names are supported. The directory must exist. |
### date
Queries the system date and time.
#### Format
date
#### Parameters
None.
### free
Displays the memory usage of the system.
#### Format
free [ -k | -m ]
#### Parameters
| Parameter| Description | Value Range|
| ---- | ----------------- | -------- |
| -k | Display the memory usage in KiB.| N/A |
| -m | Display the memory usage in MiB.| N/A |
### help
Displays all commands in this operating system.
#### Format
help
#### Parameters
None.
### ifconfig
Displays the IP address, network mask, gateway, and MAC address of a network adapter. This command can be used only after **LWIP_SHELLCMD_ENABLE** is enabled.
#### Format
ifconfig
#### Parameters
None.
### ls
Displays the content of a directory. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
ls [DIRECTORY]
#### Parameters
| Parameter | Description | Value Range |
| --------- | ---------- | ------------------------------------------------------------ |
| DIRECTORY | Path of the directory.| If **DIRECTORY** is not specified, the content of the current directory is displayed.<br>If **DIRECTORY** is a valid directory, the content of the specified directory is displayed.<br>Currently, LiteOS-M does not support the root directory /.|
### memusage
Displays the memory waterline.
#### Format
memusage [-k/-m]
#### Parameters
| Parameter| Description | Value Range|
| ---- | ----------------- | -------- |
| -k | Display the memory usage in KiB.| N/A |
| -m | Display the memory usage in MiB.| N/A |
### mkdir
Creates a directory. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
mkdir [DIRECTORY]
#### Parameters
| Parameter | Description | Value Range |
| --------- | ---------- | ------------------------------------- |
| DIRECTORY | Path of the directory.| The value of **DIRECTORY** can be an absolute path or a relative path.|
### ping
Checks whether the network is connected. This command can be used only after **LWIP_SHELLCMD_ENABLE** is enabled.
#### Format
ping [ip]
#### Parameters
| Parameter| Description | Value Range|
| ---- | ------------------------------ | -------- |
| ip | IPv4 address of the network to test.| N/A |
### pwd
Displays the current path. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
pwd
### rm
Deletes a file or folder. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
rm [FILE] or rm [-r/-R] [FILE]
#### Parameters
| Parameter | Description | Value Range |
| ----- | ------------------------------- | -------------------------------- |
| FILE | File or folder name.| The value of **FILE** can be an absolute path or a relative path.|
| -r/-R | If **FILE** is a folder, -r/-R needs to be set. | N/A |
### rmdir
Deletes a folder. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
rmdir [DIRECTORY]
#### Parameters
| Parameter | Description | Value Range |
| --------- | ---------- | ------------------------------------- |
| DIRECTORY | Path of the directory.| The value of **DIRECTORY** can be an absolute path or a relative path.|
### task
Displays the status of each task.
#### Format
task
The displayed information includes the task No., priority, status, stack information, signal, event, CPU usage, and task name.
### touch
Creates a file. This command can be used only after **LOSCFG_FS_VFS** is enabled.
#### Format
touch [FILE]
#### Parameters
| Parameter| Description| Value Range |
| ---- | -------- | -------------------------------- |
| FILE | File name.| The value of **FILE** can be an absolute path or a relative path.|
### stack
Displays the stack information of a task. This command can be used only after **LOSCFG_DEBUG_TOOLS** is enabled. Enabling this function affects the performance.
#### Format
stack [ID]
#### Parameters
| Parameter| Description| Value Range |
| ---- | -------- | ------------------------ |
| ID | Task ID.| The task corresponding to the task ID must exist.|
### hwi
Queries the interrupt usage. This command can be used only after **LOSCFG_DEBUG_TOOLS** is enabled. Enabling this function affects the performance.
#### Format
hwi
### st
Queries scheduling information. This command can be used only afterf **LOSCFG_DEBUG_TOOLS** is enabled. Enabling this function affects the performance.
#### Format
st -s | st -e
#### Parameters
| Parameter| Description | Value Range|
| ---- | ---------------------- | -------- |
| -s | Start to record scheduling information. | N/A |
| -e | Stop recording and print scheduling information.| N/A |
# CPUP # CPUP
## Basic Concepts ## Basic Concepts
The central processing unit percent \(CPUP\) includes the system CPUP and task CPUP. The central processing unit percent (CPUP) includes the system CPUP and task CPUP.
The system CPUP is the CPU usage of the system within a period of time. It reflects the CPU load and the system running status \(idle or busy\) in the given period of time. The valid range of the system CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the system runs with full load. **System CPUP**
Task CPUP refers to the CPU usage of a single task. It reflects the task status, busy or idle, in a period of time. The valid range of task CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the task is being executed for the given period of time. The system CPUP is the CPU usage of the system within a period of time. It reflects the CPU load and the system running status (idle or busy) in the given period of time. The CPUP ranges from 0 to 100, in percentage. The value **100** indicates that the system runs with full load.
With the system CPUP, you can determine whether the current system load exceeds the designed specifications. With the system CPUP, you can determine whether the current system load exceeds the designed specifications.
**Task CPUP**
Task CPUP refers to the CPU usage of a single task. It reflects the task status, busy or idle, in a period of time. The task CPUP ranges from 0 to 100, in percentage. The value **100** indicates that the task is being executed for the given period of time.
With the CPUP of each task, you can determine whether the CPU usage of each task meets expectations of the design. With the CPUP of each task, you can determine whether the CPU usage of each task meets expectations of the design.
**Interrupt CPUP**
In addition, you can enable the interrupt usage statistics function after the CPUP function is enabled.
Interrupt CPUP indicates the CPU usage of a single interrupt out of the total interrupt duration. The interrupt CPUP ranges from 0 to 100. The value **100** indicates that only the interrupt is triggered within a period of time.
## Working Principles ## Working Principles
The OpenHarmony LiteOS-M CPUP records the system CPU usage on a task basis. When task switching occurs, the task start time and task switch-out or exit time are recorded. Each time when a task exits, the system accumulates the CPU time used by the task. The OpenHarmony LiteOS-M CPUP records the system CPU usage on a task basis. When task switching occurs, the task start time and task switch-out or exit time are recorded. Each time when a task exits, the system accumulates the CPU time used by the task.
You can configure this function in **target\_config.h**. You can configure this function in **target_config.h**.
The OpenHarmony LiteOS-M provides the following types of CPUP information: The OpenHarmony LiteOS-M provides the following types of CPUP information:
- System CPUP - System CPUP
- Task CPUP - Task CPUP
In addition, the system provides the capability of querying the interrupt CPUP (the CPUP and timer must be enabled).
The CPUP is calculated as follows: The CPUP is calculated as follows:
System CPUP = Total running time of all tasks except idle tasks/Total running time of the system System CPUP = Total running time of all tasks except idle tasks/Total running time of the system
Task CPUP = Total running time of the task/Total running time of the system Task CPUP = Total running time of the task/Total running time of the system
## Available APIs<a name="section158501652121514"></a> Interrupt CPUP = Running time of a single interrupt/Total running time of all interrupts
**Table 1** Functions
## Available APIs
<a name="table18293928155615"></a>
<table><thead align="left"><tr id="row129362875613"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p19444103765618"><a name="p19444103765618"></a><a name="p19444103765618"></a>Function</p> **Table 1** APIs for CPUP
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p944473716569"><a name="p944473716569"></a><a name="p944473716569"></a>API</p> | Category| Description|
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p144445378565"><a name="p144445378565"></a><a name="p144445378565"></a>Description</p> | Obtaining the system CPUP| **LOS_SysCpuUsage**: obtains the current system CPUP.<br>**LOS_HistorySysCpuUsage**: obtains the historical CPUP of the system.|
</th> | Obtaining the task CPUP| **LOS_TaskCpuUsage**: obtains the CPUP of a task.<br>**LOS_HistoryTaskCpuUsage**: obtains the historical CPUP of a task.<br>**LOS_AllTaskCpuUsage**: obtains the CPUP of all tasks.|
</tr> | Outputting the task CPUP| **LOS_CpupUsageMonitor**: outputs the historical CPUP of a task.|
</thead> | Obtaining the interrupt CPUP| **LOS_GetAllIrqCpuUsage**: obtains the CPUP of all interrupts.|
<tbody><tr id="row1143613475615"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p942993405610"><a name="p942993405610"></a><a name="p942993405610"></a>Obtaining the system CPU usage</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p242973419563"><a name="p242973419563"></a><a name="p242973419563"></a>LOS_SysCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p7429163416565"><a name="p7429163416565"></a><a name="p7429163416565"></a>Obtains the current system CPUP.</p>
</td>
</tr>
<tr id="row15436163435611"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p20429183410563"><a name="p20429183410563"></a><a name="p20429183410563"></a>LOS_HistorySysCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p542953465617"><a name="p542953465617"></a><a name="p542953465617"></a>Obtains the historical CPUP of the system.</p>
</td>
</tr>
<tr id="row143610342562"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p174295347568"><a name="p174295347568"></a><a name="p174295347568"></a>Obtaining the task CPUP</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p124291734155614"><a name="p124291734155614"></a><a name="p124291734155614"></a>LOS_TaskCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1042963410568"><a name="p1042963410568"></a><a name="p1042963410568"></a>Obtains the CPUP of a specified task.</p>
</td>
</tr>
<tr id="row12436143414561"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6429834185613"><a name="p6429834185613"></a><a name="p6429834185613"></a>LOS_HistoryTaskCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p74302034175614"><a name="p74302034175614"></a><a name="p74302034175614"></a>Obtains the historical CPUP of a specified task.</p>
</td>
</tr>
<tr id="row2435834135618"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p843073420563"><a name="p843073420563"></a><a name="p843073420563"></a>LOS_AllCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p4430134185614"><a name="p4430134185614"></a><a name="p4430134185614"></a>Obtains the CPUP of all tasks.</p>
</td>
</tr>
<tr id="row15435934155618"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1543033435615"><a name="p1543033435615"></a><a name="p1543033435615"></a>Outputting the task CPUP</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1643016342562"><a name="p1643016342562"></a><a name="p1643016342562"></a>LOS_CpupUsageMonitor</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p84301234115617"><a name="p84301234115617"></a><a name="p84301234115617"></a>Outputs the historical CPUP of a task.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop ## How to Develop
In the **kernel/liteos_m** directory, run the **make menuconfig** command and choose **Kernel > Enable Cpup** to enable CPUP.
Choose **Enable Cpup include irq** to enable interrupt CPUP.
The typical CPUP development process is as follows: The typical CPUP development process is as follows:
1. Call **LOS\_SysCpuUsage** to obtain the system CPUP. 1. Call **LOS_SysCpuUsage** to obtain the system CPUP.
2. Call **LOS\_HistorySysCpuUsage** to obtain the historical CPUP of the system.
3. Call **LOS\_TaskCpuUsage** to obtain the CPUP of a specified task. 2. Call **LOS_HistorySysCpuUsage** to obtain the historical CPUP of the system.
3. Call **LOS_TaskCpuUsage** to obtain the CPUP of a task.
- If the task has been created, disable interrupt, obtain the CPUP, and then enable interrupt. - If the task has been created, disable interrupt, obtain the CPUP, and then enable interrupt.
- If the task is not created, return an error code. - If the task is not created, return an error code.
4. Call **LOS\_HistoryTaskCpuUsage** to obtain the historical CPUP of a specified task. 4. Call **LOS_HistoryTaskCpuUsage** to obtain the historical CPUP of a task.
- If the task has been created, disable interrupt, obtain the CPUP in different modes, and then enable interrupt. - If the task has been created, disable interrupt, obtain the CPUP in different modes, and then enable interrupt.
- If the task is not created, return an error code. - If the task is not created, return an error code.
5. Call **LOS\_AllCpuUsage** to obtain the CPUP of all tasks. 5. Call **LOS_AllCpuUsage** to obtain the CPUP of all tasks.
- If the CPUP is initialized, disable interrupt, obtain the CPUP in different modes, and then enable interrupt. - If CPUP has been initialized, disable interrupt, obtain the CPUP in different modes, and then enable interrupt.
- If CPUP is not initialized or has invalid input parameters, return an error code. - If CPUP is not initialized or has invalid input parameters, return an error code.
## Development Example ## Development Example
### Example Description ### Example Description
This example implements the following: This example implements the following:
1. Create a task for the CPUP test. 1. Create a task for the CPUP test.
2. Obtain the CPUP of the current system. 2. Obtain the CPUP of the current system.
3. Obtain the historical system CPUP in different modes. 3. Obtain the historical system CPUP in different modes.
4. Obtain the CPUP of the created test task.
5. Obtain the CPUP of the created test task in different modes. 4. Obtain the CPUP of the created task.
5. Obtain the CPUP of the created task in different modes.
### Sample Code ### Sample Code
Prerequisites **Prerequisites**
In **target\_config.h**, the **LOSCFG\_BASE\_CORE\_CPUP** parameter is enabled. CPUP is enabled.<br>To enable CPUP, run **make menuconfig** in the **kernel/liteos_m** directory and choose **Kernel->Enable Cpup** to enable CPUP.
The sample code is as follows: The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleCpup** function is called in **TestTaskEntry**.
``` ```
#include "los_task.h" #include "los_task.h"
#include "los_cpup.h" #include "los_cpup.h"
#define MODE 4
UINT32 g_cpuTestTaskID; #define TEST_TASK_PRIO 5
VOID ExampleCpup(VOID) #define TASK_DELAY_TIME 100
VOID CpupTask(VOID)
{ {
printf("entry cpup test example\n"); printf("entry cpup test example\n");
while(1) { usleep(TASK_DELAY_TIME);
usleep(100); usleep(TASK_DELAY_TIME);
} printf("exit cpup test example\n");
} }
UINT32 ItCpupTest(VOID)
UINT32 ExampleCpup(VOID)
{ {
UINT32 ret; UINT32 ret;
UINT32 cpupUse; UINT32 cpupUse;
UINT32 taskID;
TSK_INIT_PARAM_S cpupTestTask = { 0 }; TSK_INIT_PARAM_S cpupTestTask = { 0 };
memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S));
cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup; cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)CpupTask;
cpupTestTask.pcName = "TestCpupTsk"; cpupTestTask.pcName = "TestCpupTsk";
cpupTestTask.uwStackSize = 0x800; cpupTestTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
cpupTestTask.usTaskPrio = 5; cpupTestTask.usTaskPrio = TEST_TASK_PRIO;
ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask); ret = LOS_TaskCreate(&taskID, &cpupTestTask);
if(ret != LOS_OK) { if(ret != LOS_OK) {
printf("cpupTestTask create failed .\n"); printf("cpupTestTask create failed .\n");
return LOS_NOK; return LOS_NOK;
} }
usleep(100); usleep(TASK_DELAY_TIME);
/* Obtain the current CPUP of the system. */ /* Obtain the current system CPUP. */
cpupUse = LOS_SysCpuUsage(); cpupUse = LOS_SysCpuUsage();
printf("the current system cpu usage is: %u.%u\n", printf("the current system cpu usage is: %u.%u\n",
cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT);
cpupUse = LOS_HistorySysCpuUsage(CPU_LESS_THAN_1S); /* Obtain the historical CPUP of the system. */
/* Obtain the CPUP of the specified task (cpupTestTask in this example).*/ cpupUse = LOS_HistorySysCpuUsage(CPUP_LESS_THAN_1S);
printf("the history system CPUP in all time: %u.%u\n", printf("the history system cpu usage in all time: %u.%u\n",
cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT);
cpupUse = LOS_TaskCpuUsage(g_cpuTestTaskID);
/* Obtain the CPUP of the specified historical task (cpupTestTask in this example) since the system startup. */ /* Obtain the CPUP of a specified task. */
cpupUse = LOS_TaskCpuUsage(taskID);
printf("cpu usage of the cpupTestTask:\n TaskID: %d\n usage: %u.%u\n", printf("cpu usage of the cpupTestTask:\n TaskID: %d\n usage: %u.%u\n",
g_cpuTestTaskID, cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); taskID, cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT);
cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPU_LESS_THAN_1S);
/* Obtain the CPUP of a specified task since the system starts. */
cpupUse = LOS_HistoryTaskCpuUsage(taskID, CPUP_LESS_THAN_1S);
printf("cpu usage of the cpupTestTask in all time:\n TaskID: %d\n usage: %u.%u\n", printf("cpu usage of the cpupTestTask in all time:\n TaskID: %d\n usage: %u.%u\n",
g_cpuTestTaskID, cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); taskID, cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT);
return LOS_OK; return LOS_OK;
} }
``` ```
### Verification ### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
entry cpup test example entry cpup test example
the current system cpu usage is : 1.5 the current system cpu usage is: 8.2
the history system cpu usage in all time: 3.0 the history system cpu usage in all time: 8.9
cpu usage of the cpupTestTask: TaskID:10 usage: 0.0 cpu usage of the cpupTestTask:
cpu usage of the cpupTestTask&nbsp;in all time: TaskID:10 usage: 0.0 TaskID: 5
usage: 0.5
cpu usage of the cpupTestTask in all time:
TaskID: 5
usage: 0.5
exit cpup test example
The preceding data may vary depending on the running environment.
``` ```
# File System # File Systems
The OpenHarmony LiteOS-M kernel supports File Allocation Table file system (FATFS) and LittleFS file systems. Like the OpenHarmony LiteOS-A kernel, the OpenHarmony LiteOS-M kernel provides POSIX over the virtual file system (VFS) to ensure interface consistency. However, the VFS of the LiteOS-M kernel is light due to insufficient resources and does not provide advanced functions (such as pagecache). Therefore, the VFS of the LiteOS-M kernel implements only API standardization and adaptation. The file systems handle specific transactions. ## VFS
The following tables list the APIs supported by the file systems of the LiteOS-M kernel.
### Basic Concepts
**Table 1** File management operations The Virtual File System (VFS) is not a real file system. It is an abstract layer on top of a heterogeneous file system and provides you with a unified Unix-like interface for file operations. Different types of file systems use different file operation interfaces. If there are multiple types of file systems in a system, different and non-standard interfaces are required for accessing these file systems. The VFS is introduced as an abstract layer to shield the differences between these heterogeneous file systems. With the VFS, you do not need to care about the underlying storage medium and file system type.
| API| Description| FATFS | LITTLEFS | The OpenHarmony LiteOS-M kernel supports the File Allocation Table (FAT) and LittleFS file systems. It provides the Portable Operating System Interface (POSIX) over the VFS to ensure interface consistency. However, the VFS of the LiteOS-M kernel is light and does not provide advanced functions (such as pagecache) due to insufficient resources. Therefore, the VFS of the LiteOS-M kernel implements only API standardization and adaptation. The file systems handle specific transactions. The following tables describe the APIs supported by the file systems of the LiteOS-M kernel.
### Available APIs
**Table 1** APIs for file operations
| API| Description| FAT | LittleFS |
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| open | Opens a file.| Supported| Supported| | open | Opens a file.| Supported| Supported|
| close | Closes a file.| Supported| Supported| | close | Closes a file.| Supported| Supported|
| read | Reads the file content.| Supported| Supported| | read | Reads the file content. | Supported | Supported |
| write | Writes data to a file.| Supported| Supported| | write | Writes data to a file. | Supported | Supported |
| lseek | Sets the file offset.| Supported| Supported| | lseek | Sets the file offset. | Supported | Supported |
| stat | Obtains file information based on the file path name.| Supported | Supported |
| unlink | Deletes a file.| Supported| Supported| | unlink | Deletes a file.| Supported| Supported|
| rename | Renames the file.| Supported| Supported| | rename | Renames the file.| Supported| Supported|
| fstat | Obtains file information based on the file handle.| Supported| Supported| | fstat | Obtains file information based on the file handle. | Supported | Supported |
| stat | Obtains file information based on the file path name.| Supported| Supported| | fsync | Saves a file to a storage device. | Supported | Supported |
| fsync | Saves file updates to a storage device.| Supported| Supported|
**Table 2** Directory management operations **Table 2** APIs for directory operations
| API| Description| FATFS | LITTLEFS | | API| Description| FATFS | LITTLEFS |
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
...@@ -31,8 +36,7 @@ The following tables list the APIs supported by the file systems of the LiteOS-M ...@@ -31,8 +36,7 @@ The following tables list the APIs supported by the file systems of the LiteOS-M
| closedir | Closes a directory.| Supported| Supported| | closedir | Closes a directory.| Supported| Supported|
| rmdir | Deletes a directory.| Supported| Supported| | rmdir | Deletes a directory.| Supported| Supported|
**Table 3** APIs for partition operations
**Table 3** Partition operations
| API| Description| FATFS | LITTLEFS | | API| Description| FATFS | LITTLEFS |
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
...@@ -41,14 +45,18 @@ The following tables list the APIs supported by the file systems of the LiteOS-M ...@@ -41,14 +45,18 @@ The following tables list the APIs supported by the file systems of the LiteOS-M
| umount2 | Forcibly unmounts a partition using the **MNT_FORCE** parameter.| Supported| Not supported| | umount2 | Forcibly unmounts a partition using the **MNT_FORCE** parameter.| Supported| Not supported|
| statfs | Obtains partition information.| Supported| Not supported| | statfs | Obtains partition information.| Supported| Not supported|
Interfaces, such as **ioctl** and **fcntl**, are supported by different libraries and are irrelevant to the underlying file system.
## FAT ## FAT
### Basic Concepts ### Basic Concepts
File Allocation Table (FAT) is a file system developed for personal computers. It consists of the DOS Boot Record (DBR) region, FAT region, and Data region. Each entry in the FAT region records information about the corresponding cluster in the storage device. The cluster information includes whether the cluster is used, number of the next cluster of the file, whether the file ends with the cluster. The FAT file system supports multiple formats, such as FAT12, FAT16, and FAT32. The numbers 12, 16, and 32 indicate the number of bits per cluster within the FAT, respectively. The FAT file system supports multiple media, especially removable media (such as USB flash drives, SD cards, and removable hard drives). The FAT file system ensures good compatibility between embedded devices and desktop systems (such as Windows and Linux) and facilitates file management. As a file system designed for personal computers, the FAT file system consists of the DOS Boot Record (DBR) region, FAT region, and Data region. Each entry in the FAT region records information about the corresponding cluster in the storage device. The cluster information includes whether the cluster is used, number of the next cluster of the file, whether the file ends with the cluster.
The OpenHarmony kernel supports FAT12, FAT16, and FAT32 file systems. These file systems require a tiny amount of code to implement, use less resources, support a variety of physical media, and are tailorable and compatible with Windows and Linux systems. They also support identification of multiple devices and partitions. The kernel supports multiple partitions on hard drives and allows creation of the FAT file system on the primary partition and logical partition. The FAT file system supports a variety of formats, including FAT12, FAT16, and FAT32. The numbers 12, 16, and 32 indicate the number of bits per cluster within the FAT, respectively. The FAT file system also supports diversified storage media, especially removable media (such as USB flash drives, SD cards, and removable hard drives). It features good compatibility between embedded devices and desktop systems (such as Windows and Linux) and facilitates file management.
The OpenHarmony kernel supports FAT12, FAT16, and FAT32 file systems. These file systems require a tiny amount of code to implement, use less resources, support a variety of physical media, and are tailorable and compatible with Windows and Linux systems. They also support identification of multiple devices and partitions. The kernel supports multiple partitions on hard drives and allows creation of the FAT file system on the primary and logical partitions.
### Development Guidelines ### Development Guidelines
...@@ -56,11 +64,13 @@ The OpenHarmony kernel supports FAT12, FAT16, and FAT32 file systems. These file ...@@ -56,11 +64,13 @@ The OpenHarmony kernel supports FAT12, FAT16, and FAT32 file systems. These file
#### Driver Adaptation #### Driver Adaptation
The use of the FAT file system requires support from the underlying MultiMediaCard (MMC) drivers. To run FatFS on a board with an MMC storage device, you must: The use of a FAT file system requires support from the underlying MultiMediaCard (MMC) driver. Before using a FAT file system on a board with an MMC, you must perform the following operations:
1. Implement the **disk_status**, **disk_initialize**, **disk_read**, **disk_write**, and **disk_ioctl** APIs to adapt to the embedded MMC (eMMC) driver on the board.
1. Implement the **disk_status**, **disk_initialize**, **disk_read**, **disk_write**, and **disk_ioctl** APIs to adapt to the embedded MMC (eMMC) drivers on the board. 2. Add the **fs_config.h** file with information such as **FS_MAX_SS** (maximum sector size of the storage device) and **FF_VOLUME_STRS** (partition names) configured.
2. Add the **fs_config.h** file with information such as **FS_MAX_SS** (maximum sector size of the storage device) and **FF_VOLUME_STRS** (partition names) configured. The following is an example: The following is an example:
``` ```
...@@ -69,29 +79,115 @@ The use of the FAT file system requires support from the underlying MultiMediaCa ...@@ -69,29 +79,115 @@ The use of the FAT file system requires support from the underlying MultiMediaCa
#define FAT_MAX_OPEN_FILES 50 #define FAT_MAX_OPEN_FILES 50
``` ```
#### Mounting Partitions
Before using a FAT file system on a device, you need to initialize the flash drive and partition the device storage.
API for partitioning the storage:
**int LOS_DiskPartition(const char \*dev, const char \*fsType, int \*lengthArray, int \*addrArray, int partNum);**
- **dev**: pointer to the device name, for example, **spinorblk0**.
- **fsType**: pointer to the file system type, which is **vfat** for the FAT file system.
- **lengthArray**: pointer to a list of partition lengths (in percentage for a FAT file system) of the device.
- **addrArray**: pointer to a list of partition start addresses of the device.
- **partNum**: number of partitions.
API for formatting a partition:
**int LOS_PartitionFormat(const char \*partName, char \*fsType, void \*data);**
- **partName**: pointer to the partition name, in the *Device_name*+**p**+*Partition_ number* format. For example, **spinorblk0p0**.
- **fsType**: pointer to the file system type, which is **vfat** for the FAT file system.
- **data**: pointer to the private data that passes in **(VOID \*) formatType**, for example, **FMT_FAT** or **FMT_FAT32**.
API for mounting a partition:
**int mount(const char \*source, const char \*target, const char \*filesystemtype, unsigned long mountflags, const void \*data);**
- **source**: pointer to the partition name, in the *Device_name*+**p**+*Partition_ number* format. For example, **spinorblk0p0**.
- **target**: pointer to the target path to mount.
- **filesystemtype**: pointer to the file system type, which is **vfat** for the FAT file system.
- **mountflags**: parameters used for the mount operation.
- **data**: pointer to the private data that passes in **(VOID \*) formatType**, for example, **FMT_FAT** or **FMT_FAT32**.
The sample code is implemented in **./device/qemu/arm_mps2_an386/liteos_m/board/fs/fs_init.c** and can be directly used on the Quick EMUlator (QEMU) that uses the LiteOS-M kernel. You can modify the code based on the hardware you use.
#include "fatfs_conf.h"
#include "fs_config.h"
#include "los_config.h"
#include "ram_virt_flash.h"
#include "los_fs.h"
struct fs_cfg {
CHAR *mount_point;
struct PartitionCfg partCfg;
};
INT32 FatfsLowLevelInit()
{
INT32 ret;
INT32 i;
UINT32 addr;
int data = FMT_FAT32;
const char * const pathName[FF_VOLUMES] = {FF_VOLUME_STRS};
HalLogicPartition *halPartitionsInfo = getPartitionInfo(); /* Function for obtaining the partition lengths and start addresses. Modify it as required. */
INT32 lengthArray[FF_VOLUMES] = {25, 25, 25, 25};
INT32 addrArray[FF_VOLUMES];
/* Set the address and length for each partition. */
for (i = 0; i < FF_VOLUMES; i++) {
addr = halPartitionsInfo[FLASH_PARTITION_DATA1].partitionStartAddr + i * 0x10000;
addrArray[i] = addr;
FlashInfoInit(i, addr);
}
/* Set partition information. */
SetupDefaultVolToPartTable();
ret = LOS_DiskPartition("spinorblk0", "vfat", lengthArray, addrArray, FF_VOLUMES);
printf("%s: DiskPartition %s\n", __func__, (ret == 0) ? "succeed" : "failed");
if (ret != 0) {
return -1;
}
ret = LOS_PartitionFormat("spinorblk0p0", "vfat", &data);
printf("%s: PartitionFormat %s\n", __func__, (ret == 0) ? "succeed" : "failed");
if (ret != 0) {
return -1;
}
ret = mount("spinorblk0p0", "/system", "vfat", 0, &data);
printf("%s: mount fs on '%s' %s\n", __func__, pathName[0], (ret == 0) ? "succeed" : "failed");
if (ret != 0) {
return -1;
}
return 0;
}
#### How to Develop #### How to Develop
Note the following when managing FatFS files and directories: Observe the following when managing files and directories in a FAT file system:
- A file cannot exceed 4 GB. - A file cannot exceed 4 GB.
- **FAT_MAX_OPEN_FILES** specifies the maximum number files you can open at a time, and **FAT_MAX_OPEN_DIRS** specifies the maximum number of folders you can open at a time. - **FAT_MAX_OPEN_FILES** specifies the maximum number files you can open at a time, and **FAT_MAX_OPEN_DIRS** specifies the maximum number of folders you can open at a time.
- Root directory management is not supported. File and directory names start with the partition name. For example, **user/testfile** indicates the file or directory **testfile** in the **user** partition. - Root directory management is not supported. File and directory names start with the partition name. For example, **user/testfile** indicates the **testfile** file or directory in the **user** partition.
- To open a file multiple times, use **O_RDONLY** (read-only mode). **O_RDWR** or **O_WRONLY** (writable mode) can open a file only once. - To open a file multiple times at the same time, use **O_RDONLY** (read-only mode). **O_RDWR** or **O_WRONLY** (writable mode) can open a file only once at a time.
- The read and write pointers are not separated. If a file is open in **O_APPEND** mode, the read pointer is also at the end of the file. If you want to read the file from the beginning, you must manually set the position of the read pointer. - The read and write pointers are not separated. If a file is open in **O_APPEND** mode, the read pointer is also at the end of the file. If you want to read the file from the beginning, you must manually set the position of the read pointer.
- File and directory permission management is not supported. - File and directory permission management is not supported.
- The **stat** and **fstat** APIs do not support query of the modification time, creation time, and last access time. The Microsoft FAT protocol does not support time before A.D. 1980. - The **stat** and **fstat** APIs do not support query of the modification time, creation time, and last access time. The Microsoft FAT protocol does not support time before A.D. 1980.
Note the following when mounting and unmounting FatFS partitions: Observe the following when managing files and directories in a FAT file system:
- Partitions can be mounted with the read-only attribute. When the input parameter of the **mount** function is **MS_RDONLY**, all APIs with the write attribute, such as **write**, **mkdir**, **unlink**, and **open** with **non-O_RDONLY** attributes, will be rejected.
- You can use the **MS_REMOUNT** flag with **mount** to modify the permission for a mounted partition. - Partitions can be mounted with the read-only attribute. If the input parameter of **mount()** is **MS_RDONLY**, all APIs with the write attribute, such as **write()**, **mkdir()**, **unlink()**, and **open()** with **non-O_RDONLY** attributes, will be rejected.
- You can use the **MS_REMOUNT** flag in **mount()** to modify the permissions for a mounted partition.
- Before unmounting a partition, ensure that all directories and files in the partition are closed. - Before unmounting a partition, ensure that all directories and files in the partition are closed.
- You can use **umount2** with the **MNT_FORCE** parameter to forcibly close all files and folders and unmount the partition. However, this may cause data loss. Therefore, exercise caution when running **umount2**. - You can use **umount2** with the **MNT_FORCE** parameter to forcibly close all files and folders and unmount the partition. However, this may cause data loss. Therefore, exercise caution when using **umount2**.
The FAT file system supports re-partitioning and formatting of storage devices using **fatfs_fdisk** and **fatfs_format**. You can use **fatfs_fdisk()** and **fatfs_format()** to re-partition the device storage and format the partitions. Observe the following:
- If a partition is mounted before being formatted using **fatfs_format**, you must close all directories and files in the partition and unmount the partition first.
- Before calling **fatfs_fdisk**, ensure that all partitions in the device are unmounted. - Before using **fatfs_format()**, ensure that the target partition is unmounted and all directories and files in the partition are closed.
- Before using **fatfs_fdisk**, ensure that all partitions in the device are unmounted.
- Using **fatfs_fdisk** and **fatfs_format** may cause data loss. Exercise caution when using them. - Using **fatfs_fdisk** and **fatfs_format** may cause data loss. Exercise caution when using them.
...@@ -102,9 +198,9 @@ The FAT file system supports re-partitioning and formatting of storage devices u ...@@ -102,9 +198,9 @@ The FAT file system supports re-partitioning and formatting of storage devices u
This example implements the following: This example implements the following:
1. Create the **user/test** directory. 1. Create a **system/test** directory.
2. Create the **file.txt** file in the **user/test** directory. 2. Create a **file.txt** file in the **system/test** directory.
3. Write **Hello OpenHarmony!** at the beginning of the file. 3. Write **Hello OpenHarmony!** at the beginning of the file.
...@@ -123,99 +219,103 @@ This example implements the following: ...@@ -123,99 +219,103 @@ This example implements the following:
#### Sample Code #### Sample Code
**Prerequisites** **Prerequisites**
The MMC device partition is mounted to the **user** directory.
The sample code is as follows: - The **system** partition is mounted to the QEMU.
- FAT is enabled.
1. In the **kernel/liteos_m** directory, run the **make menuconfig** command and choose **FileSystem->Enable FS VFS** to enable VFS.
2. Select **Enable FAT** to enable the FAT file system.
``` **Implementation**
#include <stdio.h>
#include <string.h>
#include "sys/stat.h"
#include "fcntl.h"
#include "unistd.h"
#define LOS_OK 0 The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleFatfs** function is called in **TestTaskEntry**.
#define LOS_NOK -1
int FatfsTest(void) ```
{ #include <stdio.h>
#include <string.h>
#include "sys/stat.h"
#include "fcntl.h"
#include "unistd.h"
#define BUF_SIZE 20
#define TEST_ROOT "system" /* Set the test root directory. */
VOID ExampleFatfs(VOID)
{
int ret; int ret;
int fd = -1; int fd;
ssize_t len; ssize_t len;
off_t off; off_t off;
char dirName[20] = "user/test"; char dirName[BUF_SIZE] = TEST_ROOT"/test";
char fileName[20] = "user/test/file.txt"; char fileName[BUF_SIZE] = TEST_ROOT"/test/file.txt";
char writeBuf[20] = "Hello OpenHarmony!"; char writeBuf[BUF_SIZE] = "Hello OpenHarmony!";
char readBuf[20] = {0}; char readBuf[BUF_SIZE] = {0};
/* Create the user/test directory. */ /* Create a test directory. */
ret = mkdir(dirName, 0777); ret = mkdir(dirName, 0777);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("mkdir failed.\n"); printf("mkdir failed.\n");
return LOS_NOK; return;
} }
/* Create a readable and writable file named file.txt in the user/test/ directory. */ /* Create a file that is readable and writable. */
fd = open(fileName, O_RDWR | O_CREAT, 0777); fd = open(fileName, O_RDWR | O_CREAT, 0777);
if (fd < 0) { if (fd < 0) {
printf("open file failed.\n"); printf("open file failed.\n");
return LOS_NOK; return;
} }
/* Write the content from writeBuf to the file. */ /* Write the content from writeBuf to the file. */
len = write(fd, writeBuf, strlen(writeBuf)); len = write(fd, writeBuf, strlen(writeBuf));
if (len != strlen(writeBuf)) { if (len != strlen(writeBuf)) {
printf("write file failed.\n"); printf("write file failed.\n");
return LOS_NOK; return;
} }
/* Save the file to a storage device. */ /* Save the file to a storage device. */
ret = fsync(fd); ret = fsync(fd);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("fsync failed.\n"); printf("fsync failed.\n");
return LOS_NOK; return;
} }
/* Move the read/write pointer to the beginning of the file. */ /* Move the read/write pointer to the beginning of the file. */
off = lseek(fd, 0, SEEK_SET); off = lseek(fd, 0, SEEK_SET);
if (off != 0) { if (off != 0) {
printf("lseek failed.\n"); printf("lseek failed.\n");
return LOS_NOK; return;
} }
/* Read the file content with the length of readBuf to readBuf. */ /* Read the file content with the length of readBuf to readBuf. */
len = read(fd, readBuf, sizeof(readBuf)); len = read(fd, readBuf, sizeof(readBuf));
if (len != strlen(writeBuf)) { if (len != strlen(writeBuf)) {
printf("read file failed.\n"); printf("read file failed.\n");
return LOS_NOK; return;
} }
printf("%s\n", readBuf); printf("%s\n", readBuf);
/* Close the file. */ /* Close the test file. */
ret = close(fd); ret = close(fd);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("close failed.\n"); printf("close failed.\n");
return LOS_NOK; return;
} }
/* Delete file.txt from the user/test directory. */ /* Delete the test file. */
ret = unlink(fileName); ret = unlink(fileName);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("unlink failed.\n"); printf("unlink failed.\n");
return LOS_NOK; return;
} }
/* Delete the user/test directory. */ /* Delete the test directory. */
ret = rmdir(dirName); ret = rmdir(dirName);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("rmdir failed.\n"); printf("rmdir failed.\n");
return LOS_NOK; return;
} }
return LOS_OK; return;
} }
``` ```
...@@ -232,102 +332,219 @@ Hello OpenHarmony! ...@@ -232,102 +332,219 @@ Hello OpenHarmony!
### Basic Concepts ### Basic Concepts
LittleFS is a small file system designed for flash. By combining the log-structured file system and the copy-on-write (COW) file system, LittleFS stores metadata in log structure and data in the COW structure. This special storage empowers LittleFS high power-loss resilience. LittleFS uses the statistical wear leveling algorithm when allocating COW data blocks, effectively prolonging the service life of flash devices. LittleFS is designed for small-sized devices with limited resources, such as ROM and RAM. All RAM resources are allocated through a buffer with the fixed size (configurable). That is, the RAM usage does not grow with the file system. LittleFS is a small file system designed for the flash drive. It stores metadata in log structure and data in the copy-on-write (COW) structure. This feature empowers LittleFS high power-loss resilience. LittleFS uses the statistical wear leveling algorithm when allocating COW data blocks, effectively prolonging the service life of flash devices. LittleFS is designed for small-sized devices with limited resources, such as ROM and RAM. All RAM resources are allocated through a buffer with the fixed size (configurable). That is, the RAM usage does not grow with the file system.
LittleFS is a good choice when you look for a flash file system that is power-cut resilient and has wear leveling support on a small device with limited resources. LittleFS is a good choice when you look for a flash file system that is power-cut resilient and has wear leveling support on a small device with limited resources.
### Development Guidelines ### Development Guidelines
Before porting LittleFS to a new hardware device, you need to declare **lfs_config**: Before using a LittleFS to a device, you need to initialize the flash drive and partition the device storage
API for partitioning the storage:
**int LOS_DiskPartition(const char \*dev, const char \*fsType, int \*lengthArray, int \*addrArray, int partNum);**
- **dev**: pointer to the device name.
- **fsType**: pointer to the file system type, which is **littlefs** for LittleFS.
- **lengthArray**: pointer to a list of partition lengths of the device.
- **addrArray**: pointer to a list of partition start addresses of the device.
- **partNum**: number of partitions.
API for formatting a partition:
**int LOS_PartitionFormat(const char \*partName, char \*fsType, void \*data);**
- **partName**: pointer to the partition name.
- **fsType**: pointer to the file system type, which is **littlefs** for LittleFS.
- **data**: pointer to the private data that passes in **void pass (VOID \*) struct fs_cfg**.
API for mounting a partition:
**int mount(const char \*source, const char \*target, const char \*filesystemtype, unsigned long mountflags, const void \*data);**
- **source**: pointer to the partition name.
- **target**: pointer to the target path to mount.
- **filesystemtype**: pointer to the file system type, which is **littlefs** for LittleFS.
- **mountflags**: parameters used for the mount operation.
- **data**: pointer to the private data that passes in **void pass (VOID \*) struct fs_cfg**.
The sample code is implemented in **./device/qemu/arm_mps2_an386/liteos_m/board/fs/fs_init.c** and can be directly used on the QEMU that uses the LiteOS-M kernel. You can modify the code based on the hardware you use.
``` ```
const struct lfs_config cfg = { #include "los_config.h"
// block device operations #include "ram_virt_flash.h"
.read = user_provided_block_device_read, #include "los_fs.h"
.prog = user_provided_block_device_prog,
.erase = user_provided_block_device_erase, struct fs_cfg {
.sync = user_provided_block_device_sync, CHAR *mount_point;
struct PartitionCfg partCfg;
// block device configuration
.read_size = 16,
.prog_size = 16,
.block_size = 4096,
.block_count = 128,
.cache_size = 16,
.lookahead_size = 16,
.block_cycles = 500,
}; };
INT32 LfsLowLevelInit()
{
INT32 ret;
struct fs_cfg fs[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
HalLogicPartition *halPartitionsInfo = getPartitionInfo(); /* Function for obtaining the partition lengths and start addresses. You can modify the function to match your development. */
INT32 lengthArray[2];
lengthArray[0]= halPartitionsInfo[FLASH_PARTITION_DATA0].partitionLength;
INT32 addrArray[2];
addrArray[0] = halPartitionsInfo[FLASH_PARTITION_DATA0].partitionStartAddr;
ret = LOS_DiskPartition("flash0", "littlefs", lengthArray, addrArray, 2);
printf("%s: DiskPartition %s\n", __func__, (ret == 0) ? "succeed" : "failed");
if (ret != 0) {
return -1;
}
fs[0].mount_point = "/littlefs";
fs[0].partCfg.partNo = 0;
fs[0].partCfg.blockSize = 4096; /* 4096, lfs block size */
fs[0].partCfg.blockCount = 1024; /* 2048, lfs block count */
fs[0].partCfg.readFunc = virt_flash_read; /* Function for reading data from the flash drive. You can modify it to match your development. */
fs[0].partCfg.writeFunc = virt_flash_write; /* Function for writing data to the flash drive. You can modify it to match your development. */
fs[0].partCfg.eraseFunc = virt_flash_erase; /* Function for erasing the flash driver. You can modify it to match your development. */
fs[0].partCfg.readSize = 256; /* 256, lfs read size */
fs[0].partCfg.writeSize = 256; /* 256, lfs prog size */
fs[0].partCfg.cacheSize = 256; /* 256, lfs cache size */
fs[0].partCfg.lookaheadSize = 16; /* 16, lfs lookahead size */
fs[0].partCfg.blockCycles = 1000; /* 1000, lfs block cycles */
ret = LOS_PartitionFormat("flash0", "littlefs", &fs[0].partCfg);
printf("%s: PartitionFormat %s\n", __func__, (ret == 0) ? "succeed" : "failed");
if (ret != 0) {
return -1;
}
ret = mount(NULL, fs[0].mount_point, "littlefs", 0, &fs[0].partCfg);
printf("%s: mount fs on '%s' %s\n", __func__, fs[0].mount_point, (ret == 0) ? "succeed" : "failed");
if (ret != 0) {
return -1;
}
return 0;
}
``` ```
**.read**, **.prog**, **.erase**, and **.sync** correspond to the read, write, erase, and synchronization APIs at the bottom layer of the hardware platform, respectively. The **.readFunc**, **.writeFunc**, and **.eraseFunc** functions correspond to **read()**, **write()**, and **erase()** of the underlying hardware platform.
**read_size** indicates the number of bytes read each time. You can set it to a value greater than the physical read unit to improve performance. This value determines the size of the read cache. However, if the value is too large, more memory is consumed. **readSize** indicates the number of bytes read each time. You can set it to a value greater than the physical read unit to improve performance. This value determines the size of the read cache. However, if the value is too large, more memory is consumed.
**prog_size** indicates the number of bytes written each time. You can set it to a value greater than the physical write unit to improve performance. This value determines the size of the write cache and must be an integral multiple of **read_size**. However, if the value is too large, more memory is consumed. **writeSize** indicates the number of bytes written each time. You can set it to a value greater than the physical write unit to improve performance. This value determines the size of the write cache and must be an integral multiple of **readSize**. However, if the value is too large, more memory is consumed.
**block_size**: indicates the number of bytes in each erase block. The value can be greater than that of the physical erase unit. However, a smaller value is recommended because each file occupies at least one block. The value must be an integral multiple of **prog_size**. **blockSize** indicates the number of bytes in each erase block. The value can be greater than that of the physical erase unit. However, a smaller value is recommended because each file occupies at least one block. The value must be an integral multiple of **writeSize**.
**block_count** indicates the number of blocks that can be erased, which depends on the capacity of the block device and the size of the block to be erased (**block_size**). **blockCount** indicates the number of blocks that can be erased, which depends on the capacity of the block device and the size of the block to be erased (**blockSize**).
### Sample Code ### Sample Code
The sample code is as follows: **Prerequisites**
- **/littlefs** is mounted to the QEMU.
- LittleFS is enabled.
1. In the **kernel/liteos_m** directory, run the **make menuconfig** command and choose **FileSystem->Enable FS VFS** to enable VFS.
2. Select **Enable Little FS** to enable the LittleFS.
The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleLittlefs** function is called in **TestTaskEntry**.
``` ```
#include "lfs.h" #include <stdio.h>
#include "stdio.h" #include <string.h>
lfs_t lfs; #include "sys/stat.h"
lfs_file_t file; #include "fcntl.h"
const struct lfs_config cfg = { #include "unistd.h"
// block device operations
.read = user_provided_block_device_read, #define BUF_SIZE 20
.prog = user_provided_block_device_prog, #define TEST_ROOT "/littlefs" /* Set the test root directory. */
.erase = user_provided_block_device_erase, VOID ExampleLittlefs(VOID)
.sync = user_provided_block_device_sync, {
// block device configuration int ret;
.read_size = 16, int fd;
.prog_size = 16, ssize_t len;
.block_size = 4096, off_t off;
.block_count = 128, char dirName[BUF_SIZE] = TEST_ROOT"/test";
.cache_size = 16, char fileName[BUF_SIZE] = TEST_ROOT"/test/file.txt";
.lookahead_size = 16, char writeBuf[BUF_SIZE] = "Hello OpenHarmony!";
.block_cycles = 500, char readBuf[BUF_SIZE] = {0};
};
int main(void) { /* Create a test directory. */
// mount the filesystem ret = mkdir(dirName, 0777);
int err = lfs_mount(&lfs, &cfg); if (ret != LOS_OK) {
// reformat if we can't mount the filesystem printf("mkdir failed.\n");
// this should only happen on the first boot return;
if (err) { }
lfs_format(&lfs, &cfg);
lfs_mount(&lfs, &cfg); /* Create a file that is readable and writable. */
fd = open(fileName, O_RDWR | O_CREAT, 0777);
if (fd < 0) {
printf("open file failed.\n");
return;
} }
// read current count
uint32_t boot_count = 0; /* Write the content from writeBuf to the file. */
lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); len = write(fd, writeBuf, strlen(writeBuf));
lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); if (len != strlen(writeBuf)) {
// update boot count printf("write file failed.\n");
boot_count += 1; return;
lfs_file_rewind(&lfs, &file); }
lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count));
// remember the storage is not updated until the file is closed successfully /* Save the file to a storage device. */
lfs_file_close(&lfs, &file); ret = fsync(fd);
// release any resources we were using if (ret != LOS_OK) {
lfs_unmount(&lfs); printf("fsync failed.\n");
// print the boot count return;
printf("boot_count: %d\n", boot_count); }
/* Move the read/write pointer to the beginning of the file. */
off = lseek(fd, 0, SEEK_SET);
if (off != 0) {
printf("lseek failed.\n");
return;
}
/* Read the file content with the length of readBuf to readBuf. */
len = read(fd, readBuf, sizeof(readBuf));
if (len != strlen(writeBuf)) {
printf("read file failed.\n");
return;
}
printf("%s\n", readBuf);
/* Close the test file. */
ret = close(fd);
if (ret != LOS_OK) {
printf("close failed.\n");
return;
}
/* Delete the test file. */
ret = unlink(fileName);
if (ret != LOS_OK) {
printf("unlink failed.\n");
return;
}
/* Delete the directory. */
ret = rmdir(dirName);
if (ret != LOS_OK) {
printf("rmdir failed.\n");
return;
}
return LOS_OK;
} }
``` ```
**Verification**
**Verification**
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
Say hello 1 times. Hello OpenHarmony!
``` ```
...@@ -11,16 +11,16 @@ The purpose of memory debugging is to locate problems related to dynamic memory. ...@@ -11,16 +11,16 @@ The purpose of memory debugging is to locate problems related to dynamic memory.
Memory information includes the memory pool size, memory usage, remaining memory size, maximum free memory, memory waterline, number of memory nodes, and fragmentation rate. Memory information includes the memory pool size, memory usage, remaining memory size, maximum free memory, memory waterline, number of memory nodes, and fragmentation rate.
- Memory waterline: indicates the maximum memory used in a memory pool. The waterline value is updated upon each memory allocation and release. The memory pool size can be optimized based on this value. - Memory waterline indicates the maximum memory used in a memory pool. The waterline value is updated upon each memory allocation and release. The memory pool size can be optimized based on this value.
- Fragmentation rate: indicates the fragmentation degree of the memory pool. If the fragmentation rate is high, there are a large number of free memory blocks in the memory pool but each block is small. You can use the following formula to calculate the fragmentation rate:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size - Fragmentation rate indicates the fragmentation degree of the memory pool. If the fragmentation rate is high, there are a large number of free memory blocks in the memory pool but each block is small. You can use the following formula to calculate the fragmentation rate:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
- Other parameters: You can call APIs described in [Memory Management](../kernel/kernel-mini-basic-memory.md) to scan node information in the memory pool and collect statistics. - You can use [APIs for memory management](kernel-mini-basic-memory.md) to scan node information in the memory pool and collect statistics.
### Function Configuration ### Function Configuration
**LOSCFG_MEM_WATERLINE**: specifies the setting of the memory information statistics function. This function is enabled by default. To disable the function, set this macro to **0** in **target_config.h**. If you want to obtain the memory waterline, you must enable this macro. **LOSCFG_MEM_WATERLINE** specifies the setting of the memory information statistics function. This function is enabled by default. To disable the function, set this macro to **0** in **target_config.h**. If you want to obtain the memory waterline, you must enable this macro.
### Development Guidelines ### Development Guidelines
...@@ -38,15 +38,15 @@ typedef struct { ...@@ -38,15 +38,15 @@ typedef struct {
UINT32 maxFreeNodeSize; // Maximum size of the free memory block in the memory pool. UINT32 maxFreeNodeSize; // Maximum size of the free memory block in the memory pool.
UINT32 usedNodeNum; // Number of non-free memory blocks in the memory pool. UINT32 usedNodeNum; // Number of non-free memory blocks in the memory pool.
UINT32 freeNodeNum; // Number of free memory blocks in the memory pool. UINT32 freeNodeNum; // Number of free memory blocks in the memory pool.
#if (LOSCFG_MEM_WATERLINE == 1) //The function is enabled by default. To disable it, set this macro to 0 in target_config.h. #if (LOSCFG_MEM_WATERLINE == 1) // The function is enabled by default. To disable it, set this macro to 0 in target_config.h.
UINT32 usageWaterLine; // Waterline of the memory pool. UINT32 usageWaterLine; // Waterline of the memory pool.
#endif #endif
} LOS_MEM_POOL_STATUS; } LOS_MEM_POOL_STATUS;
``` ```
- To obtain the memory waterline, call **LOS_MemInfoGet**. The first parameter in the API is the start address of the memory pool, and the second parameter is the handle of the **LOS_MEM_POOL_STATUS** type. The **usageWaterLine** field indicates the waterline. To obtain the memory waterline, call **LOS_MemInfoGet**. The first parameter in the API is the start address of the memory pool, and the second parameter is the handle of the **LOS_MEM_POOL_STATUS** type. The **usageWaterLine** field indicates the waterline.
- To calculate the memory fragmentation rate, call **LOS_MemInfoGet** to obtain the remaining memory size and the maximum free memory block size in the memory pool, and then calculate the fragmentation rate of the dynamic memory pool as follows:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size To calculate the memory fragmentation rate, call **LOS_MemInfoGet** to obtain the remaining memory size and the maximum free memory block size in the memory pool, and then calculate the fragmentation rate of the dynamic memory pool as follows:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
#### Development Example #### Development Example
...@@ -62,7 +62,9 @@ This example implements the following: ...@@ -62,7 +62,9 @@ This example implements the following:
#### Sample Code #### Sample Code
The sample code is as follows: The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **MemTest** function is called in **TestTaskEntry**.
``` ```
#include <stdio.h> #include <stdio.h>
...@@ -71,7 +73,7 @@ This example implements the following: ...@@ -71,7 +73,7 @@ This example implements the following:
#include "los_memory.h" #include "los_memory.h"
#include "los_config.h" #include "los_config.h"
#define TEST_TASK_PRIO 5
void MemInfoTaskFunc(void) void MemInfoTaskFunc(void)
{ {
LOS_MEM_POOL_STATUS poolStatus = {0}; LOS_MEM_POOL_STATUS poolStatus = {0};
...@@ -80,11 +82,11 @@ void MemInfoTaskFunc(void) ...@@ -80,11 +82,11 @@ void MemInfoTaskFunc(void)
void *pool = OS_SYS_MEM_ADDR; void *pool = OS_SYS_MEM_ADDR;
LOS_MemInfoGet(pool, &poolStatus); LOS_MemInfoGet(pool, &poolStatus);
/* Calculate the fragmentation rate of the memory pool. */ /* Calculate the fragmentation rate of the memory pool. */
unsigned char fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; float fragment = 100 - poolStatus.maxFreeNodeSize * 100.0 / poolStatus.totalFreeSize;
/* Calculate the memory usage of the memory pool. */ /* Calculate the memory usage of the memory pool. */
unsigned char usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); float usage = LOS_MemTotalUsedGet(pool) * 100.0 / LOS_MemPoolSizeGet(pool);
printf("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment, poolStatus.maxFreeNodeSize, printf("usage = %f, fragment = %f, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment,
poolStatus.totalFreeSize, poolStatus.usageWaterLine); poolStatus.maxFreeNodeSize, poolStatus.totalFreeSize, poolStatus.usageWaterLine);
} }
int MemTest(void) int MemTest(void)
...@@ -93,9 +95,9 @@ int MemTest(void) ...@@ -93,9 +95,9 @@ int MemTest(void)
unsigned int taskID; unsigned int taskID;
TSK_INIT_PARAM_S taskStatus = {0}; TSK_INIT_PARAM_S taskStatus = {0};
taskStatus.pfnTaskEntry = (TSK_ENTRY_FUNC)MemInfoTaskFunc; taskStatus.pfnTaskEntry = (TSK_ENTRY_FUNC)MemInfoTaskFunc;
taskStatus.uwStackSize = 0x1000; taskStatus.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
taskStatus.pcName = "memInfo"; taskStatus.pcName = "memInfo";
taskStatus.usTaskPrio = 10; taskStatus.usTaskPrio = TEST_TASK_PRIO;
ret = LOS_TaskCreate(&taskID, &taskStatus); ret = LOS_TaskCreate(&taskID, &taskStatus);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task create failed\n"); printf("task create failed\n");
...@@ -112,7 +114,9 @@ The result is as follows: ...@@ -112,7 +114,9 @@ The result is as follows:
``` ```
usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414 usage = 0.458344, fragment = 0.000000, maxFreeSize = 16474928, totalFreeSize = 16474928, waterLine = 76816
The preceding data may vary depending on the running environment.
``` ```
## Memory Leak Check ## Memory Leak Check
...@@ -124,14 +128,15 @@ As an optional function of the kernel, memory leak check is used to locate dynam ...@@ -124,14 +128,15 @@ As an optional function of the kernel, memory leak check is used to locate dynam
### Function Configuration ### Function Configuration
1. **LOSCFG_MEM_LEAKCHECK**: specifies the setting of the memory leak check. This function is disabled by default. To enable the function, set this macro to **1** in **target_config.h**. **LOSCFG_MEM_LEAKCHECK** specifies the setting of the memory leak check. This function is disabled by default. To enable the function, set this macro to **1** in **target_config.h**.
**LOSCFG_MEM_RECORD_LR_CNT** specifies the number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof(void \*)** bytes.
2. **LOSCFG_MEM_RECORD_LR_CNT**: specifies the number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof(void\*)** bytes. **LOSCFG_MEM_OMIT_LR_CNT** specifies the number of ignored LRs. The default value is **4**, which indicates that LRs are recorded from the time when **LOS_MemAlloc** is called. You can change the value based on actual requirements. This macro is configured because:
3. **LOSCFG_MEM_OMIT_LR_CNT**: specifies the number of ignored LRs. The default value is **4**, which indicates that LRs are recorded from the time when **LOS_MemAlloc** is called. You can change the value based on actual requirements. This macro is configured because: - **LOS_MemAlloc** is also called internally.
- **LOS_MemAlloc** is also called internally. - **LOS_MemAlloc** may be encapsulated externally.
- **LOS_MemAlloc** may be encapsulated externally. - The number of LRs configured by **LOSCFG_MEM_RECORD_LR_CNT** is limited.
- The number of LRs configured by **LOSCFG_MEM_RECORD_LR_CNT** is limited.
Correctly setting this macro can ignore invalid LRs and reduce memory consumption. Correctly setting this macro can ignore invalid LRs and reduce memory consumption.
...@@ -156,7 +161,8 @@ node size LR[0] LR[1] LR[2] ...@@ -156,7 +161,8 @@ node size LR[0] LR[1] LR[2]
0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0
``` ```
> ![icon-caution.gif](../public_sys-resources/icon-caution.gif) **CAUTION**<br/> > **CAUTION**
>
> Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead. > Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead.
...@@ -179,6 +185,12 @@ This example implements the following: ...@@ -179,6 +185,12 @@ This example implements the following:
The sample code is as follows: The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **MemLeakTest** function is called in **TestTaskEntry**.
When QEMU is running, ensure that the value of **LOSCFG_MEM_FREE_BY_TASKID** in **target_config.h** is **0**.
After the memory check function is enabled, other tasks running on certain platforms may frequently print memory-related information such as "psp, start = xxxxx, end = xxxxxxx". Ignore the information or delete the print information called by **OsStackAddrGet**.
``` ```
#include <stdio.h> #include <stdio.h>
...@@ -217,6 +229,8 @@ node size LR[0] LR[1] LR[2] ...@@ -217,6 +229,8 @@ node size LR[0] LR[1] LR[2]
0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220 0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220
0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6
0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000
The preceding data may vary depending on the running environment.
``` ```
The difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak. The difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak.
...@@ -225,6 +239,8 @@ The difference between the two logs is as follows. The following memory nodes ar ...@@ -225,6 +239,8 @@ The difference between the two logs is as follows. The following memory nodes ar
``` ```
0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6
0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000
The preceding data may vary depending on the running environment.
``` ```
The following is part of the assembly file: The following is part of the assembly file:
...@@ -246,6 +262,8 @@ The following is part of the assembly file: ...@@ -246,6 +262,8 @@ The following is part of the assembly file:
0x80041f0: 0xf7fd 0xf933 BL LOS_MemUsedNodeShow ; 0x800145a 0x80041f0: 0xf7fd 0xf933 BL LOS_MemUsedNodeShow ; 0x800145a
0x80041f4: 0xbd10 POP {R4, PC} 0x80041f4: 0xbd10 POP {R4, PC}
0x80041f6: 0x0000 MOVS R0, R0 0x80041f6: 0x0000 MOVS R0, R0
The preceding data may vary depending on the running environment.
``` ```
The memory node addressed by **0x080041ee** is not released after being requested in **MemLeakTest**. The memory node addressed by **0x080041ee** is not released after being requested in **MemLeakTest**.
...@@ -260,15 +278,16 @@ As an optional function of the kernel, memory corruption check is used to check ...@@ -260,15 +278,16 @@ As an optional function of the kernel, memory corruption check is used to check
### Function Configuration ### Function Configuration
**LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK**: specifies the setting of the memory corruption check. This function is disabled by default. To enable the function, set this macro to **1** in **target_config.h**. **LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** specifies the setting of the memory corruption check. This function is disabled by default. To enable the function, set this macro to **1** in **target_config.h**.
1. If this macro is enabled, the memory pool integrity will be checked in real time upon each memory allocation. 1. If this macro is enabled, the memory pool integrity will be checked in real time upon each memory allocation.
2. If this macro is not enabled, you can call **LOS_MemIntegrityCheck** to check the memory pool integrity when required. Using **LOS_MemIntegrityCheck** does not affect the system performance. In addition, the check accuracy decreases because the node header does not contain the magic number (which is available only when **LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** is enabled). 2. If this macro is not enabled, you can call **LOS_MemIntegrityCheck** to check the memory pool integrity when required. Using **LOS_MemIntegrityCheck** does not affect the system performance. However, the check accuracy decreases because the node header does not contain the magic number (which is available only when **LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** is enabled).
This check only detects the corrupted memory node and provides information about the previous node (because memory is contiguous, a node is most likely corrupted by the previous node). To further determine the location where the previous node is requested, you need to enable the memory leak check and use LRs to locate the fault. This check only detects the corrupted memory node and provides information about the previous node (because memory is contiguous, a node is most likely corrupted by the previous node). To further determine the location where the previous node is requested, you need to enable the memory leak check and use LRs to locate the fault.
> ![icon-caution.gif](../public_sys-resources/icon-caution.gif) **CAUTION**<br/> > **CAUTION**
>
> If memory corruption check is enabled, a magic number is added to the node header, which increases the size of the node header. The real-time integrity check has a great impact on the performance. In performance-sensitive scenarios, you are advised to disable this function and use **LOS_MemIntegrityCheck** to check the memory pool integrity. > If memory corruption check is enabled, a magic number is added to the node header, which increases the size of the node header. The real-time integrity check has a great impact on the performance. In performance-sensitive scenarios, you are advised to disable this function and use **LOS_MemIntegrityCheck** to check the memory pool integrity.
...@@ -295,6 +314,12 @@ This example implements the following: ...@@ -295,6 +314,12 @@ This example implements the following:
The sample code is as follows: The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **MemIntegrityTest** function is called in **TestTaskEntry**.
When QEMU is running, ensure that the value of **LOSCFG_MEM_FREE_BY_TASKID** in **target_config.h** is **0**.
Because the exception is triggered intentionally, you need to restart QEMU when the execution is complete. For example, open a new terminal and run **killall qemu-system-arm**.
``` ```
#include <stdio.h> #include <stdio.h>
...@@ -320,20 +345,28 @@ The log is as follows: ...@@ -320,20 +345,28 @@ The log is as follows:
``` ```
[ERR][OsMemMagicCheckPrint], 2028, memory check error!
memory used but magic num wrong, magic num = 0x00000000 /* Error information, indicating that the first four bytes, that is, the magic number, of the next node are corrupted. */ /* Error information indicating the field corrupted. In this example, the first four bytes of the next node are cleared, that is, the magic number field is corrupted. */
[ERR][IT_TST_INI][OsMemMagicCheckPrint], 1664, memory check error!
broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020 memory used but magic num wrong, magic num = 0x0
/* Key information about the corrupted node and its previous node, including the address of the previous node, magic number of the node, and sizeAndFlag of the node. In this example, the magic number of the corrupted node is cleared. */
/* Key information about the corrupted node and its previous node, including the address of the previous node, magic number of the node, and sizeAndFlag of the node. In this example, the magic number of the corrupted node is cleared. */
broken node head LR info: /* The node LR information can be output only after the memory leak check is enabled. */ broken node head: 0x2103d7e8 0x0 0x80000020, prev node head: 0x2103c7cc 0xabcddcba 0x80000020
LR[0]:0x0800414e
LR[1]:0x08000cc2 /*The node LR information can be output only after the memory leak check is enabled. */
LR[2]:0x00000000 broken node head LR info:
LR[0]:0x2101906c
pre node head LR info: /* Based on the LR information, you can find where the previous node is requested in the assembly file and then perform further analysis. */ LR[1]:0x0
LR[0]:0x08004144 LR[2]:0x0
LR[1]:0x08000cc2
LR[2]:0x00000000 /* Based on the LR information, you can determine where the previous node in requsted in the assembly file and check the use of the node. */
[ERR]Memory integrity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* Addresses of the corrupted node and its previous node */ pre node head LR info:
LR[0]:0x2101906c
LR[1]:0x0
LR[2]:0x0
/* Addresses of the corrupted node and its previous node. */
[ERR][IT_TST_INI]Memory integrity check error, cur node: 0x2103d784, pre node: 0x0
The preceding data may vary depending on the running environment.
``` ```
# Exception Debugging # Exception Debugging
## Basic Concepts ## Basic Concepts
The OpenHarmony LiteOS-M provides exception handling and debugging measures to help locate and analyze problems. Exception handling involves a series of actions taken by the OS to respond to exceptions occurred during the OS running, for example, printing the exception type, system status, call stack information of the current function, CPU information, and call stack information of tasks. The OpenHarmony LiteOS-M provides exception handling and debugging measures to help locate and analyze problems. Exception handling involves a series of actions taken by the OS to respond to exceptions occurred during the OS running, for example, printing the exception type, system status, call stack information of the current function, CPU information, and call stack information of tasks.
## Working Principles ## Working Principles
A stack frame contains information such as function parameters, variables, and return value in a function call process. When a function is called, a stack frame of the subfunction is created, and the input parameters, local variables, and registers of the function are stored into the stack. Stack frames grow towards lower addresses. The ARM32 CPU architecture is used as an example. Each stack frame stores the historical values of the program counter \(PC\), LR \(link register\), stack pointer \(SP\), and frame pointer \(FP\) registers. The LR points to the return address of a function, and the FP points to the start address of the stack frame of the function's parent function. The FP helps locate the parent function's stack frame, which further helps locate the parent function's FP. The parent function's FP helps locate the grandparent function's stack frame and FP... In this way, the call stack of the program can be traced to obtain the relationship between the functions called. A stack frame contains information such as function parameters, variables, and return value in a function call process. When a function is called, a stack frame of the subfunction is created, and the input parameters, local variables, and registers of the function are stored into the stack. Stack frames grow towards lower addresses. The ARM32 CPU architecture is used as an example. Each stack frame stores the historical values of the program counter (PC), link register (LR), stack pointer (SP), and frame pointer (FP) registers. The LR points to the return address of a function, and the FP points to the start address of the stack frame of the function's parent function. The FP helps locate the parent function's stack frame, which further helps locate the parent function's FP. The parent function's FP helps locate the grandparent function's stack frame and FP... In this way, the call stack of the program can be traced to obtain the relationship between the functions called.
When an exception occurs in the system, the system prints the register information in the stack frame of the abnormal function as well as the LRs and FPs in the stack frames of its parent function and grandfather function. The relationships between the functions help you locate the cause of the exception. When an exception occurs in the system, the system prints the register information in the stack frame of the abnormal function as well as the LRs and FPs in the stack frames of its parent function and grandfather function. The relationships between the functions help you locate the cause of the exception.
The following figure illustrates the stack analysis mechanism for your reference. The actual stack information varies depending on the CPU architecture. The following figure illustrates the stack analysis mechanism for your reference. The actual stack information varies depending on the CPU architecture.
**Figure 1** Stack analysis mechanism **Figure 1** Stack analysis mechanism
![](figures/stack-analysis-mechanism.png "stack-analysis-mechanism") ![](figures/stack-analysis-mechanism.png "stack-analysis-mechanism")
In the figure, the registers in different colors indicate different functions. The registers save related data when functions are called. The FP register helps track the stack to the parent function of the abnormal function and further presents the relationships between the functions called. In the figure, the registers in different colors indicate different functions. The registers save related data when functions are called. The FP register helps track the stack to the parent function of the abnormal function and further presents the relationships between the functions called.
## Available APIs ## Available APIs
The following table describes APIs available for the OpenHarmony LiteOS-M stack trace module. For more details about the APIs, see the API reference. The following table describes APIs available for the OpenHarmony LiteOS-M stack trace module. For more details about the APIs, see the API reference.
**Table 1** APIs of the stack trace module **Table 1** APIs of the stack trace module
<a name="table1415203765610"></a> | Category| API|
<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Function</p> | -------- | -------- |
</th> | Stack tracing| **LOS_BackTrace**: prints the call stack relationship at the calling point.<br>**LOS_RecordLR**: obtains the call stack relationship at the calling point when print is unavailable.|
<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p> ## Development Guidelines
</th>
</tr>
</thead>
<tbody><tr id="row1841519376561"><td class="cellrowborder" rowspan="2" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p294964222410"><a name="p294964222410"></a><a name="p294964222410"></a>Stack trace</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p4166128181614"><a name="p4166128181614"></a><a name="p4166128181614"></a>LOS_BackTrace</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1516617282165"><a name="p1516617282165"></a><a name="p1516617282165"></a>Prints the call stack relationship at the function calling point.</p>
</td>
</tr>
<tr id="row1187514443616"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p682431610715"><a name="p682431610715"></a><a name="p682431610715"></a>LOS_RecordLR</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p4969192715710"><a name="p4969192715710"></a><a name="p4969192715710"></a>Obtains the call stack relationship at the function calling point when print is unavailable.</p>
</td>
</tr>
</tbody>
</table>
## Usage Guidelines
### How to Develop ### How to Develop
The typical process for enabling exception debugging is as follows: The typical process for enabling exception debugging is as follows:
1. Configure the macros related to exception handling. 1. Configure the macros related to exception handling
in the **target_config.h** file.
Modify the configuration in the **target\_config.h** file. | Configuration Item| Description| Value|
| -------- | -------- | -------- |
<a name="table1078714915105"></a> | LOSCFG_BACKTRACE_DEPTH | Depth of the function call stack. The default value is **15**.| 15 |
<table><thead align="left"><tr id="row1280518971010"><th class="cellrowborder" valign="top" width="20.1%" id="mcps1.1.4.1.1"><p id="p1380510912104"><a name="p1380510912104"></a><a name="p1380510912104"></a>Parameter</p> | LOSCFG_BACKTRACE_TYPE | Type of the stack tracing.<br>**0**: The stack tracing is disabled.<br>**1**: supports call stack analysis of the Cortex-M series hardware.<br>**2**: supports call stack analysis of the RISC-V series hardware.| Set this parameter to **1** or **2** based on the toolchain type.|
</th>
<th class="cellrowborder" valign="top" width="37.47%" id="mcps1.1.4.1.2"><p id="p08051291106"><a name="p08051291106"></a><a name="p08051291106"></a>Description</p>
</th>
<th class="cellrowborder" valign="top" width="42.43%" id="mcps1.1.4.1.3"><p id="p12805149151012"><a name="p12805149151012"></a><a name="p12805149151012"></a>Value</p>
</th>
</tr>
</thead>
<tbody><tr id="row168052913104"><td class="cellrowborder" valign="top" width="20.1%" headers="mcps1.1.4.1.1 "><p id="p180618915101"><a name="p180618915101"></a><a name="p180618915101"></a>LOSCFG_BACKTRACE_DEPTH</p>
</td>
<td class="cellrowborder" valign="top" width="37.47%" headers="mcps1.1.4.1.2 "><p id="p198061196105"><a name="p198061196105"></a><a name="p198061196105"></a>Depth of the function call stack. The default value is <strong id="b1041811416176"><a name="b1041811416176"></a><a name="b1041811416176"></a>15</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="42.43%" headers="mcps1.1.4.1.3 "><p id="p1980609121010"><a name="p1980609121010"></a><a name="p1980609121010"></a>15</p>
</td>
</tr>
<tr id="row4806990105"><td class="cellrowborder" valign="top" width="20.1%" headers="mcps1.1.4.1.1 "><p id="p18940141181618"><a name="p18940141181618"></a><a name="p18940141181618"></a>LOSCFG_BACKTRACE_TYPE</p>
</td>
<td class="cellrowborder" valign="top" width="37.47%" headers="mcps1.1.4.1.2 "><p id="p280620917109"><a name="p280620917109"></a><a name="p280620917109"></a>Type of the stack trace.</p>
<p id="p9133142211184"><a name="p9133142211184"></a><a name="p9133142211184"></a><strong id="b9882230181814"><a name="b9882230181814"></a><a name="b9882230181814"></a>0</strong>: disabled</p>
<p id="p1133122212183"><a name="p1133122212183"></a><a name="p1133122212183"></a><strong id="b1863620373182"><a name="b1863620373182"></a><a name="b1863620373182"></a>1</strong>: supports function call stack analysis of the Cortex-m series hardware.</p>
<p id="p1133822101814"><a name="p1133822101814"></a><a name="p1133822101814"></a><strong id="b106211355191914"><a name="b106211355191914"></a><a name="b106211355191914"></a>2</strong>: supports function call stack analysis of the RISC-V series hardware.</p>
</td>
<td class="cellrowborder" valign="top" width="42.43%" headers="mcps1.1.4.1.3 "><p id="p780614919107"><a name="p780614919107"></a><a name="p780614919107"></a>Set this parameter to <strong id="b1926720398209"><a name="b1926720398209"></a><a name="b1926720398209"></a>1</strong> or <strong id="b149341042172017"><a name="b149341042172017"></a><a name="b149341042172017"></a>2</strong> based on the toolchain type.</p>
</td>
</tr>
</tbody>
</table>
1. Use the error code in the example to build and run a project, and check the error information displayed on the serial port terminal. The sample code simulates error code. During actual product development, use the exception debugging mechanism to locate exceptions. 1. Use the error code in the example to build and run a project, and check the error information displayed on the serial port terminal. The sample code simulates error code. During actual product development, use the exception debugging mechanism to locate exceptions.
The following example demonstrates the exception output through a task. The task entry function simulates calling of multiple functions and finally calls a function that simulates an exception. The sample code is as follows: The following example demonstrates the exception output through a task. The task entry function simulates calling of multiple functions and finally calls a function that simulates an exception. The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleExcEntry** function is called in **TestTaskEntry**.
``` ```
#include <stdio.h> #include <stdio.h>
#include "los_config.h" #include "los_config.h"
...@@ -100,30 +60,31 @@ The typical process for enabling exception debugging is as follows: ...@@ -100,30 +60,31 @@ The typical process for enabling exception debugging is as follows:
UINT32 g_taskExcId; UINT32 g_taskExcId;
#define TSK_PRIOR 4 #define TSK_PRIOR 4
/* Simulate an abnormal function. */ /* Simulate an exception. */
UINT32 GetResultException0(UINT16 dividend){
UINT32 Get_Result_Exception_0(UINT16 dividend){ UINT32 result = *(UINT32 *)(0xffffffff);
UINT32 divisor = 0; printf("Enter GetResultException0. %u\r\n", result);
UINT32 result = dividend / divisor;
return result; return result;
} }
UINT32 Get_Result_Exception_1(UINT16 dividend){ UINT32 GetResultException1(UINT16 dividend){
return Get_Result_Exception_0(dividend); printf("Enter GetResultException1.\r\n");
return GetResultException0(dividend);
} }
UINT32 Get_Result_Exception_2(UINT16 dividend){ UINT32 GetResultException2(UINT16 dividend){
return Get_Result_Exception_1(dividend); printf("Enter GetResultException2.\r\n");
return GetResultException1(dividend);
} }
UINT32 Example_Exc(VOID) UINT32 ExampleExc(VOID)
{ {
UINT32 ret; UINT32 ret;
printf("Enter Example_Exc Handler.\r\n"); printf("Enter Example_Exc Handler.\r\n");
/* Simulate the function calling. */ /* Simulate the triggering of the exception. */
ret = Get_Result_Exception_2(TSK_PRIOR); ret = GetResultException2(TSK_PRIOR);
printf("Divided result =%u.\r\n", ret); printf("Divided result =%u.\r\n", ret);
printf("Exit Example_Exc Handler.\r\n"); printf("Exit Example_Exc Handler.\r\n");
...@@ -131,22 +92,22 @@ The typical process for enabling exception debugging is as follows: ...@@ -131,22 +92,22 @@ The typical process for enabling exception debugging is as follows:
} }
/* Task entry function used to create a task with an exception. */ /* Create a task with an exception in the task entry function. */
UINT32 Example_Exc_Entry(VOID) UINT32 ExampleExcEntry(VOID)
{ {
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S initParam; TSK_INIT_PARAM_S initParam = { 0 };
/* Lock task scheduling to prevent newly created tasks from being scheduled prior to this task due to higher priority.*/ /* Lock task scheduling to prevent newly created tasks from being scheduled prior to this task due to higher priority. */
LOS_TaskLock(); LOS_TaskLock();
printf("LOS_TaskLock() Success!\r\n"); printf("LOS_TaskLock() Success!\r\n");
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Exc; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleExc;
initParam.usTaskPrio = TSK_PRIOR; initParam.usTaskPrio = TSK_PRIOR;
initParam.pcName = "Example_Exc"; initParam.pcName = "Example_Exc";
initParam.uwStackSize = LOSCFG_SECURE_STACK_DEFAULT_SIZE; initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
/* Create a task with higher priority. The task will not be executed immediately after being created, because task scheduling is locked.*/ /* Create a task with a higher priority. The task will not be executed because task scheduling is locked. */
ret = LOS_TaskCreate(&g_taskExcId, &initParam); ret = LOS_TaskCreate(&g_taskExcId, &initParam);
if (ret != LOS_OK) { if (ret != LOS_OK) {
LOS_TaskUnlock(); LOS_TaskUnlock();
...@@ -157,81 +118,70 @@ The typical process for enabling exception debugging is as follows: ...@@ -157,81 +118,70 @@ The typical process for enabling exception debugging is as follows:
printf("Example_Exc create Success!\r\n"); printf("Example_Exc create Success!\r\n");
/* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed.*/ /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed. */
LOS_TaskUnlock(); LOS_TaskUnlock();
return LOS_OK; return LOS_OK;
} }
``` ```
The error information output by the serial port terminal is as follows:
1. The error information displayed on the serial port terminal is as follows:
``` ```
entering kernel init...
LOS_TaskLock() Success! LOS_TaskLock() Success!
Example_Exc create Success! Example_Exc create Success!
Entering scheduler
Enter Example_Exc Handler. Enter Example_Exc Handler.
Enter GetResultException2.
Enter GetResultException1.
*************Exception Information************** *************Exception Information**************
Type = 10 Type = 4
ThrdPid = 4 ThrdPid = 5
Phase = exc in task Phase = exc in task
FaultAddr = 0xabababab FaultAddr = 0xfffffffc
Current task info: Current task info:
Task name = Example_Exc Task name = Example_Exc
Task ID = 4 Task ID = 5
Task SP = 0x200051ac Task SP = 0x210549bc
Task ST = 0x20004ff0 Task ST = 0x21053a00
Task SS = 0x200 Task SS = 0x1000
Exception reg dump: Exception reg dump:
PC = 0x80037da PC = 0x2101c61a
LR = 0x80037fe LR = 0x2101c64d
SP = 0x20005190 SP = 0x210549a8
R0 = 0x4 R0 = 0x4
R1 = 0x40 R1 = 0xa
R2 = 0x4 R2 = 0x0
R3 = 0x0 R3 = 0xffffffff
R4 = 0x4040404 R4 = 0x2103fb20
R5 = 0x5050505 R5 = 0x5050505
R6 = 0x6060606 R6 = 0x6060606
R7 = 0x20005190 R7 = 0x210549a8
R8 = 0x8080808 R8 = 0x8080808
R9 = 0x9090909 R9 = 0x9090909
R10 = 0x10101010 R10 = 0x10101010
R11 = 0x11111111 R11 = 0x11111111
R12 = 0x12121212 R12 = 0x0
PriMask = 0x0 PriMask = 0x0
xPSR = 0x41000000 xPSR = 0x41000000
----- backtrace start ----- ----- backtrace start -----
backtrace 0 -- lr = 0x800381a backtrace 0 -- lr = 0x2101c64c
backtrace 1 -- lr = 0x8003836 backtrace 1 -- lr = 0x2101c674
backtrace 2 -- lr = 0x8005a4e backtrace 2 -- lr = 0x2101c696
backtrace 3 -- lr = 0x8000494 backtrace 3 -- lr = 0x2101b1ec
backtrace 4 -- lr = 0x8008620
backtrace 5 -- lr = 0x800282c
backtrace 6 -- lr = 0x80008a0
backtrace 7 -- lr = 0x80099f8
backtrace 8 -- lr = 0x800a01a
backtrace 9 -- lr = 0x800282c
backtrace 10 -- lr = 0x80008a0
backtrace 11 -- lr = 0x80099f8
backtrace 12 -- lr = 0x8009bf0
backtrace 13 -- lr = 0x8009c52
backtrace 14 -- lr = 0x80099aa
----- backtrace end ----- ----- backtrace end -----
TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID name TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID CPUUSE CPUUSE10s CPUUSE1s TaskEntry name
--- -------- -------- --------- ---------- ---------- ---------- --------- ----- ---- --- -------- -------- --------- --------- ---------- ---------- --------- ------ ------- --------- -------- ---------- ----
0 0 Pend 0x2d0 0x104 0x200029bc 0x200027f0 0x0 0xffff Swt_Task 0 0 Pend 0x1000 0xdc 0x2104730c 0x210463e8 0 0xffff 0.0 0.0 0.0 0x2101a199 Swt_Task
1 31 Ready 0x500 0x44 0x20002f84 0x20002ac8 0x0 0xffff IdleCore000 1 31 Ready 0x500 0x44 0x210478e4 0x21047428 0 0xffff 0.0 0.0 0.0 0x2101a9c9 IdleCore000
2 6 Ready 0x1000 0x44 0x20003f94 0x20002fd8 0x0 0xffff TaskSampleEntry1 2 5 PendTime 0x6000 0xd4 0x2104e8f4 0x210489c8 0 0xffff 5.7 5.7 0.0 0x21016149 tcpip_thread
3 7 Ready 0x1000 0x44 0x20004f9c 0x20003fe0 0x0 0xffff TaskSampleEntry2 3 3 Pend 0x1000 0x488 0x2104f90c 0x2104e9e8 0x1 0xffff 8.6 8.6 0.0 0x21016db5 ShellTaskEntry
4 4 Running 0x200 0xec 0x200051ac 0x20004ff0 0x0 0xffff Example_Exc 4 25 Ready 0x4000 0x460 0x21053964 0x2104f9f0 0 0xffff 9.0 8.9 0.0 0x2101c765 IT_TST_INI
5 4 Running 0x1000 0x458 0x210549bc 0x21053a00 0 0xffff 76.5 76.6 0.0 0x2101c685 Example_Exc
OS exception NVIC dump: OS exception NVIC dump:
interrupt enable register, base address: 0xe000e100, size: 0x20 interrupt enable register, base address: 0xe000e100, size: 0x20
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x2001 0x0 0x0 0x0 0x0 0x0 0x0 0x0
interrupt pending register, base address: 0xe000e200, size: 0x20 interrupt pending register, base address: 0xe000e200, size: 0x20
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
interrupt active register, base address: 0xe000e300, size: 0x20 interrupt active register, base address: 0xe000e300, size: 0x20
...@@ -244,13 +194,15 @@ The typical process for enabling exception debugging is as follows: ...@@ -244,13 +194,15 @@ The typical process for enabling exception debugging is as follows:
interrupt exception register, base address: 0xe000ed18, size: 0xc interrupt exception register, base address: 0xe000ed18, size: 0xc
0x0 0x0 0xf0f00000 0x0 0x0 0xf0f00000
interrupt shcsr register, base address: 0xe000ed24, size: 0x4 interrupt shcsr register, base address: 0xe000ed24, size: 0x4
0x70008 0x70002
interrupt control register, base address: 0xe000ed04, size: 0x4 interrupt control register, base address: 0xe000ed04, size: 0x4
0x400f806 0x1000e805
memory pools check: memory pools check:
system heap memcheck over, all passed! system heap memcheck over, all passed!
memory pool check end! memory pool check end!
The preceding data may vary depending on the running environment.
``` ```
...@@ -258,64 +210,68 @@ The typical process for enabling exception debugging is as follows: ...@@ -258,64 +210,68 @@ The typical process for enabling exception debugging is as follows:
The procedure for locating the exception is as follows: The procedure for locating the exception is as follows:
1. Open the image disassembly file \(.asm\) generated after compilation. If the file is not generated by default, use the objdump tool to generate it. Run the following command: 1. Ensure that the compiler optimization is disabled. Otherwise, the following problems may be optimized during the compilation process.
2. Open the image disassembly file (.asm) generated. If the file is not generated, use the objdump tool to generate it. The command is as follows:
``` ```
arm-none-eabi-objdump -S -l XXX.elf arm-none-eabi-objdump -S -l XXX.elf
``` ```
3. Search for the PC (pointing to the instruction being executed) in the .asm file to locate the abnormal function.
1. Search for the PC \(pointing to the instruction being executed\) in the ASM file to locate the abnormal function. The PC address directs to the instruction being executed when the exception occurs. In the .asm file corresponding to the currently executed binary file, search for the PC value **0x2101c61a** and locate the instruction being executed by the CPU. Disassemble the code as follows:
The PC address directs to the instruction being executed when the exception occurs. In the ASM file corresponding to the currently executed binary file, search for the PC value **0x80037da** and locate the instruction being executed by the CPU. Disassemble the code as follows:
``` ```
UINT32 Get_Result_Exception_0(UINT16 dividend){ 2101c60c <GetResultException0>:
80037c8: b480 push {r7} 2101c60c: b580 push {r7, lr}
80037ca: b085 sub sp, #20 2101c60e: b084 sub sp, #16
80037cc: af00 add r7, sp, #0 2101c610: af00 add r7, sp, #0
80037ce: 4603 mov r3, r0 2101c612: 4603 mov r3, r0
80037d0: 80fb strh r3, [r7, #6] 2101c614: 80fb strh r3, [r7, #6]
kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:10 2101c616: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff
UINT32 divisor = 0; 2101c61a: 681b ldr r3, [r3, #0]
80037d2: 2300 movs r3, #0 2101c61c: 60fb str r3, [r7, #12]
80037d4: 60fb str r3, [r7, #12] 2101c61e: 68f9 ldr r1, [r7, #12]
kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:11 2101c620: 4803 ldr r0, [pc, #12] ; (2101c630 <GetResultException0+0x24>)
UINT32 result = dividend / divisor; 2101c622: f001 f92b bl 2101d87c <printf>
80037d6: 88fa ldrh r2, [r7, #6] 2101c626: 68fb ldr r3, [r7, #12]
80037d8: 68fb ldr r3, [r7, #12] 2101c628: 4618 mov r0, r3
80037da: fbb2 f3f3 udiv r3, r2, r3 2101c62a: 3710 adds r7, #16
80037de: 60bb str r3, [r7, #8] 2101c62c: 46bd mov sp, r7
2101c62e: bd80 pop {r7, pc}
2101c630: 21025f90 .word 0x21025f90
``` ```
As indicated by the information displayed:
1. <a name="li18973161743110"></a>As indicated by the code: - The CPU is executing **ldr r3, [r3, #0]** when an exception occurs. The value of **r3** is **0xffffffff**, which causes an invalid address.
1. When the exception occurs, the CPU is executing **udiv r3, r2, r3**. The value of **r3** is **0**, which causes the divide-by-zero error. - The exception occurs in the **GetResultException0** function.
2. The exception occurs in the **Get\_Result\_Exception\_0** function.
2. Locate the parent function of the abnormal function based on the LR value. 4. Search for the parent function of the abnormal function based on the LR value.
The code disassembly of the LR value **0x2101c64d** is as follows:
The code disassembly of the LR value **0x80037fe** is as follows:
``` ```
080037ec <Get_Result_Exception_1>: 2101c634 <GetResultException1>:
Get_Result_Exception_1(): 2101c634: b580 push {r7, lr}
kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:15 2101c636: b082 sub sp, #8
UINT32 Get_Result_Exception_1(UINT16 dividend){ 2101c638: af00 add r7, sp, #0
80037ec: b580 push {r7, lr} 2101c63a: 4603 mov r3, r0
80037ee: b082 sub sp, #8 2101c63c: 80fb strh r3, [r7, #6]
80037f0: af00 add r7, sp, #0 2101c63e: 4806 ldr r0, [pc, #24] ; (2101c658 <GetResultException1+0x24>)
80037f2: 4603 mov r3, r0 2101c640: f001 f91c bl 2101d87c <printf>
80037f4: 80fb strh r3, [r7, #6] 2101c644: 88fb ldrh r3, [r7, #6]
kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:16 2101c646: 4618 mov r0, r3
return Get_Result_Exception_0(dividend); 2101c648: f7ff ffe0 bl 2101c60c <GetResultException0>
80037f6: 88fb ldrh r3, [r7, #6] 2101c64c: 4603 mov r3, r0
80037f8: 4618 mov r0, r3 2101c64e: 4618 mov r0, r3
80037fa: f7ff ffe5 bl 80037c8 <Get_Result_Exception_0> 2101c650: 3708 adds r7, #8
80037fe: 4603 mov r3, r0 2101c652: 46bd mov sp, r7
2101c654: bd80 pop {r7, pc}
2101c656: bf00 nop
2101c658: 21025fb0 .word 0x21025fb0
``` ```
The previous line of LR **2101c648** is **bl2101c60c <GetResultException0>**, which calls the abnormal function. The parent function is **GetResultException1**.
1. The previous line of LR **80037fe** is **bl 80037c8 <Get\_Result\_Exception\_0\>**, which calls the abnormal function. The parent function that calls the abnormal function is **Get\_Result\_Exception\_1\(\)**. 5. Parse the LR value between **backtrace start** and **backtrace end** in the exception information to obtain the call stack relationship where the exception occurs and find the cause of the exception.
2. Repeat [3](#li18973161743110) to analyze the LR values between **backtrace start** and **backtrace end** in the exception information to obtain the call stack relationship and find the exception cause. \ No newline at end of file
# LMS # LMS
## Basic Concepts ## Basic Concepts
Lite Memory Sanitizer \(LMS\) is a tool used to detect memory errors on a real-time basis. LMS can detect buffer overflow, Use-After-Free \(UAF\), and double free errors in real time, and notify the operating system immediately. Together with locating methods such as Backtrace, LMS can locate the code line that causes the memory error. It greatly improves the efficiency of locating memory errors. Lite Memory Sanitizer (LMS) is a tool used to detect memory errors on a real-time basis. It can detect buffer overflow, Use-After-Free (UAF), and double free errors in real time, and notify the operating system immediately. Together with Backtrace, the LMS can locate the code line that causes the memory error. It greatly improves the efficiency of locating memory errors.
The LMS module of the OpenHarmony LiteOS-M kernel provides the following functions: The LMS module of the OpenHarmony LiteOS-M kernel provides the following functions:
- Supports check of multiple memory pools. - Supports check of multiple memory pools.
- Checks the memory allocated by **LOS\_MemAlloc**, **LOS\_MemAllocAlign**, and **LOS\_MemRealloc**.
- Checks the memory when bounds-checking functions are called \(enabled by default\). - Checks the memory allocated by **LOS_MemAlloc**, **LOS_MemAllocAlign**, and **LOS_MemRealloc**.
- Checks the memory when bounds-checking functions are called (enabled by default).
- Checks the memory when libc frequently accessed functions, including **memset**, **memcpy**, **memmove**, **strcat**, **strcpy**, **strncat** and **strncpy**, are called. - Checks the memory when libc frequently accessed functions, including **memset**, **memcpy**, **memmove**, **strcat**, **strcpy**, **strncat** and **strncpy**, are called.
## Working Principles ## Working Principles
LMS uses shadow memory mapping to mark the system memory state. There are three states: **Accessible**, **RedZone**, and **Freed**. The shadow memory is located in the tail of the memory pool. The LMS uses shadow memory mapping to mark the system memory state. There are three states: **Accessible**, **RedZone**, and **Freed**. The shadow memory is located in the tail of the memory pool.
- After memory is allocated from the heap, the shadow memory in the data area is set to the **Accessible** state, and the shadow memory in the head node area is set to the **RedZone** state. - After memory is allocated from the heap, the shadow memory in the data area is set to the **Accessible** state, and the shadow memory in the head node area is set to the **RedZone** state.
- When memory is released from the heap, the shadow memory of the released memory is set to the **Freed** state. - When memory is released from the heap, the shadow memory of the released memory is set to the **Freed** state.
- During code compilation, a function is inserted before the read/write instructions in the code to check the address validity. The tool checks the state value of the shadow memory that accesses the memory. If the shadow memory is in the **RedZone** statue, an overflow error will be reported. If the shadow memory is in the **Freed** state, a UAF error will be reported. - During code compilation, a function is inserted before the read/write instructions in the code to check the address validity. The tool checks the state value of the shadow memory that accesses the memory. If the shadow memory is in the **RedZone** statue, an overflow error will be reported. If the shadow memory is in the **Freed** state, a UAF error will be reported.
- When memory is released, the tool checks the state value of the shadow memory at the released address. If the shadow memory is in the **RedZone** state, a double free error will be reported. - When memory is released, the tool checks the state value of the shadow memory at the released address. If the shadow memory is in the **RedZone** state, a double free error will be reported.
## Available APIs ## Available APIs
The LMS module of the OpenHarmony LiteOS-M kernel provides the following APIs. For more details about the APIs, see the [API](https://gitee.com/openharmony/kernel_liteos_m/blob/master/components/lms/los_lms.h) reference. The LMS module of the OpenHarmony LiteOS-A kernel provides the following APIs. For more details, see [API reference](https://gitee.com/openharmony/kernel_liteos_m/blob/master/components/lms/los_lms.h).
**Table 1** LMS module APIs **Table 1** APIs of the LMS module
<a name="table15483333125018"></a> | Category| API | Description|
<table><thead align="left"><tr id="row04831333145018"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p2968123815504"><a name="p2968123815504"></a><a name="p2968123815504"></a>Function</p> | -------- | -------- | -------- |
</th> | Adding a memory pool to be checked| LOS_LmsCheckPoolAdd | Adds the address range of a memory pool to the LMS check linked list. LMS performs a validity check when the accessed address is within the linked list. In addition, **LOS_MemInit** calls this API to add the initialized memory pool to the LMS check linked list by default.|
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p896843825020"><a name="p896843825020"></a><a name="p896843825020"></a>API</p> | Deleting a memory pool from the LMS check linked list| LOS_LmsCheckPoolDel | Cancels the validity check on the specified memory pool.|
</th> | Protecting a specified memory chunk| LOS_LmsAddrProtect | Locks a memory chunk to prevent it from being read or written. Once the locked memory chunk is accessed, an error will be reported.|
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p10968123865011"><a name="p10968123865011"></a><a name="p10968123865011"></a>Description</p> | Disabling protection of a specified memory chunk| LOS_LmsAddrDisableProtect | Unlocks a memory chunk to make it readable and writable.|
</th>
</tr>
</thead>
<tbody><tr id="row12671943185014"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p926044310503"><a name="p926044310503"></a><a name="p926044310503"></a>Adding a memory pool to be checked</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1226094375013"><a name="p1226094375013"></a><a name="p1226094375013"></a>LOS_LmsCheckPoolAdd</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1226024365018"><a name="p1226024365018"></a><a name="p1226024365018"></a>Adds the address range of a memory pool to the LMS check linked list. LMS performs a validity check when the accessed address is within the linked list. In addition, <strong id="b126321851183511"><a name="b126321851183511"></a><a name="b126321851183511"></a>LOS_MemInit</strong> calls this API to add the initialized memory pool to the LMS check linked list by default.</p>
</td>
</tr>
<tr id="row4267104318501"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p926164395017"><a name="p926164395017"></a><a name="p926164395017"></a>Deleting a memory pool from the LMS check linked list</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p13261134310503"><a name="p13261134310503"></a><a name="p13261134310503"></a>LOS_LmsCheckPoolDel</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p62611438504"><a name="p62611438504"></a><a name="p62611438504"></a>Cancels the validity check on the specified memory pool.</p>
</td>
</tr>
<tr id="row1226794310500"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p2026154317502"><a name="p2026154317502"></a><a name="p2026154317502"></a>Protecting a specified memory chunk</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p5261643145019"><a name="p5261643145019"></a><a name="p5261643145019"></a>LOS_LmsAddrProtect</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p9261134365018"><a name="p9261134365018"></a><a name="p9261134365018"></a>Locks a memory chunk to prevent it from being read or written. Once the locked memory chunk is accessed, an error will be reported.</p>
</td>
</tr>
<tr id="row32662437507"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1261164325018"><a name="p1261164325018"></a><a name="p1261164325018"></a>Disabling protection of a specified memory chunk</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1426115437506"><a name="p1426115437506"></a><a name="p1426115437506"></a>LOS_LmsAddrDisableProtect</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p426194395019"><a name="p426194395019"></a><a name="p426194395019"></a>Unlocks a memory chunk to make it readable and writable.</p>
</td>
</tr>
</tbody>
</table>
## Development Guidelines ## Development Guidelines
### How to Develop ### How to Develop
The typical process for enabling LMS is as follows: The typical process for enabling LMS is as follows:
1. Configure the macros related to the LMS module. 1. Configure the macros related to the LMS module.
Configure the LMS macro **LOSCFG_KERNEL_LMS**, which is disabled by default.
Run the **make menuconfig** command in the **kernel/liteos_m** directory, and set **Kernel-&gt;Enable Lite Memory Sanitizer** to **YES**. If this option is unavailable, select **Enable Backtrace**.
Configure the LMS macro **LOSCFG\_KERNEL\_LMS**, which is disabled by default. Run the **make update\_config** command in the **kernel/liteos\_m** directory, choose **Kernel**, and set **Enable Lite Memory Sanitizer** to **Yes**. | Macro| menuconfig Option| Description| Value|
| -------- | -------- | -------- | -------- |
<a name="table1475284717333"></a> | LOSCFG_KERNEL_LMS | Enable&nbsp;Lms&nbsp;Feature | Whether to enable LMS.| YES/NO |
<table><thead align="left"><tr id="row10752747163310"><th class="cellrowborder" valign="top" width="25%" id="mcps1.1.5.1.1"><p id="p3575105253315"><a name="p3575105253315"></a><a name="p3575105253315"></a>Macro</p> | LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms&nbsp;check&nbsp;pool&nbsp;max&nbsp;num | Maximum number of memory pools that can be checked by LMS.| INT |
</th> | LOSCFG_LMS_LOAD_CHECK | Enable&nbsp;lms&nbsp;read&nbsp;check | Whether to enable LMS read check.| YES/NO |
<th class="cellrowborder" valign="top" width="25%" id="mcps1.1.5.1.2"><p id="p1957565253310"><a name="p1957565253310"></a><a name="p1957565253310"></a>menuconfig Option</p> | LOSCFG_LMS_STORE_CHECK | Enable&nbsp;lms&nbsp;write&nbsp;check | Whether to enable LMS write check.| YES/NO |
</th> | LOSCFG_LMS_CHECK_STRICT | Enable&nbsp;lms&nbsp;strict&nbsp;check,&nbsp;byte-by-byte | Whether to enable LMS byte-by-byte check.| YES/NO |
<th class="cellrowborder" valign="top" width="25%" id="mcps1.1.5.1.3"><p id="p657510523332"><a name="p657510523332"></a><a name="p657510523332"></a>Description</p>
</th> 2. Modify the build script of the target module.
<th class="cellrowborder" valign="top" width="25%" id="mcps1.1.5.1.4"><p id="p157520521332"><a name="p157520521332"></a><a name="p157520521332"></a>Value</p> Add **-fsanitize=kernel-address** to insert memory access checks, and add **-O0** to disable optimization performed by the compiler.
</th>
</tr> The modifications vary depending on the compiler (GCC or Clang) used. The following is an example:
</thead>
<tbody><tr id="row446814582334"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.1 "><p id="p645995893313"><a name="p645995893313"></a><a name="p645995893313"></a>LOSCFG_KERNEL_LMS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.2 "><p id="p645916586337"><a name="p645916586337"></a><a name="p645916586337"></a>Enable Lms Feature</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.3 "><p id="p7459165883314"><a name="p7459165883314"></a><a name="p7459165883314"></a>Whether to enable LMS.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.4 "><p id="p1345916584332"><a name="p1345916584332"></a><a name="p1345916584332"></a>YES/NO</p>
</td>
</tr>
<tr id="row846815810336"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.1 "><p id="p945915812332"><a name="p945915812332"></a><a name="p945915812332"></a>LOSCFG_LMS_MAX_RECORD_POOL_NUM</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.2 "><p id="p12459135823316"><a name="p12459135823316"></a><a name="p12459135823316"></a>Lms check pool max num</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.3 "><p id="p445975819335"><a name="p445975819335"></a><a name="p445975819335"></a>Maximum number of memory pools that can be checked by LMS.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.4 "><p id="p7459165812336"><a name="p7459165812336"></a><a name="p7459165812336"></a>INT</p>
</td>
</tr>
<tr id="row74689584332"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.1 "><p id="p145913583333"><a name="p145913583333"></a><a name="p145913583333"></a>LOSCFG_LMS_LOAD_CHECK</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.2 "><p id="p1045985863318"><a name="p1045985863318"></a><a name="p1045985863318"></a>Enable lms read check</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.3 "><p id="p74591158183311"><a name="p74591158183311"></a><a name="p74591158183311"></a>Whether to enable LMS read check.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.4 "><p id="p144590588332"><a name="p144590588332"></a><a name="p144590588332"></a>YES/NO</p>
</td>
</tr>
<tr id="row1146755819337"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.1 "><p id="p54591258163318"><a name="p54591258163318"></a><a name="p54591258163318"></a>LOSCFG_LMS_STORE_CHECK</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.2 "><p id="p645925814331"><a name="p645925814331"></a><a name="p645925814331"></a>Enable lms write check</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.3 "><p id="p1045918585334"><a name="p1045918585334"></a><a name="p1045918585334"></a>Whether to enable LMS write check.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.4 "><p id="p1745920587338"><a name="p1745920587338"></a><a name="p1745920587338"></a>YES/NO</p>
</td>
</tr>
<tr id="row17467185818337"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.1 "><p id="p134594582336"><a name="p134594582336"></a><a name="p134594582336"></a>LOSCFG_LMS_CHECK_STRICT</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.2 "><p id="p1645925893319"><a name="p1645925893319"></a><a name="p1645925893319"></a>Enable lms strict check, byte-by-byte</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.3 "><p id="p7459258103311"><a name="p7459258103311"></a><a name="p7459258103311"></a>Whether to enable LMS byte-by-byte check.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.1.5.1.4 "><p id="p1745985814336"><a name="p1745985814336"></a><a name="p1745985814336"></a>YES/NO</p>
</td>
</tr>
</tbody>
</table>
2. Modify the compile script of the target module.
Add "-fsanitize=kernel-address" to insert memory access checks, and add the **-O0** option to disable optimization performed by the compiler.
The modifications vary depending on the compiler \(GCC or Clang\) used. The following is an example:
``` ```
if ("$ohos_build_compiler_specified" == "gcc") { if ("$ohos_build_compiler_specified" == "gcc") {
...@@ -161,20 +88,30 @@ The typical process for enabling LMS is as follows: ...@@ -161,20 +88,30 @@ The typical process for enabling LMS is as follows:
} }
``` ```
3. Recompile the code and check the serial port output. The memory problem detected will be displayed. 3. Recompile the code and check the serial port output.
The memory problem detected will be displayed.
### Development Example ### Development Example
This example implements the following: This example implements the following:
1. Create a task for LMS. 1. Create a task for LMS.
2. Construct a buffer overflow error and a UAF error. 2. Construct a buffer overflow error and a UAF error.
3. Add "-fsanitize=kernel-address", execute the compilation, and check the output. 3. Add "-fsanitize=kernel-address", execute the compilation, and check the output.
### Sample Code ### Sample Code
The code is as follows: The code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **Example_Lms_test** function is called in **TestTaskEntry**.
Modify **./kernel/liteos_m/testsuites/BUILD.gn** corresponding to **osTest.c**.
``` ```
#define PAGE_SIZE (0x1000U) #define PAGE_SIZE (0x1000U)
#define INDEX_MAX 20 #define INDEX_MAX 20
...@@ -217,7 +154,7 @@ UINT32 Example_Lms_test(VOID){ ...@@ -217,7 +154,7 @@ UINT32 Example_Lms_test(VOID){
/* Create a task for LMS. */ /* Create a task for LMS. */
memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S)); memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S));
lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask; lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask;
lmsTestTask.pcName = "TestLmsTsk"; /* Task name. */ lmsTestTask.pcName = "TestLmsTsk"; /* Test task name. */
lmsTestTask.uwStackSize = 0x800; lmsTestTask.uwStackSize = 0x800;
lmsTestTask.usTaskPrio = 5; lmsTestTask.usTaskPrio = 5;
lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED; lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED;
...@@ -230,67 +167,117 @@ UINT32 Example_Lms_test(VOID){ ...@@ -230,67 +167,117 @@ UINT32 Example_Lms_test(VOID){
} }
``` ```
### Verification ### Verification
The output is as follows: The following is an example of the command output. The data may vary depending on the running environment.
``` ```
######LmsTestOsmallocOverflow start ###### ######LmsTestOsmallocOverflow start ######
[ERR]***** Kernel Address Sanitizer Error Detected Start ***** [ERR][TestLmsTsk]***** Kernel Address Sanitizer Error Detected Start *****
[ERR]Heap buffer overflow error detected [ERR][TestLmsTsk]Heap buffer overflow error detected
[ERR]Illegal READ address at: [0x4157a3c8] [ERR][TestLmsTsk]Illegal READ address at: [0x21040414]
[ERR]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2] [ERR][TestLmsTsk]Shadow memory address: [0x21041e84 : 6] Shadow memory value: [2]
OsBackTrace fp = 0x402c0f88 psp, start = 21057d88, end = 21057e80
runTask->taskName = LmsTestCaseTask taskName = TestLmsTsk
runTask->taskID = 2 taskID = 5
*******backtrace begin******* ----- traceback start -----
traceback fp fixed, trace using fp = 0x402c0fd0 traceback 0 -- lr = 0x210099f4
traceback 0 -- lr = 0x400655a4 fp = 0x402c0ff8 traceback 1 -- lr = 0x2101da6e
traceback 1 -- lr = 0x40065754 fp = 0x402c1010 traceback 2 -- lr = 0x2101db38
traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 traceback 3 -- lr = 0x2101c494
traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca ----- traceback end -----
[LMS] Dump info around address [0x4157a3c8]:
[0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1 [LMS] Dump info around address [0x21040414]:
[0x4157a3a8]: ba dc cd ab 00 00 00 00 | [0x4157be3a | 4]: 2 2
[0x4157a3b0]: 20 00 00 80 00 00 00 00 | [0x4157be3b | 0]: 2 0 [0x21040390]: 00 00 00 00 00 00 00 00 | [0x21041e7c | 4]: 1 1
[0x4157a3b8]: 00 00 00 00 00 00 00 00 | [0x4157be3b | 4]: 0 0 [0x21040398]: 00 00 00 00 00 00 00 00 | [0x21041e7d | 0]: 1 1
[0x4157a3c0]: 00 00 00 00 00 00 00 00 | [0x4157be3c | 0]: 0 0 [0x210403a0]: 00 00 00 00 00 00 00 00 | [0x21041e7d | 4]: 1 1
[0x4157a3c8]: [ba] dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: [2] 2 [0x210403a8]: 00 00 00 00 00 00 00 00 | [0x21041e7e | 0]: 1 1
[0x4157a3d0]: 2c 1a 00 00 00 00 00 00 | [0x4157be3d | 0]: 2 3 [0x210403b0]: 00 00 00 00 00 00 00 00 | [0x21041e7e | 4]: 1 1
[0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 [0x210403b8]: 00 00 00 00 00 00 00 00 | [0x21041e7f | 0]: 1 1
[0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 [0x210403c0]: 00 00 00 00 00 00 00 00 | [0x21041e7f | 4]: 1 1
[0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3 [0x210403c8]: 00 00 00 00 00 00 00 00 | [0x21041e80 | 0]: 1 1
[0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3 [0x210403d0]: 00 00 00 00 00 00 00 00 | [0x21041e80 | 4]: 1 1
[ERR]***** Kernel Address Sanitizer Error Detected End ***** [0x210403d8]: 00 00 00 00 00 00 00 00 | [0x21041e81 | 0]: 1 1
str[20]=0xffffffba [0x210403e0]: 00 00 00 00 00 00 00 00 | [0x21041e81 | 4]: 1 1
[0x210403e8]: 00 00 00 00 00 00 00 00 | [0x21041e82 | 0]: 1 1
[0x210403f0]: 00 00 00 00 00 00 00 00 | [0x21041e82 | 4]: 1 1
[0x210403f8]: 40 1e 04 21 05 07 00 80 | [0x21041e83 | 0]: 2 2
[0x21040400]: 00 00 00 00 00 00 00 00 | [0x21041e83 | 4]: 0 0
[0x21040408]: 00 00 00 00 00 00 00 00 | [0x21041e84 | 0]: 0 0
[0x21040410]: 00 00 00 00 [f8] 03 04 21 | [0x21041e84 | 4]: 0 [2]
[0x21040418]: 00 8b 06 00 00 00 00 00 | [0x21041e85 | 0]: 2 3
[0x21040420]: 00 00 00 00 00 00 00 00 | [0x21041e85 | 4]: 3 3
[0x21040428]: 00 00 00 00 00 00 00 00 | [0x21041e86 | 0]: 3 3
[0x21040430]: 00 00 00 00 00 00 00 00 | [0x21041e86 | 4]: 3 3
[0x21040438]: 00 00 00 00 00 00 00 00 | [0x21041e87 | 0]: 3 3
[0x21040440]: 00 00 00 00 00 00 00 00 | [0x21041e87 | 4]: 3 3
[0x21040448]: 00 00 00 00 00 00 00 00 | [0x21041e88 | 0]: 3 3
[0x21040450]: 00 00 00 00 00 00 00 00 | [0x21041e88 | 4]: 3 3
[0x21040458]: 00 00 00 00 00 00 00 00 | [0x21041e89 | 0]: 3 3
[0x21040460]: 00 00 00 00 00 00 00 00 | [0x21041e89 | 4]: 3 3
[0x21040468]: 00 00 00 00 00 00 00 00 | [0x21041e8a | 0]: 3 3
[0x21040470]: 00 00 00 00 00 00 00 00 | [0x21041e8a | 4]: 3 3
[0x21040478]: 00 00 00 00 00 00 00 00 | [0x21041e8b | 0]: 3 3
[0x21040480]: 00 00 00 00 00 00 00 00 | [0x21041e8b | 4]: 3 3
[0x21040488]: 00 00 00 00 00 00 00 00 | [0x21041e8c | 0]: 3 3
[0x21040490]: 00 00 00 00 00 00 00 00 | [0x21041e8c | 4]: 3 3
[ERR][TestLmsTsk]***** Kernel Address Sanitizer Error Detected End *****
str[20]=0xfffffff8
######LmsTestOsmallocOverflow stop ###### ######LmsTestOsmallocOverflow stop ######
###### LmsTestUseAfterFree start ######
[ERR]***** Kernel Address Sanitizer Error Detected Start ***** ######LmsTestUseAfterFree start ######
[ERR]Use after free error detected [ERR][TestLmsTsk]***** Kernel Address Sanitizer Error Detected Start *****
[ERR]Illegal READ address at: [0x4157a3d4] [ERR][TestLmsTsk]Use after free error detected
[ERR]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3] [ERR][TestLmsTsk]Illegal READ address at: [0x2104041c]
OsBackTrace fp = 0x402c0f90 [ERR][TestLmsTsk]Shadow memory address: [0x21041e85 : 2] Shadow memory value: [3]
runTask->taskName = LmsTestCaseTask psp, start = 21057d90, end = 21057e80
runTask->taskID = 2 taskName = TestLmsTsk
*******backtrace begin******* taskID = 5
traceback fp fixed, trace using fp = 0x402c0fd8 ----- traceback start -----
traceback 0 -- lr = 0x40065680 fp = 0x402c0ff8 traceback 0 -- lr = 0x210099f4
traceback 1 -- lr = 0x40065758 fp = 0x402c1010 traceback 1 -- lr = 0x2101daec
traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 traceback 2 -- lr = 0x2101db3c
traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca traceback 3 -- lr = 0x2101c494
[LMS] Dump info around address [0x4157a3d4]: ----- traceback end -----
[0x4157a3a8]: ba dc cd ab 00 00 00 00 | [0x4157be3a | 4]: 2 2
[0x4157a3b0]: 20 00 00 80 00 00 00 00 | [0x4157be3b | 0]: 2 0 [LMS] Dump info around address [0x2104041c]:
[0x4157a3b8]: 00 00 00 00 00 00 00 00 | [0x4157be3b | 4]: 0 0
[0x4157a3c0]: 00 00 00 00 00 00 00 00 | [0x4157be3c | 0]: 0 0 [0x21040398]: 00 00 00 00 00 00 00 00 | [0x21041e7d | 0]: 1 1
[0x4157a3c8]: ba dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: 2 2 [0x210403a0]: 00 00 00 00 00 00 00 00 | [0x21041e7d | 4]: 1 1
[0x4157a3d0]: 2c 1a 00 00 [00] 00 00 00 | [0x4157be3d | 0]: 2 [3] [0x210403a8]: 00 00 00 00 00 00 00 00 | [0x21041e7e | 0]: 1 1
[0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 [0x210403b0]: 00 00 00 00 00 00 00 00 | [0x21041e7e | 4]: 1 1
[0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 [0x210403b8]: 00 00 00 00 00 00 00 00 | [0x21041e7f | 0]: 1 1
[0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2 [0x210403c0]: 00 00 00 00 00 00 00 00 | [0x21041e7f | 4]: 1 1
[0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3 [0x210403c8]: 00 00 00 00 00 00 00 00 | [0x21041e80 | 0]: 1 1
[0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3 [0x210403d0]: 00 00 00 00 00 00 00 00 | [0x21041e80 | 4]: 1 1
[ERR]***** Kernel Address Sanitizer Error Detected End ***** [0x210403d8]: 00 00 00 00 00 00 00 00 | [0x21041e81 | 0]: 1 1
[0x210403e0]: 00 00 00 00 00 00 00 00 | [0x21041e81 | 4]: 1 1
[0x210403e8]: 00 00 00 00 00 00 00 00 | [0x21041e82 | 0]: 1 1
[0x210403f0]: 00 00 00 00 00 00 00 00 | [0x21041e82 | 4]: 1 1
[0x210403f8]: 40 1e 04 21 05 07 00 80 | [0x21041e83 | 0]: 2 2
[0x21040400]: 00 00 00 00 00 00 00 00 | [0x21041e83 | 4]: 0 0
[0x21040408]: 00 00 00 00 00 00 00 00 | [0x21041e84 | 0]: 0 0
[0x21040410]: 00 00 00 00 f8 03 04 21 | [0x21041e84 | 4]: 0 2
[0x21040418]: 05 8b 06 00 [00] 00 00 00 | [0x21041e85 | 0]: 2 [3]
[0x21040420]: 00 00 00 00 00 00 00 00 | [0x21041e85 | 4]: 3 3
[0x21040428]: 00 00 00 00 00 00 00 00 | [0x21041e86 | 0]: 3 3
[0x21040430]: 14 04 04 21 00 84 06 00 | [0x21041e86 | 4]: 2 2
[0x21040438]: 00 00 00 00 00 00 00 00 | [0x21041e87 | 0]: 3 3
[0x21040440]: 00 00 00 00 00 00 00 00 | [0x21041e87 | 4]: 3 3
[0x21040448]: 00 00 00 00 00 00 00 00 | [0x21041e88 | 0]: 3 3
[0x21040450]: 00 00 00 00 00 00 00 00 | [0x21041e88 | 4]: 3 3
[0x21040458]: 00 00 00 00 00 00 00 00 | [0x21041e89 | 0]: 3 3
[0x21040460]: 00 00 00 00 00 00 00 00 | [0x21041e89 | 4]: 3 3
[0x21040468]: 00 00 00 00 00 00 00 00 | [0x21041e8a | 0]: 3 3
[0x21040470]: 00 00 00 00 00 00 00 00 | [0x21041e8a | 4]: 3 3
[0x21040478]: 00 00 00 00 00 00 00 00 | [0x21041e8b | 0]: 3 3
[0x21040480]: 00 00 00 00 00 00 00 00 | [0x21041e8b | 4]: 3 3
[0x21040488]: 00 00 00 00 00 00 00 00 | [0x21041e8c | 0]: 3 3
[0x21040490]: 00 00 00 00 00 00 00 00 | [0x21041e8c | 4]: 3 3
[0x21040498]: 00 00 00 00 00 00 00 00 | [0x21041e8d | 0]: 3 3
[ERR][TestLmsTsk]***** Kernel Address Sanitizer Error Detected End *****
str[ 0]=0x 0 str[ 0]=0x 0
######LmsTestUseAfterFree stop ###### ######LmsTestUseAfterFree stop ######
``` ```
...@@ -307,12 +294,10 @@ The key output information is as follows: ...@@ -307,12 +294,10 @@ The key output information is as follows:
- Illegal double free - Illegal double free
- Context: - Context:
- Task information \(**taskName** and **taskId**\) - Task information (**taskName** and **taskId**)
- Backtrace - Backtrace
- Memory information of the error addresses: - Memory information of the error addresses:
- Memory value and the value of the corresponding shadow memory - Memory value and the value of the corresponding shadow memory
- Memory address: memory value|\[shadow memory address|shadow memory byte offset\]: shadow memory value - Memory address: memory value|[shadow memory address|shadow memory byte offset]: shadow memory value
- Shadow memory value. **0** \(Accessible\), **3** \(Freed\), **2** \(RedZone\), and **1** \(filled value\) - Shadow memory value. **0** (Accessible), **3** (Freed), **2** (RedZone), and **1** (filled value)
# Trace # Trace
## Basic Concepts ## Basic Concepts
Trace helps you learn about the kernel running process and the execution sequence of modules and tasks. With the information, you can better understand the code running process of the kernel and locate time sequence problems. Trace helps you learn about the kernel running process and the execution sequence of modules and tasks. With the traced information, you can better understand the code running process of the kernel and locate time sequence problems.
## Working Principles ## Working Principles
...@@ -16,142 +18,86 @@ In offline mode, trace frames are stored in a circular buffer. If too many frame ...@@ -16,142 +18,86 @@ In offline mode, trace frames are stored in a circular buffer. If too many frame
![](figures/kernel-small-mode-process.png) ![](figures/kernel-small-mode-process.png)
The online mode must be used with the integrated development environment \(IDE\). Trace frames are sent to the IDE in real time. The IDE parses the records and displays them in a visualized manner. The online mode must be used with the integrated development environment (IDE). Trace frames are sent to the IDE in real time. The IDE parses the records and displays them in a visualized manner.
## Available APIs ## Available APIs
The trace module of the OpenHarmony LiteOS-M kernel provides the following functions. For more details about the APIs, see the API reference. The trace module of the OpenHarmony LiteOS-M kernel provides the following APIs. For more details about the APIs, see the API reference.
**Table 1** Trace module APIs **Table 1** APIs of the trace module
<a name="table208266479117"></a> | Category| API|
<table><thead align="left"><tr id="row19826947121114"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Function</p> | -------- | -------- |
</th> | Starting/Stopping trace| - **LOS_TraceStart**: starts a trace.<br>- **LOS_TraceStop**: stops the trace.|
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>API</p> | Managing trace records| - **LOS_TraceRecordDump**: dumps data from the trace buffer.<br>- **LOS_TraceRecordGet**: obtains the start address of the trace buffer.<br>- **LOS_TraceReset**: clears events in the trace buffer.|
</th> | Filtering trace records| **LOS_TraceEventMaskSet**: sets the event mask to trace only events of the specified modules.|
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p> | Masking events of specified interrupt IDs| **LOS_TraceHwiFilterHookReg**: registers a hook to filter out events of specified interrupt IDs.|
</th> | Performing function instrumentation| - **LOS_TRACE_EASY**: performs simple instrumentation.<br>- **LOS_TRACE**: performs standard instrumentation.|
</tr>
</thead>
<tbody><tr id="row7235182719585"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p92241727105816"><a name="p92241727105816"></a><a name="p92241727105816"></a>Starting and stopping trace</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p222418279581"><a name="p222418279581"></a><a name="p222418279581"></a>LOS_TraceStart</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p18224112711581"><a name="p18224112711581"></a><a name="p18224112711581"></a>Starts trace.</p>
</td>
</tr>
<tr id="row142340271586"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p2224152795812"><a name="p2224152795812"></a><a name="p2224152795812"></a>LOS_TraceStop</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p722492710584"><a name="p722492710584"></a><a name="p722492710584"></a>Stops trace.</p>
</td>
</tr>
<tr id="row12341278583"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p14224627175816"><a name="p14224627175816"></a><a name="p14224627175816"></a>Managing trace records</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p0224827145816"><a name="p0224827145816"></a><a name="p0224827145816"></a>LOS_TraceRecordDump</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p16224427125810"><a name="p16224427125810"></a><a name="p16224427125810"></a>Exports data in the trace buffer.</p>
</td>
</tr>
<tr id="row14234527185811"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p152241327165810"><a name="p152241327165810"></a><a name="p152241327165810"></a>LOS_TraceRecordGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1422412274584"><a name="p1422412274584"></a><a name="p1422412274584"></a>Obtains the start address of the trace buffer.</p>
</td>
</tr>
<tr id="row16234112725816"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p122244272582"><a name="p122244272582"></a><a name="p122244272582"></a>LOS_TraceReset</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1222413276581"><a name="p1222413276581"></a><a name="p1222413276581"></a>Clears events in the trace buffer.</p>
</td>
</tr>
<tr id="row14234727155817"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p19224227205814"><a name="p19224227205814"></a><a name="p19224227205814"></a>Filtering trace records</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1922410277585"><a name="p1922410277585"></a><a name="p1922410277585"></a>LOS_TraceEventMaskSet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p122242272585"><a name="p122242272585"></a><a name="p122242272585"></a>Sets the event mask to trace only events of the specified modules.</p>
</td>
</tr>
<tr id="row5234627145818"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p152244272589"><a name="p152244272589"></a><a name="p152244272589"></a>Masking events of specified interrupt IDs</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p182244276586"><a name="p182244276586"></a><a name="p182244276586"></a>LOS_TraceHwiFilterHookReg</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p12224627135819"><a name="p12224627135819"></a><a name="p12224627135819"></a>Registers a hook to filter out events of specified interrupt IDs.</p>
</td>
</tr>
<tr id="row22341027115815"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1222462716588"><a name="p1222462716588"></a><a name="p1222462716588"></a>Performing function instrumentation</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p42242271585"><a name="p42242271585"></a><a name="p42242271585"></a>LOS_TRACE_EASY</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1622416274584"><a name="p1622416274584"></a><a name="p1622416274584"></a>Performs simple instrumentation.</p>
</td>
</tr>
<tr id="row16234627175820"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p622515274583"><a name="p622515274583"></a><a name="p622515274583"></a>LOS_TRACE</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p2225527185810"><a name="p2225527185810"></a><a name="p2225527185810"></a>Performs standard instrumentation.</p>
</td>
</tr>
</tbody>
</table>
- You can perform function instrumentation in the source code to trace specific events. The system provides the following APIs for instrumentation: - You can perform function instrumentation in the source code to trace specific events. The system provides the following APIs for instrumentation:
- **LOS\_TRACE\_EASY\(TYPE, IDENTITY, params...\)** for simple instrumentation - **LOS_TRACE_EASY(TYPE, IDENTITY, params...)** for simple instrumentation
- You only need to insert this API into the source code. - You only need to insert this API into the source code.
- **TYPE** specifies the event type. The value range is 0 to 0xF. The meaning of each value is user-defined. - **TYPE** specifies the event type. The value range is 0 to 0xF. The meaning of each value is user-defined.
- **IDENTITY** specifies the object of the event operation. The value is of the **UIntPtr** type. - **IDENTITY** specifies the object of the event operation. The value is of the **UIntPtr** type.
- **Params** specifies the event parameters. The value is of the **UIntPtr** type. - **Params** specifies the event parameters. The value is of the **UIntPtr** type.
- Example: - Example of simple instrumentation for reading and writing data based on the file FDs:
``` ```
Perform simple instrumentation for reading and writing files fd1 and fd2. /* Set TYPE to 1 for read operation and 2 for write operations. */
Set TYPE to 1 for read operations and 2 for write operations. LOS_TRACE_EASY(1, fd, flag, size); /* Add it to a proper position. */
Insert the following to the position where the fd1 file is read: LOS_TRACE_EASY(2, fd, flag, size); /* Add it to a proper position. */
LOS_TRACE_EASY(1, fd1, flag, size);
Insert the following to the position where the fd2 file is read:
LOS_TRACE_EASY(1, fd2, flag, size);
Insert the following to the position where the fd1 file is written:
LOS_TRACE_EASY(2, fd1, flag, size);
Insert the following in the position where the fd2 file is written:
LOS_TRACE_EASY(2, fd2, flag, size);
``` ```
- **LOS_TRACE(TYPE, IDENTITY, params...)** for standard instrumentation.
- **LOS\_TRACE\(TYPE, IDENTITY, params...\)** for standard instrumentation.
- Compared with simple instrumentation, standard instrumentation supports dynamic event filtering and parameter tailoring. However, you need to extend the functions based on rules. - Compared with simple instrumentation, standard instrumentation supports dynamic event filtering and parameter tailoring. However, you need to extend the functions based on rules.
- **TYPE** specifies the event type. You can define the event type in **enum LOS\_TRACE\_TYPE** in the header file **los\_trace.h**. For details about methods and rules for defining events, see other event types. - **TYPE** specifies the event type. You can define the event type in **enum LOS_TRACE_TYPE** in the header file **los_trace.h**. For details about methods and rules for defining events, see other event types.
- The **IDENTITY** and **Params** are the same as those of simple instrumentation. - The **IDENTITY** and **Params** are the same as those of simple instrumentation.
- Example: - Example:
1. Define the type of the FS module (event mask of the FS module) in **enum LOS_TRACE_MASK**.
``` ```
1. Set the event mask (module-level event type) in enum LOS_TRACE_MASK. /* Define the event mask in the format of TRACE_#MOD#_FLAG, where #MOD# indicates the module name. */
Format: TRACE_#MOD#_FLAG (MOD indicates the module name)
Example:
TRACE_FS_FLAG = 0x4000 TRACE_FS_FLAG = 0x4000
2. Define the event type in enum LOS_TRACE_TYPE.
Format: #TYPE# = TRACE_#MOD#_FLAG | NUMBER
Example:
FS_READ = TRACE_FS_FLAG | 0; // Read files
FS_WRITE = TRACE_FS_FLAG | 1; // Write files
3. Set event parameters in the #TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ... format.
#TYPE# is the #TYPE# defined in step 2.
Example:
#define FS_READ_PARAMS(fp, fd, flag, size) fp, fd, flag, size
The parameters defined by the macro correspond to the event parameters recorded in the trace buffer. You can modify the parameters as required.
If no parameter is specified, events of this type are not traced.
#define FS_READ_PARAMS(fp, fd, flag, size) // File reading events are not traced.
4. Insert a code stub in a proper position.
Format: LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...))
LOS_TRACE(FS_READ, fp, fd, flag, size); // Code stub for reading files
The parameters following #TYPE# are the input parameter of the FS_READ_PARAMS function in step 3.
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** 2. Define the event types of the FS module.
>The trace event types and parameters can be modified as required. For details about the parameters, see **kernel\\include\\los\_trace.h**.
```
/* Define the event type in the format: #TYPE# = TRACE_#MOD#_FLAG | NUMBER */
FS_READ = TRACE_FS_FLAG | 0; /* Read data. */
FS_WRITE = TRACE_FS_FLAG | 1; /* Write data. */
```
3. Define event parameters.
```
/* Define the parameters in the format: #TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ... */
#define FS_READ_PARAMS(fp, fd, flag, size) fp, fd, flag, size /* The parameters defined by the macro correspond to the event parameters recorded in the trace buffer. You can tailor the parameters as required. */
#define FS_READ_PARAMS(fp, fd, flag, size) /* If no parameters are defined, events of this type are not traced. */
```
4. Add the code stubs in the code.
```
/* Format: LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...)) */
LOS_TRACE(FS_READ, fp, fd, flag, size); /* Code stub for reading data. */
```
> **NOTE**<br>
> You can modify the traced event types and parameters as required. For details about the parameters, see **kernel\include\los_trace.h**.
- For **LOS_TraceEventMaskSet(UINT32 mask)**, only the most significant 28 bits (corresponding to the enable bit of the module in **LOS_TRACE_MASK**) of the mask take effect and are used only for module-based tracing. Currently, fine-grained event-based tracing is not supported. For example, in **LOS_TraceEventMaskSet(0x202)**, the effective mask is **0x200 (TRACE_QUE_FLAG)** and all events of the QUE module are collected. The recommended method is **LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG);**.
- To enable trace of only simple instrumentation events, set **Trace Mask** to **TRACE_MAX_FLAG**.
- The trace buffer has limited capacity. When the trace buffer is full, events will be overwritten. You can use **LOS_TraceRecordDump** to export data from the trace buffer and locate the latest records by **CurEvtIndex**.
- For **LOS\_TraceEventMaskSet\(UINT32 mask\)**, only the most significant 28 bits \(corresponding to the enable bit of the module in **LOS\_TRACE\_MASK**\) of the mask take effect and are used only for module-based tracing. Currently, fine-grained event-based tracing is not supported. For example, in **LOS\_TraceEventMaskSet\(0x202\)**, the effective mask is **0x200 \(TRACE\_QUE\_FLAG\)** and all events of the QUE module are collected. The recommended method is **LOS\_TraceEventMaskSet\(TRACE\_EVENT\_FLAG | TRACE\_MUX\_FLAG | TRACE\_SEM\_FLAG | TRACE\_QUE\_FLAG\);**. - The typical trace operation process includes **LOS_TraceStart**, **LOS_TraceStop**, and **LOS_TraceRecordDump**.
- To enable trace of only simple instrumentation events, set **Trace Mask** to **TRACE\_MAX\_FLAG**.
- The trace buffer has limited capacity. When the trace buffer is full, events will be overwritten. You can use **LOS\_TraceRecordDump** to export data from the trace buffer and locate the latest records by **CurEvtIndex**.
- The typical trace operation process includes **LOS\_TraceStart**, **LOS\_TraceStop**, and **LOS\_TraceRecordDump**.
- You can filter out interrupt events by interrupt ID to prevent other events from being overwritten due to frequent triggering of a specific interrupt in some scenarios. You can customize interrupt filtering rules.
- You can filter out interrupt events by interrupt ID to prevent other events from being overwritten due to frequent triggering of a specific interrupt in some scenarios. You can customize interrupt filtering rules.<br>
The sample code is as follows: The sample code is as follows:
``` ```
...@@ -165,116 +111,75 @@ The trace module of the OpenHarmony LiteOS-M kernel provides the following funct ...@@ -165,116 +111,75 @@ The trace module of the OpenHarmony LiteOS-M kernel provides the following funct
LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); LOS_TraceHwiFilterHookReg(Example_HwiNumFilter);
``` ```
The interrupt events with interrupt ID of **TIMER\_INT** or **DMA\_INT** are not traced. The interrupt events with interrupt ID of **TIMER_INT** or **DMA_INT** are not traced.
## Development Guidelines ## Development Guidelines
### How to Develop ### How to Develop
The typical trace process is as follows: The typical development process is as follows:
1. Configure the macro related to the trace module. 1. Configure the macros related to the trace module in the **target_config.h** file.
| Configuration Item| Description| Value|
Modify the configuration in the **target\_config.h** file. | -------- | -------- | -------- |
| LOSCFG_KERNEL_TRACE | Whether to enable the trace feature. | YES/NO |
<a name="table86631147151516"></a> | LOSCFG_RECORDER_MODE_OFFLINE | Whether to enable the online trace mode. | YES/NO |
<table><thead align="left"><tr id="row5664134715156"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p1466404761518"><a name="p1466404761518"></a><a name="p1466404761518"></a>Configuration</p> | LOSCFG_RECORDER_MODE_ONLINE | Whether to enable the offline trace mode. | YES/NO |
</th> | LOSCFG_TRACE_CLIENT_INTERACT | Whether to enable interaction with Trace IDE (dev tools), including data visualization and process control. | YES/NO |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p18664347131518"><a name="p18664347131518"></a><a name="p18664347131518"></a>Description</p> | LOSCFG_TRACE_FRAME_CORE_MSG | Whether to enable trace of the CPU ID, interruption state, and lock task state. | YES/NO |
</th> | LOSCFG_TRACE_FRAME_EVENT_COUNT | Whether to enable trace of the event sequence number. | YES/NO |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p166413478159"><a name="p166413478159"></a><a name="p166413478159"></a>Value</p> | LOSCFG_TRACE_FRAME_MAX_PARAMS | Specifies the maximum number of parameters for event tracing. | INT |
</th> | LOSCFG_TRACE_BUFFER_SIZE | Specifies the trace buffer size.| INT |
</tr>
</thead> 2. (Optional) Preset event parameters and stubs (or use the default event parameter settings and event stubs).
<tbody><tr id="row22591620121620"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p225117203162"><a name="p225117203162"></a><a name="p225117203162"></a>LOSCFG_KERNEL_TRACE</p>
</td> 3. (Optional) Call **LOS_TraceStop** to stop trace and **LOS_TraceReset** to clear the trace buffer. (Trace is started by default.)
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p72519205167"><a name="p72519205167"></a><a name="p72519205167"></a>Specifies whether to enable the trace feature.</p>
</td> 4. (Optional) Call **LOS_TraceEventMaskSet** to set the event mask for trace (only the interrupts and task events are enabled by default). For details about the event mask, see **LOS_TRACE_MASK** in **los_trace.h**.
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p925182081614"><a name="p925182081614"></a><a name="p925182081614"></a>YES/NO</p>
</td> 5. Call **LOS_TraceStart** at the start of the code where the event needs to be traced.
</tr>
<tr id="row4259182012168"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p72515204168"><a name="p72515204168"></a><a name="p72515204168"></a>LOSCFG_RECORDER_MODE_OFFLINE</p> 6. Call **LOS_TraceStop** at the end of the code where the event needs to be traced.
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p4251620111614"><a name="p4251620111614"></a><a name="p4251620111614"></a>Specifies whether to enable the online trace mode.</p> 7. Call **LOS_TraceRecordDump** to output the data in the buffer. (The input parameter of the function is of the Boolean type. The value **FALSE** means to output data in the specified format, and the value **TRUE** means to output data to a Windows client.)
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p425162020167"><a name="p425162020167"></a><a name="p425162020167"></a>YES/NO</p>
</td>
</tr>
<tr id="row1825902061611"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p122511220191613"><a name="p122511220191613"></a><a name="p122511220191613"></a>LOSCFG_RECORDER_MODE_ONLINE</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p7251192018169"><a name="p7251192018169"></a><a name="p7251192018169"></a>Specifies whether to enable the offline trace mode.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1225115205163"><a name="p1225115205163"></a><a name="p1225115205163"></a>YES/NO</p>
</td>
</tr>
<tr id="row3259152015163"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p225118205169"><a name="p225118205169"></a><a name="p225118205169"></a>LOSCFG_TRACE_CLIENT_INTERACT</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p225182016163"><a name="p225182016163"></a><a name="p225182016163"></a>Specifies whether to enable interaction with Trace IDE (dev tools), including data visualization and process control.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p182512208167"><a name="p182512208167"></a><a name="p182512208167"></a>YES/NO</p>
</td>
</tr>
<tr id="row02591120201618"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p82511920101615"><a name="p82511920101615"></a><a name="p82511920101615"></a>LOSCFG_TRACE_FRAME_CORE_MSG</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p425192015165"><a name="p425192015165"></a><a name="p425192015165"></a>Specifies whether to enable recording of the CPU ID, interruption state, and lock task state.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1925119204166"><a name="p1925119204166"></a><a name="p1925119204166"></a>YES/NO</p>
</td>
</tr>
<tr id="row1525916202166"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p3251162017161"><a name="p3251162017161"></a><a name="p3251162017161"></a>LOSCFG_TRACE_FRAME_EVENT_COUNT</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p18251142021619"><a name="p18251142021619"></a><a name="p18251142021619"></a>Specifies whether to enables recording of the event sequence number.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1251020171616"><a name="p1251020171616"></a><a name="p1251020171616"></a>YES/NO</p>
</td>
</tr>
<tr id="row1025920204167"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p2025172010166"><a name="p2025172010166"></a><a name="p2025172010166"></a>LOSCFG_TRACE_FRAME_MAX_PARAMS</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p172511020141611"><a name="p172511020141611"></a><a name="p172511020141611"></a>Specifies the maximum number of parameters for event recording.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p12251182041610"><a name="p12251182041610"></a><a name="p12251182041610"></a>INT</p>
</td>
</tr>
<tr id="row225982091614"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p1725114206168"><a name="p1725114206168"></a><a name="p1725114206168"></a>LOSCFG_TRACE_BUFFER_SIZE</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p4251142014161"><a name="p4251142014161"></a><a name="p4251142014161"></a>Specifies the trace buffer size.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p2251152014162"><a name="p2251152014162"></a><a name="p2251152014162"></a>INT</p>
</td>
</tr>
</tbody>
</table>
2. \(Optional\) Preset event parameters and stubs \(or use the default event parameter settings and event stubs\).
3. \(Optional\) Call **LOS\_TraceStop** to stop trace and call **LOS\_TraceReset** to clear the trace buffer. \(Trace is started by default.\)
4. \(Optional\) Call **LOS\_TraceEventMaskSet** to set the event mask for trace \(only the interrupts and task events are enabled by default\). For details about the event mask, see **LOS\_TRACE\_MASK** in **los\_trace.h**.
5. Call **LOS\_TraceStart** at the start of the code where the event needs to be traced.
6. Call **LOS\_TraceStop** at the end of the code where the event needs to be traced.
7. Call **LOS\_TraceRecordDump** to output the data in the buffer. \(The input parameter of the function is of the Boolean type. The value **FALSE** means to output data in the specified format, and the value **TRUE** means to output data to a Windows client.\)
The methods in steps 3 to 7 are encapsulated with shell commands. After the shell is enabled, the corresponding commands can be executed. The mapping is as follows: The methods in steps 3 to 7 are encapsulated with shell commands. After the shell is enabled, the corresponding commands can be executed. The mapping is as follows:
- LOS\_TraceReset —— trace\_reset - LOS_TraceReset —— trace_reset
- LOS\_TraceEventMaskSet —— trace\_mask
- LOS\_TraceStart —— trace\_start - LOS_TraceEventMaskSet —— trace_mask
- LOS\_TraceStop —— trace\_stop
- LOS\_TraceRecordDump —— trace\_dump - LOS_TraceStart —— trace_start
- LOS_TraceStop —— trace_stop
- LOS_TraceRecordDump —— trace_dump
### Development Example ### Development Example
This example implements the following: This example implements the following:
1. Create a trace task. 1. Create a trace task.
2. Set the event mask. 2. Set the event mask.
3. Start trace. 3. Start trace.
4. Stop trace. 4. Stop trace.
5. Output trace data in the specified format. 5. Output trace data in the specified format.
### Sample Code ### Sample Code
The sample code is as follows: The sample code is as follows:
The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleTraceTest** function is called in **TestTaskEntry**.
``` ```
#include "los_trace.h" #include "los_trace.h"
UINT32 g_traceTestTaskId; UINT32 g_traceTestTaskId;
...@@ -288,21 +193,21 @@ VOID Example_Trace(VOID) ...@@ -288,21 +193,21 @@ VOID Example_Trace(VOID)
dprintf("trace start error\n"); dprintf("trace start error\n");
return; return;
} }
/* Trigger a task switching event.*/ /* Trigger a task switching event. */
LOS_TaskDelay(1); LOS_TaskDelay(1);
LOS_TaskDelay(1); LOS_TaskDelay(1);
LOS_TaskDelay(1); LOS_TaskDelay(1);
/* Stop trace.*/ /* Stop trace. */
LOS_TraceStop(); LOS_TraceStop();
LOS_TraceRecordDump(FALSE); LOS_TraceRecordDump(FALSE);
} }
UINT32 Example_Trace_test(VOID){ UINT32 ExampleTraceTest(VOID){
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S traceTestTask; TSK_INIT_PARAM_S traceTestTask = { 0 };
/* Create a trace task. */ /* Create a trace task. */
memset(&traceTestTask, 0, sizeof(TSK_INIT_PARAM_S)); memset(&traceTestTask, 0, sizeof(TSK_INIT_PARAM_S));
traceTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Trace; traceTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Trace;
traceTestTask.pcName = "TestTraceTsk"; /* Trace task name*/ traceTestTask.pcName = "TestTraceTsk"; /* Trace task name. */
traceTestTask.uwStackSize = 0x800; traceTestTask.uwStackSize = 0x800;
traceTestTask.usTaskPrio = 5; traceTestTask.usTaskPrio = 5;
traceTestTask.uwResved = LOS_TASK_STATUS_DETACHED; traceTestTask.uwResved = LOS_TASK_STATUS_DETACHED;
...@@ -311,7 +216,7 @@ UINT32 Example_Trace_test(VOID){ ...@@ -311,7 +216,7 @@ UINT32 Example_Trace_test(VOID){
dprintf("TraceTestTask create failed .\n"); dprintf("TraceTestTask create failed .\n");
return LOS_NOK; return LOS_NOK;
} }
/* Trace is started by default. Therefore, you can stop trace, clear the buffer, and then restart trace. */ /* Trace is started by default. You can stop trace, clear the buffer, and restart trace. */
LOS_TraceStop(); LOS_TraceStop();
LOS_TraceReset(); LOS_TraceReset();
/* Enable trace of the Task module events. */ /* Enable trace of the Task module events. */
...@@ -320,12 +225,14 @@ UINT32 Example_Trace_test(VOID){ ...@@ -320,12 +225,14 @@ UINT32 Example_Trace_test(VOID){
} }
``` ```
### Verification ### Verification
The output is as follows: The output is as follows:
``` ```
*******TraceInfo begin******* ***TraceInfo begin***
clockFreq = 50000000 clockFreq = 50000000
CurEvtIndex = 7 CurEvtIndex = 7
Index Time(cycles) EventType CurTask Identity params Index Time(cycles) EventType CurTask Identity params
...@@ -337,36 +244,43 @@ Index Time(cycles) EventType CurTask Identity params ...@@ -337,36 +244,43 @@ Index Time(cycles) EventType CurTask Identity params
5 0x36eec810 0x45 0xc 0x1 0x9 0x8 0x1f 5 0x36eec810 0x45 0xc 0x1 0x9 0x8 0x1f
6 0x3706f804 0x45 0x1 0x0 0x1f 0x4 0x0 6 0x3706f804 0x45 0x1 0x0 0x1f 0x4 0x0
7 0x37070e59 0x45 0x0 0x1 0x0 0x8 0x1f 7 0x37070e59 0x45 0x0 0x1 0x0 0x8 0x1f
*******TraceInfo end******* ***TraceInfo end***
The preceding data may vary depending on the running environment.
``` ```
The output event information includes the occurrence time, event type, task in which the event occurs, object of the event operation, and other parameters of the event. The output event information includes the occurrence time, event type, task in which the event occurs, object of the event operation, and other parameters of the event.
- **EventType**: event type. For details, see **enum LOS\_TRACE\_TYPE** in the header file **los\_trace.h**. - **EventType**: event type. For details, see **enum LOS_TRACE_TYPE** in the header file **los_trace.h**.
- **CurrentTask**: ID of the running task. - **CurrentTask**: ID of the running task.
- **Identity**: object of the event operation. For details, see **\#TYPE\#\_PARAMS** in the header file **los\_trace.h**.
- **params**: event parameters. For details, see **\#TYPE\#\_PARAMS** in the header file **los\_trace.h**. - **Identity**: object of the event operation. For details, see **#TYPE#_PARAMS** in the header file **los_trace.h**.
- **params**: event parameters. For details, see **#TYPE#_PARAMS** in the header file **los_trace.h**.
The following uses output No. 0 as an example. The following uses output No. 0 as an example.
``` ```
Index Time(cycles) EventType CurTask Identity params Index Time(cycles) EventType CurTask Identity params
0 0x366d5e88 0x45 0x1 0x0 0x1f 0x4 0 0x366d5e88 0x45 0x1 0x0 0x1f 0x4
``` ```
- **Time \(cycles\)** can be converted into time \(in seconds\) by dividing the cycles by clockFreq. - **Time (cycles)** can be converted into time (in seconds) by dividing the cycles by clockFreq.
- **0x45** indicates the task switching event. **0x1** is the ID of the task in running. - **0x45** indicates the task switching event. **0x1** is the ID of the task in running.
- For details about the meanings of **Identity** and **params**, see the **TASK\_SWITCH\_PARAMS** macro.
- For details about the meanings of **Identity** and **params**, see the **TASK_SWITCH_PARAMS** macro.
``` ```
#define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ #define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \
taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus
``` ```
Because of **\#TYPE\#\_PARAMS\(IDENTITY, parma1...\) IDENTITY, ...**, **Identity** is **taskId \(0x0\)** and the first parameter is **oldPriority \(0x1f\)**. **Identity** is **taskId (0x0)**, and the first parameter is **oldPriority (0x1f)**.
> **NOTE**<br>
>![](../public_sys-resources/icon-note.gif) **NOTE:** > The number of parameters in **params** is specified by **LOSCFG_TRACE_FRAME_MAX_PARAMS**. The default value is **3**. Excess parameters are not recorded. Set **LOSCFG_TRACE_FRAME_MAX_PARAMS** based on service requirements.
>The number of parameters in **params** is specified by the **LOSCFG\_TRACE\_FRAME\_MAX\_PARAMS** parameter. The default value is **3**. Excess parameters are not recorded. You need to set **LOSCFG\_TRACE\_FRAME\_MAX\_PARAMS** based on service requirements.
Task 0x1 is switched to Task 0x0. The priority of task 0x1 is **0x1f**, and the state is **0x4**. The priority of the task 0x0 is **0x0**.
Task 0x1 is switched to Task 0x0. The priority of task 0x1 is **0x1f**, and the state is **0x4**. The priority of task 0x0 is **0x0**.
# Bitwise Operation # Bitwise Operation
## Basic Concepts ## Basic Concepts
A bitwise operation operates on a binary number at the level of its individual bits. For example, a variable can be set as a program status word \(PSW\), and each bit \(flag bit\) in the PSW can have a self-defined meaning. A bitwise operation operates on the bits of a binary number. A variable can be set as a program status word (PSW), and each bit (flag bit) in the PSW can have a self-defined meaning.
## Available APIs<a name="section848334511411"></a>
## **Available APIs**
The system provides operations for setting the flag bit to **1** or **0**, changing the flag bit content, and obtaining the most significant bit and least significant bit of the flag bit 1 in a PSW. You can also perform bitwise operations on system registers. The following table describes the APIs available for the bitwise operation module. For more details about the APIs, see the API reference.
The system provides operations for setting the flag bit to **1** or **0**, changing the flag bit content, and obtaining the most significant bit (MSB) and least significant bit (LSB) of the flag bit 1 in a PSW. You can also perform bitwise operations on system registers. The following table describes the APIs available for the bitwise operation module. For more details about the APIs, see the API reference.
**Table 1** Bitwise operation module APIs
**Table 1** APIs of the bitwise operation module
<a name="table148791521769"></a>
<table><thead align="left"><tr id="row13880624615"><th class="cellrowborder" valign="top" width="16.89168916891689%" id="mcps1.2.4.1.1"><p id="p1587119571763"><a name="p1587119571763"></a><a name="p1587119571763"></a>Function</p> | Category | API Description |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="35.54355435543554%" id="mcps1.2.4.1.2"><p id="p38714577610"><a name="p38714577610"></a><a name="p38714577610"></a>API</p> | Setting a flag bit| - **LOS_BitmapSet**: sets a flag bit of a PSW to **1**.<br>- **LOS_BitmapClr**: sets a flag bit of a PSW to **0**. |
</th> | Obtaining the bit whose flag bit is **1**| -**LOS_HighBitGet**: obtains the most significant bit of 1 in a PSW.<br>- **LOS_LowBitGet**: obtains the least significant bit of 1 in a PSW. |
<th class="cellrowborder" valign="top" width="47.56475647564757%" id="mcps1.2.4.1.3"><p id="p108711657563"><a name="p108711657563"></a><a name="p108711657563"></a>Description</p> | Operating continuous bits| - **LOS_BitmapSetNBits**: sets the consecutive flag bits of a PSW to **1**.<br>- **LOS_BitmapClrNBits**: sets the consecutive flag bits of a PSW to **0**.<br>- **LOS_BitmapFfz**: obtains the first 0 bit starting from the LSB. |
</th>
</tr>
</thead> ## Development Example
<tbody><tr id="row18801722069"><td class="cellrowborder" rowspan="2" valign="top" width="16.89168916891689%" headers="mcps1.2.4.1.1 "><p id="p108717579612"><a name="p108717579612"></a><a name="p108717579612"></a>Setting the flag bit to <strong id="b129301229122320"><a name="b129301229122320"></a><a name="b129301229122320"></a>1</strong> or <strong id="b1899463182312"><a name="b1899463182312"></a><a name="b1899463182312"></a>0</strong></p>
</td>
<td class="cellrowborder" valign="top" width="35.54355435543554%" headers="mcps1.2.4.1.2 "><p id="p88717574616"><a name="p88717574616"></a><a name="p88717574616"></a>LOS_BitmapSet</p> ### Example Description
</td>
<td class="cellrowborder" valign="top" width="47.56475647564757%" headers="mcps1.2.4.1.3 "><p id="p16871957668"><a name="p16871957668"></a><a name="p16871957668"></a>Sets a flag bit of a PSW to <strong id="b1283195411179"><a name="b1283195411179"></a><a name="b1283195411179"></a>1</strong>.</p>
</td>
</tr>
<tr id="row38805219612"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p68713574610"><a name="p68713574610"></a><a name="p68713574610"></a>LOS_BitmapClr</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p14871155718618"><a name="p14871155718618"></a><a name="p14871155718618"></a>Sets a flag bit of a PSW to <strong id="b15267438112312"><a name="b15267438112312"></a><a name="b15267438112312"></a>0</strong>.</p>
</td>
</tr>
<tr id="row16880112663"><td class="cellrowborder" rowspan="2" valign="top" width="16.89168916891689%" headers="mcps1.2.4.1.1 "><p id="p158710579615"><a name="p158710579615"></a><a name="p158710579615"></a>Obtaining the bit whose flag bit is <strong id="b58742415239"><a name="b58742415239"></a><a name="b58742415239"></a>1</strong></p>
</td>
<td class="cellrowborder" valign="top" width="35.54355435543554%" headers="mcps1.2.4.1.2 "><p id="p1787145718612"><a name="p1787145718612"></a><a name="p1787145718612"></a>LOS_HighBitGet</p>
</td>
<td class="cellrowborder" valign="top" width="47.56475647564757%" headers="mcps1.2.4.1.3 "><p id="p168713571468"><a name="p168713571468"></a><a name="p168713571468"></a>Obtains the most significant bit of <strong id="b485014714235"><a name="b485014714235"></a><a name="b485014714235"></a>1</strong> in the PSW.</p>
</td>
</tr>
<tr id="row138803219613"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p15871957467"><a name="p15871957467"></a><a name="p15871957467"></a>LOS_LowBitGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p148719571569"><a name="p148719571569"></a><a name="p148719571569"></a>Obtains the least significant bit of <strong id="b9907125542319"><a name="b9907125542319"></a><a name="b9907125542319"></a>1</strong> in the PSW.</p>
</td>
</tr>
<tr id="row0880182168"><td class="cellrowborder" rowspan="3" valign="top" width="16.89168916891689%" headers="mcps1.2.4.1.1 "><p id="p10871957265"><a name="p10871957265"></a><a name="p10871957265"></a>Operating continuous bits</p>
</td>
<td class="cellrowborder" valign="top" width="35.54355435543554%" headers="mcps1.2.4.1.2 "><p id="p787185717616"><a name="p787185717616"></a><a name="p787185717616"></a>LOS_BitmapSetNBits</p>
</td>
<td class="cellrowborder" valign="top" width="47.56475647564757%" headers="mcps1.2.4.1.3 "><p id="p10871135714613"><a name="p10871135714613"></a><a name="p10871135714613"></a>Sets the continuous flag bits of a PSW to <strong id="b145631313234"><a name="b145631313234"></a><a name="b145631313234"></a>1</strong>.</p>
</td>
</tr>
<tr id="row12881728619"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p18710575615"><a name="p18710575615"></a><a name="p18710575615"></a>LOS_BitmapClrNBits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1387145711610"><a name="p1387145711610"></a><a name="p1387145711610"></a>Sets the continuous flag bits of a PSW to <strong id="b185031722103115"><a name="b185031722103115"></a><a name="b185031722103115"></a>0</strong>.</p>
</td>
</tr>
<tr id="row4881192262"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1987155714611"><a name="p1987155714611"></a><a name="p1987155714611"></a>LOS_BitmapFfz</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p187115571369"><a name="p187115571369"></a><a name="p187115571369"></a>Obtains the first 0 bit starting from the least significant bit (LSB).</p>
</td>
</tr>
</tbody>
</table>
## Development Example<a name="section67569495514"></a>
### Example Description<a name="section33551554391"></a>
This example implements the following: This example implements the following:
1. Set a flag bit to **1**. 1. Set a flag bit to **1**.
2. Obtain the most significant bit of flag bit 1.
2. Obtain the MSB of flag bit 1.
3. Set a flag bit to **0**. 3. Set a flag bit to **0**.
4. Obtain the least significant bit of the flag bit 1.
4. Obtain the LSB of flag bit 1.
### Sample Code
The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **BitSample** function is called in **TestTaskEntry**.
``` ```
#include "los_bitmap.h" #include "los_bitmap.h"
...@@ -105,10 +67,12 @@ static UINT32 BitSample(VOID) ...@@ -105,10 +67,12 @@ static UINT32 BitSample(VOID)
} }
``` ```
### Verification ### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
Bitmap Sample! Bitmap Sample!
The flag is 0x10101010 The flag is 0x10101010
...@@ -117,4 +81,3 @@ LOS_HighBitGet:The highest one bit is 28, the flag is 0x10101110 ...@@ -117,4 +81,3 @@ LOS_HighBitGet:The highest one bit is 28, the flag is 0x10101110
LOS_BitmapClr: pos : 28, the flag is 0x00101110 LOS_BitmapClr: pos : 28, the flag is 0x00101110
LOS_LowBitGet: The lowest one bit is 4, the flag is 0x00101110 LOS_LowBitGet: The lowest one bit is 4, the flag is 0x00101110
``` ```
...@@ -8,19 +8,18 @@ A doubly linked list (DLL) is a linked data structure that consists of a set of ...@@ -8,19 +8,18 @@ A doubly linked list (DLL) is a linked data structure that consists of a set of
## Available APIs ## Available APIs
The table below describes the DLL APIs. For more details about the APIs, see the API reference. The table below describes APIs available for the DLL. For more details about the APIs, see the API reference.
| **Category**| **API**| | Category | API Description |
| -------- | -------- | | ------------------------ | ------------------------------------------------------------ |
| Initializing a DLL| - **LOS_ListInit**: initializes a node as a DLL node.<br>- **LOS_DL_LIST_HEAD**: defines a node and initializes it as a DLL node.| | Initializing a DLL | - **LOS_ListInit**: initializes a node as a DLL node.<br>- **LOS_DL_LIST_HEAD**: defines a node and initializes it as a DLL node.|
| Adding a node| - **LOS_ListAdd**: adds a node to the head of a DLL.<br>- **LOS_ListHeadInsert**: same as **LOS_ListAdd**.<br>- **LOS_ListTailInsert**: inserts a node to the tail of a DLL.| | Adding a node | - **LOS_ListAdd**: adds a node to the head of a DLL.<br>- **LOS_ListHeadInsert**: same as **LOS_ListAdd**.<br>- **LOS_ListTailInsert**: inserts a node to the tail of a DLL.|
| Adding a DLL| - **LOS_ListAddList**: adds the head of a DLL to the head of this DLL.<br>- **LOS_ListHeadInsertList**: inserts the head of a DLL to the head of this DLL.<br>- **LOS_ListTailInsertList**: Inserts the end of a DLL to the head of this DLL.| | Adding a DLL | - **LOS_ListAddList**: adds the head of a DLL to the head of this DLL.<br>- **LOS_ListHeadInsertList**: inserts the head of a DLL to the head of this DLL.<br>- **LOS_ListTailInsertList**: inserts the end of a DLL to the head of this DLL.|
| Deleting a node| - **LOS_ListDelete**: deletes a node from this DLL.<br>- **LOS_ListDelInit**: deletes a node from this DLL and uses this node to initialize the DLL.| | Deleting a node | - **LOS_ListDelete**: deletes a node from this DLL.<br>- **LOS_ListDelInit**: deletes a node from this DLL and uses this node to initialize the DLL.|
| Checking a DLL| - **LOS_ListEmpty**: checks whether a DLL is empty.<br>- **LOS_DL_LIST_IS_END**: checks whether a node is the tail of the DLL.<br>- **LOS_DL_LIST_IS_ON_QUEUE**: checks whether a node is in the DLL.| | Checking a DLL | - **LOS_ListEmpty**: checks whether a DLL is empty.<br>- **LOS_DL_LIST_IS_END**: checks whether a node is the tail of the DLL.<br>- **LOS_DL_LIST_IS_ON_QUEUE**: checks whether a node is in the DLL.|
| Obtains structure information.| - **LOS_OFF_SET_OF**: obtains the offset of a member in the specified structure relative to the start address of the structure.<br>- **LOS_DL_LIST_ENTRY**: obtains the address of the structure that contains the first node in the DLL. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the name of the structure to be obtained, and the third input parameter indicates the name of the linked list in the structure.<br>- **LOS_ListPeekHeadType**: obtains the address of the structure that contains the first node in the linked list. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the name of the structure to be obtained, and the third input parameter indicates the name of the linked list in the structure. Null will be returned if the DLL is empty.<br>- **LOS_ListRemoveHeadType**: obtains the address of the structure that contains the first node in the linked list, and deletes the first node from the list. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the name of the structure to be obtained, and the third input parameter indicates the name of the linked list in the structure. Null will be returned if the DLL is empty.<br>- **LOS_ListNextType**: obtains the address of the structure that contains the next node of the specified node in the linked list. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the specified node, the third parameter indicates the name of the structure to be obtained, and the fourth input parameter indicates the name of the linked list in the structure. If the next node of the linked list node is the head node and is empty, NULL will be returned.| | Obtaining structure information | - **LOS_OFF_SET_OF**: obtains the offset of a member in the specified structure relative to the start address of the structure.<br>- **LOS_DL_LIST_ENTRY**: obtains the address of the structure that contains the first node in the DLL. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the name of the structure to be obtained, and the third input parameter indicates the name of the linked list in the structure.<br>- **LOS_ListPeekHeadType**: obtains the address of the structure that contains the first node in the linked list. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the name of the structure to be obtained, and the third input parameter indicates the name of the linked list in the structure. Null will be returned if the DLL is empty.<br>- **LOS_ListRemoveHeadType**: obtains the address of the structure that contains the first node in the linked list, and deletes the first node from the list. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the name of the structure to be obtained, and the third input parameter indicates the name of the linked list in the structure. Null will be returned if the DLL is empty.<br>- **LOS_ListNextType**: obtains the address of the structure that contains the next node of the specified node in the linked list. The first input parameter of the API indicates the head node in the list, the second input parameter indicates the specified node, the third parameter indicates the name of the structure to be obtained, and the fourth input parameter indicates the name of the linked list in the structure. If the next node of the linked list node is the head node and is empty, NULL will be returned.|
| Traversing a DLL| - **LOS_DL_LIST_FOR_EACH**: traverses a DLL.<br>- **LOS_DL_LIST_FOR_EACH_SAFE**: traverses the DLL and stores the subsequent nodes of the current node for security verification.| | Traversing a DLL | - **LOS_DL_LIST_FOR_EACH**: traverses a DLL.<br>- **LOS_DL_LIST_FOR_EACH_SAFE**: traverses the DLL and stores the subsequent nodes of the current node for security verification.|
| Traversing the structure that contains the DLL| - **LOS_DL_LIST_FOR_EACH_ENTRY**: traverses a DLL and obtains the address of the structure that contains the linked list node.<br>- **LOS_DL_LIST_FOR_EACH_ENTRY_SAFE**: traverses a DLL, obtains the address of the structure that contains the linked list node, and stores the address of the structure that contains the subsequent node of the current node.| | Traversing the structure that contains a DLL| - **LOS_DL_LIST_FOR_EACH_ENTRY**: traverses a DLL and obtains the address of the structure that contains the linked list node.<br>- **LOS_DL_LIST_FOR_EACH_ENTRY_SAFE**: traverses a DLL, obtains the address of the structure that contains the linked list node, and stores the address of the structure that contains the subsequent node of the current node.|
## How to Develop ## How to Develop
...@@ -30,7 +29,7 @@ The typical development process of the DLL is as follows: ...@@ -30,7 +29,7 @@ The typical development process of the DLL is as follows:
2. Call **LOS_ListAdd** to add a node into the DLL. 2. Call **LOS_ListAdd** to add a node into the DLL.
3. Call **LOS_ListTailInsert** to insert a node to the tail of the DLL. 3. Call **LOS_ListTailInsert** to insert a node into the tail of the DLL.
4. Call **LOS_ListDelete** to delete the specified node. 4. Call **LOS_ListDelete** to delete the specified node.
...@@ -39,18 +38,19 @@ The typical development process of the DLL is as follows: ...@@ -39,18 +38,19 @@ The typical development process of the DLL is as follows:
6. Call **LOS_ListDelInit** to delete the specified node and initialize the DLL based on the node. 6. Call **LOS_ListDelInit** to delete the specified node and initialize the DLL based on the node.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > **NOTE**<br>
> - Pay attention to the operations operations of the front and back pointer of the node. >
> - Pay attention to the operations before and after the node pointer.
> >
> - The DLL APIs are underlying interfaces and do not check whether the input parameters are empty. You must ensure that the input parameters are valid. > - The DLL APIs are underlying interfaces and do not check whether the input parameters are empty. You must ensure that the input parameters are valid.
> >
> - If the memory of a linked list node is dynamically allocated, release the memory when deleting the node. > - If the memory of a linked list node is dynamically allocated, release the memory when deleting the node.
**Development Example** ## Development Example
**Example Description**
### Example Description
This example implements the following: This example implements the following:
...@@ -63,7 +63,11 @@ This example implements the following: ...@@ -63,7 +63,11 @@ This example implements the following:
4. Check the operation result. 4. Check the operation result.
### Sample Code
The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **ListSample** function is called in **TestTaskEntry**.
The sample code is as follows:
``` ```
#include "stdio.h" #include "stdio.h"
...@@ -109,6 +113,8 @@ static UINT32 ListSample(VOID) ...@@ -109,6 +113,8 @@ static UINT32 ListSample(VOID)
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
Initial head Initial head
Add listNode1 success Add listNode1 success
......
# Standard Library # Standard Library
The OpenHarmony kernel uses the musl libc library that supports the Portable Operating System Interface \(POSIX\). You can develop components and applications working on the kernel based on the POSIX. The OpenHarmony kernel uses the musl libc library that supports the Portable Operating System Interface (POSIX). You can develop components and applications working on the kernel based on the POSIX.
## Standard Library API Framework ## Standard Library API Framework
**Figure 1** POSIX framework<a name="fig153258541429"></a> **Figure 1** POSIX framework
![](figures/posix-framework.png "posix-framework") ![](figures/posix-framework.png "posix-framework")
The musl libc library supports POSIX standards. The OpenHarmony kernel adapts the related system call APIs to implement external functions. The musl libc library supports POSIX standards. The OpenHarmony kernel adapts the related system call APIs to implement external functions.
For details about the APIs supported by the standard library, see the API document of the C library, which also covers the differences between the standard library and the POSIX standard library. For details about the APIs supported by the standard library, see the API document of the C library, which also covers the differences between the standard library and the POSIX standard library.
## Development Example
In this example, the main thread creates **THREAD\_NUM** child threads. Once a child thread is started, it enters the standby state. After the main thread successfully wakes up all child threads, they continue to execute until the lifecycle ends. The main thread uses the **pthread\_join** method to wait until all child threads are executed. ### Development Example
#### Example Description
In this example, the main thread creates THREAD_NUM child threads. Once a child thread is started, it enters the standby state. After the main thread successfully wakes up all child threads, they continue to execute until the lifecycle ends. The main thread uses the **pthread_join** method to wait until all child threads are executed.
#### Sample Code
The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **ExamplePosix** function is called in **TestTaskEntry**.
The sample code is as follows:
``` ```
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define THREAD_NUM 3 #define THREAD_NUM 3
int g_startNum = 0; /* Number of started threads */ int g_startNum = 0; /* Number of threads to start */
int g_wakenNum = 0; /* Number of wakeup threads */ int g_wakenNum = 0; /* Number of threads to wake up */
struct testdata { struct testdata {
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; pthread_cond_t cond;
} g_td; } g_td;
/* /* Entry function of the child thread */
* Entry function of child threads. static VOID *ChildThreadFunc(VOID *arg)
*/
static void *ChildThreadFunc(void *arg)
{ {
int rc; int rc;
pthread_t self = pthread_self(); pthread_t self = pthread_self();
...@@ -47,7 +51,7 @@ static void *ChildThreadFunc(void *arg) ...@@ -47,7 +51,7 @@ static void *ChildThreadFunc(void *arg)
/* Acquire a mutex. */ /* Acquire a mutex. */
rc = pthread_mutex_lock(&g_td.mutex); rc = pthread_mutex_lock(&g_td.mutex);
if (rc != 0) { if (rc != 0) {
printf("ERROR:take mutex lock failed, error code is %d!\n", rc); dprintf("ERROR:take mutex lock failed, error code is %d!\n", rc);
goto EXIT; goto EXIT;
} }
...@@ -57,7 +61,7 @@ static void *ChildThreadFunc(void *arg) ...@@ -57,7 +61,7 @@ static void *ChildThreadFunc(void *arg)
/* Wait for the cond variable. */ /* Wait for the cond variable. */
rc = pthread_cond_wait(&g_td.cond, &g_td.mutex); rc = pthread_cond_wait(&g_td.cond, &g_td.mutex);
if (rc != 0) { if (rc != 0) {
printf("ERROR: pthread condition wait failed, error code is %d!\n", rc); dprintf("ERROR: pthread condition wait failed, error code is %d!\n", rc);
(void)pthread_mutex_unlock(&g_td.mutex); (void)pthread_mutex_unlock(&g_td.mutex);
goto EXIT; goto EXIT;
} }
...@@ -65,52 +69,53 @@ static void *ChildThreadFunc(void *arg) ...@@ -65,52 +69,53 @@ static void *ChildThreadFunc(void *arg)
/* Attempt to acquire a mutex, which is failed in normal cases. */ /* Attempt to acquire a mutex, which is failed in normal cases. */
rc = pthread_mutex_trylock(&g_td.mutex); rc = pthread_mutex_trylock(&g_td.mutex);
if (rc == 0) { if (rc == 0) {
printf("ERROR: mutex gets an abnormal lock!\n"); dprintf("ERROR: mutex gets an abnormal lock!\n");
goto EXIT; goto EXIT;
} }
/* The value of g_wakenNum is increased by 1. The value indicates the number of child threads that have been woken up by the cond variable. */ /* The value of g_wakenNum is increased by 1. The value indicates the number of child threads that have been woken up by the cond variable. */
g_wakenNum++; g_wakenNum++;
/* Unlock a mutex. */ /* Release a mutex. */
rc = pthread_mutex_unlock(&g_td.mutex); rc = pthread_mutex_unlock(&g_td.mutex);
if (rc != 0) { if (rc != 0) {
printf("ERROR: mutex release failed, error code is %d!\n", rc); dprintf("ERROR: mutex release failed, error code is %d!\n", rc);
goto EXIT; goto EXIT;
} }
EXIT: EXIT:
return NULL; return NULL;
} }
static int testcase(void) static int ExamplePosix(VOID)
{ {
int i, rc; int i, rc;
pthread_t thread[THREAD_NUM]; pthread_t thread[THREAD_NUM];
/* Initialize a mutex. */ /* Initialize the mutex. */
rc = pthread_mutex_init(&g_td.mutex, NULL); rc = pthread_mutex_init(&g_td.mutex, NULL);
if (rc != 0) { if (rc != 0) {
printf("ERROR: mutex init failed, error code is %d!\n", rc); dprintf("ERROR: mutex init failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
/* Initialize the cond variable. */ /* Initialize the cond variable. */
rc = pthread_cond_init(&g_td.cond, NULL); rc = pthread_cond_init(&g_td.cond, NULL);
if (rc != 0) { if (rc != 0) {
printf("ERROR: pthread condition init failed, error code is %d!\n", rc); dprintf("ERROR: pthread condition init failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
/* Create child threads in batches. The number is specified by THREAD_NUM. */ /* Create child threads in batches. */
for (i = 0; i < THREAD_NUM; i++) { for (i = 0; i < THREAD_NUM; i++) {
rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL); rc = pthread_create(&thread[i], NULL, ChildThreadFunc, NULL);
if (rc != 0) { if (rc != 0) {
printf("ERROR: pthread create failed, error code is %d!\n", rc); dprintf("ERROR: pthread create failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
} }
dprintf("pthread_create ok\n");
/* Wait until all child threads lock a mutex. */ /* Wait until all child threads obtain a mutex. */
while (g_startNum < THREAD_NUM) { while (g_startNum < THREAD_NUM) {
usleep(100); usleep(100);
} }
...@@ -118,14 +123,14 @@ static int testcase(void) ...@@ -118,14 +123,14 @@ static int testcase(void)
/* Acquire a mutex and block all threads using pthread_cond_wait. */ /* Acquire a mutex and block all threads using pthread_cond_wait. */
rc = pthread_mutex_lock(&g_td.mutex); rc = pthread_mutex_lock(&g_td.mutex);
if (rc != 0) { if (rc != 0) {
printf("ERROR: mutex lock failed, error code is %d\n", rc); dprintf("ERROR: mutex lock failed, error code is %d\n", rc);
goto ERROROUT; goto ERROROUT;
} }
/* Release a mutex. */ /* Release the mutex. */
rc = pthread_mutex_unlock(&g_td.mutex); rc = pthread_mutex_unlock(&g_td.mutex);
if (rc != 0) { if (rc != 0) {
printf("ERROR: mutex unlock failed, error code is %d!\n", rc); dprintf("ERROR: mutex unlock failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
...@@ -133,7 +138,7 @@ static int testcase(void) ...@@ -133,7 +138,7 @@ static int testcase(void)
/* Broadcast signals on the cond variable. */ /* Broadcast signals on the cond variable. */
rc = pthread_cond_signal(&g_td.cond); rc = pthread_cond_signal(&g_td.cond);
if (rc != 0) { if (rc != 0) {
printf("ERROR: pthread condition failed, error code is %d!\n", rc); dprintf("ERROR: pthread condition failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
} }
...@@ -142,73 +147,69 @@ static int testcase(void) ...@@ -142,73 +147,69 @@ static int testcase(void)
/* Check whether all child threads are woken up. */ /* Check whether all child threads are woken up. */
if (g_wakenNum != THREAD_NUM) { if (g_wakenNum != THREAD_NUM) {
printf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum); dprintf("ERROR: not all threads awaken, only %d thread(s) awaken!\n", g_wakenNum);
goto ERROROUT; goto ERROROUT;
} }
dprintf("all threads awaked\n");
/* Wait for all threads to terminate. */ /* Join all child threads, that is, wait for the end of all child threads. */
for (i = 0; i < THREAD_NUM; i++) { for (i = 0; i < THREAD_NUM; i++) {
rc = pthread_join(thread[i], NULL); rc = pthread_join(thread[i], NULL);
if (rc != 0) { if (rc != 0) {
printf("ERROR: pthread join failed, error code is %d!\n", rc); dprintf("ERROR: pthread join failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
} }
dprintf("all threads join ok\n");
/* Destroy the cond variable. */ /* Destroy the cond variable. */
rc = pthread_cond_destroy(&g_td.cond); rc = pthread_cond_destroy(&g_td.cond);
if (rc != 0) { if (rc != 0) {
printf("ERROR: pthread condition destroy failed, error code is %d!\n", rc); dprintf("ERROR: pthread condition destroy failed, error code is %d!\n", rc);
goto ERROROUT; goto ERROROUT;
} }
return 0; return 0;
ERROROUT: ERROROUT:
return -1; return -1;
} }
```
/* #### Verification
* Main function
*/
int main(int argc, char *argv[])
{
int rc;
/* Start the test function. */ The output is as follows:
rc = testcase();
if (rc != 0) {
printf("ERROR: testcase failed!\n");
}
return 0; ```
} pthread_create ok
#ifdef __cplusplus all threads awaked
#if __cplusplus all threads join ok
}
#endif /* __cplusplus */
#endif /* __cplusplus */
``` ```
## Differences from the Linux Standard Library ## Differences from the Linux Standard Library
This section describes the key differences between the standard library carried by the OpenHarmony kernel and the Linux standard library. For more differences, see the API document of the C library. The following describes the key differences between the standard library supported by the OpenHarmony kernel and the Linux standard library. For more differences, see the API document of the C library.
### Process ### Process
1. The OpenHarmony user-mode processes support only static priorities, which range from 10 \(highest\) to 31 \(lowest\). - The OpenHarmony user-mode processes support only static priorities, which range from 10 (highest) to 31 (lowest).
2. The OpenHarmony user-mode threads support only static priorities, which range from 0 \(highest\) to 31 \(lowest\).
3. The OpenHarmony process scheduling supports **SCHED\_RR** only, and thread scheduling supports **SCHED\_RR** or **SCHED\_FIFO**. - The OpenHarmony user-mode threads support only static priorities, which range from 0 (highest) to 31 (lowest).
- The OpenHarmony process scheduling supports **SCHED_RR** only, and thread scheduling supports **SCHED_RR** or **SCHED_FIFO**.
### Memory ### Memory
**h2****Difference with Linux mmap** **Differences from Linux mmap**
mmap prototype: **void \*mmap \(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\)** mmap prototype: **void \*mmap (void \*addr, size_t length, int prot, int flags, int fd, off_t offset)**
The lifecycle implementation of **fd** is different from that of Linux glibc. glibc releases the **fd** handle immediately after successfully invoking **mmap** for mapping. In the OpenHarmony kernel, you are not allowed to close the **fd** immediately after the mapping is successful. You can close the **fd** only after **munmap** is called. If you do not close **fd**, the OS reclaims the **fd** when the process exits. The lifecycle implementation of **fd** is different from that of Linux glibc. glibc releases the **fd** handle immediately after successfully invoking **mmap** for mapping. In the OpenHarmony kernel, you are not allowed to close the **fd** immediately after the mapping is successful. You can close the **fd** only after **munmap** is called. If you do not close **fd**, the OS reclaims the **fd** when the process exits.
**h2****Sample Code** **Example**
Linux OS: Linux:
``` ```
int main(int argc, char *argv[]) int main(int argc, char *argv[])
...@@ -226,13 +227,14 @@ int main(int argc, char *argv[]) ...@@ -226,13 +227,14 @@ int main(int argc, char *argv[])
perror("mmap"); perror("mmap");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
close(fd); /* OpenHarmony does not support close fd immediately after the mapping is successful. */ close(fd); /* OpenHarmony does not support closing fd immediately after the mapping is successful. */
... ...
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
``` ```
OpenHarmony:
OpenHarmony:
``` ```
int main(int argc, char *argv[]) int main(int argc, char *argv[])
...@@ -257,22 +259,27 @@ int main(int argc, char *argv[]) ...@@ -257,22 +259,27 @@ int main(int argc, char *argv[])
} }
``` ```
### File System ### File System
**System directories**: You cannot modify system directories and device mount directories, which include **/dev**, **/proc**, **/app**, **/bin**, **/data**, **/etc**, **/lib**, **/system** and **/usr**. System directories: You cannot modify system directories and device mount directories, which include **/dev**, **/proc**, **/app**, **/bin**, **/data**, **/etc**, **/lib**, **/system**, and **/usr**.
**User directory**: The user directory refers to the **/storage** directory. You can create, read, and write files in this directory, but cannot mount devices. User directory: The user directory refers to the **/storage** directory. You can create, read, and write files in this directory, but cannot mount it to a device.
Except in the system and user directories, you can create directories and mount them to devices. Note that nested mount is not allowed, that is, a mounted folder and its subfolders cannot be mounted repeatedly. A non-empty folder cannot be mounted.
Except in the system and user directories, you can create directories and mount devices. Note that nested mount is not allowed, that is, a mounted folder and its subfolders cannot be mounted repeatedly. A non-empty folder cannot be mounted.
### Signal ### Signal
- The default behavior for signals does not include **STOP**, **CONTINUE**, or **COREDUMP**. - The default behavior for signals does not include **STOP**, **CONTINUE**, or **COREDUMP**.
- A sleeping process \(for example, a process enters the sleeping status by calling the sleep function\) cannot be woken up by a signal. The signal mechanism does not support the wakeup function. The behavior for a signal can be processed only when the process is scheduled by the CPU.
- A sleeping process (for example, a process enters the sleeping status by calling the sleep function) cannot be woken up by a signal. The signal mechanism does not support the wakeup function. The behavior for a signal can be processed only when the process is scheduled by the CPU.
- After a process exits, **SIGCHLD** is sent to the parent process. The sending action cannot be canceled. - After a process exits, **SIGCHLD** is sent to the parent process. The sending action cannot be canceled.
- Only signals 1 to 30 are supported. The callback is executed only once even if the same signal is received multiple times.
### Time - Only signals 1 to 30 are supported. The callback is invoked only once even if the same signal is received multiple times.
The OpenHarmony time precision is based on tick. The default value is 10 ms/tick. The time error of the **sleep** and **timeout** functions is less than or equal to 20 ms.
### Time
The default time precision of OpenHarmony is 10 ms/tick. The time error of the **sleep** and **timeout** functions is less than or equal to 20 ms.
...@@ -3,36 +3,31 @@ ...@@ -3,36 +3,31 @@
## Basic Concepts ## Basic Concepts
In an OS that supports multiple tasks, modifying data in a memory area requires three steps: read data, modify data, and write data. However, data in a memory area may be simultaneously accessed by multiple tasks. If the data modification is interrupted by another task, the execution result of the operation is unpredictable. In an OS that supports multiple tasks, modifying data in memory involves three steps: read data, modify data, and write data. However, the data may be simultaneously accessed by multiple tasks. If the data modification is interrupted by another task, an unexpected result will be caused.
Although you can enable or disable interrupts to ensure that the multi-task execution results meet expectations, the system performance is affected. Although you can enable or disable interrupts to ensure expected results of multiple tasks, the system performance is affected.
The ARMv6 architecture has introduced the **LDREX** and **STREX** instructions to support more discreet non-blocking synchronization of the shared memory. The atomic operations implemented thereby can ensure that the "read-modify-write" operations on the same data will not be interrupted, that is, the operation atomicity is ensured. The ARMv6 architecture has introduced the **LDREX** and **STREX** instructions to support more discreet non-blocking synchronization of the shared memory. The atomic operations implemented thereby can ensure that the "read-modify-write" operations on the same data will not be interrupted, that is, the operation atomicity is ensured.
## Working Principles
The OpenHarmony system has encapsulated the **LDREX** and **STREX** in the ARMv6 architecture to provide a set of atomic operation APIs. ## Working Principles
- LDREX Rx, \[Ry\] OpenHarmony has encapsulated the **LDREX** and **STREX** in the ARMv6 architecture to provide a set of atomic operation APIs.
- LDREX Rx, [Ry]
Reads the value in the memory and marks the exclusive access to the memory segment. Reads the value in the memory and marks the exclusive access to the memory segment.
- Reads the 4-byte memory data pointed by the register **Ry** and saves the data to the **Rx** register. - Reads the 4-byte memory data pointed by the register **Ry** and saves the data to the **Rx** register.
- Adds an exclusive access flag to the memory area pointed by **Ry**. - Adds an exclusive access flag to the memory area pointed by **Ry**.
- STREX Rf, Rx, \[Ry\] - STREX Rf, Rx, [Ry]
Checks whether the memory has an exclusive access flag. If yes, the system updates the memory value and clears the flag. If no, the memory is not updated. Checks whether the memory has an exclusive access flag. If yes, the system updates the memory value and clears the flag. If no, the memory is not updated.
- If there is an exclusive access flag, the system: - If there is an exclusive access flag, the system:
- Updates the **Rx** register value to the memory pointed to by the **Ry** register. - Updates the **Rx** register value to the memory pointed to by the **Ry** register.
- Sets the **Rf** register to **0**. - Sets the **Rf** register to **0**.
- If there is no exclusive access flag: - If there is no exclusive access flag:
- The memory is not updated. - The memory is not updated.
- The system sets the **Rf** register to **1**. - The system sets the **Rf** register to **1**.
- Flag register - Flag register
- If the flag register is **0**, the system exits the loop and the atomic operation is complete. - If the flag register is **0**, the system exits the loop and the atomic operation is complete.
- If the flag register is **1**, the system continues the loop and performs the atomic operation again. - If the flag register is **1**, the system continues the loop and performs the atomic operation again.
...@@ -40,179 +35,66 @@ The OpenHarmony system has encapsulated the **LDREX** and **STREX** in the A ...@@ -40,179 +35,66 @@ The OpenHarmony system has encapsulated the **LDREX** and **STREX** in the A
## Development Guidelines ## Development Guidelines
### Available APIs ### Available APIs
The following table describes the APIs available for the OpenHarmony LiteOS-A kernel atomic operation module. For more details about the APIs, see the API reference. The following table describes the APIs available for the OpenHarmony LiteOS-A kernel atomic operation module.
**Table 1** Atomic operation APIs **Table 1** APIs for atomic operations
<a name="table29217519171"></a> | Category | API | Description |
<table><thead align="left"><tr id="row79375119172"><th class="cellrowborder" valign="top" width="21.21212121212121%" id="mcps1.2.4.1.1"><p id="p159375113174"><a name="p159375113174"></a><a name="p159375113174"></a>Function</p> | ------------ | ----------------------- | --------------------------- |
</th> | Read | LOS_AtomicRead | Reads 32-bit atomic data. |
<th class="cellrowborder" valign="top" width="33.39333933393339%" id="mcps1.2.4.1.2"><p id="p199385118173"><a name="p199385118173"></a><a name="p199385118173"></a>API</p> | Read | LOS_Atomic64Read | Reads 64-bit atomic data. |
</th> | Write | LOS_AtomicSet | Sets 32-bit atomic data. |
<th class="cellrowborder" valign="top" width="45.3945394539454%" id="mcps1.2.4.1.3"><p id="p18937511175"><a name="p18937511175"></a><a name="p18937511175"></a>Description</p> | Write | LOS_Atomic64Set | Sets 64-bit atomic data. |
</th> | Add | LOS_AtomicAdd | Adds 32-bit atomic data. |
</tr> | Add | LOS_Atomic64Add | Adds 64-bit atomic data. |
</thead> | Add | LOS_AtomicInc | Adds 1 to 32-bit atomic data. |
<tbody><tr id="row159315151712"><td class="cellrowborder" rowspan="2" valign="top" width="21.21212121212121%" headers="mcps1.2.4.1.1 "><p id="p593135115176"><a name="p593135115176"></a><a name="p593135115176"></a>Read</p> | Add | LOS_Atomic64Inc | Adds 1 to 64-bit atomic data. |
</td> | Add | LOS_AtomicIncRet | Adds 1 to 32-bit atomic data and returns the data. |
<td class="cellrowborder" valign="top" width="33.39333933393339%" headers="mcps1.2.4.1.2 "><p id="p1193651181714"><a name="p1193651181714"></a><a name="p1193651181714"></a>LOS_AtomicRead</p> | Add | LOS_Atomic64IncRet | Adds 1 to 64-bit atomic data and returns the data. |
</td> | Subtract | LOS_AtomicSub | Performs subtraction on 32-bit atomic data. |
<td class="cellrowborder" valign="top" width="45.3945394539454%" headers="mcps1.2.4.1.3 "><p id="p09316512178"><a name="p09316512178"></a><a name="p09316512178"></a>Reads 32-bit atomic data.</p> | Subtract | LOS_Atomic64Sub | Performs subtraction on 64-bit atomic data. |
</td> | Subtract | LOS_AtomicDec | Subtracts 1 from 32-bit atomic data. |
</tr> | Subtract | LOS_Atomic64Dec | Subtracts 1 from 64-bit atomic data. |
<tr id="row1493151161719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p119395111718"><a name="p119395111718"></a><a name="p119395111718"></a>LOS_Atomic64Read</p> | Subtract | LOS_AtomicDecRet | Subtracts 1 from 32-bit atomic data and returns the result. |
</td> | Subtract | LOS_Atomic64DecRet | Subtracts 1 from 64-bit atomic data and returns the result. |
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p49311514178"><a name="p49311514178"></a><a name="p49311514178"></a>Reads 64-bit atomic data.</p> | Swap | LOS_AtomicXchgByte | Swaps 8-bit memory data. |
</td> | Swap | LOS_AtomicXchg16bits | Swaps 16-bit memory data. |
</tr> | Swap | LOS_AtomicXchg32bits | Swaps 32-bit memory data. |
<tr id="row69365111712"><td class="cellrowborder" rowspan="2" valign="top" width="21.21212121212121%" headers="mcps1.2.4.1.1 "><p id="p199355111175"><a name="p199355111175"></a><a name="p199355111175"></a>Write</p> | Swap | LOS_AtomicXchg64bits | Swaps 64-bit memory data. |
</td> | Compare and swap| LOS_AtomicCmpXchgByte | Compares and swaps 8-bit memory data. |
<td class="cellrowborder" valign="top" width="33.39333933393339%" headers="mcps1.2.4.1.2 "><p id="p1693175191714"><a name="p1693175191714"></a><a name="p1693175191714"></a>LOS_AtomicSet</p> | Compare and swap| LOS_AtomicCmpXchg16bits | Compares and swaps 16-bit memory data.|
</td> | Compare and swap| LOS_AtomicCmpXchg32bits | Compares and swaps 32-bit memory data.|
<td class="cellrowborder" valign="top" width="45.3945394539454%" headers="mcps1.2.4.1.3 "><p id="p129320516173"><a name="p129320516173"></a><a name="p129320516173"></a>Sets 32-bit atomic data.</p> | Compare and swap| LOS_AtomicCmpXchg64bits | Compares and swaps 64-bit memory data.|
</td>
</tr>
<tr id="row1593651111718"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p7944510176"><a name="p7944510176"></a><a name="p7944510176"></a>LOS_Atomic64Set</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p294115191713"><a name="p294115191713"></a><a name="p294115191713"></a>Sets 64-bit atomic data.</p>
</td>
</tr>
<tr id="row149495114177"><td class="cellrowborder" rowspan="6" valign="top" width="21.21212121212121%" headers="mcps1.2.4.1.1 "><p id="p1394165151718"><a name="p1394165151718"></a><a name="p1394165151718"></a>Add</p>
</td>
<td class="cellrowborder" valign="top" width="33.39333933393339%" headers="mcps1.2.4.1.2 "><p id="p494115112179"><a name="p494115112179"></a><a name="p494115112179"></a>LOS_AtomicAdd</p>
</td>
<td class="cellrowborder" valign="top" width="45.3945394539454%" headers="mcps1.2.4.1.3 "><p id="p1694155120174"><a name="p1694155120174"></a><a name="p1694155120174"></a>Adds 32-bit atomic data.</p>
</td>
</tr>
<tr id="row394651101719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p179435113171"><a name="p179435113171"></a><a name="p179435113171"></a>LOS_Atomic64Add</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p594851181718"><a name="p594851181718"></a><a name="p594851181718"></a>Adds 64-bit atomic data.</p>
</td>
</tr>
<tr id="row294185110171"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1834102212615"><a name="p1834102212615"></a><a name="p1834102212615"></a>LOS_AtomicInc</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p129413519173"><a name="p129413519173"></a><a name="p129413519173"></a>Adds 1 to 32-bit atomic data.</p>
</td>
</tr>
<tr id="row1894175101713"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1981302213264"><a name="p1981302213264"></a><a name="p1981302213264"></a>LOS_Atomic64Inc</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p167671640113316"><a name="p167671640113316"></a><a name="p167671640113316"></a>Adds 1 to 64-bit atomic data.</p>
</td>
</tr>
<tr id="row12946512178"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1994051181716"><a name="p1994051181716"></a><a name="p1994051181716"></a>LOS_AtomicIncRet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p59414511172"><a name="p59414511172"></a><a name="p59414511172"></a>Adds 1 to 32-bit atomic data and returns the data.</p>
</td>
</tr>
<tr id="row1994551101712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p129414519173"><a name="p129414519173"></a><a name="p129414519173"></a>LOS_Atomic64IncRet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1194951111713"><a name="p1194951111713"></a><a name="p1194951111713"></a>Adds 1 to 64-bit atomic data and returns the data.</p>
</td>
</tr>
<tr id="row1794451121719"><td class="cellrowborder" rowspan="6" valign="top" width="21.21212121212121%" headers="mcps1.2.4.1.1 "><p id="p179412517173"><a name="p179412517173"></a><a name="p179412517173"></a>Subtract</p>
</td>
<td class="cellrowborder" valign="top" width="33.39333933393339%" headers="mcps1.2.4.1.2 "><p id="p89495115176"><a name="p89495115176"></a><a name="p89495115176"></a>LOS_AtomicSub</p>
</td>
<td class="cellrowborder" valign="top" width="45.3945394539454%" headers="mcps1.2.4.1.3 "><p id="p18220416345"><a name="p18220416345"></a><a name="p18220416345"></a>Performs subtraction on 32-bit atomic data.</p>
</td>
</tr>
<tr id="row139485131718"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1894195116176"><a name="p1894195116176"></a><a name="p1894195116176"></a>LOS_Atomic64Sub</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p20822124173415"><a name="p20822124173415"></a><a name="p20822124173415"></a>Performs subtraction on 64-bit atomic data.</p>
</td>
</tr>
<tr id="row209505110175"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p7951051141713"><a name="p7951051141713"></a><a name="p7951051141713"></a>LOS_AtomicDec</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p382234117340"><a name="p382234117340"></a><a name="p382234117340"></a>Subtracts 1 from 32-bit atomic data.</p>
</td>
</tr>
<tr id="row995151171711"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p395151131715"><a name="p395151131715"></a><a name="p395151131715"></a>LOS_Atomic64Dec</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1982244117340"><a name="p1982244117340"></a><a name="p1982244117340"></a>Subtracts 1 from 64-bit atomic data.</p>
</td>
</tr>
<tr id="row895155117179"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p395155151719"><a name="p395155151719"></a><a name="p395155151719"></a>LOS_AtomicDecRet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p198222414349"><a name="p198222414349"></a><a name="p198222414349"></a>Subtracts 1 from 32-bit atomic data and returns the result.</p>
</td>
</tr>
<tr id="row59511518170"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1495125119175"><a name="p1495125119175"></a><a name="p1495125119175"></a>LOS_Atomic64DecRet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p198221841103419"><a name="p198221841103419"></a><a name="p198221841103419"></a>Subtracts 1 from 64-bit atomic data and returns the result.</p>
</td>
</tr>
<tr id="row159575131714"><td class="cellrowborder" rowspan="4" valign="top" width="21.21212121212121%" headers="mcps1.2.4.1.1 "><p id="p159585110177"><a name="p159585110177"></a><a name="p159585110177"></a>Swap</p>
</td>
<td class="cellrowborder" valign="top" width="33.39333933393339%" headers="mcps1.2.4.1.2 "><p id="p29515114174"><a name="p29515114174"></a><a name="p29515114174"></a>LOS_AtomicXchgByte</p>
</td>
<td class="cellrowborder" valign="top" width="45.3945394539454%" headers="mcps1.2.4.1.3 "><p id="p6956510177"><a name="p6956510177"></a><a name="p6956510177"></a>Swaps 8-bit memory data.</p>
</td>
</tr>
<tr id="row14951451111710"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p8952514173"><a name="p8952514173"></a><a name="p8952514173"></a>LOS_AtomicXchg16bits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p12334173143919"><a name="p12334173143919"></a><a name="p12334173143919"></a>Swaps 16-bit memory data.</p>
</td>
</tr>
<tr id="row595251131716"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1495145117171"><a name="p1495145117171"></a><a name="p1495145117171"></a>LOS_AtomicXchg32bits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p9951513173"><a name="p9951513173"></a><a name="p9951513173"></a>Swaps 32-bit memory data.</p>
</td>
</tr>
<tr id="row195165131718"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p18951151141717"><a name="p18951151141717"></a><a name="p18951151141717"></a>LOS_AtomicXchg64bits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p169685115172"><a name="p169685115172"></a><a name="p169685115172"></a>Swaps 64-bit memory data.</p>
</td>
</tr>
<tr id="row149616511175"><td class="cellrowborder" rowspan="4" valign="top" width="21.21212121212121%" headers="mcps1.2.4.1.1 "><p id="p49615120172"><a name="p49615120172"></a><a name="p49615120172"></a>Compare and swap</p>
</td>
<td class="cellrowborder" valign="top" width="33.39333933393339%" headers="mcps1.2.4.1.2 "><p id="p129605112171"><a name="p129605112171"></a><a name="p129605112171"></a>LOS_AtomicCmpXchgByte</p>
</td>
<td class="cellrowborder" valign="top" width="45.3945394539454%" headers="mcps1.2.4.1.3 "><p id="p6965510178"><a name="p6965510178"></a><a name="p6965510178"></a>Compares and swaps 8-bit memory data.</p>
</td>
</tr>
<tr id="row99605171713"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p109675131711"><a name="p109675131711"></a><a name="p109675131711"></a>LOS_AtomicCmpXchg16bits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p17961951191719"><a name="p17961951191719"></a><a name="p17961951191719"></a>Compares and swaps 16-bit memory data.</p>
</td>
</tr>
<tr id="row169614513177"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p49645115172"><a name="p49645115172"></a><a name="p49645115172"></a>LOS_AtomicCmpXchg32bits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p129611512175"><a name="p129611512175"></a><a name="p129611512175"></a>Compares and swaps 32-bit memory data.</p>
</td>
</tr>
<tr id="row696175110179"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p16961051161715"><a name="p16961051161715"></a><a name="p16961051161715"></a>LOS_AtomicCmpXchg64bits</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1296205118179"><a name="p1296205118179"></a><a name="p1296205118179"></a>Compares and swaps 64-bit memory data.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop ### How to Develop
When multiple tasks perform addition, subtraction, and swap operations on the same memory data, use atomic operations to ensure predictability of results. When multiple tasks perform addition, subtraction, and swap operations on the same memory data, use atomic operations to ensure predictability of results.
>![](../public_sys-resources/icon-note.gif) **NOTE**<br/> > **NOTE**<br>
>Atomic operation APIs support only integer data. > Atomic operation APIs support only integers.
### Development Example<a name="section8538651511"></a> ### Development Example
Example Description **Example Description**
Call the atomic operation APIs and observe the result. Call the atomic operation APIs and observe the result.
1. Create two tasks. 1. Create two tasks.
- Task 1: Call **LOS\_AtomicInc** to add the global variables 100 times. - Task 1: Call **LOS_AtomicInc** to add a global variable 100 times.
- Task 2: Call **LOS\_AtomicDec** to subtract the global variables 100 times. - Task 2: Call **LOS_AtomicDec** to subtract a global variable 100 times.
2. After the subtasks are complete, print the values of the global variables in the main task. 2. After the subtasks are complete, print the values of the global variable in the main task.
**Sample Code** **Sample Code**
The sample code is as follows: The sample code is as follows:
``` ```
#include "los_hwi.h" #include "los_hwi.h"
#include "los_atomic.h" #include "los_atomic.h"
...@@ -275,7 +157,7 @@ UINT32 Example_AtomicTaskEntry(VOID) ...@@ -275,7 +157,7 @@ UINT32 Example_AtomicTaskEntry(VOID)
**Verification** **Verification**
``` ```
g_sum = 0 g_sum = 0
``` ```
# Interrupt and Exception Handling # Interrupt and Exception Handling
## Basic Concepts<a name="section439816296117"></a> ## Basic Concepts
An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor of a high-priority condition requiring interruption of the code being executed by the processor. In this way, the CPU does not need to spend a lot of time in waiting and querying the peripheral status, which effectively improves the real-time performance and execution efficiency of the system. An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor of a high-priority condition requiring interruption of the code being executed by the processor. In this way, the CPU does not need to spend a lot of time in waiting and querying the peripheral status, which effectively improves the real-time performance and execution efficiency of the system.
Exception handling involves a series of actions taken by the OS to respond to exceptions \(chip hardware faults\) that occurred during the OS running, for example, printing the call stack information of the current function, CPU information, and call stack information of tasks when the virtual memory page is missing. OpenHarmony supports the following interrupt operations:
## Working Principles<a name="section2792838318"></a> + Initializing an interrupt.
+ Creating an interrupt.
+ Enabling or disabling interrupts.
+ Restoring the system status before interrupts are disabled.
+ Deleting an interrupt.
Peripherals can complete certain work without the intervention of the CPU. In some cases, however, the CPU needs to perform certain work for peripherals. With the interrupt mechanism, the CPU responds to the interrupt request from a peripheral only when required, and execute other tasks when the peripherals do not require the CPU. The interrupt controller receives the input of other peripheral interrupt pins and sends interrupt signals to the CPU. You can enable or disable the interrupt source and set the priority and trigger mode of the interrupt source by programming the interrupt controller. Common interrupt controllers include vector interrupt controllers \(VICs\) and general interrupt controllers \(GICs\). The ARM Cortex-A7 uses GICs. After receiving an interrupt signal sent by the interrupt controller, the CPU interrupts the current task to respond to the interrupt request. Exception handling involves a series of actions taken by the OS to respond to exceptions (chip hardware faults) that occurred during the OS running, for example, printing the call stack information of the current function, CPU information, and call stack information of tasks when the virtual memory page is missing.
Exception handling interrupts the normal running process of the CPU to handle exceptions, such as, undefined instructions, an attempt to modify read-only data, and unaligned address access. When an exception occurs, the CPU suspends the current program, handles the exception, and then continues to execute the program interrupted by the exception.
## Working Principles
Peripherals can complete certain work without the intervention of the CPU. In some cases, however, the CPU needs to perform certain work for peripherals. With the interrupt mechanism, the CPU responds to the interrupt request from a peripheral only when required, and execute other tasks when the peripherals do not require the CPU.
The interrupt controller receives the input from the interrupt pins of other peripherals and sends interrupt signals to the CPU. You can enable or disable the interrupt source and set the priority and trigger mode of the interrupt source by programming the interrupt controller. Common interrupt controllers include vector interrupt controllers (VICs) and general interrupt controllers (GICs). The ARM Cortex-A7 uses GICs.
After receiving an interrupt signal sent by the interrupt controller, the CPU interrupts the current task to respond to the interrupt request.
An exception interrupts the normal running process of the CPU to handle exceptions, such as, undefined instructions, an attempt to modify read-only data, and unaligned address access. When an exception occurs, the CPU suspends the current program, handles the exception, and then continues to execute the program interrupted by the exception.
The following uses the ARMv7-a architecture as an example. The interrupt vector table is the entry for interrupt and exception handling. The interrupt vector table contains the entry function for each interrupt and exception handling. The following uses the ARMv7-a architecture as an example. The interrupt vector table is the entry for interrupt and exception handling. The interrupt vector table contains the entry function for each interrupt and exception handling.
**Figure 1** Interrupt vector table<a name="fig1552753243714"></a> **Figure 1** Interrupt vector table
![](figures/interrupt-vector-table.png "interrupt-vector-table") ![](figures/interrupt-vector-table.png "interrupt-vector-table")
## Development Guidelines<a name="section15415165510110"></a>
## Development Guidelines
### Available APIs<a name="section57441612024"></a>
Exception handling is an internal mechanism and does not provide external APIs. The following table describes APIs available for the interrupt module. ### Available APIs
<a name="table11657113333110"></a> Exception handling is an internal mechanism and does not provide external APIs. The following tables describe the APIs available for the interrupt module.
<table><thead align="left"><tr id="row1170612337312"><th class="cellrowborder" valign="top" width="19.900000000000002%" id="mcps1.1.4.1.1"><p id="p4706133373112"><a name="p4706133373112"></a><a name="p4706133373112"></a><strong id="b7792162213202"><a name="b7792162213202"></a><a name="b7792162213202"></a>Function</strong></p>
</th> ##### Creating or Deleting an Interrupt
<th class="cellrowborder" valign="top" width="18.43%" id="mcps1.1.4.1.2"><p id="p1070653343117"><a name="p1070653343117"></a><a name="p1070653343117"></a><strong id="b19958356201"><a name="b19958356201"></a><a name="b19958356201"></a>API</strong></p>
</th> | API | Description |
<th class="cellrowborder" valign="top" width="61.67%" id="mcps1.1.4.1.3"><p id="p370613330311"><a name="p370613330311"></a><a name="p370613330311"></a><strong id="b1551072610204"><a name="b1551072610204"></a><a name="b1551072610204"></a>Description</strong></p> |------------ | ----------------------------------------------------------- |
</th> | LOS_HwiCreate | Creates an interrupt and registers the interrupt ID, triggering mode, priority, and interrupt handler. When the interrupt is triggered, the interrupt handler will be called.|
</tr> | LOS_HwiDelete | Deletes an interrupt based on the interrupt number. |
</thead>
<tbody><tr id="row8706123317311"><td class="cellrowborder" rowspan="2" valign="top" width="19.900000000000002%" headers="mcps1.1.4.1.1 "><p id="p4706193319318"><a name="p4706193319318"></a><a name="p4706193319318"></a>Creating or deleting interrupts</p> ##### Enabling or Disabling Interrupts
</td>
<td class="cellrowborder" valign="top" width="18.43%" headers="mcps1.1.4.1.2 "><p id="p170683310317"><a name="p170683310317"></a><a name="p170683310317"></a>LOS_HwiCreate</p> | API | Description |
</td> | -------------- | ------------------------------------------- |
<td class="cellrowborder" valign="top" width="61.67%" headers="mcps1.1.4.1.3 "><p id="p15706833163110"><a name="p15706833163110"></a><a name="p15706833163110"></a>Creates an interrupt and registers the interrupt ID, interrupt triggering mode, interrupt priority, and interrupt handler. When an interrupt is triggered, the interrupt handler will be called.</p> | LOS_IntUnlock | Enables all interrupts for the current processor. |
</td> | LOS_IntLock | Disables all interrupts for the current processor. |
</tr> | LOS_IntRestore | Restores the status in which the system was before **LOS_IntLock** is called.|
<tr id="row18706153318316"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1870615332312"><a name="p1870615332312"></a><a name="p1870615332312"></a>LOS_HwiDelete</p>
</td> ##### Obtaining Interrupt Information
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p770616333313"><a name="p770616333313"></a><a name="p770616333313"></a>Deletes an interrupt.</p>
</td> | API | Description |
</tr> | ----------------------- | ------------------------ |
<tr id="row1370633316316"><td class="cellrowborder" rowspan="3" valign="top" width="19.900000000000002%" headers="mcps1.1.4.1.1 "><p id="p970611333318"><a name="p970611333318"></a><a name="p970611333318"></a>Enabling and disabling all interrupts</p> | LOS_GetSystemHwiMaximum | Obtains the maximum number of interrupts supported by the system.|
</td>
<td class="cellrowborder" valign="top" width="18.43%" headers="mcps1.1.4.1.2 "><p id="p147061033103117"><a name="p147061033103117"></a><a name="p147061033103117"></a>LOS_IntUnLock</p>
</td>
<td class="cellrowborder" valign="top" width="61.67%" headers="mcps1.1.4.1.3 "><p id="p93681327171713"><a name="p93681327171713"></a><a name="p93681327171713"></a>Enables all interrupts of the current processor.</p> ### How to Develop
</td>
</tr> 1. Call **LOS_HwiCreate** to create an interrupt.
<tr id="row1270603314312"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1970623343114"><a name="p1970623343114"></a><a name="p1970623343114"></a>LOS_IntLock</p>
</td> 2. Call **LOS_HwiDelete** to delete the specified interrupt. Use this API based on actual requirements.
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1161283971712"><a name="p1161283971712"></a><a name="p1161283971712"></a>Disables all interrupts for the current processor.</p>
</td>
</tr> ### Development Example
<tr id="row8706233173113"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1770620337313"><a name="p1770620337313"></a><a name="p1770620337313"></a>LOS_IntRestore</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1470643323112"><a name="p1470643323112"></a><a name="p1470643323112"></a>Restores to the status before all interrupts are disabled by using <strong id="b354311504226"><a name="b354311504226"></a><a name="b354311504226"></a>LOS_IntLock</strong>.</p>
</td>
</tr>
<tr id="row870793320317"><td class="cellrowborder" valign="top" width="19.900000000000002%" headers="mcps1.1.4.1.1 "><p id="p1970763318316"><a name="p1970763318316"></a><a name="p1970763318316"></a>Obtaining the maximum number of interrupts supported</p>
</td>
<td class="cellrowborder" valign="top" width="18.43%" headers="mcps1.1.4.1.2 "><p id="p1707333123115"><a name="p1707333123115"></a><a name="p1707333123115"></a>LOS_GetSystemHwiMaximum</p>
</td>
<td class="cellrowborder" valign="top" width="61.67%" headers="mcps1.1.4.1.3 "><p id="p4707173323111"><a name="p4707173323111"></a><a name="p4707173323111"></a>Obtains the maximum number of interrupts supported by the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section64332181221"></a>
1. Call **LOS\_HwiCreate** to create an interrupt.
2. Call **LOS\_HwiDelete** to delete the specified interrupt. Use this API based on actual requirements.
### Development Example<a name="section204698276478"></a>
This example implements the following: This example implements the following:
1. Create an interrupt. 1. Create an interrupt.
2. Delete an interrupt. 2. Delete an interrupt.
The following sample code shows how to create and delete an interrupt. When the interrupt **HWI\_NUM\_TEST** is generated, the interrupt handler function will be called. The following sample code demostrates how to create and delete an interrupt, and call the interrupt handler when the specified interrupt **HWI_NUM_TEST** is triggered. You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites/kernel/src/osTest.c** for testing.
``` The sample code is as follows:
```c
#include "los_hwi.h" #include "los_hwi.h"
/* Interrupt handler function*/ /* Interrupt handler function*/
STATIC VOID HwiUsrIrq(VOID) STATIC VOID HwiUsrIrq(VOID)
{ {
printf("in the func HwiUsrIrq \n"); PRINTK("in the func HwiUsrIrq \n");
} }
static UINT32 Example_Interrupt(VOID) static UINT32 Example_Interrupt(VOID)
{ {
UINT32 ret; UINT32 ret;
HWI_HANDLE_T hwiNum = 7; HWI_HANDLE_T hwiNum = 7; // The interrupt number is 7.
HWI_PRIOR_T hwiPrio = 3; HWI_PRIOR_T hwiPrio = 3; // The interrupt priority is 3.
HWI_MODE_T mode = 0; HWI_MODE_T mode = 0;
HWI_ARG_T arg = 0; HWI_ARG_T arg = 0;
/* Create an interrupt.*/ /* Create an interrupt. */
ret = LOS_HwiCreate(hwiNum, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, (HwiIrqParam *)arg); ret = LOS_HwiCreate(hwiNum, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, (HwiIrqParam *)arg);
if(ret == LOS_OK){ if (ret == LOS_OK) {
printf("Hwi create success!\n"); PRINTK("Hwi create success!\n");
} else { } else {
printf("Hwi create failed!\n"); PRINTK("Hwi create failed!\n");
return LOS_NOK; return LOS_NOK;
} }
/* Delay 50 ticks. When a hardware interrupt occurs, call the HwiUsrIrq function.*/ /* Delay 50 ticks. Call HwiUsrIrq when a hardware interrupt occurs. */
LOS_TaskDelay(50); LOS_TaskDelay(50);
/* Delete an interrupt./ /* Delete the interrupt. */
ret = LOS_HwiDelete(hwiNum, (HwiIrqParam *)arg); ret = LOS_HwiDelete(hwiNum, (HwiIrqParam *)arg);
if(ret == LOS_OK){ if (ret == LOS_OK) {
printf("Hwi delete success!\n"); PRINTK("Hwi delete success!\n");
} else { } else {
printf("Hwi delete failed!\n"); PRINTK("Hwi delete failed!\n");
return LOS_NOK; return LOS_NOK;
} }
return LOS_OK; return LOS_OK;
} }
``` ```
### Verification<a name="section1466144215476"></a>
### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
...@@ -134,4 +133,3 @@ The development is successful if the return result is as follows: ...@@ -134,4 +133,3 @@ The development is successful if the return result is as follows:
Hwi create success! Hwi create success!
Hwi delete success! Hwi delete success!
``` ```
# Process # Process
## Basic Concepts<a name="section89346055119"></a> ## Basic Concepts
A process is the minimum unit for system resource management. The process module provided by the OpenHarmony LiteOS-A kernel is used to isolate user-mode processes. The kernel mode is considered as a process space and does not have other processes except KIdle, which is an idle process provided by the system and shares the same process space with KProcess. A process is the minimum unit for system resource management. The process module provided by the OpenHarmony LiteOS-A kernel isolates user-mode processes. The kernel mode is considered as a process space and does not have other processes except KIdle, which is an idle process provided by the system and shares the same process space with KProcess. KProcess is the root process of kernel-mode processes, and KIdle is its child process.
- The process module provides multiple processes for users and implements switching and communication between processes, facilitating your management over service programs. - The process module provides multiple processes for users and implements switching and communication between processes, facilitating your management over service programs.
- The processes use the preemption scheduling mechanism. The processes with a higher priority are scheduled first, and the processes with the same priority are scheduled using the time slice polling.
- The processes are assigned 32 priorities \(**0** to **31**\). Among them, user processes can be configured with 22 priorities from **10** \(highest\) to **31** \(lowest\). - The processes use the preemption scheduling mechanism. The processes with a higher priority are scheduled first, and the processes with the same priority are scheduled using the time slice round robin.
- The processes are assigned 32 priorities (**0** to **31**). Among them, user processes can be configured with 22 priorities from **10** (highest) to **31** (lowest).
- A higher-priority process can preempt the resources of a lower-priority process. The lower-priority process can be scheduled only after the higher-priority process is blocked or terminated. - A higher-priority process can preempt the resources of a lower-priority process. The lower-priority process can be scheduled only after the higher-priority process is blocked or terminated.
- Each user-mode process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other. - Each user-mode process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other.
- The user-mode root process **init** is created by the kernel. Other user-mode processes are created by the **init** process via the **fork** call. - The user-mode root process **init** is created by the kernel. Other user-mode processes are created by the **init** process via the **fork** call.
**Process States:** **Process States**
- Init: The process is being created. - Init: The process is being created.
- Ready: The process is in the Ready queue and waits for scheduling by the CPU. - Ready: The process is in the Ready queue and waits for scheduling by the CPU.
- Running: The process is running. - Running: The process is running.
- Pending: The process is blocked and suspended. When all threads in a process are blocked, the process is blocked and suspended. - Pending: The process is blocked and suspended. When all threads in a process are blocked, the process is blocked and suspended.
- Zombies: The process stops running and waits for the parent process to reclaim its control block resources. - Zombies: The process stops running and waits for the parent process to reclaim its control block resources.
**Figure 1** Process state transition<a name="fig536823565718"></a> **Figure 1** Process state transition
![](figures/process-state-transition.png "process-state-transition")
**Process State Transition:** ![](figures/process-state-transition.png "process-state-transition")
- Init→Ready: **Process State Transition**
When a process is created, the process enters the Init state after obtaining the process control block to start initialization. After the process is initialized, the process is inserted into the scheduling queue and therefore enters the Ready state. - Init→Ready:
When a process is created or forked, the process enters the Init state after obtaining the process control block. When the process initialization is complete, the process is added to the scheduling queue, and the process enters the Ready state.
- Ready→Running: - Ready→Running:
When process switching occurs, the process that has the highest priority and time slice in the Ready queue is executed and enters the Running state. If this process has no thread in the Ready state, the process is deleted from the Ready queue and resides only in the Running state. If it has threads in the Ready state, the process still stays in the Ready queue. In this case, the process is in both the Ready and Running states, but presented as the Running state.
When a process switchover is triggered, the process with the highest priority in the Ready queue is executed and enters the Running state. If this process has no thread in the Ready state, the process is deleted from the Ready queue and resides only in the Running state. If it has threads in the Ready state, the process still stays in the Ready queue. In this case, the process is in both the Ready and Running states, but presented as the Running state.
- Running→Pending: - Running→Pending:
When the last thread of a process enters the Pending state, all threads in the process are in the Pending state. Then, the process enters the Pending state, and process switching occurs. When the last thread of a process enters the Pending state, all threads in the process are in the Pending state. Then, the process enters the Pending state, and process switching occurs.
- Pending→Ready: - Pending→Ready:
When any thread in a Pending process restores to the Ready state, the process is added to the Ready queue and changes to the Ready state. When any thread in a Pending process restores to the Ready state, the process is added to the Ready queue and changes to the Ready state.
- Ready→Pending: - Ready→Pending:
When the last ready thread in a process enters the Pending state, the process is deleted from the Ready queue, and the process changes from the Ready state to the Pending state. When the last ready thread in a process enters the Pending state, the process is deleted from the Ready queue, and the process changes from the Ready state to the Pending state.
- Running→Ready: - Running→Ready:
A process may change from the Running state to the Ready state in either of the following scenarios: A process may change from the Running state to the Ready state in either of the following scenarios:
1. After a process with a higher priority is created or restored, processes will be scheduled. The process with the highest priority in the Ready queue will change to the Running state, and the originally running process will change from the Running state to the Ready state. 1. After a process with a higher priority is created or restored, processes will be scheduled. The process with the highest priority in the Ready queue will change to the Running state, and the originally running process will change from the Running state to the Ready state.
2. If scheduling policy for a process is **LOS\_SCHED\_RR** and its priority is the same as that of another process in the Ready state, this process will change from the Running state to the Ready state after its time slices are used up, and the other process with the same priority will change from the Ready state to the Running state. 2. If scheduling policy for a process is **LOS_SCHED_RR** (time slice round robin) and its priority is the same as that of another process in the Ready state, this process will change from the Running state to the Ready state after its time slices are used up, and the other process with the same priority will change from the Ready state to the Running state.
- Running→Zombies: - Running→Zombies:
After the main thread or all threads of a process are stopped, the process changes from the **Running** state to the **Zombies** state and waits for the parent process to reclaim resources. After the main thread or all threads of a process are stopped, the process changes from the **Running** state to the **Zombies** state and waits for the parent process to reclaim resources.
## Working Principles<a name="section174514474512"></a> ## Working Principles
The OpenHarmony process module is used to isolate user-mode processes and supports the following functions: creating and exiting user-mode processes, reclaiming process resources, setting and obtaining scheduling parameters and process group IDs, and obtaining process IDs. The OpenHarmony process module is used to isolate user-mode processes and supports the following functions: creating and exiting user-mode processes, reclaiming process resources, setting and obtaining scheduling parameters and process group IDs, and obtaining process IDs.
...@@ -66,105 +68,65 @@ A user-mode process is created by forking a parent process. During forking, the ...@@ -66,105 +68,65 @@ A user-mode process is created by forking a parent process. During forking, the
A process is only a resource management unit, and the actual running is executed by threads in the process. When switching occurs between threads in different processes, the process space will be switched. A process is only a resource management unit, and the actual running is executed by threads in the process. When switching occurs between threads in different processes, the process space will be switched.
**Figure 2** Process management<a name="fig123709256334"></a> **Figure 2** Process management
![](figures/process-management.png "process-management") ![](figures/process-management.png "process-management")
## Development Guidelines<a name="section159637182521"></a>
## Development Guidelines
### Available APIs<a name="section1153124135212"></a>
**Table 1** Process management module APIs ### Available APIs
<a name="table359914125718"></a> **Table 1** APIs for processes and process groups
<table><thead align="left"><tr id="row85991712770"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p13162121815218"><a name="p13162121815218"></a><a name="p13162121815218"></a><strong id="b1498913473"><a name="b1498913473"></a><a name="b1498913473"></a>Function</strong></p>
</th> | API | Description |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p12162618623"><a name="p12162618623"></a><a name="p12162618623"></a><strong id="b3249144342911"><a name="b3249144342911"></a><a name="b3249144342911"></a>API</strong></p> | ------------------------- | ---------------------- |
</th> | LOS_GetCurrProcessID | Obtains the ID of the current process. |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p16162118427"><a name="p16162118427"></a><a name="p16162118427"></a><strong id="b1858304911219"><a name="b1858304911219"></a><a name="b1858304911219"></a>Description</strong></p> | LOS_GetProcessGroupID | Obtains the process group ID of the specified process.|
</th> | LOS_GetCurrProcessGroupID | Obtains the process group ID of the current process.|
</tr>
</thead> **Table 2** APIs for users and user groups
<tbody><tr id="row66002121074"><td class="cellrowborder" rowspan="4" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p13571544484"><a name="p13571544484"></a><a name="p13571544484"></a>Process scheduling parameter control</p>
</td> | API | Description |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p7571644283"><a name="p7571644283"></a><a name="p7571644283"></a>LOS_GetProcessScheduler</p> | ----------------- | ---------------------------------------- |
</td> | LOS_GetUserID | Obtains the user ID of the current process. |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p205724410813"><a name="p205724410813"></a><a name="p205724410813"></a>Obtains the scheduling policy of the specified process.</p> | LOS_GetGroupID | Obtains the user group ID of the current process. |
</td> | LOS_CheckInGroups | Checks whether the specified user group ID is in the user group of the current process.|
</tr>
<tr id="row166001712574"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6571144286"><a name="p6571144286"></a><a name="p6571144286"></a>LOS_SetProcessScheduler</p> **Table 3** APIs for process scheduling
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p18572443819"><a name="p18572443819"></a><a name="p18572443819"></a>Sets the scheduling parameters, including the priority and scheduling policy, for the specified process.</p> | API | API |
</td> | ----------------------- | -------------------------------------------- |
</tr> | LOS_GetProcessScheduler | Obtains the scheduling policy of a process. |
<tr id="row1560071212719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3571144885"><a name="p3571144885"></a><a name="p3571144885"></a>LOS_GetProcessPriority</p> | LOS_SetProcessScheduler | Sets scheduling parameters, including the priority and scheduling policy, for a process.|
</td> | LOS_SetProcessPriority | Sets the process priority. |
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p95710448818"><a name="p95710448818"></a><a name="p95710448818"></a>Obtains the priority of the specified process.</p> | LOS_GetProcessPriority | Obtains the priority of a process. |
</td>
</tr> **Table 4** APIs for obtaining system process information
<tr id="row1274011131587"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17572443812"><a name="p17572443812"></a><a name="p17572443812"></a>LOS_SetProcessPriority</p>
</td> | API | Description |
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p16573445819"><a name="p16573445819"></a><a name="p16573445819"></a>Sets the priority of the specified process.</p> | --------------------------- | -------------------------- |
</td> | LOS_GetSystemProcessMaximum | Obtains the maximum number of processes supported by the system.|
</tr> | LOS_GetUsedPIDList | Obtains a list of used process IDs. |
<tr id="row162882182816"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p175734417814"><a name="p175734417814"></a><a name="p175734417814"></a>Waiting for reclaiming child processes</p>
</td> **Table 5** APIs for managing processes
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p165754410812"><a name="p165754410812"></a><a name="p165754410812"></a>LOS_Wait</p>
</td> | API | Description |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p5578441687"><a name="p5578441687"></a><a name="p5578441687"></a>Waits for the specified child process to terminate, and reclaims its resources.</p> | ---------- | -------------------------- |
</td> | LOS_Fork | Creates a child process. |
</tr> | LOS_Wait | Waits for the child process to terminate, and reclaims its resources.|
<tr id="row81051920589"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p4571844289"><a name="p4571844289"></a><a name="p4571844289"></a>Process group</p> | LOS_Waitid | Wait for the specified process to terminate. |
</td> | LOS_Exit | Exits a process. |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p20578442083"><a name="p20578442083"></a><a name="p20578442083"></a>LOS_GetProcessGroupID</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p145704416818"><a name="p145704416818"></a><a name="p145704416818"></a>Obtains the process group ID of the specified process.</p>
</td> ### How to Develop
</tr>
<tr id="row13410161611819"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p657944289"><a name="p657944289"></a><a name="p657944289"></a>LOS_GetCurrProcessGroupID</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p165816445819"><a name="p165816445819"></a><a name="p165816445819"></a>Obtains the process group ID of the current process.</p>
</td>
</tr>
<tr id="row1260011213718"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p125818441781"><a name="p125818441781"></a><a name="p125818441781"></a>Obtaining the process ID.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p25814445819"><a name="p25814445819"></a><a name="p25814445819"></a>LOS_GetCurrProcessID</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1058644687"><a name="p1058644687"></a><a name="p1058644687"></a>Obtains the ID of the current process.</p>
</td>
</tr>
<tr id="row060019121871"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p145810441285"><a name="p145810441285"></a><a name="p145810441285"></a>User and user group</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p10581744783"><a name="p10581744783"></a><a name="p10581744783"></a>LOS_GetUserID</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p7581944287"><a name="p7581944287"></a><a name="p7581944287"></a>Obtains the user ID of the current process.</p>
</td>
</tr>
<tr id="row1160021211713"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p18582447814"><a name="p18582447814"></a><a name="p18582447814"></a>LOS_GetGroupID</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p3581444382"><a name="p3581444382"></a><a name="p3581444382"></a>Obtains the user group ID of the current process.</p>
</td>
</tr>
<tr id="row1160018123717"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p19589442084"><a name="p19589442084"></a><a name="p19589442084"></a>LOS_CheckInGroups</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p5581144689"><a name="p5581144689"></a><a name="p5581144689"></a>Checks whether the specified user group ID is in the user group of the current process.</p>
</td>
</tr>
<tr id="row317461111812"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p105814419818"><a name="p105814419818"></a><a name="p105814419818"></a>Maximum number of processes supported</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p3583441888"><a name="p3583441888"></a><a name="p3583441888"></a>LOS_GetSystemProcessMaximum</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p115818441187"><a name="p115818441187"></a><a name="p115818441187"></a>Obtains the maximum number of processes supported by the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section1533674618526"></a>
Kernel-mode processes cannot be created. Therefore, kernel-mode process development is not involved. Kernel-mode processes cannot be created. Therefore, kernel-mode process development is not involved.
>![](../public_sys-resources/icon-note.gif) **NOTE:** > **NOTE**
>- The number of idle threads depends on the number of CPU cores. Each CPU has a corresponding idle thread. >
> - The number of idle threads depends on the number of CPU cores. Each CPU has a corresponding idle thread.
>- Except KProcess and KIdle, other kernel-mode processes cannot be created. >- Except KProcess and KIdle, other kernel-mode processes cannot be created.
>- If a thread is created after a user-mode process enters the kernel mode by a system call, the thread belongs to a KProcess not a user-mode process. > - If a thread is created after a user-mode process enters the kernel mode by a system call, the thread belongs to a KProcess not a user-mode process.
# Scheduler # Scheduler
## Basic Concepts<a name="section123882355719"></a> ## Basic Concepts
The OpenHarmony LiteOS-A kernel uses the preemptive scheduling mechanism for tasks. The tasks with a higher priority are scheduled first, and the tasks with the same priority are scheduled using the time slice polling. The system runs based on the real-time timeline from the startup, which ensures good real-time performance of the scheduling algorithm. The OpenHarmony LiteOS-A kernel uses the preemptive scheduling mechanism for tasks. The tasks with a higher priority are scheduled first, and the tasks with the same priority are scheduled using the time slice polling. The system runs based on the real-time timeline from the startup, which ensures good real-time performance of the scheduling algorithm.
The OpenHarmony scheduling algorithm is embedded with the tickless mechanism, which ensures lower power consumption and on-demand response to tick interrupts. This minimizes useless tick interrupt response time and further improves the real-time performance of the system. The OpenHarmony scheduling algorithm is embedded with the tickless mechanism, which ensures lower power consumption and on-demand response to tick interrupts. This minimizes useless tick interrupt response time and further improves the real-time performance of the system.
The OpenHarmony process scheduling policy is **SCHED\_RR**, and the thread scheduling policy can be **SCHED\_RR** or **SCHED\_FIFO**. OpenHarmony supports **SCHED_RR** (time slice round robin) for process scheduling and **SCHED_RR** and **SCHED_FIFO** (first in, first out) for thread scheduling .
Threads are the minimum scheduling units in the OpenHarmony. Threads are the minimum scheduling units in OpenHarmony.
## Working Principles<a name="section143015396572"></a>
The OpenHarmony uses process priority queue and thread priority queue for scheduling. The process priority ranges from 0 to 31, and there are 32 process priority bucket queues. Each bucket queue corresponds to a thread priority bucket queue. The thread priority ranges from 0 to 31, and a thread priority bucket queue also has 32 priority queues. ## Working Principles
OpenHarmony uses process priority queue and thread priority queue for scheduling. The process priority ranges from 0 to 31, and there are 32 process priority bucket queues. Each bucket queue corresponds to a thread priority bucket queue. The thread priority ranges from 0 to 31, and a thread priority bucket queue also has 32 priority queues.
**Figure 1** Scheduling priority bucket queue
**Figure 1** Scheduling priority bucket queue<a name="fig124425991619"></a>
![](figures/scheduling-priority-bucket-queue.png "scheduling-priority-bucket-queue") ![](figures/scheduling-priority-bucket-queue.png "scheduling-priority-bucket-queue")
The OpenHarmony system starts scheduling after the kernel initialization is complete. The processes or threads created during running are added to the scheduling queues. The system selects the optimal thread for scheduling based on the priorities of the processes and threads and the time slice consumption of the threads. Once a thread is scheduled, it is deleted from the scheduling queue. If a thread is blocked during running, the thread is added to the corresponding blocking queue and triggers scheduling of another thread. If no thread in the scheduling queue can be scheduled, the system selects the thread of the KIdle process for scheduling. The OpenHarmony system starts scheduling after the kernel initialization is complete. The processes or threads created during running are added to the scheduling queues. The system selects the optimal thread for scheduling based on the priorities of the processes and threads and the time slice consumption of the threads. Once a thread is scheduled, it is deleted from the scheduling queue. If a thread is blocked during running, the thread is added to the corresponding blocking queue and triggers scheduling of another thread. If no thread in the scheduling queue can be scheduled, the system selects the thread of the KIdle process for scheduling.
**Figure 2** Scheduling process<a name="fig1163494931810"></a> **Figure 2** Scheduling process
![](figures/scheduling-process.png "scheduling-process") ![](figures/scheduling-process.png "scheduling-process")
## Development Guidelines<a name="section10604192145816"></a>
### Available APIs<a name="section207985910582"></a>
<a name="table687929113814"></a>
<table><thead align="left"><tr id="row513082983812"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p121309298384"><a name="p121309298384"></a><a name="p121309298384"></a><strong id="b1684811125913"><a name="b1684811125913"></a><a name="b1684811125913"></a>Function</strong></p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p713082933817"><a name="p713082933817"></a><a name="p713082933817"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p20130829123810"><a name="p20130829123810"></a><a name="p20130829123810"></a><strong id="b66639257454"><a name="b66639257454"></a><a name="b66639257454"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row713032973813"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p0130429133818"><a name="p0130429133818"></a><a name="p0130429133818"></a>System scheduling</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p71581556124414"><a name="p71581556124414"></a><a name="p71581556124414"></a>LOS_Schedule</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p181303297387"><a name="p181303297387"></a><a name="p181303297387"></a>Triggers system scheduling.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section1015110331584"></a>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Scheduling cannot be triggered during the system initialization process.
## Development Guidelines
### Available APIs
| API| Description|
| -------- | -------- |
| LOS_Schedule | Triggers system scheduling.|
| LOS_GetTaskScheduler | Obtains the scheduling policy of a task.|
| LOS_SetTaskScheduler | Sets the scheduling policy for a task.|
| LOS_GetProcessScheduler | Obtains the scheduling policy of a process.|
| LOS_SetProcessScheduler | Sets scheduling parameters, including the priority and scheduling policy, for a process.|
### How to Develop
> **NOTE**
>
> Scheduling cannot be triggered during the system initialization process.
# Task # Task
## Basic Concepts<a name="section138411646175417"></a>
## Basic Concepts
Tasks are the minimum running units that compete for system resources. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another. Tasks are the minimum running units that compete for system resources. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another.
In the OpenHarmony kernel, a task represents a thread. In the OpenHarmony kernel, a task represents a thread.
Tasks in the processes of the same priority in the OpenHarmony kernel are scheduled and run in a unified manner. Tasks for the processes of the same priority in the OpenHarmony kernel are scheduled and run in a unified manner.
The tasks in the kernel use the preemptive scheduling mechanism, either round-robin \(RR\) scheduling or First In First Out \(FIFO\) scheduling. The tasks in the kernel use the preemptive scheduling mechanism, either round-robin (RR) scheduling or First In First Out (FIFO) scheduling.
Tasks are assigned 32 priorities, ranging from **0** \(highest\) to **31** \(lowest\). Tasks are assigned 32 priorities, ranging from **0** (highest) to **31** (lowest).
In the same process, a higher-priority task can preempt resources of a lower-priority task. The lower-priority task can be scheduled only after the higher-priority task is blocked or terminated. In the same process, a higher-priority task can preempt resources of a lower-priority task. The lower-priority task can be scheduled only after the higher-priority task is blocked or terminated.
**Task Status Description** **Task States**
- Init: The task is being created. - Init: The task is being created.
- Ready: The task is in the Ready queue and waits for scheduling by the CPU. - Ready: The task is in the Ready queue and waits for scheduling by the CPU.
- Running: The task is running. - Running: The task is running.
- Blocked: The task is blocked and suspended. The Blocked states include pending \(blocked due to lock, event, or semaphore issues\), suspended \(active pending\), delay \(blocked due to delays\), and pendtime \(blocked by waiting timeout of locks, events, or semaphores\).
- Blocked: The task is blocked and suspended. The Blocked states include pending (blocked due to lock, event, or semaphore issues), suspended (active pending), delay (blocked due to delays), and pendtime (blocked by waiting timeout of locks, events, or semaphores).
- Exit: The task is complete and waits for the parent task to reclaim its control block resources. - Exit: The task is complete and waits for the parent task to reclaim its control block resources.
**Figure 1** Task state transition<a name="fig5251243193113"></a> **Figure 1** Task state transition
![](figures/task-state-transition.png "task-state-transition")
![](figures/task-state-transition.png "task-state-transition")
**Task State Transition** **Task State Transition**
- Init→Ready: - Init→Ready:
When a task is created, the task obtains the control block and enters the Init state (initialization). After the initialization is complete, the task is inserted into the scheduling queue and enters the Ready state.
When a task is created, the task obtains the control block and enters the Init state \(initialization\). After the initialization is complete, the task is inserted into the scheduling queue and enters the Ready state.
- Ready→Running: - Ready→Running:
When a task switching is triggered, the task with the highest priority in the Ready queue is executed and enters the Running state. Then, this task is deleted from the Ready queue. When a task switching is triggered, the task with the highest priority in the Ready queue is executed and enters the Running state. Then, this task is deleted from the Ready queue.
- Running→Blocked: - Running→Blocked:
When a running task is blocked (for example, is pended, delayed, or reading semaphores), its state changes from Running to Blocked. Then, a task switching is triggered to run the task with the highest priority in the Ready queue.
When a running task is blocked \(for example, is pended, delayed, or reading semaphores\), its state changes from Running to Blocked. Then, a task switching is triggered to run the task with the highest priority in the Ready queue.
- Blocked→Ready: - Blocked→Ready:
After the blocked task is restored (the task is restored, the delay times out, the semaphore reading times out, or the semaphore is read), the task is added to the Ready queue and will change from the Blocked state to the Ready state.
After the blocked task is restored \(the task is restored, the delay times out, the semaphore reading times out, or the semaphore is read\), the task is added to the Ready queue and will change from the Blocked state to the Ready state.
- Ready→Blocked: - Ready→Blocked:
When a task in the Ready state is blocked (suspended), the task changes to the Blocked state and is deleted from the Ready queue. The blocked task will not be scheduled until it is recovered.
When a task in the Ready state is blocked \(suspended\), the task changes to the Blocked state and is deleted from the Ready queue. The blocked task will not be scheduled until it is recovered.
- Running→Ready: - Running→Ready:
When a task with a higher priority is created or recovered, tasks will be scheduled. The task with the highest priority in the Ready queue changes to the Running state. The originally running task changes to the Ready state and is added to the Ready queue. When a task with a higher priority is created or recovered, tasks will be scheduled. The task with the highest priority in the Ready queue changes to the Running state. The originally running task changes to the Ready state and is added to the Ready queue.
- Running→Exit: - Running→Exit:
When a running task is complete, it changes to the Exit state. If the task has a detach attribute (set by **LOS_TASK_STATUS_DETACHED** in **los_task.h**), it will be destroyed directly.
When a running task is complete, it changes to the Exit state. If the task is set with a detach attribute \(**LOS\_TASK\_STATUS\_DETACHED**\), it will be directly destroyed after being terminated.
## Working Principles<a name="section1381918945512"></a> ## Working Principles
The OpenHarmony task management module provides the following functions: creating, delaying, suspending, and restoring tasks, locking and unlocking task scheduling, and querying task control block information by ID. The OpenHarmony task management module provides the following functions: creating, delaying, suspending, and restoring tasks, locking and unlocking task scheduling, and querying task control block information by ID.
When a task is created, the system initializes the task stack and presets the context. The system also places the task entry function in the corresponding position so that the function can be executed when the task enters the running state for the first time. When a user creates a task, the system initializes the task stack and presets the context. The system places the task entry function in the corresponding position so that the function can be executed when the task enters the running state for the first time.
## Development Guidelines<a name="section10649727135519"></a>
## Development Guidelines
### Available APIs<a name="section78333315555"></a>
<a name="table687929113814"></a> ### Available APIs
<table><thead align="left"><tr id="row513082983812"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p121309298384"><a name="p121309298384"></a><a name="p121309298384"></a><strong id="b1288394945813"><a name="b1288394945813"></a><a name="b1288394945813"></a>Function</strong></p>
</th> **Table 1** APIs for creating and deleting a task
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p713082933817"><a name="p713082933817"></a><a name="p713082933817"></a><strong id="b184372716456"><a name="b184372716456"></a><a name="b184372716456"></a>API</strong></p>
</th> | API | Description |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p20130829123810"><a name="p20130829123810"></a><a name="p20130829123810"></a><strong id="b27211529174516"><a name="b27211529174516"></a><a name="b27211529174516"></a>Description</strong></p> | ------------------ | ------------------------------------------------------------ |
</th> | LOS_TaskCreate | Creates a task. If the priority of the created task is higher than that of the task in running and task scheduling is not locked, the task will be scheduled to run. |
</tr> | LOS_TaskCreateOnly | Creates a task and blocks it. The task will not be added to the Ready queue unless it is resumed. |
</thead> | LOS_TaskDelete | Deletes a task and reclaims the resources consumed by the task control block and task stack. |
<tbody><tr id="row431611256303"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p0297202573015"><a name="p0297202573015"></a><a name="p0297202573015"></a>Task creation and deletion</p>
</td> **Table 2** APIs for controlling task status
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1229720252303"><a name="p1229720252303"></a><a name="p1229720252303"></a>LOS_TaskCreateOnly</p>
</td> | API | Description |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p12297825123016"><a name="p12297825123016"></a><a name="p12297825123016"></a>Creates a task and places the task in the Init state without scheduling.</p> | --------------- | ------------------------------------------------------------ |
</td> | LOS_TaskResume | Resumes a suspended task. |
</tr> | LOS_TaskSuspend | Suspends a task. The suspended task will be removed from the Ready queue. |
<tr id="row19316182517304"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1829732511308"><a name="p1829732511308"></a><a name="p1829732511308"></a>LOS_TaskCreate</p> | LOS_TaskJoin | Blocks the current task until the specified task is complete, and reclaims its resources. |
</td> | LOS_TaskDetach | Changes the task attribute from **joinable** to **detach**. When a task of the **detach** attribute is complete, the task control block resources will be automatically reclaimed.|
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p19297122518303"><a name="p19297122518303"></a><a name="p19297122518303"></a>Creates a task and places it in the Init state for scheduling.</p> | LOS_TaskDelay | Delays the current task for the specified time (number of ticks). |
</td> | LOS_TaskYield | Moves the current task from the queue of the tasks with the same priority to the end of the Ready queue.|
</tr>
<tr id="row7316192593013"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p3297162583020"><a name="p3297162583020"></a><a name="p3297162583020"></a>LOS_TaskDelete</p> **Table 3** APIs for task scheduling
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p3297162517308"><a name="p3297162517308"></a><a name="p3297162517308"></a>Deletes the specified task.</p> | API | Description |
</td> | -------------------- | ------------------------------------------------------------ |
</tr> | LOS_TaskLock | Locks task scheduling to prevent task switching. |
<tr id="row13316112533020"><td class="cellrowborder" rowspan="6" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p172979255306"><a name="p172979255306"></a><a name="p172979255306"></a>Task status control</p> | LOS_TaskUnlock | Unlocks task scheduling. After that, the task lock count decrements by 1. If a task is locked multiple times, the task can be scheduled only when the number of locks is reduced to 0. |
</td> | LOS_GetTaskScheduler | Obtains the scheduling policy of a task. |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p14297425103016"><a name="p14297425103016"></a><a name="p14297425103016"></a>LOS_TaskResume</p> | LOS_SetTaskScheduler | Sets the scheduling parameters, including the priority and scheduling policy, for a task. |
</td> | LOS_Schedule | Triggers active task scheduling. |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1929732593018"><a name="p1929732593018"></a><a name="p1929732593018"></a>Resumes a suspended task.</p>
</td> **Table 4** APIs for obtaining task information
</tr>
<tr id="row1231632513012"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p5297132553014"><a name="p5297132553014"></a><a name="p5297132553014"></a>LOS_TaskSuspend</p> | API | Description |
</td> | ------------------------ | ------------------------ |
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p8297182563015"><a name="p8297182563015"></a><a name="p8297182563015"></a>Suspends the specified task.</p> | LOS_CurTaskIDGet | Obtains the ID of the current task. |
</td> | LOS_TaskInfoGet | Obtains task information. |
</tr> | LOS_GetSystemTaskMaximum | Obtains the maximum number of tasks supported by the system.|
<tr id="row1547201019421"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p5885913184219"><a name="p5885913184219"></a><a name="p5885913184219"></a>LOS_TaskJoin</p>
</td> **Table 5** APIs for managing task priorities
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p28851313104213"><a name="p28851313104213"></a><a name="p28851313104213"></a>Suspends this task till the specified task is complete and the task control block resources are reclaimed.</p>
</td> | API | Description |
</tr> | ----------------- | ------------------------------ |
<tr id="row69281012114217"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p68857132427"><a name="p68857132427"></a><a name="p68857132427"></a>LOS_TaskDetach</p> | LOS_CurTaskPriSet | Sets a priority for the current task.|
</td> | LOS_TaskPriSet | Sets a priority for a task. |
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p188851813184219"><a name="p188851813184219"></a><a name="p188851813184219"></a>Changes the task attribute from <strong id="b1986175411125"><a name="b1986175411125"></a><a name="b1986175411125"></a>joinable</strong> to <strong id="b18996959101215"><a name="b18996959101215"></a><a name="b18996959101215"></a>detach</strong>. After the task of the <strong id="b15851429171317"><a name="b15851429171317"></a><a name="b15851429171317"></a>detach</strong> attribute is complete, the task control block resources will be automatically reclaimed.</p> | LOS_TaskPriGet | Obtains the priority of a task. |
</td>
</tr> **Table 6** APIs for setting CPU pinning
<tr id="row1231672512301"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p92979251305"><a name="p92979251305"></a><a name="p92979251305"></a>LOS_TaskDelay</p>
</td> | API | Description |
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1297182517306"><a name="p1297182517306"></a><a name="p1297182517306"></a>Delays a task.</p> | ------------------ | ------------------------------------------- |
</td> | LOS_TaskCpuAffiSet | Binds a task to the specified CPU core. This API is used only in multi-core CPUs.|
</tr> | LOS_TaskCpuAffiGet | Obtains information about the core binding of a task. This API is used only in multi-core CPUs. |
<tr id="row73161725163018"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p10297152573014"><a name="p10297152573014"></a><a name="p10297152573014"></a>LOS_TaskYield</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p2297325163019"><a name="p2297325163019"></a><a name="p2297325163019"></a>Adjusts the scheduling sequence of tasks that call the task priority.</p>
</td> ### How to Develop
</tr>
<tr id="row1231520259306"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p9297142511307"><a name="p9297142511307"></a><a name="p9297142511307"></a>Task scheduling control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p429719257307"><a name="p429719257307"></a><a name="p429719257307"></a>LOS_TaskLock</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p11297142510306"><a name="p11297142510306"></a><a name="p11297142510306"></a>Locks task scheduling.</p>
</td>
</tr>
<tr id="row431442573010"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p17297625193015"><a name="p17297625193015"></a><a name="p17297625193015"></a>LOS_TaskUnlock</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p829715252308"><a name="p829715252308"></a><a name="p829715252308"></a>Unlocks task scheduling.</p>
</td>
</tr>
<tr id="row53141525123010"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p1729732593014"><a name="p1729732593014"></a><a name="p1729732593014"></a>Task priority control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p629715254308"><a name="p629715254308"></a><a name="p629715254308"></a>LOS_CurTaskPriSet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p142981925183020"><a name="p142981925183020"></a><a name="p142981925183020"></a>Sets the priority for the current task.</p>
</td>
</tr>
<tr id="row18314102563015"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p11298202513303"><a name="p11298202513303"></a><a name="p11298202513303"></a>LOS_TaskPriSet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p629822563014"><a name="p629822563014"></a><a name="p629822563014"></a>Sets the priority for a specified task.</p>
</td>
</tr>
<tr id="row731442543011"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1029892517302"><a name="p1029892517302"></a><a name="p1029892517302"></a>LOS_TaskPriGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p19298182563018"><a name="p19298182563018"></a><a name="p19298182563018"></a>Obtains the priority of a specified task.</p>
</td>
</tr>
<tr id="row18314172523011"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p17298225203011"><a name="p17298225203011"></a><a name="p17298225203011"></a>Obtaining task information</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p229811251307"><a name="p229811251307"></a><a name="p229811251307"></a>LOS_CurTaskIDGet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1029842519303"><a name="p1029842519303"></a><a name="p1029842519303"></a>Obtains the ID of the current task.</p>
</td>
</tr>
<tr id="row1331452516307"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p172984256301"><a name="p172984256301"></a><a name="p172984256301"></a>LOS_TaskInfoGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p122988259303"><a name="p122988259303"></a><a name="p122988259303"></a>Obtains information about the specified task.</p>
</td>
</tr>
<tr id="row93146250305"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p82986256300"><a name="p82986256300"></a><a name="p82986256300"></a>Binding tasks to CPU cores</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1929862583018"><a name="p1929862583018"></a><a name="p1929862583018"></a>LOS_TaskCpuAffiSet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p82981925163013"><a name="p82981925163013"></a><a name="p82981925163013"></a>Binds a specified task to the specified CPU. It is used only in multi-core scenarios.</p>
</td>
</tr>
<tr id="row5314192543014"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p02984251305"><a name="p02984251305"></a><a name="p02984251305"></a>LOS_TaskCpuAffiGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1729822513017"><a name="p1729822513017"></a><a name="p1729822513017"></a>Obtains the core binding information of the specified task. It is used only in multi-core scenarios.</p>
</td>
</tr>
<tr id="row43141525193013"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p16298152514308"><a name="p16298152514308"></a><a name="p16298152514308"></a>Task scheduling parameter control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1529872563011"><a name="p1529872563011"></a><a name="p1529872563011"></a>LOS_GetTaskScheduler</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1298182513010"><a name="p1298182513010"></a><a name="p1298182513010"></a>Obtains the scheduling policy of the specified task.</p>
</td>
</tr>
<tr id="row1331472519305"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p15298152514301"><a name="p15298152514301"></a><a name="p15298152514301"></a>LOS_SetTaskScheduler</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p11298172553015"><a name="p11298172553015"></a><a name="p11298172553015"></a>Sets the scheduling parameters, including the priority and scheduling policy, for the specified task.</p>
</td>
</tr>
<tr id="row831492514307"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p12981250307"><a name="p12981250307"></a><a name="p12981250307"></a>Maximum number of tasks supported</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p112981425183019"><a name="p112981425183019"></a><a name="p112981425183019"></a>LOS_GetSystemTaskMaximum</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p6298525123017"><a name="p6298525123017"></a><a name="p6298525123017"></a>Obtains the maximum number of tasks supported by the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section16229657115514"></a>
The typical task development process is as follows: The typical task development process is as follows:
1. Call **LOS\_TaskCreate** to create a task. 1. Call **LOS_TaskCreate** to create a task.
- Specify the execution entry function for the task. - Specify the execution entry function for the task.
- Specifies the task name. - Specifies the task name.
- Specify the task stack size. - Specify the task stack size.
- Specify the priority of the task. - Specify the priority of the task.
- Specify the task attribute, which can be **LOS\_TASK\_ATTR\_JOINABLE** or **LOS\_TASK\_STATUS\_DETACHED**. - Specify the task attribute, which can be **LOS_TASK_ATTR_JOINABLE** or **LOS_TASK_STATUS_DETACHED**.
- Specify the task-core binding attribute for multi-core environment. - Specify the task-core binding attribute for multi-core environment.
2. Run the service code to implement task scheduling. 2. Run the service code to implement task scheduling.
3. Reclaim resources when the task is complete. If the task attribute is **LOS\_TASK\_STATUS\_DETACHED**, the task resources are automatically reclaimed. If the task attribute is **LOS\_TASK\_ATTR\_JOINABLE**, call **LOS\_TaskJoin** to reclaim task resources. The default task attribute is **LOS\_TASK\_STATUS\_DETACHED**.
>![](../public_sys-resources/icon-note.gif) **NOTE:** 3. Reclaim resources when the task is complete. If the task attribute is **LOS_TASK_STATUS_DETACHED**, the task resources are automatically reclaimed. If the task attribute is **LOS_TASK_ATTR_JOINABLE**, call **LOS_TaskJoin** to reclaim task resources. The default task attribute is **LOS_TASK_STATUS_DETACHED**.
>- The kernel mode has the highest permission and can operate tasks in any process.
>- If a task is created after a user-mode process enters the kernel mode by a system call, the task belongs to a KProcess not a user-mode process.
### Development Example<a name="section2809723165612"></a> > **NOTE**
>
> - The kernel mode has the highest permission and can operate tasks in any process.
>
> - If a task is created after a user-mode process enters the kernel mode by a system call, the task belongs to a KProcess not a user-mode process.
The sample code is as follows:
``` ### Development Example
The sample code is as follows. You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites/kernel/src /osTest.c** for testing
```c
UINT32 g_taskLoID; UINT32 g_taskLoID;
UINT32 g_taskHiID; UINT32 g_taskHiID;
#define TSK_PRIOR_HI 4 #define TSK_PRIOR_HI 4
...@@ -231,15 +158,15 @@ UINT32 ExampleTaskHi(VOID) ...@@ -231,15 +158,15 @@ UINT32 ExampleTaskHi(VOID)
{ {
UINT32 ret; UINT32 ret;
PRINTK("Enter TaskHi Handler.\n"); PRINTK("Enter TaskHi Handler.\n");
/* Delay the task for 2 ticks. The task is then suspended, and the remaining task with the highest priority (g_taskLoID) will be executed.*/ /* Delay the task for 2 ticks. The task is suspended, and the remaining task with the highest priority (g_taskLoID) will be executed. */
ret = LOS_TaskDelay(2); ret = LOS_TaskDelay(2);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Delay Task Failed.\n"); PRINTK("Delay Task Failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* After 2 ticks elapse, the task is resumed and executed.*/ /* After 2 ticks elapse, the task is resumed and executed. */
PRINTK("TaskHi LOS_TaskDelay Done.\n"); PRINTK("TaskHi LOS_TaskDelay Done.\n");
/* Suspend the task.*/ /* Suspend the task. */
ret = LOS_TaskSuspend(g_taskHiID); ret = LOS_TaskSuspend(g_taskHiID);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Suspend TaskHi Failed.\n"); PRINTK("Suspend TaskHi Failed.\n");
...@@ -249,19 +176,19 @@ UINT32 ExampleTaskHi(VOID) ...@@ -249,19 +176,19 @@ UINT32 ExampleTaskHi(VOID)
return LOS_OK; return LOS_OK;
} }
/* Entry function of the lower-priority task */ /* Entry function of the low-priority task. */
UINT32 ExampleTaskLo(VOID) UINT32 ExampleTaskLo(VOID)
{ {
UINT32 ret; UINT32 ret;
PRINTK("Enter TaskLo Handler.\n"); PRINTK("Enter TaskLo Handler.\n");
/* Delay the task for 2 ticks. The task is then suspended, and the remaining task with the highest priority (background task) will be executed.*/ /* Delay the task for 2 ticks. The task is suspended, and the remaining task with the highest priority (background task) will be executed. */
ret = LOS_TaskDelay(2); ret = LOS_TaskDelay(2);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Delay TaskLo Failed.\n"); PRINTK("Delay TaskLo Failed.\n");
return LOS_NOK; return LOS_NOK;
} }
PRINTK("TaskHi LOS_TaskSuspend Success.\n"); PRINTK("TaskHi LOS_TaskSuspend Success.\n");
/* Resume the suspended task g_taskHiID.*/ /* Resume the suspended task g_taskHiID. */
ret = LOS_TaskResume(g_taskHiID); ret = LOS_TaskResume(g_taskHiID);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Resume TaskHi Failed.\n"); PRINTK("Resume TaskHi Failed.\n");
...@@ -270,22 +197,23 @@ UINT32 ExampleTaskLo(VOID) ...@@ -270,22 +197,23 @@ UINT32 ExampleTaskLo(VOID)
PRINTK("TaskHi LOS_TaskDelete Success.\n"); PRINTK("TaskHi LOS_TaskDelete Success.\n");
return LOS_OK; return LOS_OK;
} }
/* Task test entry function, which is used to create two tasks with different priorities.*/ /* Create two tasks with different priorities in the task test entry function. */
UINT32 ExampleTaskCaseEntry(VOID) UINT32 ExampleTaskCaseEntry(VOID)
{ {
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S initParam = {0}; TSK_INIT_PARAM_S initParam = {0};
/* Lock task scheduling.*/ /* Lock task scheduling. */
LOS_TaskLock(); LOS_TaskLock();
PRINTK("LOS_TaskLock() Success!\n"); PRINTK("LOS_TaskLock() Success!\n");
/* Parameters used to initialize the high-priority task, the resources of which can be reclaimed by LOS_TaskJoin. */
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskHi; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskHi;
initParam.usTaskPrio = TSK_PRIOR_HI; initParam.usTaskPrio = TSK_PRIOR_HI;
initParam.pcName = "HIGH_NAME"; initParam.pcName = "HIGH_NAME";
initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE;
initParam.uwResved = LOS_TASK_ATTR_JOINABLE; initParam.uwResved = LOS_TASK_ATTR_JOINABLE;
/* Create a task with a higher priority. The task will not be executed immediately after being created, because task scheduling is locked.*/ /* Create a task with higher priority. The task will not be executed immediately after being created, because task scheduling is locked. */
ret = LOS_TaskCreate(&g_taskHiID, &initParam); ret = LOS_TaskCreate(&g_taskHiID, &initParam);
if (ret != LOS_OK) { if (ret != LOS_OK) {
LOS_TaskUnlock(); LOS_TaskUnlock();
...@@ -294,13 +222,14 @@ UINT32 ExampleTaskCaseEntry(VOID) ...@@ -294,13 +222,14 @@ UINT32 ExampleTaskCaseEntry(VOID)
} }
PRINTK("ExampleTaskHi create Success!\n"); PRINTK("ExampleTaskHi create Success!\n");
/* Parameters used to initialize the low-priority task, which will be automatically destroyed after the task is complete. */
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskLo; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskLo;
initParam.usTaskPrio = TSK_PRIOR_LO; initParam.usTaskPrio = TSK_PRIOR_LO;
initParam.pcName = "LOW_NAME"; initParam.pcName = "LOW_NAME";
initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE;
initParam.uwResved = LOS_TASK_STATUS_DETACHED; initParam.uwResved = LOS_TASK_STATUS_DETACHED;
/* Create a task with a lower priority. The task will not be executed immediately after being created, because task scheduling is locked.*/ /* Create a low-priority task. The task will not be executed immediately after being created, because task scheduling is locked. */
ret = LOS_TaskCreate(&g_taskLoID, &initParam); ret = LOS_TaskCreate(&g_taskLoID, &initParam);
if (ret!= LOS_OK) { if (ret!= LOS_OK) {
LOS_TaskUnlock(); LOS_TaskUnlock();
...@@ -309,7 +238,7 @@ UINT32 ExampleTaskCaseEntry(VOID) ...@@ -309,7 +238,7 @@ UINT32 ExampleTaskCaseEntry(VOID)
} }
PRINTK("ExampleTaskLo create Success!\n"); PRINTK("ExampleTaskLo create Success!\n");
/* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed.*/ /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed. */
LOS_TaskUnlock(); LOS_TaskUnlock();
ret = LOS_TaskJoin(g_taskHiID, NULL); ret = LOS_TaskJoin(g_taskHiID, NULL);
if (ret != LOS_OK) { if (ret != LOS_OK) {
...@@ -324,6 +253,7 @@ UINT32 ExampleTaskCaseEntry(VOID) ...@@ -324,6 +253,7 @@ UINT32 ExampleTaskCaseEntry(VOID)
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
LOS_TaskLock() Success! LOS_TaskLock() Success!
ExampleTaskHi create Success! ExampleTaskHi create Success!
...@@ -336,4 +266,3 @@ TaskHi LOS_TaskResume Success. ...@@ -336,4 +266,3 @@ TaskHi LOS_TaskResume Success.
TaskHi LOS_TaskDelete Success. TaskHi LOS_TaskDelete Success.
Join ExampleTaskHi Success! Join ExampleTaskHi Success!
``` ```
# Software Timer # Software Timer
## Basic Concepts<a name="section4118241563"></a> ## Basic Concepts
The software timer is a software-simulated timer based on system tick interrupts. When the preset tick counter value has elapsed, the user-defined callback will be invoked. The timing precision is related to the cycle of the system tick clock. Due to the limitation in hardware, the number of hardware timers cannot meet users' requirements. Therefore, the OpenHarmony LiteOS-A kernel provides the software timer function. The software timer allows more timing services to be created, increasing the number of timers. The software timer is a software-simulated timer based on system tick interrupts. When the preset tick counter value has elapsed, the user-defined callback will be invoked. The timing precision is related to the cycle of the system tick clock.
Due to the limitation in hardware, the number of hardware timers cannot meet users' requirements. The OpenHarmony LiteOS-A kernel provides the software timer function.
The software timer allows more timing services to be created, increasing the number of timers.
The software timer supports the following functions: The software timer supports the following functions:
- Disabling the software timer using a macro - Disabling the software timer using a macro
- Creating a software timer - Creating a software timer
- Starting a software timer - Starting a software timer
- Stopping a software timer - Stopping a software timer
- Deleting a software timer - Deleting a software timer
- Obtaining the number of remaining ticks of a software timer - Obtaining the number of remaining ticks of a software timer
## Working Principles<a name="section31079397569"></a>
The software timer is a system resource. When modules are initialized, a contiguous section of memory is allocated for software timers. The maximum number of timers supported by the system is configured by the **LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT** macro in **los\_config.h**. Software timers use a queue and a task resource of the system. The software timers are triggered based on the First In First Out \(FIFO\) rule. For the timers set at the same time, the timer with a shorter value is always closer to the queue head than the timer with a longer value, and is preferentially triggered. The software timer counts time in ticks. When a software timer is created and started, the OpenHarmony system determines the timer expiry time based on the current system time \(in ticks\) and the timing interval set by the user, and adds the timer control structure to the global timing list. ## Working Principles
When a tick interrupt occurs, the tick interrupt handler scans the global timing list for expired timers. If such timers are found, the timers are recorded. The software timer is a system resource. When modules are initialized, a contiguous section of memory is allocated for software timers. The maximum number of timers supported by the system is configured by the **LOSCFG_BASE_CORE_SWTMR_LIMIT** macro in **los_config.h**.
When the tick interrupt handling function is complete, the software timer task \(with the highest priority\) is woken up. In this task, the timeout callback function for the recorded timer is called. Software timers use a queue and a task resource of the system. The software timers are triggered based on the First In First Out (FIFO) rule. For the timers set at the same time, the timer with a shorter value is always closer to the queue head than the timer with a longer value, and is preferentially triggered.
Timer States The software timer counts time in ticks. When a software timer is created and started, the OpenHarmony system determines the timer expiry time based on the current system time (in ticks) and the timing interval set by the user, and adds the timer control structure to the global timing list.
- OS\_SWTMR\_STATUS\_UNUSED When a tick interrupt occurs, the tick interrupt handler scans the global timing list for expired timers. If such timers are found, the timers are recorded.
The timer is not in use. When the timer module is initialized, all timer resources in the system are set to this state. When the tick interrupt handler is complete, the software timer task (with the highest priority) will be woken up. In this task, the timeout callback for the recorded timer is called.
- OS\_SWTMR\_STATUS\_CREATED A software timer can be in any of the following states:
The timer is created but not started or the timer is stopped. When **LOS\_SwtmrCreate** is called for a timer that is not in use or **LOS\_SwtmrStop** is called for a newly started timer, the timer changes to this state. - OS_SWTMR_STATUS_UNUSED
- OS\_SWTMR\_STATUS\_TICKING The timer is not in use. When the timer module is initialized, all timer resources in the system are set to this state.
- OS_SWTMR_STATUS_CREATED
The timer is running \(counting\). When **LOS\_SwtmrStart** is called for a newly created timer, the timer enters this state. The timer is created but not started or the timer is stopped. When **LOS_SwtmrCreate** is called for a timer that is not in use or **LOS_SwtmrStop** is called for a newly started timer, the timer changes to this state.
- OS_SWTMR_STATUS_TICKING
Timer Modes The timer is running (counting). When **LOS_SwtmrStart** is called for a newly created timer, the timer enters this state.
The OpenHarmony provides three types of software timers: OpenHarmony provides three types of software timers:
- One-shot timer: Once started, the timer is automatically deleted after triggering only one timer event. - One-shot timer: Once started, the timer is automatically deleted after triggering only one timer event.
- Periodic timer: This type of timer periodically triggers timer events until it is manually stopped. - Periodic timer: This type of timer periodically triggers timer events until it is manually stopped.
- One-shot timer deleted by calling an API - One-shot timer deleted by calling an API
## Development Guidelines<a name="section18576131520577"></a>
## Development Guidelines
### Available APIs<a name="section3138019145719"></a>
The following table describes APIs available for the OpenHarmony LiteOS-A software timer module. For more details about the APIs, see the API reference. ### Available APIs
**Table 1** Software timer APIs The following table describes the APIs of the software timer module of the OpenHarmony LiteOS-A kernel.
<a name="table107038227425"></a> **Table 1** APIs for software timers
<table><thead align="left"><tr id="row2704122217420"><th class="cellrowborder" valign="top" width="20.6020602060206%" id="mcps1.2.4.1.1"><p id="p57041622144212"><a name="p57041622144212"></a><a name="p57041622144212"></a>Function</p>
</th> | Category | Description |
<th class="cellrowborder" valign="top" width="29.542954295429542%" id="mcps1.2.4.1.2"><p id="p19704142216424"><a name="p19704142216424"></a><a name="p19704142216424"></a>API</p> | ---------------------- | ------------------------------------------------------------ |
</th> | Creating or deleting a timer | **LOS_SwtmrCreate**: creates a software timer.<br>**LOS_SwtmrDelete**: deletes a software timer.|
<th class="cellrowborder" valign="top" width="49.85498549854985%" id="mcps1.2.4.1.3"><p id="p670412224217"><a name="p670412224217"></a><a name="p670412224217"></a>Description</p> | Starting or stopping a timer | **LOS_SwtmrStart**: starts a software timer.<br>**LOS_SwtmrStop**: stops a software timer.|
</th> | Obtaining remaining ticks of a software timer| **LOS_SwtmrTimeGet**: obtains the remaining ticks of a software timer. |
</tr>
</thead>
<tbody><tr id="row1470413222429"><td class="cellrowborder" rowspan="2" valign="top" width="20.6020602060206%" headers="mcps1.2.4.1.1 "><p id="p8284115918428"><a name="p8284115918428"></a><a name="p8284115918428"></a>Creating or deleting timers</p> ### How to Develop
</td>
<td class="cellrowborder" valign="top" width="29.542954295429542%" headers="mcps1.2.4.1.2 "><p id="p117045225428"><a name="p117045225428"></a><a name="p117045225428"></a>LOS_SwtmrCreate</p>
</td>
<td class="cellrowborder" valign="top" width="49.85498549854985%" headers="mcps1.2.4.1.3 "><p id="p170422234213"><a name="p170422234213"></a><a name="p170422234213"></a>Creates a software timer.</p>
</td>
</tr>
<tr id="row11704102217425"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1970492213426"><a name="p1970492213426"></a><a name="p1970492213426"></a>LOS_SwtmrDelete</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p870442211421"><a name="p870442211421"></a><a name="p870442211421"></a>Deletes a software timer.</p>
</td>
</tr>
<tr id="row57041422184215"><td class="cellrowborder" rowspan="2" valign="top" width="20.6020602060206%" headers="mcps1.2.4.1.1 "><p id="p1476172124318"><a name="p1476172124318"></a><a name="p1476172124318"></a>Starting or stopping timers</p>
</td>
<td class="cellrowborder" valign="top" width="29.542954295429542%" headers="mcps1.2.4.1.2 "><p id="p167040225423"><a name="p167040225423"></a><a name="p167040225423"></a>LOS_SwtmrStart</p>
</td>
<td class="cellrowborder" valign="top" width="49.85498549854985%" headers="mcps1.2.4.1.3 "><p id="p1570412229421"><a name="p1570412229421"></a><a name="p1570412229421"></a>Starts a software timer.</p>
</td>
</tr>
<tr id="row15704172224219"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1170422214216"><a name="p1170422214216"></a><a name="p1170422214216"></a>LOS_SwtmrStop</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p17705122211426"><a name="p17705122211426"></a><a name="p17705122211426"></a>Stops a software timer.</p>
</td>
</tr>
<tr id="row12705222154214"><td class="cellrowborder" valign="top" width="20.6020602060206%" headers="mcps1.2.4.1.1 "><p id="p0705622134214"><a name="p0705622134214"></a><a name="p0705622134214"></a>Obtaining remaining ticks of a software timer</p>
</td>
<td class="cellrowborder" valign="top" width="29.542954295429542%" headers="mcps1.2.4.1.2 "><p id="p177052220424"><a name="p177052220424"></a><a name="p177052220424"></a>LOS_SwtmrTimeGet</p>
</td>
<td class="cellrowborder" valign="top" width="49.85498549854985%" headers="mcps1.2.4.1.3 "><p id="p3705122264210"><a name="p3705122264210"></a><a name="p3705122264210"></a>Obtains the number of remaining ticks of a software timer.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section1344817403575"></a>
The typical development process of software timers is as follows: The typical development process of software timers is as follows:
1. Configure the software timer. 1. Configure the software timer.
- Check that **LOSCFG\_BASE\_CORE\_SWTMR** and **LOSCFG\_BASE\_IPC\_QUEUE** are enabled. - Check that **LOSCFG_BASE_CORE_SWTMR** and **LOSCFG_BASE_IPC_QUEUE** are enabled.
- Configure **LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT** \(maximum number of software timers supported by the system\). - Configure **LOSCFG_BASE_CORE_SWTMR_LIMIT** (maximum number of software timers supported by the system).
- Configure **OS\_SWTMR\_HANDLE\_QUEUE\_SIZE** \(maximum length of the software timer queue\). - Configure **OS_SWTMR_HANDLE_QUEUE_SIZE** (maximum length of the software timer queue).
2. Call **LOS\_SwtmrCreate** to create a software timer. 2. Call **LOS_SwtmrCreate** to create a software timer.
- Create a software timer with the specified timing duration, timeout handling function, and triggering mode. - Create a software timer with the specified timing duration, timeout handling function, and triggering mode.
- Return the function execution result \(success or failure\). - Return the function execution result (success or failure).
3. Call **LOS\_SwtmrStart** to start the software timer. 3. Call **LOS_SwtmrStart** to start the software timer.
4. Call **LOS\_SwtmrTimeGet** to obtain the remaining number of ticks of the software timer.
5. Call **LOS\_SwtmrStop** to stop the software timer.
6. Call **LOS\_SwtmrDelete** to delete the software timer.
>![](../public_sys-resources/icon-note.gif) **NOTE:** 4. Call **LOS_SwtmrTimeGet** to obtain the remaining number of ticks of the software timer.
>- Avoid too many operations in the callback function of the software timer. Do not use APIs or perform operations that may cause task suspension or blocking.
>- The software timers use a queue and a task resource of the system. The priority of the software timer tasks is set to **0** and cannot be changed.
>- The number of software timer resources that can be configured in the system is the total number of software timer resources available to the entire system, not the number of software timer resources available to users. For example, if the system software timer occupies one more resource, the number of software timer resources available to users decreases by one.
>- If a one-shot software timer is created, the system automatically deletes the timer and reclaims resources after the timer times out and the callback function is executed.
>- For a one-shot software timer that will not be automatically deleted after expiration, you need to call **LOS\_SwtmrDelete** to delete it and reclaim the timer resource to prevent resource leakage.
### Development Example<a name="section114416313585"></a> 5. Call **LOS_SwtmrStop** to stop the software timer.
Prerequisites: 6. Call **LOS_SwtmrDelete** to delete the software timer.
- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR** is enabled. > **NOTE**<br>
- The maximum number of software timers supported by the system \(**LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT**\) is configured. >
- The maximum length of the software timer queue \(**OS\_SWTMR\_HANDLE\_QUEUE\_SIZE**\) is configured. > - Avoid too many operations in the callback of the software timer. Do not use APIs or perform operations that may cause task suspension or blocking.
>
> - The software timers use a queue and a task resource of the system. The priority of the software timer tasks is set to **0** and cannot be changed.
>
> - The number of software timer resources that can be configured in the system is the total number of software timer resources available to the entire system, not the number of software timer resources available to users. For example, if the system software timer occupies one more resource, the number of software timer resources available to users decreases by one.
>
> - If a one-shot software timer is created, the system automatically deletes the timer and reclaims resources after the timer times out and the callback is invoked.
>
> - For a one-shot software timer that will not be automatically deleted after expiration, you need to call **LOS_SwtmrDelete** to delete it and reclaim the timer resource to prevent resource leakage.
### Development Example
**Prerequisites**
- In **los_config.h**, **LOSCFG_BASE_CORE_SWTMR** is enabled.
- The maximum number of software timers supported by the system (**LOSCFG_BASE_CORE_SWTMR_LIMIT**) is configured.
- The maximum length of the software timer queue (**OS_SWTMR_HANDLE_QUEUE_SIZE**) is configured.
**Sample Code** **Sample Code**
...@@ -164,14 +150,14 @@ void Timer_example(void) ...@@ -164,14 +150,14 @@ void Timer_example(void)
UINT16 id2; // timer id UINT16 id2; // timer id
UINT32 uwTick; UINT32 uwTick;
/* Create a one-shot software timer, with the number of ticks set to 1000. When the number of ticks reaches 1000, callback function 1 is executed. */ /* Create a one-shot software timer, with the number of ticks set to 1000. Callback 1 will be invoked when the number of ticks reaches 1000. */
LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1);
/* Create a periodic software timer and execute callback function 2 every 100 ticks. */ /* Create a periodic software timer and invoke callback 2 every 100 ticks. */
LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1);
PRINTK("create Timer1 success\n"); PRINTK("create Timer1 success\n");
LOS_SwtmrStart (id1); // Start the one-shot software timer. LOS_SwtmrStart(id1); // Start the one-shot software timer.
dprintf("start Timer1 success\n"); dprintf("start Timer1 success\n");
LOS_TaskDelay(200); // Delay 200 ticks. LOS_TaskDelay(200); // Delay 200 ticks.
LOS_SwtmrTimeGet(id1, &uwTick); // Obtain the number of remaining ticks of the one-short software timer. LOS_SwtmrTimeGet(id1, &uwTick); // Obtain the number of remaining ticks of the one-short software timer.
...@@ -196,6 +182,7 @@ void Timer_example(void) ...@@ -196,6 +182,7 @@ void Timer_example(void)
**Output** **Output**
``` ```
create Timer1 success create Timer1 success
start Timer1 success start Timer1 success
...@@ -226,4 +213,3 @@ tick_last1=2101 ...@@ -226,4 +213,3 @@ tick_last1=2101
g_timercount2 =10 g_timercount2 =10
tick_last1=2201 tick_last1=2201
``` ```
...@@ -3,85 +3,64 @@ ...@@ -3,85 +3,64 @@
## Basic Concepts ## Basic Concepts
Time management provides all time-related services for applications based on the system clock. The system clock is generated by the interrupts triggered by the output pulse of a timer or counter. The system clock is generally defined as an integer or a long integer. The period of an output pulse is a "clock tick". The system clock is also called time scale or tick. The duration of a tick can be configured statically. People use second or millisecond as the time unit, while the operating system uses tick. When operations such as suspending a task or delaying a task are performed, the time management module converts time between ticks and seconds or milliseconds. Time management is performed based on the system clock. It provides time-related services for applications. The system clock is generated by the interrupts triggered by the output pulse of a timer or counter. The system clock is generally defined as an integer or a long integer. The period of an output pulse is a "clock tick".
The system clock is also called time scale or tick. The duration of a tick can be configured statically. People use second or millisecond as the time unit, while the operating system uses tick. When operations such as suspending a task or delaying a task are performed, the time management module converts time between ticks and seconds or milliseconds.
The mapping between ticks and seconds can be configured. The mapping between ticks and seconds can be configured.
- **Cycle** - Cycle
Cycle is the minimum time unit in the system. The cycle duration is determined by the system clock frequency, that is, the number of cycles per second. Cycle is the minimum time unit in the system. The cycle duration is determined by the system clock frequency, that is, the number of cycles per second.
- Tick
- **Tick**
Tick is the basic time unit of the operating system and is determined by the number of ticks per second configured by the user. Tick is the basic time unit of the operating system and is determined by the number of ticks per second configured by the user.
The OpenHarmony time management module provides time conversion, statistics, and delay functions.
The OpenHarmony time management module provides time conversion, statistics, and delay functions to meet users' time requirements.
## Development Guidelines ## Development Guidelines
The time management module provides APIs to implement conversion between the system running time, ticks, and seconds/milliseconds. Before you start, learn about the system time and the APIs for time management.
### Available APIs ### Available APIs
The following table describes APIs available for the OpenHarmony LiteOS-A time management. For more details about the APIs, see the API reference. The following table describes APIs for OpenHarmony LiteOS-A time management. For more details about the APIs, see the API reference.
**Table 1** APIs of the time management module **Table 1** APIs for time management
<a name="table1316220185211"></a> | Category| API Description |
<table><thead align="left"><tr id="row191622182021"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p13162121815218"><a name="p13162121815218"></a><a name="p13162121815218"></a>Function</p> | -------- | ------------------------------------------------------------ |
</th> | Time conversion| **LOS_MS2Tick**: converts milliseconds to ticks.<br>**LOS_Tick2MS**: converts ticks to milliseconds. |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p12162618623"><a name="p12162618623"></a><a name="p12162618623"></a>API</p> | Time statistics| **LOS_TickCountGet**: obtains the number of current ticks.<br>**LOS_CyclePerTickGet**: obtains the number of cycles of each tick.|
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p16162118427"><a name="p16162118427"></a><a name="p16162118427"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row04981218910"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p6462616696"><a name="p6462616696"></a><a name="p6462616696"></a>Time conversion</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p164931214913"><a name="p164931214913"></a><a name="p164931214913"></a>LOS_MS2Tick</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p8504121996"><a name="p8504121996"></a><a name="p8504121996"></a>Converts milliseconds into ticks.</p>
</td>
</tr>
<tr id="row7162101814216"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p816311185217"><a name="p816311185217"></a><a name="p816311185217"></a>LOS_Tick2MS</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p161632181721"><a name="p161632181721"></a><a name="p161632181721"></a>Converts ticks into milliseconds.</p>
</td>
</tr>
<tr id="row1516317181227"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1077619231696"><a name="p1077619231696"></a><a name="p1077619231696"></a>Time statistics</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p181638181921"><a name="p181638181921"></a><a name="p181638181921"></a>LOS_TickCountGet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p615864811116"><a name="p615864811116"></a><a name="p615864811116"></a>Obtains the current number of ticks.</p>
</td>
</tr>
<tr id="row101631818620"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p71633181125"><a name="p71633181125"></a><a name="p71633181125"></a>LOS_CyclePerTickGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p151631718124"><a name="p151631718124"></a><a name="p151631718124"></a>Obtains the number of cycles per tick.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop ### How to Develop
1. Call APIs to convert time. 1. Call APIs to convert time.
2. Call APIs to perform time statistics. 2. Call APIs to perform time statistics.
>![](public_sys-resources/icon-note.gif) **NOTE**<br/> > **NOTE**
>- The system tick count can be obtained only after the system clock is enabled. >
>- The time management module depends on **OS\_SYS\_CLOCK** and **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND** in **los\_config.h**. > - The system tick count can be obtained only after the system clock is enabled.
>- The number of system ticks is not counted when the interrupt feature is disabled. Therefore, the number of ticks cannot be used as the accurate time. >
> - The time management module depends on **OS_SYS_CLOCK** and **LOSCFG_BASE_CORE_TICK_PER_SECOND** in **los_config.h**.
>
> - The number of system ticks is not counted when the interrupt feature is disabled. Therefore, the number of ticks cannot be used as the accurate time.
### Development Example ### Development Example
**Prerequisites**<br> **Prerequisites**
The following parameters are configured: The following parameters are configured:
- **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**: number of ticks per second in the system. The value range is (0, 1000]. - **LOSCFG_BASE_CORE_TICK_PER_SECOND**: number of ticks/second. The value range is (0, 1000).
- **OS\_SYS\_CLOCK**: system clock, in Hz.
- **OS_SYS_CLOCK**: system clock, in Hz.
**Sample Code** **Sample Code**
...@@ -92,15 +71,16 @@ VOID Example_TransformTime(VOID) ...@@ -92,15 +71,16 @@ VOID Example_TransformTime(VOID)
{ {
UINT32 uwMs; UINT32 uwMs;
UINT32 uwTick; UINT32 uwTick;
uwTick = LOS_MS2Tick(10000);// Convert 10000 ms into ticks. uwTick = LOS_MS2Tick(10000); // Convert 10000 ms to ticks.
PRINTK("uwTick = %d \n",uwTick); PRINTK("uwTick = %d \n",uwTick);
uwMs= LOS_Tick2MS(100); // Convert 100 ticks into ms. uwMs= LOS_Tick2MS(100); // Convert 100 ticks to ms.
PRINTK("uwMs = %d \n",uwMs); PRINTK("uwMs = %d \n",uwMs);
} }
``` ```
Time statistics and delay: Time statistics and delay:
``` ```
VOID Example_GetTime(VOID) VOID Example_GetTime(VOID)
{ {
...@@ -133,6 +113,7 @@ The result is as follows: ...@@ -133,6 +113,7 @@ The result is as follows:
Time conversion: Time conversion:
``` ```
uwTick = 10000 uwTick = 10000
uwMs = 100 uwMs = 100
...@@ -140,9 +121,9 @@ uwMs = 100 ...@@ -140,9 +121,9 @@ uwMs = 100
Time statistics and delay: Time statistics and delay:
``` ```
LOS_CyclePerTickGet = 49500 LOS_CyclePerTickGet = 49500
LOS_TickCountGet = 5042 LOS_TickCountGet = 347931
LOS_TickCountGet after delay = 5242 LOS_TickCountGet after delay = 348134
``` ```
# Event # Event
## Basic Concepts<a name="section122115620816"></a>
An event is a mechanism for communication between tasks. It can be used to synchronize tasks. ## Basic Concepts
An event is a communication mechanism used to synchronize tasks.
In multi-task environment, synchronization is required between tasks. Events can be used for synchronization in the following cases: In multi-task environment, synchronization is required between tasks. Events can be used for synchronization in the following cases:
- One-to-many synchronization: A task waits for the triggering of multiple events. A task is woken up by one or multiple events. - One-to-many synchronization: A task waits for the triggering of multiple events. A task can be woken up by one or multiple events.
- Many-to-many synchronization: Multiple tasks wait for the triggering of multiple events. - Many-to-many synchronization: Multiple tasks wait for the triggering of multiple events.
The event mechanism provided by the OpenHarmony LiteOS-A event module has the following features: The event mechanism provided by the OpenHarmony LiteOS-A event module has the following features:
- A task triggers or waits for an event by creating an event control block. - A task triggers or waits for an event by creating an event control block.
- Events are independent of each other. The internal implementation is a 32-bit unsigned integer, and each bit indicates an event type. The 25th bit is unavailable. Therefore, a maximum of 31 event types are supported.
- Events are used only for synchronization between tasks, but not for data transmission. - Events are independent of each other. The internal implementation is a 32-bit unsigned integer, and each bit indicates an event type. The value **0** indicates that the event type does not occur, and the value **1** indicates that the event type has occurred. There are 31 event types in total. The 25th bit (`0x02U << 24`) is reserved.
- Writing the same event type to the event control block for multiple times is equivalent to writing the event type only once before the event control block is cleared.
- Events are used for task synchronization, but not for data transmission.
- Writing the same event type to an event control block multiple times is equivalent to writing the event type only once before the event control block is cleared.
- Multiple tasks can read and write the same event. - Multiple tasks can read and write the same event.
- The event read/write timeout mechanism is supported. - The event read/write timeout mechanism is supported.
## Working Principles<a name="section94611116593"></a>
### Event Control Block<a name="section1161415384467"></a> ## Working Principles
### Event Control Block
``` ```
/** /**
* Event control block data structure * Event control block data structure
*/ */
typedef struct tagEvent { typedef struct tagEvent {
UINT32 uwEventID; /* Event set, which is a collection of events processed (written and cleared). */ UINT32 uwEventID; /* Event set, which is a collection of events processed (written and cleared). */
LOS_DL_LIST stEventList; /* List of tasks waiting for specific events */ LOS_DL_LIST stEventList; /* List of tasks waiting for specific events. */
} EVENT_CB_S, *PEVENT_CB_S; } EVENT_CB_S, *PEVENT_CB_S;
``` ```
### Working Principles<a name="section187761153144617"></a>
**Initializing an event**: An event control block is created to maintain a collection of processed events and a linked list of tasks waiting for specific events. ### Working Principles
**Initializing an Event**
An event control block is created to maintain a set of processed events and a linked list of tasks waiting for specific events.
**Writing an event**: When a specified event is written to the event control block, the event control block updates the event set, traverses the task linked list, and determines whether to wake up related task based on the task conditions. **Writing an Event**
**Reading an event**: If the read event already exists, it is returned synchronously. In other cases, the return time is determined based on the timeout period and event triggering status. If the wait event condition is met before the timeout period expires, the blocked task will be directly woken up. Otherwise, the blocked task will be woken up only after the timeout period has expired. When an event is written to the event control block, the event control block updates the event set, traverses the task linked list, and determines whether to wake up related task based on the specified conditions.
The input parameters **eventMask** and **mode** determine whether the condition for reading an event is met. **eventMask** indicates the mask of the event. **mode** indicates the handling mode, which can be any of the following: **Reading an Event**
- **LOS\_WAITMODE\_AND**: Event reading is successful only when all the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned. If the event to read already exists, it is returned synchronously. In other cases, the event is returned based on the timeout period and event triggering conditions. If the wait condition is met before the timeout period expires, the blocked task will be directly woken up. Otherwise, the blocked task will be woken up only after the timeout period has expired.
- **LOS\_WAITMODE\_OR**: Event reading is successful when any of the events corresponding to **eventMask** occurs. Otherwise, the task will be blocked, or an error code will be returned.
- **LOS\_WAITMODE\_CLR**: This mode must be used with **LOS\_WAITMODE\_AND** or **LOS\_WAITMODE\_OR** \(LOS\_WAITMODE\_AND | LOS\_WAITMODE\_CLR or LOS\_WAITMODE\_OR | LOS\_WAITMODE\_CLR\). In this mode, if **LOS\_WAITMODE\_AND** or **LOS\_WAITMODE\_OR** is successful, the corresponding event type bit in the event control block will be automatically cleared.
**Clearing events**: Clear the event set of the event control block based on the specified mask. If the mask is **0**, the event set will be cleared. If the mask is **0xffff**, no event will be cleared, and the event set remains unchanged. The parameters **eventMask** and **mode** determine whether the condition for reading an event is met. **eventMask** specifies the event mask. **mode** specifies the handling mode, which can be any of the following:
**Destroying an event**: Destroy the specified event control block. - **LOS_WAITMODE_AND**: Read the event only when all the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned.
**Figure 1** Event working mechanism for small systems<a name="fig17799175324612"></a> - **LOS_WAITMODE_OR**: Read the event only when any of the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned.
![](figures/event-working-mechanism-for-small-systems.png "event-working-mechanism-for-small-systems")
## Development Guidelines<a name="section44744471891"></a> - **LOS_WAITMODE_CLR**: This mode must be used with one or all of the event modes (LOS_WAITMODE_AND | LOS_WAITMODE_CLR or LOS_WAITMODE_OR | LOS_WAITMODE_CLR). In this mode, if all event modes or any event mode is successful, the corresponding event type bit in the event control block will be automatically cleared.
### Available APIs<a name="section172373513919"></a> **Clearing Events**
The events in the event set of the event control block can be cleared based on the specified mask. The mask **0** means to clear the event set; the mask **0xffff** means the opposite.
**Destroying Events**
The event control block can be destroyed to release resources.
**Figure 1** Event working mechanism for small systems
![](figures/event-working-mechanism-for-small-systems.png "event-working-mechanism-for-small-systems")
## Development Guidelines
### Available APIs
The following table describes APIs available for the OpenHarmony LiteOS-A event module. The following table describes APIs available for the OpenHarmony LiteOS-A event module.
**Table 1** Event module APIs **Table 1** APIs of the event module
<a name="table1415203765610"></a> | Category| API Description |
<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Function</p> | -------- | -------- |
</th> | Initializing an event| **LOS_EventInit**: initializes an event control block.|
<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>API</p> | Reading/Writing an event| - **LOS_EventRead**: reads an event, with a relative timeout period in ticks.<br>- **LOS_EventWrite**: writes an event. |
</th> | Clearing events| **LOS_EventClear**: clears a specified type of events.|
<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p> | Checking the event mask| **LOS_EventPoll**: checks whether the specified event occurs.|
</th> | Destroying events | **LOS_EventDestroy**: destroys an event control block.|
</tr>
</thead>
<tbody><tr id="row0415737175610"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p9598124913544"><a name="p9598124913544"></a><a name="p9598124913544"></a>Initializing events</p> ### How to Develop
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p77891354175812"><a name="p77891354175812"></a><a name="p77891354175812"></a>LOS_EventInit</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p2334141425515"><a name="p2334141425515"></a><a name="p2334141425515"></a>Initializes an event control block.</p>
</td>
</tr>
<tr id="row421753455514"><td class="cellrowborder" rowspan="2" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p13441112105813"><a name="p13441112105813"></a><a name="p13441112105813"></a>Reading/Writing events</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p17234205011559"><a name="p17234205011559"></a><a name="p17234205011559"></a>LOS_EventRead</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1621275475517"><a name="p1621275475517"></a><a name="p1621275475517"></a>Reads a specified type of event, with the timeout period of a relative time period in ticks.</p>
</td>
</tr>
<tr id="row13129193718555"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17477615564"><a name="p17477615564"></a><a name="p17477615564"></a>LOS_EventWrite</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p10271958567"><a name="p10271958567"></a><a name="p10271958567"></a>Writes a specified type of event.</p>
</td>
</tr>
<tr id="row1831124035511"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p1313401559"><a name="p1313401559"></a><a name="p1313401559"></a>Clearing events</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p7788152419567"><a name="p7788152419567"></a><a name="p7788152419567"></a>LOS_EventClear</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p14862153525620"><a name="p14862153525620"></a><a name="p14862153525620"></a>Clears a specified type of event.</p>
</td>
</tr>
<tr id="row1525316428553"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p4253144265519"><a name="p4253144265519"></a><a name="p4253144265519"></a>Checking the event mask</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p768611115563"><a name="p768611115563"></a><a name="p768611115563"></a>LOS_EventPoll</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p13998115465617"><a name="p13998115465617"></a><a name="p13998115465617"></a>Returns whether the event input by the user meets the expectation based on the event ID, event mask, and read mode passed by the user.</p>
</td>
</tr>
<tr id="row6447135825614"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p104471658155615"><a name="p104471658155615"></a><a name="p104471658155615"></a>Destroying events</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p15259169573"><a name="p15259169573"></a><a name="p15259169573"></a>LOS_EventDestroy</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p32592615573"><a name="p32592615573"></a><a name="p32592615573"></a>Destroys a specified event control block.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section1118215161013"></a>
The typical event development process is as follows: The typical event development process is as follows:
1. Initialize an event control block. 1. Initialize an event control block.
2. Block a read event control block.
2. Block a read event.
3. Write related events. 3. Write related events.
4. Wake up a blocked task, read the event, and check whether the event meets conditions. 4. Wake up a blocked task, read the event, and check whether the event meets conditions.
5. Handle the event control block. 5. Handle the event control block.
6. Destroy an event control block. 6. Destroy an event control block.
>![](../public_sys-resources/icon-note.gif) **NOTE:** > **NOTE**
>- When an event is read or written, the 25th bit of the event is reserved and cannot be set. >
>- Repeated writes of the same event are treated as one write. > - For event read and write operations, the 25th bit (`0x02U << 24`) of the event is reserved and cannot be set.
>
> - Repeated writes of the same event are treated as one write.
## Development Example
### Example Description
In this example, run the **Example_TaskEntry** task to create the **Example_Event** task. Run the **Example_Event** task to read an event to trigger task switching. Run the **Example_TaskEntry** task to write an event. You can understand the task switching during event operations based on the sequence in which logs are recorded.
## Development Example<a name="section5837165132911"></a> 1. Create the **Example_Event** task in the **Example_TaskEntry** task with a higher priority than the **Example_TaskEntry** task.
### Example Description<a name="section128221510145718"></a> 2. Run the **Example_Event** task to read event **0x00000001**. Task switching is triggered to execute the **Example_TaskEntry** task.
In this example, run the **Example\_TaskEntry** task to create the **Example\_Event** task, run the **Example\_Event** task to read an event to trigger task switching, and run the **Example\_TaskEntry** task to write an event. You can understand the task switching during event operations based on the sequence in which logs are recorded. 3. Run the **Example_TaskEntry** task to write event **0x00000001**. Task switching is triggered to execute the **Example_Event** task.
1. Create the **Example\_Event** task in the **Example\_TaskEntry** task with a higher priority than the **Example\_TaskEntry** task. 4. The **Example_Event** task is executed.
2. Run the **Example\_Event** task to read event **0x00000001**. Task switching is triggered to execute the **Example\_TaskEntry** task.
3. Run the **Example\_TaskEntry** task to write event **0x00000001**. Task switching is triggered to execute the **Example\_Event** task.
4. The **Example\_Event** task is executed.
5. The **Example\_TaskEntry** task is executed.
### Sample Code<a name="section71507479577"></a> 5. The **Example_TaskEntry** task is executed.
### Sample Code
The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **Example_EventEntry** function is called in **TestTaskEntry**.
The sample code is as follows: The sample code is as follows:
...@@ -149,28 +148,28 @@ The sample code is as follows: ...@@ -149,28 +148,28 @@ The sample code is as follows:
#include "los_task.h" #include "los_task.h"
#include "securec.h" #include "securec.h"
/* Task ID*/ /* Task ID */
UINT32 g_testTaskId; UINT32 g_testTaskId;
/* Event control structure*/ /* Event control structure */
EVENT_CB_S g_exampleEvent; EVENT_CB_S g_exampleEvent;
/* Type of the wait event*/ /* Type of the wait event */
#define EVENT_WAIT 0x00000001 #define EVENT_WAIT 0x00000001
#define EVENT_TIMEOUT 500
/* Example task entry function*/ /* Example task entry function */
VOID Example_Event(VOID) VOID Example_Event(VOID)
{ {
UINT32 event; UINT32 event;
/* Set a timeout period for event reading to 100 ticks. If the specified event is not read within 100 ticks, the read operation times out and the task is woken up.*/ /* Set a timeout period for event reading to 100 ticks. If the specified event is not read within 100 ticks, the read operation times out and the task is woken up. */
printf("Example_Event wait event 0x%x \n", EVENT_WAIT); dprintf("Example_Event wait event 0x%x \n", EVENT_WAIT);
event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, EVENT_TIMEOUT);
if (event == EVENT_WAIT) { if (event == EVENT_WAIT) {
printf("Example_Event,read event :0x%x\n", event); dprintf("Example_Event,read event :0x%x\n", event);
} else { } else {
printf("Example_Event,read event timeout\n"); dprintf("Example_Event,read event timeout\n");
} }
} }
...@@ -179,14 +178,14 @@ UINT32 Example_EventEntry(VOID) ...@@ -179,14 +178,14 @@ UINT32 Example_EventEntry(VOID)
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S task1; TSK_INIT_PARAM_S task1;
/* Initialize the event.*/ /* Initialize the event. */
ret = LOS_EventInit(&g_exampleEvent); ret = LOS_EventInit(&g_exampleEvent);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("init event failed .\n"); dprintf("init event failed .\n");
return -1; return -1;
} }
/* Create a task.*/ /* Create a task. */
(VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event;
task1.pcName = "EventTsk1"; task1.pcName = "EventTsk1";
...@@ -194,39 +193,34 @@ UINT32 Example_EventEntry(VOID) ...@@ -194,39 +193,34 @@ UINT32 Example_EventEntry(VOID)
task1.usTaskPrio = 5; task1.usTaskPrio = 5;
ret = LOS_TaskCreate(&g_testTaskId, &task1); ret = LOS_TaskCreate(&g_testTaskId, &task1);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task create failed.\n"); dprintf("task create failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* Write the task wait event (g_testTaskId). */ /* Write the task wait event (g_testTaskId). */
printf("Example_TaskEntry write event.\n"); dprintf("Example_TaskEntry write event.\n");
ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("event write failed.\n"); dprintf("event write failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* Clear the flag.*/ /* Clear the flag. */
printf("EventMask:%d\n", g_exampleEvent.uwEventID); dprintf("EventMask:%d\n", g_exampleEvent.uwEventID);
LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID);
printf("EventMask:%d\n", g_exampleEvent.uwEventID); dprintf("EventMask:%d\n", g_exampleEvent.uwEventID);
/* Delete the task.*/
ret = LOS_TaskDelete(g_testTaskId);
if (ret != LOS_OK) {
printf("task delete failed.\n");
return LOS_NOK;
}
return LOS_OK; return LOS_OK;
} }
``` ```
### Verification<a name="section16570171645813"></a>
### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
Example_Event wait event 0x1 Example_Event wait event 0x1
Example_TaskEntry write event. Example_TaskEntry write event.
...@@ -234,4 +228,3 @@ Example_Event,read event :0x1 ...@@ -234,4 +228,3 @@ Example_Event,read event :0x1
EventMask:1 EventMask:1
EventMask:0 EventMask:0
``` ```
# Mutex # Mutex
## Basic Concepts
## Basic Concepts<a name="section85865329185"></a> A mutual exclusion (mutex) is a special binary semaphore used for exclusive access to shared resources. When a task holds the mutex, the task obtains the ownership of the mutex. When the task releases the mutex, the task will lose the ownership of the mutex. When a task holds a mutex, other tasks cannot hold the mutex. In an environment where multiple tasks compete for shared resources, the mutex ensures exclusive access to the shared resources.
A mutual exclusion \(mutex\) is a special binary semaphore used for exclusive access to shared resources. When a task holds the mutex, the task obtains the ownership of the mutex. When the task releases the mutex, the task will lose the ownership of the mutex. When a task holds a mutex, other tasks cannot hold the mutex. In an environment where multiple tasks compete for shared resources, the mutex ensures exclusive access to the shared resources.
A mutex has three attributes: protocol attribute, priority upper limit attribute, and type attribute. The protocol attribute is used to handle a mutex requested by tasks of different priorities. The protocol attribute can be any of the following: A mutex has three attributes: protocol attribute, priority upper limit attribute, and type attribute. The protocol attribute is used to handle a mutex requested by tasks of different priorities. The protocol attribute can be any of the following:
- LOS\_MUX\_PRIO\_NONE - LOS_MUX_PRIO_NONE
Do not inherit or protect the priority of the task requesting the mutex. Do not inherit or protect the priority of the task requesting the mutex.
- LOS\_MUX\_PRIO\_INHERIT - LOS_MUX_PRIO_INHERIT
Inherits the priority of the task that requests the mutex. This is the default protocol attribute. When the mutex protocol attribute is set to this value: If a task with a higher priority is blocked because the mutex is already held by a task, the priority of the task holding the mutex will be backed up to the priority bitmap of the task control block, and then set to be the same as that of the task of a higher priority. When the task holding the mutex releases the mutex, its task priority is restored to its original value. Inherits the priority of the task that requests the mutex. This is the default protocol attribute. When the mutex protocol attribute is set to this value: If a task with a higher priority is blocked because the mutex is already held by a task, the priority of the task holding the mutex will be backed up to the priority bitmap of the task control block, and then set to be the same as that of the task of a higher priority. When the task holding the mutex releases the mutex, its task priority is restored to its original value.
- LOS\_MUX\_PRIO\_PROTECT - LOS_MUX_PRIO_PROTECT
Protects the priority of the task that requests the mutex. When the mutex protocol attribute is set to this value: If the priority of the task that requests the mutex is lower than the upper limit of the mutex priority, the task priority will be backed up to the priority bitmap of the task control block, and then set to the upper limit value of the mutex priority. When the mutex is released, the task priority is restored to its original value. Protects the priority of the task that requests the mutex. When the mutex protocol attribute is set to this value: If the priority of the task that requests the mutex is lower than the upper limit of the mutex priority, the task priority will be backed up to the priority bitmap of the task control block, and then set to the upper limit value of the mutex priority. When the mutex is released, the task priority is restored to its original value.
The type attribute of a mutex specifies whether to check for deadlocks and whether to support recursive holding of the mutex. The type attribute can be any of the following:
The type attribute of a mutex specifies whether to check for deadlocks and whether to support recursive holding of the mutex. The type attribute can be any of the following: - LOS_MUX_NORMAL
- LOS\_MUX\_NORMAL
Common mutex, which does not check for deadlocks. If a task repeatedly attempts to hold a mutex, the thread will be deadlocked. If the mutex type attribute is set to this value, a task cannot release a mutex held by another task or repeatedly release a mutex. Otherwise, unexpected results will be caused. Common mutex, which does not check for deadlocks. If a task repeatedly attempts to hold a mutex, the thread will be deadlocked. If the mutex type attribute is set to this value, a task cannot release a mutex held by another task or repeatedly release a mutex. Otherwise, unexpected results will be caused.
- LOS\_MUX\_RECURSIVE - LOS_MUX_RECURSIVE
Recursive mutex, which is the default attribute. If the type attribute of a mutex is set to this value, a task can hold the mutex for multiple times. Another task can hold this mutex only when the number of lock holding times is the same as the number of lock release times. However, any attempt to hold a mutex held by another task or attempt to release a mutex that has been released will return an error code. Recursive mutex, which is the default attribute. If the type attribute of a mutex is set to this value, a task can hold the mutex for multiple times. Another task can hold this mutex only when the number of lock holding times is the same as the number of lock release times. However, any attempt to hold a mutex held by another task or attempt to release a mutex that has been released will return an error code.
- LOS\_MUX\_ERRORCHECK - LOS_MUX_ERRORCHECK
Allows automatic check for deadlocks. When a mutex is set to this type, an error code will be returned if a task attempts to repeatedly hold the mutex, attempts to release the mutex held by another task, or attempts to release the mutex that has been released. Mutex for error checks. When a mutex is set to this type, an error code will be returned if a task attempts to repeatedly hold the mutex, attempts to release the mutex held by another task, or attempts to release the mutex that has been released.
## Working Principles<a name="section8547454201819"></a> ## Working Principles
In a multi-task environment, multiple tasks may access the same shared resource. However, certain shared resources are not shared, and can only be accessed exclusively by tasks. A mutex can be used to address this issue. In a multi-task environment, multiple tasks may access the same shared resources. However, certain shared resources are not shared, and can only be accessed exclusively by tasks. A mutex can be used to address this issue.
When non-shared resources are accessed by a task, the mutex is locked. Other tasks will be blocked until the mutex is released by the task. The mutex allows only one task to access the shared resources at a time, ensuring integrity of operations on the shared resources. When non-shared resources are accessed by a task, the mutex is locked. Other tasks will be blocked until the mutex is released by the task. The mutex allows only one task to access the shared resources at a time, ensuring integrity of operations on the shared resources.
**Figure 1** Mutex working mechanism for small systems<a name="fig16821181173811"></a> **Figure 1** Mutex working mechanism for the small system
![](figures/mutex-working-mechanism-for-small-systems.png "mutex-working-mechanism-for-small-systems") ![](figures/mutex-working-mechanism-for-small-systems.png "mutex-working-mechanism-for-small-systems")
## Development Guidelines<a name="section2038861117194"></a>
## Development Guidelines
### Available APIs<a name="section11168318131917"></a>
**Table 1** Mutex module APIs ### Available APIs
<a name="table37108292611"></a> **Table 1** APIs of the mutex module
<table><thead align="left"><tr id="row8711112919610"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p3711102912617"><a name="p3711102912617"></a><a name="p3711102912617"></a>Function</p>
</th> | Category| API Description |
<th class="cellrowborder" valign="top" width="33.31333133313331%" id="mcps1.2.4.1.2"><p id="p1671110293610"><a name="p1671110293610"></a><a name="p1671110293610"></a>API</p> | -------- | -------- |
</th> | Initializing or destroying a mutex| - **LOS_MuxInit**: initializes a mutex.<br>- **LOS_MuxDestroy**: destroys a mutex.|
<th class="cellrowborder" valign="top" width="33.35333533353336%" id="mcps1.2.4.1.3"><p id="p87114292617"><a name="p87114292617"></a><a name="p87114292617"></a>Description</p> | Requesting or releasing a mutex| - **LOS_MuxLock**: requests a mutex.<br>- **LOS_MuxTrylock**: requests a mutex without blocking.<br>- **LOS_MuxUnlock**: releases a mutex.|
</th> | Verifying a mutex| - **LOS_MuxIsValid**: checks whether the mutex release is valid.<br>- **LOS_MuxAttrDestroy**: destroys the specified mutex attribute.|
</tr> | Setting and obtaining mutex attributes| - **LOS_MuxAttrGetType**: obtains the type attribute of a mutex.<br>- **LOS_MuxAttrSetType**: sets the type attribute for a mutex.<br>- **LOS_MuxAttrGetProtocol**: obtains the protocol attribute of a mutex.<br>- **LOS_MuxAttrSetProtocol**: sets the protocol attribute for a mutex.<br>- **LOS_MuxAttrGetPrioceiling**: obtains the priority upper limit attribute of a mutex.<br>- **LOS_MuxAttrSetPrioceiling**: sets the priority upper limit attribute for a mutex.<br>- **LOS_MuxGetPrioceiling**: obtains the priority upper limit of this mutex.<br>- **LOS_MuxSetPrioceiling**: sets the priority upper limit for this mutex. |
</thead>
<tbody><tr id="row332716281313"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1795312108911"><a name="p1795312108911"></a><a name="p1795312108911"></a>Initializing or destroying a mutex</p>
</td> ### How to Develop
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1932716285312"><a name="p1932716285312"></a><a name="p1932716285312"></a>LOS_MuxInit</p>
</td>
<td class="cellrowborder" valign="top" width="33.35333533353336%" headers="mcps1.2.4.1.3 "><p id="p932762812319"><a name="p932762812319"></a><a name="p932762812319"></a>Initializes a mutex.</p>
</td>
</tr>
<tr id="row37115291166"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p127613211335"><a name="p127613211335"></a><a name="p127613211335"></a>LOS_MuxDestroy</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p137111129965"><a name="p137111129965"></a><a name="p137111129965"></a>Destroys the specified mutex.</p>
</td>
</tr>
<tr id="row17711329268"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p18125182815396"><a name="p18125182815396"></a><a name="p18125182815396"></a>Requesting or releasing a mutex</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p215615953415"><a name="p215615953415"></a><a name="p215615953415"></a>LOS_MuxLock</p>
</td>
<td class="cellrowborder" valign="top" width="33.35333533353336%" headers="mcps1.2.4.1.3 "><p id="p20994162353515"><a name="p20994162353515"></a><a name="p20994162353515"></a>Requests the specified mutex.</p>
</td>
</tr>
<tr id="row5711192912616"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p7974187183520"><a name="p7974187183520"></a><a name="p7974187183520"></a>LOS_MuxTrylock</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1271110291969"><a name="p1271110291969"></a><a name="p1271110291969"></a>Attempts to request the specified mutex in non-block mode.</p>
</td>
</tr>
<tr id="row1571162918615"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p13021319143515"><a name="p13021319143515"></a><a name="p13021319143515"></a>LOS_MuxUnlock</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p107118291660"><a name="p107118291660"></a><a name="p107118291660"></a>Releases the specified mutex.</p>
</td>
</tr>
<tr id="row344193024114"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p16441730114110"><a name="p16441730114110"></a><a name="p16441730114110"></a>Verifying a mutex</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1544183074110"><a name="p1544183074110"></a><a name="p1544183074110"></a>LOS_MuxIsValid</p>
</td>
<td class="cellrowborder" valign="top" width="33.35333533353336%" headers="mcps1.2.4.1.3 "><p id="p3441193017416"><a name="p3441193017416"></a><a name="p3441193017416"></a>Checks whether the mutex release is valid.</p>
</td>
</tr>
<tr id="row1065116418421"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p2189182734211"><a name="p2189182734211"></a><a name="p2189182734211"></a>Initializing or destroying mutex attributes</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1565244144210"><a name="p1565244144210"></a><a name="p1565244144210"></a>LOS_MuxAttrInit</p>
</td>
<td class="cellrowborder" valign="top" width="33.35333533353336%" headers="mcps1.2.4.1.3 "><p id="p14652342426"><a name="p14652342426"></a><a name="p14652342426"></a>Initializes mutex attributes.</p>
</td>
</tr>
<tr id="row538718619427"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p538756104217"><a name="p538756104217"></a><a name="p538756104217"></a>LOS_MuxAttrDestroy</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p23875654210"><a name="p23875654210"></a><a name="p23875654210"></a>Destroys the specified mutex attributes.</p>
</td>
</tr>
<tr id="row8143848467"><td class="cellrowborder" rowspan="8" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p2926915154717"><a name="p2926915154717"></a><a name="p2926915154717"></a>Setting and obtaining mutex attributes</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p171441842465"><a name="p171441842465"></a><a name="p171441842465"></a>LOS_MuxAttrGetType</p>
</td>
<td class="cellrowborder" valign="top" width="33.35333533353336%" headers="mcps1.2.4.1.3 "><p id="p151444418461"><a name="p151444418461"></a><a name="p151444418461"></a>Obtains the type attribute of a specified mutex.</p>
</td>
</tr>
<tr id="row99314413464"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p793218404613"><a name="p793218404613"></a><a name="p793218404613"></a>LOS_MuxAttrSetType</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p51371843194813"><a name="p51371843194813"></a><a name="p51371843194813"></a>Sets the type attribute of a specified mutex.</p>
</td>
</tr>
<tr id="row204470514615"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p13447115154614"><a name="p13447115154614"></a><a name="p13447115154614"></a>LOS_MuxAttrGetProtocol</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p20871044144720"><a name="p20871044144720"></a><a name="p20871044144720"></a>Obtains the protocol attribute of a specified mutex.</p>
</td>
</tr>
<tr id="row69051358465"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p10906165124617"><a name="p10906165124617"></a><a name="p10906165124617"></a>LOS_MuxAttrSetProtocol</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1690617554610"><a name="p1690617554610"></a><a name="p1690617554610"></a>Sets the protocol attribute of a specified mutex.</p>
</td>
</tr>
<tr id="row133571666467"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6357146154616"><a name="p6357146154616"></a><a name="p6357146154616"></a>LOS_MuxAttrGetPrioceiling</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p559511469478"><a name="p559511469478"></a><a name="p559511469478"></a>Obtains the priority upper limit attribute of a specified mutex.</p>
</td>
</tr>
<tr id="row5789065465"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1778916634614"><a name="p1778916634614"></a><a name="p1778916634614"></a>LOS_MuxAttrSetPrioceiling</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p16789126134614"><a name="p16789126134614"></a><a name="p16789126134614"></a>Sets the priority upper limit attribute of a specified mutex.</p>
</td>
</tr>
<tr id="row10251772469"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p199321752124718"><a name="p199321752124718"></a><a name="p199321752124718"></a>LOS_MuxGetPrioceiling</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1128349114718"><a name="p1128349114718"></a><a name="p1128349114718"></a>Obtains the mutex priority upper limit attribute.</p>
</td>
</tr>
<tr id="row197256714468"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p72518754614"><a name="p72518754614"></a><a name="p72518754614"></a>LOS_MuxSetPrioceiling</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p177254713460"><a name="p177254713460"></a><a name="p177254713460"></a>Sets the mutex priority upper limit attribute.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section4201191122116"></a>
The typical mutex development process is as follows: The typical mutex development process is as follows:
1. Call **LOS\_MuxInit** to initialize a mutex. 1. Call **LOS_MuxInit** to initialize a mutex.
2. Call **LOS\_MuxLock** to request a mutex. 2. Call **LOS_MuxLock** to request a mutex.
The following modes are available: The following modes are available:
- Non-block mode: A task acquires the mutex if the requested mutex is not held by any task or the task holding the mutex is the same as the task requesting the mutex. - Non-block mode: A task acquires the mutex if the requested mutex is not held by any task or the task holding the mutex is the same as the task requesting the mutex.
- Permanent block mode: A task acquires the mutex if the requested mutex is not occupied. If the mutex is occupied, the task will be blocked and the task with the highest priority in the ready queue will be executed. The blocked task can be unlocked and executed only when the mutex is released.
- Permanent block mode: A task acquires the mutex if the requested mutex is not occupied. If the mutex is occupied, the task will be blocked and the task with a highest priority in the ready queue will be executed. The blocked task can be unlocked and executed only when the mutex is released.
- Scheduled block mode: A task acquires the mutex if the requested mutex is not occupied. If the mutex is occupied, the task will be blocked and the task with the highest priority in the ready queue will be executed. The blocked task can be executed only when the mutex is released within the specified timeout period or when the specified timeout period expires. - Scheduled block mode: A task acquires the mutex if the requested mutex is not occupied. If the mutex is occupied, the task will be blocked and the task with the highest priority in the ready queue will be executed. The blocked task can be executed only when the mutex is released within the specified timeout period or when the specified timeout period expires.
3. Call **LOS\_MuxUnlock** to release a mutex. 3. Call **LOS_MuxUnlock** to release a mutex.
- If tasks are blocked by the specified mutex, the task with a higher priority will be unblocked when the mutex is released. The unblocked task changes to the Ready state and is scheduled. - If tasks are blocked by the specified mutex, the task with a higher priority will be unblocked when the mutex is released. The unblocked task changes to the Ready state and is scheduled.
- If no task is blocked by the specified mutex, the mutex is released successfully. - If no task is blocked by the specified mutex, the mutex is released successfully.
4. Call **LOS\_MuxDestroy** to destroy a mutex. 4. Call **LOS_MuxDestroy** to destroy a mutex.
> **NOTE**<br>
> - Two tasks cannot lock the same mutex. If a task attempts to lock a mutex held by another task, the task will be blocked until the mutex is unclocked.
>
> - Mutexes cannot be used in the interrupt service program.
>
> - The system using the LiteOS-A kernel must ensure real-time task scheduling and avoid long-time task blocking. Therefore, a mutex must be released as soon as possible after use.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- Two tasks cannot lock the same mutex. If a task attempts to lock a mutex held by another task, the task will be blocked until the mutex is unlocked.
>- Mutexes cannot be used in the interrupt service program.
>- When using the LiteOS-A kernel, the OpenHarmony must ensure real-time task scheduling and avoid long-time task blocking. Therefore, a mutex must be released as soon as possible after use.
### Development Example<a name="section10679328202117"></a> ### Development Example
Example Description #### Example Description
This example implements the following: This example implements the following:
1. Create a mutex in the **Example\_TaskEntry** task, and lock task scheduling. Create two tasks **Example\_MutexTask1** and **Example\_MutexTask2**. and unlock task scheduling. 1. Create the **Example_TaskEntry** task. In this task, create a mutex to lock task scheduling, and create two tasks **Example_MutexTask1** (with a lower priority) and **Example_MutexTask2** (with a higher priority) to unlock task scheduling.
2. When being scheduled, **Example\_MutexTask2** requests a mutex in permanent block mode. After acquiring the mutex, **Example\_MutexTask2** enters the sleep mode for 100 ticks. **Example\_MutexTask2** is suspended, and **Example\_MutexTask1** is woken up.
3. **Example\_MutexTask1** requests a mutex in scheduled block mode, and waits for 10 ticks. Because the mutex is still held by **Example\_MutexTask2**, **Example\_MutexTask1** is suspended. After 10 ticks, **Example\_MutexTask1** is woken up and attempts to request a mutex in permanent block mode. **Example\_MutexTask1** is suspended because the mutex is still held by **Example\_MutexTask2**. 2. When being scheduled, **Example_MutexTask2** requests a mutex in permanent block mode. After acquiring the mutex, **Example_MutexTask2** enters the sleep mode for 100 ticks. **Example_MutexTask2** is suspended, and **Example_MutexTask1** is woken up.
4. After 100 ticks, **Example\_MutexTask2** is woken up and releases the mutex, and then **Example\_MutexTask1** is woken up. **Example\_MutexTask1** acquires the mutex and then releases the mutex. At last, the mutex is deleted.
3. **Example_MutexTask1** requests a mutex in scheduled block mode, and waits for 10 ticks. Because the mutex is still held by **Example_MutexTask2**, **Example_MutexTask1** is suspended. After 10 ticks, **Example_MutexTask1** is woken up and attempts to request a mutex in permanent block mode. **Example_MutexTask1** is suspended because the mutex is still held by **Example_MutexTask2**.
4. After 100 ticks, **Example_MutexTask2** is woken up and releases the mutex, and then **Example_MutexTask1** is woken up. **Example_MutexTask1** acquires the mutex and then releases the mutex. At last, the mutex is deleted.
**Sample Code** #### Sample Code
The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **Example_MutexEntry** function is called in **TestTaskEntry**.
The sample code is as follows: The sample code is as follows:
...@@ -199,7 +117,7 @@ The sample code is as follows: ...@@ -199,7 +117,7 @@ The sample code is as follows:
#include "los_mux.h" #include "los_mux.h"
/* Mutex */ /* Mutex */
LosMux g_testMux; LosMux g_testMutex;
/* Task ID*/ /* Task ID*/
UINT32 g_testTaskId01; UINT32 g_testTaskId01;
UINT32 g_testTaskId02; UINT32 g_testTaskId02;
...@@ -207,28 +125,29 @@ UINT32 g_testTaskId02; ...@@ -207,28 +125,29 @@ UINT32 g_testTaskId02;
VOID Example_MutexTask1(VOID) VOID Example_MutexTask1(VOID)
{ {
UINT32 ret; UINT32 ret;
LOS_TaskDelay(50);
printf("task1 try to get mutex, wait 10 ticks.\n"); dprintf("task1 try to get mutex, wait 10 ticks.\n");
/* Request a mutex.*/ /* Request a mutex. */
ret = LOS_MuxLock(&g_testMux, 10); ret = LOS_MuxLock(&g_testMutex, 10);
if (ret == LOS_OK) { if (ret == LOS_OK) {
printf("task1 get mutex g_testMux.\n"); dprintf("task1 get mutex g_testMux.\n");
/* Release the mutex.*/ /* Release the mutex. */
LOS_MuxUnlock(&g_testMux); LOS_MuxUnlock(&g_testMutex);
return; return;
} }
if (ret == LOS_ETIMEDOUT ) { if (ret == LOS_ETIMEDOUT) {
printf("task1 timeout and try to get mutex, wait forever.\n"); dprintf("task1 timeout and try to get mutex, wait forever.\n");
/* Request a mutex.*/ /* Request a mutex. */
ret = LOS_MuxLock(&g_testMux, LOS_WAIT_FOREVER); ret = LOS_MuxLock(&g_testMutex, LOS_WAIT_FOREVER);
if (ret == LOS_OK) { if (ret == LOS_OK) {
printf("task1 wait forever, get mutex g_testMux.\n"); dprintf("task1 wait forever, get mutex g_testMux.\n");
/*Release the mutex.*/ /* Release the mutex. */
LOS_MuxUnlock(&g_testMux); LOS_MuxUnlock(&g_testMutex);
/* Delete the mutex. */ /* Delete the mutex. */
LOS_MuxDestroy(&g_testMux); LOS_MuxDestroy(&g_testMutex);
printf("task1 post and delete mutex g_testMux.\n"); dprintf("task1 post and delete mutex g_testMux.\n");
return; return;
} }
} }
...@@ -237,18 +156,18 @@ VOID Example_MutexTask1(VOID) ...@@ -237,18 +156,18 @@ VOID Example_MutexTask1(VOID)
VOID Example_MutexTask2(VOID) VOID Example_MutexTask2(VOID)
{ {
printf("task2 try to get mutex, wait forever.\n"); dprintf("task2 try to get mutex, wait forever.\n");
/* Request a mutex.*/ /* Request a mutex. */
(VOID)LOS_MuxLock(&g_testMux, LOS_WAIT_FOREVER); (VOID)LOS_MuxLock(&g_testMutex, LOS_WAIT_FOREVER);
printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); dprintf("task2 get mutex g_testMux and suspend 100 ticks.\n");
/* Enable the task to enter sleep mode for 100 ticks.*/ /* Enable the task to enter sleep mode for 100 ticks. */
LOS_TaskDelay(100); LOS_TaskDelay(100);
printf("task2 resumed and post the g_testMux\n"); dprintf("task2 resumed and post the g_testMux\n");
/* Release the mutex.*/ /* Release the mutex. */
LOS_MuxUnlock(&g_testMux); LOS_MuxUnlock(&g_testMutex);
return; return;
} }
...@@ -258,13 +177,13 @@ UINT32 Example_MutexEntry(VOID) ...@@ -258,13 +177,13 @@ UINT32 Example_MutexEntry(VOID)
TSK_INIT_PARAM_S task1; TSK_INIT_PARAM_S task1;
TSK_INIT_PARAM_S task2; TSK_INIT_PARAM_S task2;
/* Initializes the mutex./ /* Initialize the mutex. */
LOS_MuxInit(&g_testMux, NULL); LOS_MuxInit(&g_testMutex, NULL);
/* Lock task scheduling.*/ /* Lock task scheduling. */
LOS_TaskLock(); LOS_TaskLock();
/* Create task 1.*/ /* Create task 1. */
memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); memset(&task1, 0, sizeof(TSK_INIT_PARAM_S));
task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1;
task1.pcName = "MutexTsk1"; task1.pcName = "MutexTsk1";
...@@ -272,11 +191,11 @@ UINT32 Example_MutexEntry(VOID) ...@@ -272,11 +191,11 @@ UINT32 Example_MutexEntry(VOID)
task1.usTaskPrio = 5; task1.usTaskPrio = 5;
ret = LOS_TaskCreate(&g_testTaskId01, &task1); ret = LOS_TaskCreate(&g_testTaskId01, &task1);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task1 create failed.\n"); dprintf("task1 create failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* Create task 2.*/ /* Create task 2. */
memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); memset(&task2, 0, sizeof(TSK_INIT_PARAM_S));
task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2;
task2.pcName = "MutexTsk2"; task2.pcName = "MutexTsk2";
...@@ -284,11 +203,11 @@ UINT32 Example_MutexEntry(VOID) ...@@ -284,11 +203,11 @@ UINT32 Example_MutexEntry(VOID)
task2.usTaskPrio = 4; task2.usTaskPrio = 4;
ret = LOS_TaskCreate(&g_testTaskId02, &task2); ret = LOS_TaskCreate(&g_testTaskId02, &task2);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task2 create failed.\n"); dprintf("task2 create failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* Unlock task scheduling.*/ /* Unlock task scheduling. */
LOS_TaskUnlock(); LOS_TaskUnlock();
return LOS_OK; return LOS_OK;
...@@ -299,13 +218,13 @@ UINT32 Example_MutexEntry(VOID) ...@@ -299,13 +218,13 @@ UINT32 Example_MutexEntry(VOID)
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
task1 try to get mutex, wait 10 ticks.
task2 try to get mutex, wait forever. task2 try to get mutex, wait forever.
task2 get mutex g_testMux and suspend 100 ticks. task2 get mutex g_testMux and suspend 100 ticks.
task1 try to get mutex, wait 10 ticks.
task1 timeout and try to get mutex, wait forever. task1 timeout and try to get mutex, wait forever.
task2 resumed and post the g_testMux task2 resumed and post the g_testMux
task1 wait forever, get mutex g_testMux. task1 wait forever, get mutex g_testMux.
task1 post and delete mutex g_testMux. task1 post and delete mutex g_testMux.
``` ```
# Queue # Queue
## Basic Concepts<a name="section81171363232"></a> ## Basic Concepts
A queue, also called a message queue, is a data structure used for communication between tasks. The queue receives messages of unfixed length from tasks or interrupts, and determines whether to store the transferred messages in the queue based on different APIs. A queue, also called a message queue, is a data structure used for communication between tasks. The queue receives messages of unfixed length from tasks or interrupts, and determines whether to store the transferred messages in the queue based on different APIs.
...@@ -11,17 +11,26 @@ You can adjust the timeout period of the read queue and write queue to adjust th ...@@ -11,17 +11,26 @@ You can adjust the timeout period of the read queue and write queue to adjust th
An asynchronous processing mechanism is provided to allow messages in a queue not to be processed immediately. In addition, queues can be used to buffer messages and implement asynchronous task communication. Queues have the following features: An asynchronous processing mechanism is provided to allow messages in a queue not to be processed immediately. In addition, queues can be used to buffer messages and implement asynchronous task communication. Queues have the following features:
- Messages are queued in FIFO mode and can be read and written asynchronously. - Messages are queued in first-in-first-out (FIFO) mode and can be read and written asynchronously.
- Both the read queue and write queue support the timeout mechanism. - Both the read queue and write queue support the timeout mechanism.
- Each time a message is read, the message node becomes available. - Each time a message is read, the message node becomes available.
- The types of messages to be sent are determined by the parties involved in communication. Messages of different lengths \(not exceeding the message node size of the queue\) are allowed.
- The types of messages to be sent are determined by the parties involved in communication. Messages of different lengths (not exceeding the message node size of the queue) are allowed.
- A task can receive messages from and send messages to any message queue. - A task can receive messages from and send messages to any message queue.
- Multiple tasks can receive messages from and send messages to the same queue. - Multiple tasks can receive messages from and send messages to the same queue.
- When a queue is created, the required dynamic memory space is automatically allocated in the queue API. - When a queue is created, the required dynamic memory space is automatically allocated in the queue API.
## Working Principles<a name="section1074515132316"></a>
### Queue Control Block<a name="section194431851201315"></a> ## Working Principles
### Queue Control Block
``` ```
/** /**
...@@ -43,121 +52,94 @@ typedef struct { ...@@ -43,121 +52,94 @@ typedef struct {
Each queue control block contains information about the queue status. Each queue control block contains information about the queue status.
- **OS\_QUEUE\_UNUSED**: The queue is not in use. - **OS_QUEUE_UNUSED**: The queue is not in use.
- **OS\_QUEUE\_INUSED**: The queue is in use.
- **OS_QUEUE_INUSED**: The queue is in use.
### Working Principles<a name="section89875741418"></a> ### Working Principles
- The queue ID is returned when a queue is created successfully.
- The queue ID is returned if a queue is created successfully.
- The queue control block contains **Head** and **Tail**, which indicate the storage status of messages in a queue. **Head** indicates the start position of occupied message nodes in the queue. **Tail** indicates the end position of the occupied message nodes and the start position of idle message nodes. When a queue is created, **Head** and **Tail** point to the start position of the queue. - The queue control block contains **Head** and **Tail**, which indicate the storage status of messages in a queue. **Head** indicates the start position of occupied message nodes in the queue. **Tail** indicates the end position of the occupied message nodes and the start position of idle message nodes. When a queue is created, **Head** and **Tail** point to the start position of the queue.
- When data is to be written to a queue, **readWriteableCnt\[1\]** is used to determine whether data can be written to the queue. If **readWriteableCnt\[1\]** is **0**, the queue is full and data cannot be written to it. Data can be written to the head node or tail node of a queue. To write data to the tail node, locate the start idle message node based on **Tail** and write data to it. If **Tail** is pointing to the tail of the queue, the rewind mode is used. To write data to the head node, locate previous node based on **Head** and write data to it. If **Head** is pointing to the start position of the queue, the rewind mode is used.
- When a queue is to be read, **readWriteableCnt\[0\]** is used to determine whether the queue has messages to read. Reading an idle queue \(**readWriteableCnt\[0\]** is** 0**\) will cause task suspension. If the queue has messages to read, the system locates the first node to which data is written based on **Head** and read the message from the node. If **Head** is pointing to the tail of the queue, the rewind mode is used.
- When a queue is to be deleted, the system locates the queue based on the queue ID, sets the queue status to **OS\_QUEUE\_UNUSED**, sets the queue control block to the initial state, and releases the memory occupied by the queue.
**Figure 1** Reading and writing data in a queue<a name="fig139854471119"></a> - When data is to be written to a queue, **readWriteableCnt[1]** is used to determine whether data can be written to the queue. If **readWriteableCnt[1]** is **0**, the queue is full and data cannot be written to it. Data can be written to the head node or tail node of a queue. To write data to the tail node, locate the start idle message node based on **Tail** and write data to it. If **Tail** is pointing to the tail of the queue, the rewind mode is used. To write data to the head node, locate previous node based on **Head** and write data to it. If **Head** is pointing to the start position of the queue, the rewind mode is used.
![](figures/reading-and-writing-data-in-a-queue-3.png "reading-and-writing-data-in-a-queue-3")
- When a queue is to be read, **readWriteableCnt[0]** is used to determine whether the queue has messages to read. Reading an idle queue (**readWriteableCnt[0]** is** 0**) will cause task suspension. If the queue has messages to read, the system locates the first node to which data is written based on **Head** and read the message from the node. If **Head** is pointing to the tail of the queue, the rewind mode is used.
- When a queue is to be deleted, the system locates the queue based on the queue ID, sets the queue status to **OS_QUEUE_UNUSED**, sets the queue control block to the initial state, and releases the memory occupied by the queue.
**Figure 1** Reading and writing data in a queue
![](figures/reading-and-writing-data-in-a-queue-3.png "reading-and-writing-data-in-a-queue-3")
The preceding figure illustrates how to write data to the tail node only. Writing data to the head node is similar. The preceding figure illustrates how to write data to the tail node only. Writing data to the head node is similar.
## Development Guidelines<a name="section827981242419"></a>
## Development Guidelines
### Available APIs<a name="section19327151642413"></a>
<a name="table10903105695114"></a> ### Available APIs
<table><thead align="left"><tr id="row1293645645110"><th class="cellrowborder" valign="top" width="23.56%" id="mcps1.1.4.1.1"><p id="p59361562512"><a name="p59361562512"></a><a name="p59361562512"></a>Function</p>
</th> | Category| API Description |
<th class="cellrowborder" valign="top" width="24.29%" id="mcps1.1.4.1.2"><p id="p1393665645118"><a name="p1393665645118"></a><a name="p1393665645118"></a>API</p> | -------- | -------- |
</th> | Creating or deleting a message queue| - **LOS_QueueCreate**: creates a message queue. The system dynamically allocates the queue space.<br>- **LOS_QueueDelete**: deletes a queue.|
<th class="cellrowborder" valign="top" width="52.15%" id="mcps1.1.4.1.3"><p id="p119363564516"><a name="p119363564516"></a><a name="p119363564516"></a>Description</p> | Reading or writing data (address without the content) in a queue| - **LOS_QueueRead**: reads data in the head node of the specified queue. The data in the queue node is an address.<br>- **LOS_QueueWrite**: writes the value of **bufferAddr** (buffer address) to the tail node of a queue.<br>- **LOS_QueueWrite**: writes the value of **bufferAddr** (buffer address) to the head node of a queue.|
</th> | Reading or writing data (data and address) in a queue| - **LOS_QueueReadCopy**: reads data from the head node of a queue.<br>- **LOS_QueueWriteCopy**: writes the data saved in **bufferAddr** to the tail node of a queue.<br>- **LOS_QueueWriteHeadCopy**: writes the data saved in **bufferAddr** to the head node of a queue.|
</tr> | Obtaining queue information| **LOS_QueueInfoGet**: obtains queue information, including the queue ID, queue length, message node size, head node, tail node, number of readable/writable nodes, and tasks waiting for read/write operations.|
</thead>
<tbody><tr id="row1693665613516"><td class="cellrowborder" rowspan="2" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p193675615514"><a name="p193675615514"></a><a name="p193675615514"></a>Creating or deleting a message queue</p>
</td> ### How to Develop
<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p11936115612514"><a name="p11936115612514"></a><a name="p11936115612514"></a>LOS_QueueCreate</p>
</td> 1. Call **LOS_QueueCreate** to create a queue. The queue ID is returned when the queue is created.
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p1593620562517"><a name="p1593620562517"></a><a name="p1593620562517"></a>Creates a message queue. The system dynamically allocates the queue space.</p>
</td> 2. Call **LOS_QueueWrite** or **LOS_QueueWriteCopy** to write data to the queue.
</tr>
<tr id="row79361156175113"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p893615567517"><a name="p893615567517"></a><a name="p893615567517"></a>LOS_QueueDelete</p> 3. Call **LOS_QueueRead** or **LOS_QueueReadCopy** to read data from the queue.
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p4936155695111"><a name="p4936155695111"></a><a name="p4936155695111"></a>Deletes the specified queue based on the queue ID. </p> 4. Call **LOS_QueueInfoGet** to obtain queue information.
</td>
</tr> 5. Call **LOS_QueueDelete** to delete a queue.
<tr id="row093614566519"><td class="cellrowborder" rowspan="3" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p1593685614513"><a name="p1593685614513"></a><a name="p1593685614513"></a>Reading or writing data in a queue (without the content contained in the address)</p>
</td> > **NOTE**<br>
<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p6936556155118"><a name="p6936556155118"></a><a name="p6936556155118"></a>LOS_QueueRead</p> > - The maximum number of queues supported by the system is the total number of queue resources of the system, not the number of queue resources available to users. For example, if the system software timer occupies one more queue resource, the number of queue resources available to users decreases by one.
</td> >
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p11936556155118"><a name="p11936556155118"></a><a name="p11936556155118"></a>Reads data in the head node of the specified queue. The data in the queue node is an address.</p> > - The queue name and flags passed in when a queue is created are reserved for future use.
</td> >
</tr> > - The parameter **timeOut** in the queue function is relative time.
<tr id="row199369565518"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p393655620513"><a name="p393655620513"></a><a name="p393655620513"></a>LOS_QueueWrite</p> >
</td> > - **LOS_QueueReadCopy**, **LOS_QueueWriteCopy**, and **LOS_QueueWriteHeadCopy** are a group of APIs that must be used together. **LOS_QueueRead**, **LOS_QueueWrite**, and **LOS_QueueWriteHead** are a group of APIs that must be used together.
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p12936256175120"><a name="p12936256175120"></a><a name="p12936256175120"></a>Writes the value of the input parameter <strong id="b9518118105313"><a name="b9518118105313"></a><a name="b9518118105313"></a>bufferAddr</strong> (buffer address) to the tail node of the specified queue.</p> >
</td> > - As **LOS_QueueWrite**, **LOS_QueueWriteHead**, and **LOS_QueueRead** are used to manage data addresses, you must ensure that the memory directed by the pointer obtained by calling **LOS_QueueRead** is not modified or released abnormally when the queue is being read. Otherwise, unpredictable results may occur.
</tr> >
<tr id="row1293615635114"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p893625665119"><a name="p893625665119"></a><a name="p893625665119"></a>LOS_QueueWriteHead</p> > - If the length of the data to read in **LOS_QueueRead** or **LOS_QueueReadCopy** is less than the actual message length, the message will be truncated.
</td> >
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p193620566515"><a name="p193620566515"></a><a name="p193620566515"></a>Writes the value of the input parameter <strong id="b16808172214534"><a name="b16808172214534"></a><a name="b16808172214534"></a>bufferAddr</strong> (buffer address) to the head node of the specified queue.</p> > - **LOS_QueueWrite**, **LOS_QueueWriteHead**, and **LOS_QueueRead** are called to manage data addresses, which means that the actual data read or written is pointer data. Therefore, before using these APIs, ensure that the message node size is the pointer length during queue creation, to avoid waste and read failures.
</td>
</tr>
<tr id="row593675635117"><td class="cellrowborder" rowspan="3" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p293675615111"><a name="p293675615111"></a><a name="p293675615111"></a>Reading or writing in a queue (with the content contained in the address)</p> ## Development Example
</td>
<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p14936356155113"><a name="p14936356155113"></a><a name="p14936356155113"></a>LOS_QueueReadCopy</p>
</td> ### Example Description
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p11936155616510"><a name="p11936155616510"></a><a name="p11936155616510"></a>Reads data from the head node of the specified queue.</p>
</td> Create a queue and two tasks. Enable task 1 to write data to the queue, and task 2 to read data from the queue.
</tr>
<tr id="row093619569510"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p179361256175117"><a name="p179361256175117"></a><a name="p179361256175117"></a>LOS_QueueWriteCopy</p> 1. Call **LOS_TaskCreate** to create task 1 and task 2.
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p6936155616515"><a name="p6936155616515"></a><a name="p6936155616515"></a>Writes the data saved in the input parameter <strong id="b14415194615537"><a name="b14415194615537"></a><a name="b14415194615537"></a>bufferAddr</strong> to the tail node of the specified queue.</p> 2. Call **LOS_QueueCreate** to create a message queue.
</td>
</tr> 3. Task 1 sends a message in **SendEntry**.
<tr id="row16936856185111"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p49361156195113"><a name="p49361156195113"></a><a name="p49361156195113"></a>LOS_QueueWriteHeadCopy</p>
</td> 4. Task 2 receives message in **RecvEntry**.
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1193625675116"><a name="p1193625675116"></a><a name="p1193625675116"></a>Writes the data saved in the input parameter <strong id="b1030118493534"><a name="b1030118493534"></a><a name="b1030118493534"></a>bufferAddr</strong> to the head node of the specified queue.</p>
</td> 5. Call **LOS_QueueDelete** to delete the queue.
</tr>
<tr id="row1936756155114"><td class="cellrowborder" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p149371956105114"><a name="p149371956105114"></a><a name="p149371956105114"></a>Obtaining queue information</p>
</td> ### Sample Code
<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p7937145613516"><a name="p7937145613516"></a><a name="p7937145613516"></a>LOS_QueueInfoGet</p>
</td> The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **ExampleQueue** function is called in **TestTaskEntry**.
<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p19371356175110"><a name="p19371356175110"></a><a name="p19371356175110"></a>Obtains information about the specified queue, including the queue ID, queue length, message node size, head node, tail node, number of readable nodes, number of writable nodes, tasks waiting for read operations, and tasks waiting for write operations.</p>
</td> To avoid excessive printing, call **LOS_Msleep(5000)** to cause a short delay before calling **ExampleQueue**.
</tr>
</tbody>
</table>
### How to Develop<a name="section1390154210243"></a>
1. Call **LOS\_QueueCreate** to create a queue. The queue ID is returned when the queue is created.
2. Call **LOS\_QueueWrite** or **LOS\_QueueWriteCopy** to write messages to the queue.
3. Call **LOS\_QueueRead** or **LOS\_QueueReadCopy** to read messages from the queue.
4. Call **LOS\_QueueInfoGet** to obtain queue information.
5. Call **LOS\_QueueDelete** to delete a queue.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- The maximum number of queues supported by the system is the total number of queue resources of the system, not the number of queue resources available to users. For example, if the system software timer occupies one more queue resource, the number of queue resources available to users decreases by one.
>- The input parameters queue name and flags passed when a queue is created are reserved for future use.
>- The input parameter **timeOut** in the queue interface function is relative time.
>- **LOS\_QueueReadCopy**, **LOS\_QueueWriteCopy**, and **LOS\_QueueWriteHeadCopy** are a group of APIs that must be used together. **LOS\_QueueRead**, **LOS\_QueueWrite**, and **LOS\_QueueWriteHead** are a group of APIs that must be used together.
>- As **LOS\_QueueWrite**, **LOS\_QueueWriteHead**, and **LOS\_QueueRead** are used to manage data addresses, you must ensure that the memory directed by the pointer obtained by calling **LOS\_QueueRead** is not modified or released abnormally when the queue is being read. Otherwise, unpredictable results may occur.
>- If the input parameter **bufferSize** in **LOS\_QueueRead** and **LOS\_QueueReadCopy** is less than the length of the message, the message will be truncated.
>- **LOS\_QueueWrite**, **LOS\_QueueWriteHead**, and **LOS\_QueueRead** are called to manage data addresses, which means that the actual data read or written is pointer data. Therefore, before using these APIs, ensure that the message node size is the pointer length during queue creation, to avoid waste and read failures.
## Development Example<a name="section27132341285"></a>
### Example Description<a name="section197311443141017"></a>
Create a queue and two tasks. Enable task 1 to call the queue write API to send messages, and enable task 2 to receive messages by calling the queue read API.
1. Create task 1 and task 2 by calling **LOS\_TaskCreate**.
2. Create a message queue by calling **LOS\_QueueCreate**.
3. Enable messages to be sent in task 1 by calling **SendEntry**.
4. Enable messages to be received in task 2 by calling **RecvEntry**.
5. Call **LOS\_QueueDelete** to delete a queue.
### Sample Code<a name="section972214490107"></a>
The sample code is as follows: The sample code is as follows:
...@@ -175,7 +157,7 @@ VOID SendEntry(VOID) ...@@ -175,7 +157,7 @@ VOID SendEntry(VOID)
ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0);
if(ret != LOS_OK) { if(ret != LOS_OK) {
printf("send message failure, error: %x\n", ret); dprintf("send message failure, error: %x\n", ret);
} }
} }
...@@ -185,30 +167,36 @@ VOID RecvEntry(VOID) ...@@ -185,30 +167,36 @@ VOID RecvEntry(VOID)
CHAR readBuf[BUFFER_LEN] = {0}; CHAR readBuf[BUFFER_LEN] = {0};
UINT32 readLen = BUFFER_LEN; UINT32 readLen = BUFFER_LEN;
// Sleep for 1s. LOS_Msleep(1000);
usleep(1000000);
ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0);
if(ret != LOS_OK) { if(ret != LOS_OK) {
printf("recv message failure, error: %x\n", ret); dprintf("recv message failure, error: %x\n", ret);
} }
printf("recv message: %s\n", readBuf); dprintf("recv message: %s\n", readBuf);
ret = LOS_QueueDelete(g_queue); ret = LOS_QueueDelete(g_queue);
if(ret != LOS_OK) { if(ret != LOS_OK) {
printf("delete the queue failure, error: %x\n", ret); dprintf("delete the queue failure, error: %x\n", ret);
} }
printf("delete the queue success!\n"); dprintf("delete the queue success!\n");
} }
UINT32 ExampleQueue(VOID) UINT32 ExampleQueue(VOID)
{ {
printf("start queue example\n"); dprintf("start queue example\n");
UINT32 ret = 0; UINT32 ret = 0;
UINT32 task1, task2; UINT32 task1, task2;
TSK_INIT_PARAM_S initParam = {0}; TSK_INIT_PARAM_S initParam = {0};
ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50);
if(ret != LOS_OK) {
dprintf("create queue failure, error: %x\n", ret);
}
dprintf("create the queue success!\n");
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry;
initParam.usTaskPrio = 9; initParam.usTaskPrio = 9;
initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
...@@ -217,7 +205,8 @@ UINT32 ExampleQueue(VOID) ...@@ -217,7 +205,8 @@ UINT32 ExampleQueue(VOID)
LOS_TaskLock(); LOS_TaskLock();
ret = LOS_TaskCreate(&task1, &initParam); ret = LOS_TaskCreate(&task1, &initParam);
if(ret != LOS_OK) { if(ret != LOS_OK) {
printf("create task1 failed, error: %x\n", ret); dprintf("create task1 failed, error: %x\n", ret);
LOS_QueueDelete(g_queue);
return ret; return ret;
} }
...@@ -225,29 +214,26 @@ UINT32 ExampleQueue(VOID) ...@@ -225,29 +214,26 @@ UINT32 ExampleQueue(VOID)
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry;
ret = LOS_TaskCreate(&task2, &initParam); ret = LOS_TaskCreate(&task2, &initParam);
if(ret != LOS_OK) { if(ret != LOS_OK) {
printf("create task2 failed, error: %x\n", ret); dprintf("create task2 failed, error: %x\n", ret);
LOS_QueueDelete(g_queue);
return ret; return ret;
} }
ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50);
if(ret != LOS_OK) {
printf("create queue failure, error: %x\n", ret);
}
printf("create the queue success!\n");
LOS_TaskUnlock(); LOS_TaskUnlock();
LOS_Msleep(5000);
return ret; return ret;
} }
``` ```
### Verification<a name="section19287165416106"></a>
### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
start test example start queue example
create the queue success! create the queue success!
recv message: test message recv message: test message
delete the queue success! delete the queue success!
``` ```
# Semaphore # Semaphore
## Basic Concepts<a name="section1577111168131"></a> ## Basic Concepts
Semaphore is a mechanism for implementing inter-task communication. It implements synchronization between tasks or exclusive access to shared resources. Semaphore is a mechanism used to implement synchronization between tasks or exclusive access to shared resources.
In the data structure of a semaphore, there is a value indicating the number of shared resources available. The value can be: In the semaphore data structure, there is a value indicating the number of shared resources available. The value can be:
- **0**: The semaphore is unavailable. In this case, tasks waiting for the semaphore may exist.
- **0**: The semaphore is unavailable. Tasks waiting for the semaphore may exist.
- Positive number: The semaphore is available. - Positive number: The semaphore is available.
The semaphore for exclusive access is different from the semaphore for synchronization: The semaphore used for exclusive access to resources is different from the semaphore used for synchronization:
- Semaphore used for exclusive access: The initial semaphore counter value \(non-zero\) indicates the number of shared resources available. A semaphore must be acquired before a shared resource is used, and released when the resource is no longer required. When all shared resources are used, the semaphore counter is reduced to 0 and all tasks requiring the semaphore will be blocked. This ensures exclusive access to shared resources. In addition, if the number of shared resources is 1, a binary semaphore \(similar to the mutex mechanism\) is recommended.
- Semaphore used for synchronization: The initial semaphore counter value is **0**. A task without the semaphore will be blocked, and enters the Ready or Running state only when the semaphore is released by another task or an interrupt.
- Semaphore used for exclusive access: The initial semaphore counter value \(non-zero\) indicates the number of shared resources available. The semaphore counter value must be acquired before a shared resource is used, and released when the resource is no longer required. When all shared resources are used, the semaphore counter is reduced to 0 and the tasks that need to obtain the semaphores will be blocked. This ensures exclusive access to shared resources. In addition, when the number of shared resources is 1, a binary semaphore \(similar to the mutex mechanism\) is recommended.
- Semaphore used for synchronization: The initial semaphore counter value is **0**. Task 1 cannot acquire the semaphore and is blocked. Task 1 enters Ready or Running state only when the semaphore is released by task 2 or an interrupt. In this way, task synchronization is implemented.
## Working Principles<a name="section118423019134"></a> ## Working Principles
**Semaphore Control Block** **Semaphore Control Block**
``` ```
/** /**
* Data structure of the semaphore control block * Data structure of the semaphore control block
*/ */
typedef struct { typedef struct {
UINT16 semStat; /* Semaphore status */ UINT16 semStat; /* Semaphore status */
UINT16 semType; /* Semaphore type*/ UINT16 semType; /* Semaphore type */
UINT16 semCount; /* Semaphore count*/ UINT16 semCount; /* Semaphore count */
UINT16 semId; /* Semaphore index*/ UINT16 semId; /* Semaphore ID */
LOS_DL_LIST semList; /* Mount the task blocked by the semaphore.*/ LOS_DL_LIST semList; /* List of blocked tasks */
} LosSemCB; } LosSemCB;
``` ```
...@@ -38,100 +42,87 @@ Semaphore allows only a specified number of tasks to access a shared resource at ...@@ -38,100 +42,87 @@ Semaphore allows only a specified number of tasks to access a shared resource at
- Semaphore initialization - Semaphore initialization
The system allocates memory for the semaphores configured \(you can configure the number of semaphores using the **LOSCFG\_BASE\_IPC\_SEM\_LIMIT** macro\), initializes all semaphores to be unused semaphores, and adds them to a linked list for the system to use. Allocate memory for the semaphores (the number of semaphores is specified by the **LOSCFG_BASE_IPC_SEM_LIMIT** macro), set all semaphores to the unused state, and add them to a linked list.
- Semaphore creation - Semaphore creation
The system obtains a semaphore from the linked list of unused semaphores and assigns an initial value to the semaphore. Obtain a semaphore from the linked list of unused semaphores and assign an initial value to the semaphore.
- Semaphore request - Semaphore request
If the counter value is greater than 0, the system allocates a semaphore, decreases the value by 1, and returns a success message. Otherwise, the system blocks the task and moves the task to the end of a task queue waiting for semaphores. The wait timeout period can be set. If the counter value is greater than 0 when a semaphore is requsted, the counter is decreased by 1 and a success message is returned. Otherwise, the task is blocked and added to the end of a task queue waiting for semaphores. The wait timeout period can be set.
- Semaphore release - Semaphore release
When a semaphore is released, if there is no task waiting for it, the counter value is increased by 1. Otherwise, the first task in the wait queue is woken up. If no task is waiting for the semaphore, the counter is incremented by 1. Otherwise, wake up the first task in the wait queue.
- Semaphore deletion - Semaphore deletion
The system sets a semaphore in use to unused state and inserts it to the linked list of unused semaphores. Set a semaphore in use to the unused state and add it to the linked list of unused semaphores.
The following figure illustrates the semaphore working mechanism. The following figure illustrates the semaphore working mechanism.
**Figure 1** Semaphore working mechanism for small systems<a name="fig467314634214"></a> **Figure 1** Semaphore working mechanism for the small system
![](figures/semaphore-working-mechanism-for-small-systems.png "semaphore-working-mechanism-for-small-systems") ![](figures/semaphore-working-mechanism-for-small-systems.png "semaphore-working-mechanism-for-small-systems")
## Development Guidelines<a name="section01419503131"></a>
## Development Guidelines
### Available APIs<a name="section1232345431312"></a>
**Table 1** Semaphore module APIs ### Available APIs
<a name="table1415203765610"></a> **Table 1** APIs for creating and deleting a semaphore
<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Function</p>
</th> | API| Description|
<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>API</p> | -------- | -------- |
</th> | LOS_SemCreate | Creates a semaphore and returns the semaphore ID.|
<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p> | LOS_BinarySemCreate | Creates a binary semaphore. The maximum counter value is **1**.|
</th> | LOS_SemDelete | Deletes a semaphore.|
</tr>
</thead> **Table 2** APIs for requesting and releasing a semaphore
<tbody><tr id="row0415737175610"><td class="cellrowborder" rowspan="3" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p8866127195914"><a name="p8866127195914"></a><a name="p8866127195914"></a>Creating or deleting a semaphore</p>
</td> | API| Description|
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p58621910185914"><a name="p58621910185914"></a><a name="p58621910185914"></a>LOS_SemCreate</p> | -------- | -------- |
</td> | LOS_SemPend | Requests a semaphore and sets a timeout period.|
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p48623102592"><a name="p48623102592"></a><a name="p48623102592"></a>Creates a semaphore and returns the semaphore ID.</p> | LOS_SemPost | Releases a semaphore.|
</td>
</tr>
<tr id="row1213865218584"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p20862510115911"><a name="p20862510115911"></a><a name="p20862510115911"></a>LOS_BinarySemCreate</p> ### How to Develop
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1886211011599"><a name="p1886211011599"></a><a name="p1886211011599"></a>Creates a binary semaphore. The maximum counter value is <strong id="b4125169919"><a name="b4125169919"></a><a name="b4125169919"></a>1</strong>.</p> 1. Call **LOS_SemCreate** to create a semaphore. To create a binary semaphore, call **LOS_BinarySemCreate**.
</td>
</tr> 2. Call **LOS_SemPend** to request a semaphore.
<tr id="row3231257145813"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p38621410205919"><a name="p38621410205919"></a><a name="p38621410205919"></a>LOS_SemDelete</p>
</td> 3. Call **LOS_SemPost** to release a semaphore.
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p586261085913"><a name="p586261085913"></a><a name="p586261085913"></a>Deletes a semaphore.</p>
</td> 4. Call **LOS_SemDelete** to delete a semaphore.
</tr>
<tr id="row73651459105815"><td class="cellrowborder" rowspan="2" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p16927183515593"><a name="p16927183515593"></a><a name="p16927183515593"></a>Requesting or releasing a semaphore</p> > **NOTE**<br>
</td> > As interrupts cannot be blocked, semaphores cannot be requested in block mode for interrupts.
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p955271555916"><a name="p955271555916"></a><a name="p955271555916"></a>LOS_SemPend</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p555221518598"><a name="p555221518598"></a><a name="p555221518598"></a>Requests a specified semaphore and sets the timeout period.</p> ### Development Example
</td>
</tr>
<tr id="row178321454145812"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17552101519596"><a name="p17552101519596"></a><a name="p17552101519596"></a>LOS_SemPost</p> ### Example Description
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1555261595915"><a name="p1555261595915"></a><a name="p1555261595915"></a>Posts (releases) a semaphore.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section154261711141419"></a>
1. Call **LOS\_SemCreate** to create a semaphore. To create a binary semaphore, call **LOS\_BinarySemCreate**.
2. Call **LOS\_SemPend** to request a semaphore.
3. Call **LOS\_SemPost** to release a semaphore.
4. Call **LOS\_SemDelete** to delete a semaphore.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>As interrupts cannot be blocked, semaphores cannot be requested in block mode for interrupts.
### Development Example<a name="section658135571417"></a>
### Example Description<a name="section125244411653"></a>
This example implements the following: This example implements the following:
1. Create a semaphore in task **ExampleSem** and lock task scheduling. Create two tasks **ExampleSemTask1** and **ExampleSemTask2** \(with higher priority\). Enable the two tasks to request the same semaphore. Unlock task scheduling. Enable task **ExampleSem** to enter sleep mode for 400 ticks. Release the semaphore in task **ExampleSem**. 1. Create a semaphore in task **ExampleSem** and lock task scheduling. Create two tasks **ExampleSemTask1** and **ExampleSemTask2** (with higher priority). Enable the two tasks to request the same semaphore. Unlock task scheduling. Enable task **ExampleSem** to enter sleep mode for 400 ticks. Release the semaphore in task **ExampleSem**.
2. Enable** ExampleSemTask2** to enter sleep mode for 20 ticks after acquiring the semaphore. \(When **ExampleSemTask2** is delayed, **ExampleSemTask1** is woken up.\)
3. Enable **ExampleSemTask1** to request the semaphore in scheduled block mode, with a wait timeout period of 10 ticks. \(Because the semaphore is still held by **ExampleSemTask2**, **ExampleSemTask1** is suspended. **ExampleSemTask1** is woken up after 10 ticks.\) Enable **ExampleSemTask1** to request the semaphore in permanent block mode after it is woken up 10 ticks later. \(Because the semaphore is still held by **ExampleSemTask2**, **ExampleSemTask1** is suspended.\) 2. Enable **ExampleSemTask2** to enter sleep mode for 20 ticks after acquiring the semaphore. (When **ExampleSemTask2** is delayed, **ExampleSemTask1** is woken up.)
3. Enable **ExampleSemTask1** to request the semaphore in scheduled block mode, with a wait timeout period of 10 ticks. (Because the semaphore is still held by **ExampleSemTask2**, **ExampleSemTask1** is suspended. **ExampleSemTask1** is woken up after 10 ticks.) Enable **ExampleSemTask1** to request the semaphore in permanent block mode after it is woken up 10 ticks later. (Because the semaphore is still held by **ExampleSemTask2**, **ExampleSemTask1** is suspended.)
4. After 20 ticks, **ExampleSemTask2** is woken up and releases the semaphore. **ExampleSemTask1** acquires the semaphore and is scheduled to run. When **ExampleSemTask1** is complete, it releases the semaphore. 4. After 20 ticks, **ExampleSemTask2** is woken up and releases the semaphore. **ExampleSemTask1** acquires the semaphore and is scheduled to run. When **ExampleSemTask1** is complete, it releases the semaphore.
5. Task **ExampleSem** is woken up after 400 ticks and deletes the semaphore.
### Sample Code<a name="section1742105514512"></a> 5. Task **ExampleSem** is woken up after 400 ticks. After that, delete the semaphore.
### Sample Code
The sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **ExampleSem** function is called in **TestTaskEntry**.
The sample code is as follows: The sample code is as follows:
...@@ -144,33 +135,34 @@ static UINT32 g_testTaskId01; ...@@ -144,33 +135,34 @@ static UINT32 g_testTaskId01;
static UINT32 g_testTaskId02; static UINT32 g_testTaskId02;
/* Task priority */ /* Task priority */
#define TASK_PRIO_TEST 5 #define TASK_PRIO_LOW 5
#define TASK_PRIO_HI 4
/* Semaphore structure ID*/ /* Semaphore structure ID */
static UINT32 g_semId; static UINT32 g_semId;
VOID ExampleSemTask1(VOID) VOID ExampleSemTask1(VOID)
{ {
UINT32 ret; UINT32 ret;
printf("ExampleSemTask1 try get sem g_semId, timeout 10 ticks.\n"); dprintf("ExampleSemTask1 try get sem g_semId, timeout 10 ticks.\n");
/* Request the semaphore in scheduled block mode, with a wait timeout period of 10 ticks.*/ /* Request the semaphore in scheduled block mode, with a wait timeout period of 10 ticks. */
ret = LOS_SemPend(g_semId, 10); ret = LOS_SemPend(g_semId, 10);
/* The semaphore is acquired. */
/* The semaphore is acquired.*/
if (ret == LOS_OK) { if (ret == LOS_OK) {
LOS_SemPost(g_semId); LOS_SemPost(g_semId);
return; return;
} }
/* The semaphore is not acquired when the timeout period has expired.*/ /* The semaphore is not acquired when the timeout period has expired. */
if (ret == LOS_ERRNO_SEM_TIMEOUT) { if (ret == LOS_ERRNO_SEM_TIMEOUT) {
printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); dprintf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n");
/* Request the semaphore in permanent block mode.*/ /* Request the semaphore in permanent block mode. */
ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); dprintf("ExampleSemTask1 wait_forever and get sem g_semId.\n");
if (ret == LOS_OK) { if (ret == LOS_OK) {
dprintf("ExampleSemTask1 post sem g_semId.\n");
LOS_SemPost(g_semId); LOS_SemPost(g_semId);
return; return;
} }
...@@ -180,20 +172,19 @@ VOID ExampleSemTask1(VOID) ...@@ -180,20 +172,19 @@ VOID ExampleSemTask1(VOID)
VOID ExampleSemTask2(VOID) VOID ExampleSemTask2(VOID)
{ {
UINT32 ret; UINT32 ret;
printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); dprintf("ExampleSemTask2 try get sem g_semId wait forever.\n");
/* Request the semaphore in permanent block mode.*/ /* Request the semaphore in permanent block mode. */
ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
if (ret == LOS_OK) { if (ret == LOS_OK) {
printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); dprintf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n");
} }
/* Enable the task to enter sleep mode for 20 ticks.*/ /* Enable the task to enter sleep mode for 20 ticks. */
LOS_TaskDelay(20); LOS_TaskDelay(20);
printf("ExampleSemTask2 post sem g_semId.\n"); dprintf("ExampleSemTask2 post sem g_semId.\n");
/* Release the semaphore.*/ /* Release the semaphore. */
LOS_SemPost(g_semId); LOS_SemPost(g_semId);
return; return;
} }
...@@ -204,42 +195,45 @@ UINT32 ExampleSem(VOID) ...@@ -204,42 +195,45 @@ UINT32 ExampleSem(VOID)
TSK_INIT_PARAM_S task1; TSK_INIT_PARAM_S task1;
TSK_INIT_PARAM_S task2; TSK_INIT_PARAM_S task2;
/* Create a semaphore.*/ /* Create a semaphore. */
LOS_SemCreate(0, &g_semId); LOS_SemCreate(0, &g_semId);
/* Lock task scheduling.*/ /* Lock task scheduling. */
LOS_TaskLock(); LOS_TaskLock();
/* Create task 1.*/ /* Create task 1. */
(VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1;
task1.pcName = "TestTask1"; task1.pcName = "TestTask1";
task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
task1.usTaskPrio = TASK_PRIO_TEST; task1.usTaskPrio = TASK_PRIO_LOW;
ret = LOS_TaskCreate(&g_testTaskId01, &task1); ret = LOS_TaskCreate(&g_testTaskId01, &task1);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task1 create failed .\n"); dprintf("task1 create failed .\n");
return LOS_NOK; return LOS_NOK;
} }
/* Create task 2.*/ /* Create task 2. */
(VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2;
task2.pcName = "TestTask2"; task2.pcName = "TestTask2";
task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
task2.usTaskPrio = (TASK_PRIO_TEST - 1); task2.usTaskPrio = TASK_PRIO_HI;
ret = LOS_TaskCreate(&g_testTaskId02, &task2); ret = LOS_TaskCreate(&g_testTaskId02, &task2);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task2 create failed.\n"); dprintf("task2 create failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* Unlock task scheduling.*/ /* Unlock task scheduling. */
LOS_TaskUnlock(); LOS_TaskUnlock();
/* Enable the task to enter sleep mode for 400 ticks. */
LOS_TaskDelay(400);
ret = LOS_SemPost(g_semId); ret = LOS_SemPost(g_semId);
/* Enable the task to enter sleep mode for 400 ticks.*/ /* Enable the task to enter sleep mode for 400 ticks. */
LOS_TaskDelay(400); LOS_TaskDelay(400);
/* Delete the semaphore. */ /* Delete the semaphore. */
...@@ -248,16 +242,18 @@ UINT32 ExampleSem(VOID) ...@@ -248,16 +242,18 @@ UINT32 ExampleSem(VOID)
} }
``` ```
### Verification<a name="section11297301617"></a>
### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
ExampleSemTask2 try get sem g_semId wait forever. ExampleSemTask2 try get sem g_semId wait forever.
ExampleSemTask2 get sem g_semId and then delay 20 ticks.
ExampleSemTask1 try get sem g_semId, timeout 10 ticks. ExampleSemTask1 try get sem g_semId, timeout 10 ticks.
ExampleSemTask1 timeout and try get sem g_semId wait forever. ExampleSemTask1 timeout and try get sem g_semId wait forever.
ExampleSemTask2 get sem g_semId and then delay 20 ticks.
ExampleSemTask2 post sem g_semId. ExampleSemTask2 post sem g_semId.
ExampleSemTask1 wait_forever and get sem g_semId. ExampleSemTask1 wait_forever and get sem g_semId.
ExampleSemTask1 post sem g_semId.
``` ```
# Futex # Futex
## Basic Concepts<a name="section643519912920"></a> ## Basic Concepts
Fast userspace mutex \(futex\) is a system call capability provided by the kernel. It is a basic component that combines with user-mode lock logic to form a user-mode lock. It is a lock working in both user mode and kernel mode, for example, userspace mutex, barrier and cond synchronization lock, and RW lock. The user-mode part implements lock logic, and the kernel-mode part schedules locks. Fast userspace mutex (futex) is a system call capability provided by the kernel. It is a basic component that combines with user-mode lock logic to form a user-mode lock. It is a lock working in both user mode and kernel mode, for example, userspace mutex, barrier and cond synchronization lock, and RW lock. The user-mode part implements lock logic, and the kernel-mode part schedules locks.
When a user-mode thread requests a lock, the lock status is first checked in user space. If no lock contention occurs, the user-mode thread acquires the lock directly. If lock contention occurs, the futex system call is invoked to request the kernel to suspend the thread and maintain the blocking queue. When a user-mode thread requests a lock, the lock status is first checked in user space. If no lock contention occurs, the user-mode thread acquires the lock directly. If lock contention occurs, the futex system call is invoked to request the kernel to suspend the thread and maintain the blocking queue.
When a user-mode thread releases a lock, the lock status is first checked in user space. If no other thread is blocked by the lock, the lock is directly released in user space. If there are threads blocked by the lock, the futex system call is invoked to request the kernel to wake up the threads in the blocking queue. When a user-mode thread releases a lock, the lock status is first checked in user space. If no other thread is blocked by the lock, the lock is directly released in user space. If there are threads blocked by the lock, the futex system call is invoked to request the kernel to wake up the threads in the blocking queue.
## Working Principles<a name="section16834132502910"></a>
## Working Principles
When thread scheduling is required to resolve lock contention or lock release in user space, the futex system call is invoked to pass the user-mode lock address to the kernel. The user-mode locks are distinguished by lock address in the futex of the kernel. The available virtual address space in user space is 1 GiB. To facilitate search and management of lock addresses, the kernel futex uses hash buckets to store the user-mode locks. When thread scheduling is required to resolve lock contention or lock release in user space, the futex system call is invoked to pass the user-mode lock address to the kernel. The user-mode locks are distinguished by lock address in the futex of the kernel. The available virtual address space in user space is 1 GiB. To facilitate search and management of lock addresses, the kernel futex uses hash buckets to store the user-mode locks.
There are 80 hash buckets. Buckets 0 to 63 are used to store private locks \(hashed based on virtual addresses\), and buckets 64 to 79 are used to store shared locks \(hashed based on physical addresses\). The private/shared attributes are determined by initialization of user-mode locks and the input parameters in the futex system call. There are 80 hash buckets used to store shared locks (hashed based on physical addresses). The private/shared attributes are determined by initialization of user-mode locks and the input parameters in the futex system call.
## Futex Design
**Figure 1** Futex design
**Figure 1** Futex design<a name="fig651353710598"></a>
![](figures/futex-design.jpg "futex-design") ![](figures/futex-design.jpg "futex-design")
As shown in the above figure, each futex hash bucket stores the futex nodes with the same hash value linked in a futex\_list. Each futex node corresponds to a suspended task. The key value of a node uniquely identifies a user-mode lock. The nodes with the same key value added to a queue\_list indicate a queue of tasks blocked by the same lock. As shown in the above figure, each futex hash bucket stores the futex nodes with the same hash value linked in a futex_list. Each futex node corresponds to a suspended task. The key value of a node uniquely identifies a user-mode lock. The nodes with the same key value added to a queue_list indicate a queue of tasks blocked by the same lock.
The following table describes the APIs available for the futex module. ## Available APIs
**Table 1** Futex module APIs APIs of the futex module
<a name="table1316220185211"></a> | Category | API | Description |
<table><thead align="left"><tr id="row191622182021"><th class="cellrowborder" valign="top" width="27.09270927092709%" id="mcps1.2.4.1.1"><p id="p13162121815218"><a name="p13162121815218"></a><a name="p13162121815218"></a>Function</p> | -------------- | -------------- | ------------------------------------- |
</th> | Putting a thread to wait | OsFutexWait | Inserts a node representing a blocked thread into the futex list.|
<th class="cellrowborder" valign="top" width="26.52265226522652%" id="mcps1.2.4.1.2"><p id="p12162618623"><a name="p12162618623"></a><a name="p12162618623"></a>API</p> | Waking up a thread| OsFutexWake | Wakes up a thread that is blocked by a specified lock. |
</th> | Modifying the lock address | OsFutexRequeue | Adjusts the position of a specified lock in the futex list. |
<th class="cellrowborder" valign="top" width="46.384638463846386%" id="mcps1.2.4.1.3"><p id="p16162118427"><a name="p16162118427"></a><a name="p16162118427"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row04981218910"><td class="cellrowborder" valign="top" width="27.09270927092709%" headers="mcps1.2.4.1.1 "><p id="p6462616696"><a name="p6462616696"></a><a name="p6462616696"></a>Putting a thread to wait</p>
</td>
<td class="cellrowborder" valign="top" width="26.52265226522652%" headers="mcps1.2.4.1.2 "><p id="p164931214913"><a name="p164931214913"></a><a name="p164931214913"></a>OsFutexWait</p>
</td>
<td class="cellrowborder" valign="top" width="46.384638463846386%" headers="mcps1.2.4.1.3 "><p id="p8504121996"><a name="p8504121996"></a><a name="p8504121996"></a>Inserts a node representing a blocked thread into the futex list.</p>
</td>
</tr>
<tr id="row7162101814216"><td class="cellrowborder" valign="top" width="27.09270927092709%" headers="mcps1.2.4.1.1 "><p id="p37331032985"><a name="p37331032985"></a><a name="p37331032985"></a>Waking up a thread</p>
</td>
<td class="cellrowborder" valign="top" width="26.52265226522652%" headers="mcps1.2.4.1.2 "><p id="p816311185217"><a name="p816311185217"></a><a name="p816311185217"></a>OsFutexWake</p>
</td>
<td class="cellrowborder" valign="top" width="46.384638463846386%" headers="mcps1.2.4.1.3 "><p id="p161632181721"><a name="p161632181721"></a><a name="p161632181721"></a>Wakes up a thread that is blocked by a specified lock.</p>
</td>
</tr>
<tr id="row101631818620"><td class="cellrowborder" valign="top" width="27.09270927092709%" headers="mcps1.2.4.1.1 "><p id="p146111936887"><a name="p146111936887"></a><a name="p146111936887"></a>Modifying the lock address</p>
</td>
<td class="cellrowborder" valign="top" width="26.52265226522652%" headers="mcps1.2.4.1.2 "><p id="p71633181125"><a name="p71633181125"></a><a name="p71633181125"></a>OsFutexRequeue</p>
</td>
<td class="cellrowborder" valign="top" width="46.384638463846386%" headers="mcps1.2.4.1.3 "><p id="p151631718124"><a name="p151631718124"></a><a name="p151631718124"></a>Adjusts the position of a specified lock in the futex list.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>The futex system call and user-mode logic form a user-mode lock. Therefore, you are advised to use the locks via the user-mode POSIX APIs.
> **NOTE**<br>
> The futex system call and user-mode logic form a user-mode lock. Therefore, you are advised to use the locks via the user-mode POSIX APIs.
# Signal # Signal
## Basic Concepts<a name="section172788254307"></a> ## Basic Concepts
Signal is a common inter-process asynchronous communication mechanism. It uses software-simulated interrupt signals. When a process needs to communicate with another process, it sends a signal to the kernel. The kernel then transfers the signal to the destination process. The destination process does not need to wait for the signal. Signal is a common asynchronous communication mechanism between processes. It uses software-simulated interrupt signals. When a process needs to communicate with another process, it sends a signal to the kernel. The kernel transfers the signal to the target process. The target process does not need to wait for the signal.
## Working Principles<a name="section1249693812301"></a>
The following table describes the APIs available for signal operations. ## Working Principles
**Table 1** Signal operation process and APIs \(user-mode APIs\) The following table describes the APIs for signal operations.
<a name="table1316220185211"></a> **Table 1** Signal APIs (user-mode APIs)
<table><thead align="left"><tr id="row191622182021"><th class="cellrowborder" valign="top" width="27.09270927092709%" id="mcps1.2.4.1.1"><p id="p13162121815218"><a name="p13162121815218"></a><a name="p13162121815218"></a>Function</p>
</th>
<th class="cellrowborder" valign="top" width="26.49264926492649%" id="mcps1.2.4.1.2"><p id="p12162618623"><a name="p12162618623"></a><a name="p12162618623"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="46.41464146414641%" id="mcps1.2.4.1.3"><p id="p16162118427"><a name="p16162118427"></a><a name="p16162118427"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row04981218910"><td class="cellrowborder" rowspan="2" valign="top" width="27.09270927092709%" headers="mcps1.2.4.1.1 "><p id="p6462616696"><a name="p6462616696"></a><a name="p6462616696"></a>Registering the signal callback</p>
</td>
<td class="cellrowborder" valign="top" width="26.49264926492649%" headers="mcps1.2.4.1.2 "><p id="p164931214913"><a name="p164931214913"></a><a name="p164931214913"></a>signal</p>
</td>
<td class="cellrowborder" valign="top" width="46.41464146414641%" headers="mcps1.2.4.1.3 "><p id="p8504121996"><a name="p8504121996"></a><a name="p8504121996"></a>Registers the main signal entry, and registers and unregisters the callback function of a signal.</p>
</td>
</tr>
<tr id="row5449183942119"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p5450153922110"><a name="p5450153922110"></a><a name="p5450153922110"></a>sigaction</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1945083962113"><a name="p1945083962113"></a><a name="p1945083962113"></a>Same as <strong id="b1076755712371"><a name="b1076755712371"></a><a name="b1076755712371"></a>signal</strong>. This API is added with configuration options related to signal transmission. Currently, only some parameters in the <strong id="b18458105019218"><a name="b18458105019218"></a><a name="b18458105019218"></a>SIGINFO</strong> structure are supported.</p>
</td>
</tr>
<tr id="row7162101814216"><td class="cellrowborder" rowspan="5" valign="top" width="27.09270927092709%" headers="mcps1.2.4.1.1 "><p id="p37331032985"><a name="p37331032985"></a><a name="p37331032985"></a>Sending signals</p>
</td>
<td class="cellrowborder" valign="top" width="26.49264926492649%" headers="mcps1.2.4.1.2 "><p id="p816311185217"><a name="p816311185217"></a><a name="p816311185217"></a>kill</p>
</td>
<td class="cellrowborder" rowspan="5" align="left" valign="top" width="46.41464146414641%" headers="mcps1.2.4.1.3 "><p id="p161632181721"><a name="p161632181721"></a><a name="p161632181721"></a>Sends a signal to a process or sends messages to a thread in a process, and sets signal flags for threads in a process.</p>
</td>
</tr>
<tr id="row129182420243"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p149191745248"><a name="p149191745248"></a><a name="p149191745248"></a>pthread_kill</p>
</td>
</tr>
<tr id="row1026214719240"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1226313762411"><a name="p1226313762411"></a><a name="p1226313762411"></a>raise</p>
</td>
</tr>
<tr id="row05632094242"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p45643914245"><a name="p45643914245"></a><a name="p45643914245"></a>alarm</p>
</td>
</tr>
<tr id="row3241512122417"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p324211202414"><a name="p324211202414"></a><a name="p324211202414"></a>abort</p>
</td>
</tr>
<tr id="row101631818620"><td class="cellrowborder" valign="top" width="27.09270927092709%" headers="mcps1.2.4.1.1 "><p id="p146111936887"><a name="p146111936887"></a><a name="p146111936887"></a>Triggering a callback</p>
</td>
<td class="cellrowborder" valign="top" width="26.49264926492649%" headers="mcps1.2.4.1.2 "><p id="p71633181125"><a name="p71633181125"></a><a name="p71633181125"></a>None</p>
</td>
<td class="cellrowborder" valign="top" width="46.41464146414641%" headers="mcps1.2.4.1.3 "><p id="p1126941694213"><a name="p1126941694213"></a><a name="p1126941694213"></a>Triggered by a system call or an interrupt. Before the switching between the kernel mode and user mode, the specified function in user mode is entered, and the corresponding callbacks are processed. After that, the original user-mode program continues to run.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:** | Category | API | Description |
>The signal mechanism enables communication between user-mode programs. The user-mode POSIX APIs listed in the above table are recommended. | ---------------- | --------------------------------------------------- | ------------------------------------------------------------ |
>Register a callback function. | Registering/Unregistering a signal callback| signal | Registers the main signal entry, and registers or unregisters a callback for a signal. |
>``` | Registering a signal callback| sigaction | Same as **signal**. This API is added with configuration options related to signal transmission. Currently, only some parameters in the **SIGINFO** structure are supported.|
>void *signal(int sig, void (*func)(int))(int); | Sending a signal | kill<br>pthread_kill<br>raise<br>alarm<br>abort | Sends a signal to a process or sends a message to a thread in a process, and sets the signal flag for a thread in a process. |
>``` | Invoking a callback | NA | Called by a system call or an interrupt. Before the switching between the kernel mode and user mode, the callback in the specified function in user mode is processed. After that, the original user-mode program continues to run.|
>a. Signal 31 is used to register the handling entry of the process callback. Repeated registration is not allowed.
>b. Signals 0 to 30 are used to register and unregister callbacks.
>Register a callback.
>```
>int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict);
>```
>You can obtain and modify the configuration of signal registration. Currently, only the **SIGINFO** options are supported. For details, see the description of the **sigtimedwait** API.
>Transmit a signal.
>a. Among the default signal-receiving behaviors, the process does not support **STOP**, **CONTINUE**, and **COREDUMP** defined in the POSIX standard.
>b. The **SIGSTOP**, **SIGKILL**, and **SIGCONT** signals cannot be shielded.
>c. If a process killed is not reclaimed by its parent process, the process becomes a zombie process.
>d. A process will not call back the signal received until the process is scheduled.
>e. When a process is killed, **SIGCHLD** is sent to its parent process. The signal sending action cannot be canceled.
>f. A process in the DELAY state cannot be woken up by a signal.
> **NOTE**<br>
> The signal mechanism enables communication between user-mode programs. The user-mode POSIX APIs listed in the above table are recommended.
>
> **Registering a Callback**
>
>
> ```
> void *signal(int sig, void (*func)(int))(int);
> ```
>
> - Signal 31 is used to register the handling entry of the process callback. Repeated registration is not allowed.
>
>
> - Signals 0 to 30 are used to register and unregister callbacks.
>
>
> **Registering a Callback**
>
>
> ```
> int sigaction(int, const struct sigaction ***restrict, struct sigaction ***restrict);
> ```
>
> You can obtain and modify the configuration of signal registration. Currently, only the **SIGINFO** options are supported. For details, see the description of the **sigtimedwait** API.
>
> **Sending a Signal**
>
> - Among the default signal-receiving behaviors, the process does not support **STOP**, **COTINUE**, and **COREDUMP** defined in POSIX.
>
>
> - The **SIGSTOP**, **SIGKILL**, and **SIGCONT** signals cannot be shielded.
>
>
> - If a process killed is not reclaimed by its parent process, the process becomes a zombie process.
>
>
> - A process will not call back the signal received until the process is scheduled.
>
>
> - When a process is killed, **SIGCHLD** is sent to its parent process. The signal sending action cannot be canceled.
>
>
> - A process in the DELAY state cannot be woken up by a signal.
# LiteIPC # LiteIPC
## Basic Concepts<a name="section1980994712918"></a> ## Basic Concepts
LiteIPC is a new inter-process communication \(IPC\) mechanism provided by the OpenHarmony LiteOS-A kernel. Different from the traditional System V IPC, LiteIPC is designed for Remote Procedure Call \(RPC\). In addition, it provides APIs for the upper layer through device files, not through traditional API functions.
LiteIPC has two important concepts: ServiceManager and Service. The entire system can have one ServiceManager and multiple Services. ServiceManager is responsible for registering and unregistering Services, and managing Service access permission \(only authorized tasks can send IPC messages to corresponding Services\).
## Working Principles<a name="section849811592918"></a>
ServiceManager registers the task that needs to receive IPC messages as a Service, and sets the access permission for the Service task \(specifies the tasks that can send IPC messages to the Service\). LiteIPC maintains an IPC message queue for each Service task in kernel mode. The message queue provides the upper-layer user-mode programs with the read operation \(receiving IPC messages\) and the write operations \(sending IPC messages\) through LiteIPC device files.
## Development Guidelines<a name="section17571315171017"></a>
### Available APIs<a name="section725022011103"></a>
**Table 1** LiteIPC module APIs \(for LiteOS-A internal use only\)
<a name="table1415203765610"></a>
<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Function</p>
</th>
<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row0415737175610"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p8866127195914"><a name="p8866127195914"></a><a name="p8866127195914"></a>Module initialization</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p58621910185914"><a name="p58621910185914"></a><a name="p58621910185914"></a>OsLiteIpcInit</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p48623102592"><a name="p48623102592"></a><a name="p48623102592"></a>Initializes the LiteIPC module.</p>
</td>
</tr>
<tr id="row1213865218584"><td class="cellrowborder" rowspan="3" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p1219312239566"><a name="p1219312239566"></a><a name="p1219312239566"></a>IPC message memory pool</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p20862510115911"><a name="p20862510115911"></a><a name="p20862510115911"></a>LiteIpcPoolInit</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1886211011599"><a name="p1886211011599"></a><a name="p1886211011599"></a>Initializes the IPC message memory pool of processes.</p>
</td>
</tr>
<tr id="row3231257145813"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3313428135414"><a name="p3313428135414"></a><a name="p3313428135414"></a>LiteIpcPoolReInit</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p586261085913"><a name="p586261085913"></a><a name="p586261085913"></a>Re-initializes the IPC message memory pool of processes.</p>
</td>
</tr>
<tr id="row73651459105815"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p464344145411"><a name="p464344145411"></a><a name="p464344145411"></a>LiteIpcPoolDelete</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p555221518598"><a name="p555221518598"></a><a name="p555221518598"></a>Releases the IPC message memory pool of processes.</p>
</td>
</tr>
<tr id="row178321454145812"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p19527545175517"><a name="p19527545175517"></a><a name="p19527545175517"></a>Service management</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p756845455415"><a name="p756845455415"></a><a name="p756845455415"></a>LiteIpcRemoveServiceHandle</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1555261595915"><a name="p1555261595915"></a><a name="p1555261595915"></a>Deletes the specified Service.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>LiteIPC module APIs are used for LiteOS-A internal use only.
LiteIPC is a new inter-process communication (IPC) mechanism provided by the OpenHarmony LiteOS-A kernel. Different from the traditional System V IPC, LiteIPC is designed for Remote Procedure Call (RPC). In addition, it provides APIs for the upper layer through device files, not through traditional API functions.
LiteIPC has two important concepts: ServiceManager and Service. The entire system can have one ServiceManager and multiple Services.
ServiceManager provides the following functions:
- Registers and deregisters services.
- Manages the access permission of services. Only authorized tasks can send IPC messages to the service.
## Working Principles
ServiceManager registers the task that needs to receive IPC messages as a Service, and sets the access permission for the Service task (specifies the tasks that can send IPC messages to the Service).
LiteIPC maintains an IPC message queue for each Service task in kernel mode. The message queue provides the upper-layer user-mode programs with the read operation (receiving IPC messages) and the write operations (sending IPC messages) through LiteIPC device files.
## Development Guidelines
### Available APIs
**Table 1** APIs of the LiteIPC module (applicable to LiteOS-A only)
| Category | API Description |
| ------------- | ------------------------------------------------------------ |
| Module initialization | **OsLiteIpcInit**: initializes the LiteIPC module. |
| IPC message memory pool| - **LiteIpcPoolInit**: initializes the IPC message memory pool of a process.<br>- **LiteIpcPoolReInit**: reinitializes the IPC message memory pool of a process.<br>- **LiteIpcPoolDelete**: releases the IPC message memory pool of a process. |
| Service management | **LiteIpcRemoveServiceHandle**: deletes a service. |
> **NOTE**<br>
> The APIs of the LiteIPC module are dedicated for LiteOS-A internal use only.
# Dynamic Loading and Linking # Dynamic Loading and Linking
## Basic Concepts<a name="section208951139453"></a>
## Basic Concepts
The OpenHarmony dynamic loading and linking mechanism includes a kernel loader and a dynamic linker. The kernel loader loads application programs and the dynamic linker. The dynamic linker loads the shared library on which the application programs depend, and performs symbol relocation for the application programs and shared libraries. Compared with static linking, dynamic linking is a mechanism for delaying the linking of applications and dynamic libraries to run time. The OpenHarmony dynamic loading and linking mechanism includes a kernel loader and a dynamic linker. The kernel loader loads application programs and the dynamic linker. The dynamic linker loads the shared library on which the application programs depend, and performs symbol relocation for the application programs and shared libraries. Compared with static linking, dynamic linking is a mechanism for delaying the linking of applications and dynamic libraries to run time.
**Advantages of Dynamic Linking** **Advantages of Dynamic Linking**
1. Dynamic linking allows multiple applications to share code. The minimum loading unit is page. Dynamic linking saves disk and memory space than static linking. - Dynamic linking allows multiple applications to share code. The minimum loading unit is page. Dynamic linking saves disk and memory space than static linking.
2. When a shared library is upgraded, the new shared library overwrites the earlier version \(the APIs of the shared library are downward compatible\). You do not need to re-link the shared library.
3. The loading address can be randomized to prevent attacks and ensure security. - When a shared library is upgraded, the new shared library overwrites the earlier version (the APIs of the shared library are downward compatible). You do not need to re-link the shared library.
- The loading address can be randomized to prevent attacks and ensure security.
## Working Principles<a name="section14140155320511"></a> ## Working Principles
**Figure 1** Dynamic loading process
**Figure 1** Dynamic loading process<a name="fig1797764116422"></a>
![](figures/dynamic-loading-process.png "dynamic-loading-process") ![](figures/dynamic-loading-process.png "dynamic-loading-process")
1. The kernel maps the **PT\_LOAD** section in the ELF file of the application to the process space. For files of the ET\_EXEC type, fixed address mapping is performed based on **p\_vaddr** in the **PT\_LOAD** section. For files of the ET\_DYN type \(position-independent executable programs, obtained through the compile option **-fPIE**\), the kernel selects the **base** address via **mmap** for mapping \(load\_addr = base + p\_vaddr\). 1. The kernel maps the **PT_LOAD** section in the ELF file of the application to the process space. For files of the ET_EXEC type, fixed address mapping is performed based on **p_vaddr** in the **PT_LOAD** section. For files of the ET_DYN type (position-independent executable programs, obtained through **-fPIE**), the kernel selects the **base** address via **mmap** for mapping (load_addr = base + p_vaddr).
2. If the application is statically linked \(static linking does not support the compile option **-fPIE**\), after the stack information is set, the system redirects to the address specified by **e\_entry** in the ELF file of the application and runs the application. If the program is dynamically linked, the application ELF file contains the **PT\_INTERP** section, which stores the dynamic linker path information \(ET\_DYN type\). The dynamic linker of musl is a part of the **libc-musl.so**. The entry of **libc-musl.so** is the entry of the dynamic linker. The kernel selects the **base** address for mapping via the **mmap** API, sets the stack information, redirects to the **base + e\_entry** \(entry of the dynamic linker\) address, and runs the dynamic linker.
3. The dynamic linker bootstraps and searches for all shared libraries on which the application depends, relocates the imported symbols, and finally redirects to the **e\_entry** \(or **base + e\_entry**\) of the application to run the application. 2. If the application is statically linked (static linking does not support **-fPIE**), after the stack information is set, the system redirects to the address specified by **e_entry** in the ELF file of the application and runs the application. If the program is dynamically linked, the application ELF file contains the **PT_INTERP** section, which stores the dynamic linker path information (ET_DYN type). The dynamic linker of musl is a part of the **libc-musl.so**. The entry of **libc-musl.so** is the entry of the dynamic linker. The kernel selects the **base** address for mapping via the **mmap** API, sets the stack information, redirects to the **base + e_entry** (entry of the dynamic linker) address, and runs the dynamic linker.
3. The dynamic linker bootstraps and searches for all shared libraries on which the application depends, relocates the imported symbols, and finally redirects to the **e_entry** (or **base + e_entry**) of the application to run the application.
**Figure 2** Program execution process
**Figure 2** Program execution process<a name="fig17879151310447"></a>
![](figures/program-execution-process.png "program-execution-process") ![](figures/program-execution-process.png "program-execution-process")
1. The loader and linker call **mmap** to map the **PT\_LOAD** section. 1. The loader and linker call **mmap** to map the **PT_LOAD** section.
2. The kernel calls **map\_pages** to search for and map the existing PageCache.
2. The kernel calls **map_pages** to search for and map the existing PageCache.
3. If there is no physical memory for mapping in the virtual memory region during program execution, the system triggers a page missing interrupt, which allows the ELF file to be read into the physical memory and adds the memory block to the pagecache. 3. If there is no physical memory for mapping in the virtual memory region during program execution, the system triggers a page missing interrupt, which allows the ELF file to be read into the physical memory and adds the memory block to the pagecache.
4. Map the physical memory blocks of the file read to the virtual address region. 4. Map the physical memory blocks of the file read to the virtual address region.
5. The program continues to run. 5. The program continues to run.
## Development Guidelines<a name="section133501496612"></a>
### Available APIs<a name="section874113201669"></a> ## Development Guidelines
### Available APIs
**Table 1** APIs of the kernel loader module **Table 1** API of the kernel loader module
<a name="table1415203765610"></a> | Category | API | Description |
<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>Function</p> | ---------- | ---------------- | -------------------------------- |
</th> | Starting initialization| LOS_DoExecveFile | Executes the specified user program based on the input parameters.|
<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row0415737175610"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p8866127195914"><a name="p8866127195914"></a><a name="p8866127195914"></a>Module initialization</p>
</td>
<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p58621910185914"><a name="p58621910185914"></a><a name="p58621910185914"></a>LOS_DoExecveFile</p>
</td>
<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p48623102592"><a name="p48623102592"></a><a name="p48623102592"></a>Executes the specified user program based on the input parameters.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section196712561563"></a>
The kernel cannot directly call the **LOS\_DoExecveFile** API to start a new process. This API is generally called through the **exec\(\)** API to create a new process using the system call mechanism. ### How to Develop
The kernel cannot directly call the **LOS_DoExecveFile** API to start a new process. This API is generally called through the **exec()** API to create a new process using the system call mechanism.
# Virtual Dynamic Shared Object # Virtual Dynamic Shared Object
## Basic Concepts<a name="section174577181688"></a>
Different from a common dynamic shared library, which stores its .so files in the file system, the virtual dynamic shared object \(VDSO\) has its .so files stored in the system image. The kernel determines the .so files needed and provides them to the application program. That is why the VDSO is called a virtual dynamic shared library. ## Basic Concepts
The VDSO mechanism allows OpenHarmony user-mode programs to quickly obtain kernel-related data. It can accelerate certain system calls and implement quick read of non-sensitive data \(hardware and software configuration\). Different from a common dynamic shared library, which stores its .so files in the file system, the virtual dynamic shared object (VDSO) has its .so files stored in the system image. The kernel determines the .so files needed and provides them to the application program. That is why the VDSO is called a virtual dynamic shared library.
## Working Principles<a name="section546363114810"></a> The VDSO mechanism allows OpenHarmony user-mode programs to quickly obtain kernel-related data. It can accelerate certain system calls and implement quick read of non-sensitive data (hardware and software configuration).
The VDSO can be regarded as a section of memory \(read-only\) maintained by the kernel and mapped to the address space of the user-mode applications. By linking **vdso.so**, the applications can directly access this mapped memory instead of invoking system calls, accelerating application execution.
## Working Principles
The VDSO can be regarded as a section of memory (read-only) maintained by the kernel and mapped to the address space of the user-mode applications. By linking **vdso.so**, the applications can directly access this mapped memory instead of invoking system calls, accelerating application execution.
VDSO can be divided into: VDSO can be divided into:
- Data page: provides the kernel-time data mapped to the user process. - Data page: provides the kernel-time data mapped to the user process.
- Code page: provides the logic for shielding system calls. - Code page: provides the logic for shielding system calls.
**Figure 1** VDSO system design<a name="fig1986131094711"></a> **Figure 1** VDSO system design
![](figures/vdso-system-design.jpg "vdso-system-design") ![](figures/vdso-system-design.jpg "vdso-system-design")
The VDSO mechanism involves the following steps: The VDSO mechanism involves the following steps:
...@@ -30,7 +33,7 @@ The VDSO mechanism involves the following steps: ...@@ -30,7 +33,7 @@ The VDSO mechanism involves the following steps:
5. Binds the VDSO symbols when the user program creates dynamic linking. 5. Binds the VDSO symbols when the user program creates dynamic linking.
6. The VDSO code page intercepts specific system calls \(for example, **clock\_gettime\(CLOCK\_REALTIME\_COARSE, &ts\)**\). 6. The VDSO code page intercepts specific system calls (for example, **clock_gettime(CLOCK_REALTIME_COARSE, &amp;ts)**).
7. The VDSO code page allows direct read of the mapped VDSO data page rather than invoking a system call. 7. The VDSO code page allows direct read of the mapped VDSO data page rather than invoking a system call.
...@@ -38,7 +41,10 @@ The VDSO mechanism involves the following steps: ...@@ -38,7 +41,10 @@ The VDSO mechanism involves the following steps:
9. Returns the data obtained from the VDSO data page to the user program. 9. Returns the data obtained from the VDSO data page to the user program.
>![](../public_sys-resources/icon-note.gif) **NOTE:** > **NOTE**<br>
>- The VDSO mechanism supports the **CLOCK\_REALTIME\_COARSE** and **CLOCK\_MONOTONIC\_COARSE** functions of the **clock\_gettime** API in the LibC library. For details about how to use the **clock\_gettime** API, see the POSIX standard. You can call **clock\_gettime\(CLOCK\_REALTIME\_COARSE, &ts\)** or **clock\_gettime\(CLOCK\_MONOTONIC\_COARSE, &ts\)** of the LibC library to use the VDSO. >
>- When VDSO is used, the time precision is the same as that of the tick interrupt of the system. The VDSO mechanism is applicable to the scenario where there is no demand for high time precision and **clock\_gettime** or **gettimeofday** is frequently triggered in a short period of time. The VDSO mechanism is not recommended for the system demanding high time precision. > - The VDSO mechanism supports the **CLOCK_REALTIME_COARSE** and **CLOCK_MONOTONIC_COARSE** functions of the **clock_gettime** API in the LibC library. For details about how to use the **clock_gettime** API, see the POSIX standard.
>
> - You can call **clock_gettime(CLOCK_REALTIME_COARSE, &amp;ts)** or **clock_gettime(CLOCK_MONOTONIC_COARSE, &amp;ts)** of the Libc library to use the VDSO.
>
> - When VDSO is used, the time precision is the same as that of the tick interrupt of the system. The VDSO mechanism is applicable to the scenario where there is no demand for high time precision and **clock_gettime** or **gettimeofday** is frequently triggered in a short period of time. The VDSO mechanism is not recommended for the system demanding high time precision.
# Memory Corruption Check # Memory Corruption Check
## Basic Concepts<a name="section17368154517335"></a> ## Basic Concepts
As an optional function of the kernel, memory corruption check is used to check the integrity of a dynamic memory pool. This mechanism can detect memory corruption errors in the memory pool in a timely manner and provide alerts. It helps reduce problem locating costs and increase troubleshooting efficiency. As an optional function of the kernel, memory corruption check is used to check the integrity of a dynamic memory pool. This mechanism can detect memory corruption errors in the memory pool in a timely manner and provide alerts. It helps reduce problem locating costs and increase troubleshooting efficiency.
## Function Configuration<a name="section4696190123420"></a>
**LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK**: specifies the setting of the memory corruption check. This function is disabled by default. To enable this function, configure it in **Debug-\> Enable integrity check or not**. ## Function Configuration
**LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** specifies the setting of the memory corruption check. This function is disabled by default. You can enable it in **Debug -> Enable integrity check or not**.
If this macro is enabled, the memory pool integrity will be checked in real time upon each memory allocation. If this macro is enabled, the memory pool integrity will be checked in real time upon each memory allocation.
If this macro is not enabled, you can call **LOS\_MemIntegrityCheck** to check the memory pool integrity when required. Using **LOS\_MemIntegrityCheck** does not affect the system performance. In addition, the check accuracy decreases because the node header does not contain the magic number \(which is available only when **LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK** is enabled\). If this macro is not enabled, you can call **LOS_MemIntegrityCheck** to check the memory pool integrity when required. Using **LOS_MemIntegrityCheck** does not affect the system performance. However, the check accuracy decreases because the node header does not contain the magic number (which is available only when **LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** is enabled).
This check only detects the corrupted memory node and provides information about the previous node (because memory is contiguous, a node is most likely corrupted by the previous node). To further determine the location where the previous node is requested, you need to enable the memory leak check and use LRs to locate the fault.
> **CAUTION**<br/>
> If memory corruption check is enabled, a magic number is added to the node header, which increases the size of the node header. The real-time integrity check has a great impact on the performance. In performance-sensitive scenarios, you are advised to disable this function and use **LOS_MemIntegrityCheck** to check the memory pool integrity.
This check only detects the corrupted memory node and provides information about the previous node \(because memory is contiguous, a node is most likely corrupted by the previous node\). To further determine the location where the previous node is requested, you need to enable the memory leak check and use LRs to locate the fault. ## Development Guidelines
>![](../public_sys-resources/icon-caution.gif) **CAUTION:**
>If memory corruption check is enabled, a magic number is added to the node header, which increases the size of the node header. The real-time integrity check has a great impact on the performance. In performance-sensitive scenarios, you are advised to disable this function and use **LOS\_MemIntegrityCheck** to check the memory pool integrity.
## Development Guidelines<a name="section672362973417"></a> ### How to Develop
### How to Develop<a name="section026014863416"></a> Use **LOS_MemIntegrityCheck** to check for memory corruption. If no memory corruption occurs, **0** is returned and no log is output. If memory corruption occurs, the related log is output. For details, see the output of the following example.
Check for memory corruption by calling **LOS\_MemIntegrityCheck**. If no memory corruption occurs, **0** is returned and no log is output. If memory corruption occurs, the related log is output. For details, see the output of the following example.
### Development Example<a name="section186311302356"></a> ### Development Example
This example implements the following: This example implements the following:
1. Requests two physically adjacent memory blocks. 1. Request two physically adjacent memory blocks.
2. Calls **memset** to construct an out-of-bounds access and overwrites the first four bytes of the next node.
3. Calls **LOS\_MemIntegrityCheck** to check whether memory corruption occurs. 2. Use **memset** to construct an out-of-bounds access and overwrites the first four bytes of the next node.
3. Call **LOS_MemIntegrityCheck** to check for memory corruption.
**Sample Code** **Sample Code**
You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites/kernel/src/osTest.c** for testing.
The sample code is as follows: The sample code is as follows:
```
```c
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "los_memory.h" #include "los_memory.h"
...@@ -44,7 +54,7 @@ The sample code is as follows: ...@@ -44,7 +54,7 @@ The sample code is as follows:
void MemIntegrityTest(void) void MemIntegrityTest(void)
{ {
/* Request two physically adjacent memory blocks.*/ /* Request two physically adjacent memory blocks. */
void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
/* Construct an out-of-bounds access to cause memory corruption. The memory block of the first node is 8 bytes. Clearing 12 bytes overwrites the header of the second memory node. */ /* Construct an out-of-bounds access to cause memory corruption. The memory block of the first node is 8 bytes. Clearing 12 bytes overwrites the header of the second memory node. */
...@@ -55,24 +65,26 @@ void MemIntegrityTest(void) ...@@ -55,24 +65,26 @@ void MemIntegrityTest(void)
**Verification** **Verification**
The log is as follows: The log is as follows:
``` ```
[ERR][OsMemMagicCheckPrint], 2028, memory check error! [ERR][OsMemMagicCheckPrint], 2028, memory check error!
memory used but magic num wrong, magic num = 0x00000000 /* Error information, indicating that the first four bytes, that is, the magic number, of the next node are corrupted.*/ memory used but magic num wrong, magic num = 0x00000000 /* Error information, indicating that the first four bytes, that is, the magic number, of the next node are corrupted. */
broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020 broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020
/* Key information about the corrupted node and its previous node, including the address of the previous node, magic number of the node, and sizeAndFlag of the node. In this example, the magic number of the corrupted node is cleared. */ /* Key information about the corrupted node and its previous node, including the address of the previous node, magic number of the node, and sizeAndFlag of the node. In this example, the magic number of the corrupted node is cleared. */
broken node head LR info: /* The node LR information can be output only after the memory leak check is enabled.*/ broken node head LR info: /* The node LR information can be output only after the memory leak check is enabled. */
LR[0]:0x0800414e LR[0]:0x0800414e
LR[1]:0x08000cc2 LR[1]:0x08000cc2
LR[2]:0x00000000 LR[2]:0x00000000
pre node head LR info: /* Based on the LR information, you can find where the previous node is requested in the assembly file and then perform further analysis.*/ pre node head LR info: /* Based on the LR information, you can find where the previous node is requested in the assembly file and then perform further analysis. */
LR[0]:0x08004144 LR[0]:0x08004144
LR[1]:0x08000cc2 LR[1]:0x08000cc2
LR[2]:0x00000000 LR[2]:0x00000000
[ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* Addresses of the corrupted node and its previous node*/ [ERR]Memory integrity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* Addresses of the corrupted node and its previous node */
``` ```
# Memory Information Statistics # Memory Information Statistics
## Basic Concepts<a name="section52691565235"></a>
## Basic Concepts
Memory information includes the memory pool size, memory usage, remaining memory size, maximum free memory, memory waterline, number of memory nodes, and fragmentation rate. Memory information includes the memory pool size, memory usage, remaining memory size, maximum free memory, memory waterline, number of memory nodes, and fragmentation rate.
- Memory waterline: indicates the maximum memory used in a memory pool. The waterline value is updated upon each memory allocation and release. The memory pool size can be optimized based on this value. - The memory waterline indicates the maximum memory used in a memory pool. The waterline value is updated each time the memory is allocated or released. The memory pool size can be optimized based on this value.
- The fragmentation rate indicates the fragmentation degree of the memory pool. If the fragmentation rate is high, there are a large number of free memory blocks in the memory pool but each block is small. You can use the following formula to calculate the fragmentation rate:<br>Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
- Fragmentation rate: indicates the fragmentation degree of the memory pool. If the fragmentation rate is high, there are a large number of free memory blocks in the memory pool but each block is small. You can use the following formula to calculate the fragmentation rate: - You can use **LOS_MemInfoGet()** to scan the node information in the memory pool and collect the related statistics.
Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
## Function Configuration
- Other statistics: When **LOS\_MemInfoGet** is called, the node information in the memory pool is scanned and related statistics are collected. **LOSCFG_MEM_WATERLINE** specifies the setting of the memory information statistics function. This function is disabled by default. If you want to obtain the memory waterline, enable it in **Debug-&gt; Enable MEM Debug-&gt; Enable memory pool waterline or not**.
## Function Configuration<a name="section470611682411"></a>
**LOSCFG\_MEM\_WATERLINE**: specifies the setting of the memory information statistics function. This function is disabled by default. To enable this function, configure it in **Debug-\> Enable memory pool waterline or not in the configuration item**. If you want to obtain the memory waterline, you must enable this macro. ## Development Guidelines
## Development Guidelines<a name="section9368374243"></a>
### How to Develop<a name="section679912407257"></a> ### How to Develop
Key structure: Key structure:
```
```c
typedef struct { typedef struct {
UINT32 totalUsedSize; // Memory usage of the memory pool UINT32 totalUsedSize; // Memory usage of the memory pool.
UINT32 totalFreeSize; // Remaining memory in the memory pool UINT32 totalFreeSize; // Remaining size of the memory pool.
UINT32 maxFreeNodeSize; // Maximum size of the free memory block in the memory pool UINT32 maxFreeNodeSize; // Maximum size of the free memory block in the memory pool.
UINT32 usedNodeNum; // Number of non-free memory blocks in the memory pool UINT32 usedNodeNum; // Number of non-free memory blocks in the memory pool.
UINT32 freeNodeNum; // Number of free memory blocks in the memory pool UINT32 freeNodeNum; // Number of free memory blocks in the memory pool.
#if (LOSCFG_MEM_WATERLINE == 1) // This function is disabled by default and can be enabled using the menuconfig tool. #if (LOSCFG_MEM_WATERLINE == 1) // This function is disabled by default and can be enabled using the **menuconfig** tool.
UINT32 usageWaterLine; // Waterline of the memory pool UINT32 usageWaterLine; // Waterline of the memory pool.
#endif #endif
} LOS_MEM_POOL_STATUS; } LOS_MEM_POOL_STATUS;
``` ```
- To obtain the memory waterline, call **LOS\_MemInfoGet**. The first parameter in the API is the start address of the memory pool, and the second parameter is the handle of the **LOS\_MEM\_POOL\_STATUS** type. The **usageWaterLine** field indicates the waterline. To obtain the memory waterline, call **LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)**. The first parameter specifies the start address of the memory pool, and the second parameter specifies the handle of the **LOS_MEM_POOL_STATUS** type. The **usageWaterLine** field indicates the waterline.
- To calculate the memory fragmentation rate, call **LOS\_MemInfoGet** to obtain the remaining memory size and the maximum free memory block size in the memory pool, and then calculate the fragmentation rate of the dynamic memory pool as follows: To calculate the memory fragmentation rate, call **LOS_MemInfoGet** to obtain the remaining memory size and the maximum free memory block size in the memory pool, and then calculate the fragmentation rate of the dynamic memory pool as follows:
Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size Fragmentation rate = 100 – 100 x Maximum free memory block size/Remaining memory size
### Development Example<a name="section1025453412611"></a> ### Development Example
This example implements the following: This example implements the following:
1. Creates a monitoring task to obtain information about the memory pool. 1. Create a monitoring task to obtain information about the memory pool.
2. Calls **LOS\_MemInfoGet** to obtain the basic information about the memory pool.
3. Calculates the memory usage and fragmentation rate. 2. Call **LOS_MemInfoGet** to obtain the basic information about the memory pool.
3. Calculate the memory usage and fragmentation rate.
**Sample Code** **Sample Code**
You can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **MemTest()** function is called in **TestTaskEntry**.
The sample code is as follows: The sample code is as follows:
``` ```c
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "los_task.h" #include "los_task.h"
...@@ -66,15 +72,14 @@ void MemInfoTaskFunc(void) ...@@ -66,15 +72,14 @@ void MemInfoTaskFunc(void)
{ {
LOS_MEM_POOL_STATUS poolStatus = {0}; LOS_MEM_POOL_STATUS poolStatus = {0};
/* pool is the memory address of the information to be collected. OS_SYS_MEM_ADDR is used as an example.*/ /* pool is the memory address of the information to be collected. OS_SYS_MEM_ADDR is used as an example. */
void *pool = OS_SYS_MEM_ADDR; void *pool = OS_SYS_MEM_ADDR;
LOS_MemInfoGet(pool, &poolStatus); LOS_MemInfoGet(pool, &poolStatus);
/* Calculate the fragmentation rate of the memory pool. */ /* Calculate the fragmentation rate of the memory pool. */
unsigned char fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize; unsigned char fragment = 100 - poolStatus.maxFreeNodeSize * 100 / poolStatus.totalFreeSize;
/* Calculate the memory usage of the memory pool. */ /* Calculate the memory usage of the memory pool. */
unsigned char usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool); unsigned char usage = LOS_MemTotalUsedGet(pool) * 100 / LOS_MemPoolSizeGet(pool);
printf("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment, poolStatus.maxFreeNodeSize, dprintf("usage = %d, fragment = %d, maxFreeSize = %d, totalFreeSize = %d, waterLine = %d\n", usage, fragment, poolStatus.maxFreeNodeSize, poolStatus.totalFreeSize, poolStatus.usageWaterLine);
poolStatus.totalFreeSize, poolStatus.usageWaterLine);
} }
int MemTest(void) int MemTest(void)
...@@ -88,18 +93,20 @@ int MemTest(void) ...@@ -88,18 +93,20 @@ int MemTest(void)
taskStatus.usTaskPrio = 10; taskStatus.usTaskPrio = 10;
ret = LOS_TaskCreate(&taskID, &taskStatus); ret = LOS_TaskCreate(&taskID, &taskStatus);
if (ret != LOS_OK) { if (ret != LOS_OK) {
printf("task create failed\n"); dprintf("task create failed\n");
return -1; return LOS_NOK;
} }
return 0; return LOS_OK;
} }
``` ```
**Verification** **Verification**
The result is as follows: The result is as follows:
The data may vary depending on the running environment.
``` ```
usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414 usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414
``` ```
# Memory Leak Check # Memory Leak Check
## Basic Concepts<a name="section1026719436293"></a> ## Basic Concepts
As an optional function of the kernel, memory leak check is used to locate dynamic memory leak problems. After this function is enabled, the dynamic memory mechanism automatically records the link registers \(LRs\) used when memory is allocated. If a memory leak occurs, the recorded information helps locate the memory allocated for further analysis. As an optional function of the kernel, memory leak check is used to locate dynamic memory leak problems. After this function is enabled, the dynamic memory mechanism automatically records the link registers (LRs) used when memory is allocated. If a memory leak occurs, the recorded information helps locate the memory allocated for further analysis.
## Function Configuration<a name="section13991354162914"></a>
1. **LOSCFG\_MEM\_LEAKCHECK**: specifies the setting of the memory leak check. This function is disabled by default. To enable this function, configure it in **Debug-\> Enable Function call stack of Mem operation recorded**. ## Function Configuration
2. **LOS\_RECORD\_LR\_CNT**: number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof\(void \*\)** bytes.
3. **LOS\_OMIT\_LR\_CNT**: number of ignored LRs. The default value is **2**, which indicates that LRs are recorded from the time when **LOS\_MemAlloc** is called. You can change the value based on actual requirements. This macro is configured because:
- **LOS\_MemAlloc** is also called internally.
- **LOS\_MemAlloc** may be encapsulated externally.
- The number of LRs configured by **LOS\_RECORD\_LR\_CNT** is limited.
**LOSCFG_MEM_LEAKCHECK** specifies the setting of the memory leak check. This function is disabled by default. You can enable it in **Debug-&gt; Enable MEM Debug-&gt; Enable Function call stack of Mem operation recorded**.
**LOS_RECORD_LR_CNT** specifies the number of LRs recorded. The default value is **3**. Each LR consumes the memory of **sizeof(void *)** bytes.
**LOS_OMIT_LR_CNT** specifies the number of ignored LRs. The default value is **2**, which indicates that LRs are recorded from the time when **LOS_MemAlloc** is called. You can change the value based on actual requirements. The reasons for this configuration are as follows:
- **LOS_MemAlloc** is also called internally.
- **LOS_MemAlloc** may be encapsulated externally.
- The number of LRs configured by **LOS_RECORD_LR_CNT** is limited.
Correctly setting this macro can ignore invalid LRs and reduce memory consumption. Correctly setting this macro can ignore invalid LRs and reduce memory consumption.
## Development Guidelines<a name="section95828159308"></a>
### How to Develop<a name="section369844416304"></a> ## Development Guidelines
Memory leak check provides a method to check for memory leak in key code logic. If this function is enabled, LR information is recorded each time when memory is allocated. When **LOS\_MemUsedNodeShow** is called before and after the code snippet is checked, information about all nodes that have been used in the specified memory pool is printed. You can compare the node information. The newly added node information indicates the node where the memory leak may occur. You can locate the code based on the LR and further check whether a memory leak occurs. ### How to Develop
The node information output by calling **LOS\_MemUsedNodeShow** is in the following format: Memory leak check provides a method to check for memory leak in key code logic. If this function is enabled, LR information is recorded each time when memory is allocated. When **LOS_MemUsedNodeShow** is called before and after the code snippet is checked, information about all nodes that have been used in the specified memory pool is printed. You can compare the node information. The newly added node information indicates the node where the memory leak may occur. You can locate the code based on the LR and further check whether a memory leak occurs.
- Each line contains information about a node. The node information output by calling **LOS_MemUsedNodeShow** is in the following format: <br>Each line contains information about a node. The first column indicates the node address, based on which you can obtain complete node information using a tool such as a GNU Debugger (GDB). The second column indicates the node size, which is equal to the node header size plus the data field size. Columns 3 to 5 list the LR addresses. You can determine the specific memory location of the node based on the LR addresses and the assembly file.
- The first column indicates the node address, based on which you can obtain complete node information using a tool such as a GNU Debugger \(GDB\).
- The second column indicates the node size, which is equal to the node header size plus the data field size.
- Columns 3 to 5 list the LR addresses.
You can determine the specific memory location of the node based on the LR addresses and the assembly file.
``` ```
node size LR[0] LR[1] LR[2] node size LR[0] LR[1] LR[2]
...@@ -42,86 +41,111 @@ node size LR[0] LR[1] LR[2] ...@@ -42,86 +41,111 @@ node size LR[0] LR[1] LR[2]
0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0
``` ```
>![](../public_sys-resources/icon-caution.gif) **CAUTION:** > **CAUTION**
>Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead. > Enabling memory leak check affects memory application performance. LR addresses will be recorded for each memory node, increasing memory overhead.
### Development Example<a name="section460801313313"></a>
### Development Example
This example implements the following: This example implements the following:
1. Call **OsMemUsedNodeShow** to print information about all nodes. 1. Call **OsMemUsedNodeShow** to print information about all nodes.
2. Simulate a memory leak by requesting memory without releasing it. 2. Simulate a memory leak by requesting memory without releasing it.
3. Call **OsMemUsedNodeShow** to print information about all nodes. 3. Call **OsMemUsedNodeShow** to print information about all nodes.
4. Compare the logs to obtain information about the node where a memory leak occurred. 4. Compare the logs to obtain information about the node where a memory leak occurred.
5. Locate the code based on the LR address. 5. Locate the code based on the LR address.
**Sample Code** **Sample Code**
You can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **MemLeakTest()** function is called in **TestTaskEntry**.
In this example, a memory pool is created. To achieve this purpose, you need to define **LOSCFG_MEM_MUL_POOL** in **target_config.h**.
The sample code is as follows: The sample code is as follows:
``` ```c
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "los_memory.h" #include "los_memory.h"
#include "los_config.h" #include "los_config.h"
#define TEST_NEW_POOL_SIZE 2000
#define TEST_MALLOC_SIZE 8
void MemLeakTest(void) void MemLeakTest(void)
{ {
OsMemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR); VOID *pool = NULL;
void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8);
void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); /* Create a memory pool. */
OsMemUsedNodeShow(LOSCFG_SYS_HEAP_ADDR); pool = LOS_MemAlloc(OS_SYS_MEM_ADDR, TEST_NEW_POOL_SIZE);
(VOID)LOS_MemInit(pool, TEST_NEW_POOL_SIZE);
OsMemUsedNodeShow(pool);
void *ptr1 = LOS_MemAlloc(pool, TEST_MALLOC_SIZE);
void *ptr2 = LOS_MemAlloc(pool, TEST_MALLOC_SIZE);
OsMemUsedNodeShow(pool);
/* Release the memory pool. */
(VOID)LOS_MemDeInit(pool);
} }
``` ```
**Verification** **Verification**
The log is as follows: The log is as follows:
``` ```
node size LR[0] LR[1] LR[2] /* Log for the first OsMemUsedNodeShow. Because the memory pool is not allocated, there is no memory node. */
0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc node LR[0] LR[1] LR[2]
0x20002058: 0x40 0x08002fe8 0x08003626 0x080028fc
0x200022ac: 0x40 0x08000e0c 0x08000e56 0x0800359e
0x20002594: 0x120 0x08000e0c 0x08000e56 0x08000c8a /* Log for the second OsMemUsedNodeShow. There are two memory nodes. */
0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220 node LR[0] LR[1] LR[2]
0x00402e0d90: 0x004009f040 0x0040037614 0x0040005480
0x00402e0db0: 0x004009f04c 0x0040037614 0x0040005480
node size LR[0] LR[1] LR[2]
0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc
0x20002058: 0x40 0x08002fe8 0x08003626 0x080028fc
0x200022ac: 0x40 0x08000e0c 0x08000e56 0x0800359e
0x20002594: 0x120 0x08000e0c 0x08000e56 0x08000c8a
0x20002aac: 0x56 0x08000e0c 0x08000e56 0x08004220
0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6
0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000
``` ```
The difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak. The difference between the two logs is as follows. The following memory nodes are suspected to have blocks with a memory leak.
``` ```
0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 0x00402e0d90: 0x004009f040 0x0040037614 0x0040005480
0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 0x00402e0db0: 0x004009f04c 0x0040037614 0x0040005480
``` ```
The following is part of the assembly file: The following is part of the assembly file:
``` ```
MemLeakTest: 4009f014: 7d 1e a0 e3 mov r1, #2000
0x80041d4: 0xb510 PUSH {R4, LR} 4009f018: 00 00 90 e5 ldr r0, [r0]
0x80041d6: 0x4ca8 LDR.N R4, [PC, #0x2a0] ; g_memStart 4009f01c: 67 7a fe eb bl #-398948 <LOS_MemAlloc>
0x80041d8: 0x0020 MOVS R0, R4 4009f020: 7d 1e a0 e3 mov r1, #2000
0x80041da: 0xf7fd 0xf93e BL LOS_MemUsedNodeShow ; 0x800145a 4009f024: 00 40 a0 e1 mov r4, r0
0x80041de: 0x2108 MOVS R1, #8 4009f028: c7 79 fe eb bl #-399588 <LOS_MemInit>
0x80041e0: 0x0020 MOVS R0, R4 4009f02c: 04 00 a0 e1 mov r0, r4
0x80041e2: 0xf7fd 0xfbd9 BL LOS_MemAlloc ; 0x8001998 4009f030: 43 78 fe eb bl #-401140 <OsMemUsedNodeShow>
0x80041e6: 0x2108 MOVS R1, #8 4009f034: 04 00 a0 e1 mov r0, r4
0x80041e8: 0x0020 MOVS R0, R4 4009f038: 08 10 a0 e3 mov r1, #8
0x80041ea: 0xf7fd 0xfbd5 BL LOS_MemAlloc ; 0x8001998 4009f03c: 5f 7a fe eb bl #-398980 <LOS_MemAlloc>
0x80041ee: 0x0020 MOVS R0, R4 4009f040: 04 00 a0 e1 mov r0, r4
0x80041f0: 0xf7fd 0xf933 BL LOS_MemUsedNodeShow ; 0x800145a 4009f044: 08 10 a0 e3 mov r1, #8
0x80041f4: 0xbd10 POP {R4, PC} 4009f048: 5c 7a fe eb bl #-398992 <LOS_MemAlloc>
0x80041f6: 0x0000 MOVS R0, R0 4009f04c: 04 00 a0 e1 mov r0, r4
4009f050: 3b 78 fe eb bl #-401172 <OsMemUsedNodeShow>
4009f054: 3c 00 9f e5 ldr r0, [pc, #60]
4009f058: 40 b8 fe eb bl #-335616 <dprintf>
4009f05c: 04 00 a0 e1 mov r0, r4
4009f060: 2c 7a fe eb bl #-399184 <LOS_MemDeInit>
``` ```
The memory node addressed by **0x080041ee** is not released after being requested in **MemLeakTest**.
The memory node addressed by **0x4009f040** is not released after being allocated in **MemLeakTest**.
# perf
## Basic Concepts
perf is a performance analysis tool. It uses the performance monitoring unit (PMU) to count sampling events and collect context information and provides hot spot distribution and hot paths.
## Working Principles
When a performance event occurs, the corresponding event counter overflows and triggers an interrupt. The interrupt handler records the event information, including the current PC, task ID, and call stack.
perf provides two working modes: counting mode and sampling mode.
In counting mode, perf collects only the number of event occurrences and duration. In sampling mode, perf also collects context data and stores the data in a circular buffer. The IDE then analyzes the data and provides information about hotspot functions and paths.
## Available APIs
The Perf module of the OpenHarmony LiteOS-A kernel provides the following APIs. For details, see the [API reference](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_perf.h).
**Table 1** APIs of the perf module
| Category| Description|
| -------- | -------- |
| Starting or stopping sampling| **LOS_PerfInit**: initializes perf.<br>**LOS_PerfStart**: starts sampling.<br>**LOS_PerfStop**: stops sampling. |
| Configuring perf sampling events| **LOS_PerfConfig**: sets the event type and sampling period. |
| Reading sampling data| **LOS_PerfDataRead**: reads the sampling data. |
| Registering a hook for the sampling data buffer| **LOS_PerfNotifyHookReg**: registers the hook to be called when the buffer waterline is reached.<br>**LOS_PerfFlushHookReg**: registers the hook for flushing the cache in the buffer. |
**PerfConfigAttr** is the structure of the perf sampling event. For details, see [kernel\include\los_perf.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_perf.h).
The sampling data buffer is a circular buffer, and only the region that has been read in the buffer can be overwritten.
The buffer has limited space. You can register a hook to provide a buffer overflow notification or perform buffer read operation when the buffer waterline is reached. The default buffer waterline is 1/2 of the buffer size. The code snippet is as follows:
```c
VOID Example_PerfNotifyHook(VOID)
{
CHAR buf[LOSCFG_PERF_BUFFER_SIZE] = {0};
UINT32 len;
PRINT_DEBUG("perf buffer reach the waterline!\n");
len = LOS_PerfDataRead(buf, LOSCFG_PERF_BUFFER_SIZE);
OsPrintBuff(buf, len); /* print data */
}
LOS_PerfNotifyHookReg(Example_PerfNotifyHook);
```
If the buffer sampled by perf involves caches across CPUs, you can register a hook for flushing the cache to ensure cache consistency. The code snippet is as follows:
```c
VOID Example_PerfFlushHook(VOID *addr, UINT32 size)
{
OsCacheFlush(addr, size); /* platform interface */
}
LOS_PerfNotifyHookReg(Example_PerfFlushHook);
```
The API for flushing the cache is configured based on the platform.
## Development Guidelines
### Kernel-Mode Development Process
The typical process of enabling perf is as follows:
1. Configure the macros related to the perf module.
Configure the perf control macro **LOSCFG_KERNEL_PERF**, which is disabled by default. In the **kernel/liteos_a** directory, run the **make update_config** command, choose **Kernel**, and select **Enable Perf Feature**.
| Configuration Item| menuconfig Option| Description| Value|
| -------- | -------- | -------- | -------- |
| LOSCFG_KERNEL_PERF | Enable&nbsp;Perf&nbsp;Feature | Whether to enable perf.| YES/NO |
| LOSCFG_PERF_CALC_TIME_BY_TICK | Time-consuming&nbsp;Calc&nbsp;Methods-&gt;By&nbsp;Tick | Whether to use tick as the perf timing unit.| YES/NO |
| LOSCFG_PERF_CALC_TIME_BY_CYCLE | Time-consuming&nbsp;Calc&nbsp;Methods-&gt;By&nbsp;Cpu&nbsp;Cycle | Whether to use cycle as the perf timing unit.| YES/NO |
| LOSCFG_PERF_BUFFER_SIZE | Perf&nbsp;Sampling&nbsp;Buffer&nbsp;Size | Size of the buffer used for perf sampling.| INT |
| LOSCFG_PERF_HW_PMU | Enable&nbsp;Hardware&nbsp;Pmu&nbsp;Events&nbsp;for&nbsp;Sampling | Whether to enable hardware PMU events. The target platform must support the hardware PMU.| YES/NO |
| LOSCFG_PERF_TIMED_PMU | Enable&nbsp;Hrtimer&nbsp;Period&nbsp;Events&nbsp;for&nbsp;Sampling | Whether to enable high-precision periodical events. The target platform must support the high precision event timer (HPET).| YES/NO |
| LOSCFG_PERF_SW_PMU | Enable&nbsp;Software&nbsp;Events&nbsp;for&nbsp;Sampling | Whether to enable software events. **LOSCFG_KERNEL_HOOK** must also be enabled.| YES/NO |
2. Call **LOS_PerfConfig** to configure the events to be sampled.
perf provides two working modes and three types of events.
- Working modes: counting mode (counts only the number of event occurrences) and sampling mode (collects context information such as task IDs, PC, and backtrace)
- Event types: CPU hardware events (such as cycle, branch, icache, and dcache), high-precision periodical events (such as CPU clock), and OS software events (such as task switch, mux pend, and IRQ)
3. Call **LOS_PerfStart(UINT32 sectionId)** at the start of the code to be sampled. The input parameter **sectionId** specifies different sampling session IDs.
4. Call **LOS_PerfStop** at the end of the code to be sampled.
5. Call **LOS_PerfDataRead** to read the sampling data and use IDE to analyze the collected data.
#### Development Example
This example implements the following:
1. Create a perf task.
2. Configure sampling events.
3. Start perf.
4. Execute algorithms for statistics.
5. Stop perf.
6. Export the result.
#### Sample Code
Prerequisites: **Enable Hook Feature** and **Enable Software Events for Sampling** are selected for the perf module in **menuconfig**.
You can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**.
The code is as follows:
```c
#include "los_perf.h"
#define TEST_MALLOC_SIZE 200
#define TEST_TIME 5
/* Add malloc() and free() in the test() function. */
VOID test(VOID)
{
VOID *p = NULL;
int i;
for (i = 0; i < TEST_TIME; i++) {
p = LOS_MemAlloc(m_aucSysMem1, TEST_MALLOC_SIZE);
if (p == NULL) {
PRINT_ERR("test alloc failed\n");
return;
}
(VOID)LOS_MemFree(m_aucSysMem1, p);
}
}
STATIC VOID OsPrintBuff(const CHAR *buf, UINT32 num)
{
UINT32 i = 0;
PRINTK("num: ");
for (i = 0; i < num; i++) {
PRINTK(" %02d", i);
}
PRINTK("\n");
PRINTK("hex: ");
for (i = 0; i < num; i++) {
PRINTK(" %02x", buf[i]);
}
PRINTK("\n");
}
STATIC VOID perfTestHwEvent(VOID)
{
UINT32 ret;
CHAR *buf = NULL;
UINT32 len;
//LOS_PerfInit(NULL, 0);
PerfConfigAttr attr = {
.eventsCfg = {
.type = PERF_EVENT_TYPE_SW,
.events = {
[0] = {PERF_COUNT_SW_TASK_SWITCH, 0xff}, /* Collect task scheduling information. */
[1] = {PERF_COUNT_SW_MEM_ALLOC, 0xff}, /* Collect memory allocation information. */
PERF_COUNT_SW_TASK_SWITCH
},
.eventsNr = 2,
.predivided = 1, /* cycle counter increase every 64 cycles */
},
.taskIds = {0},
.taskIdsNr = 0,
.needSample = 0,
.sampleType = PERF_RECORD_IP | PERF_RECORD_CALLCHAIN,
};
ret = LOS_PerfConfig(&attr);
if (ret != LOS_OK) {
PRINT_ERR("perf config error %u\n", ret);
return;
}
PRINTK("------count mode------\n");
LOS_PerfStart(0);
test(); /* this is any test function*/
LOS_PerfStop();
PRINTK("--------sample mode------ \n");
attr.needSample = 1;
LOS_PerfConfig(&attr);
LOS_PerfStart(2); // 2: set the section id to 2.
test(); /* this is any test function*/
LOS_PerfStop();
buf = LOS_MemAlloc(m_aucSysMem1, LOSCFG_PERF_BUFFER_SIZE);
if (buf == NULL) {
PRINT_ERR("buffer alloc failed\n");
return;
}
/* get sample data */
len = LOS_PerfDataRead(buf, LOSCFG_PERF_BUFFER_SIZE);
OsPrintBuff(buf, len); /* print data */
(VOID)LOS_MemFree(m_aucSysMem1, buf);
}
UINT32 Example_Perf_test(VOID)
{
UINT32 ret;
TSK_INIT_PARAM_S perfTestTask = {0};
UINT32 taskID;
/* Create a perf task. */
perfTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)perfTestHwEvent;
perfTestTask.pcName = "TestPerfTsk"; /* Test task name. */
perfTestTask.uwStackSize = 0x1000; // 0x8000: perf test task stack size
perfTestTask.usTaskPrio = 5; // 5: perf test task priority
ret = LOS_TaskCreate(&taskID, &perfTestTask);
if (ret != LOS_OK) {
PRINT_ERR("PerfTestTask create failed. 0x%x\n", ret);
return LOS_NOK;
}
return LOS_OK;
}
LOS_MODULE_INIT(perfTestHwEvent, LOS_INIT_LEVEL_KMOD_EXTENDED);
```
#### Verification
The output is as follows:
```
type: 2
events[0]: 1, 0xff
events[1]: 3, 0xff
predivided: 1
sampleType: 0x60
needSample: 0
------count mode------
[task switch] eventType: 0x1 [core 0]: 0
[mem alloc] eventType: 0x3 [core 0]: 5
time used: 0.005000(s)
--------sample mode------
type: 2
events[0]: 1, 0xff
events[1]: 3, 0xff
predivided: 1
sampleType: 0x60
needSample: 1
dump perf data, addr: 0x402c3e6c length: 0x5000
time used: 0.000000(s)
num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
hex: 00 ffffffef ffffffef ffffffef 02 00 00 00 14 00 00 00 60 00 00 00 02 00 00 00
The print information may vary depending on the running environment.
```
- For the counting mode, the following information is displayed after perf is stopped:
Event name (cycles), event type (0xff), and number of event occurrences (5466989440)
For hardware PMU events, the displayed event type is the hardware event ID, not the abstract type defined in **enum PmuHWId**.
- For the sampling mode, the address and length of the sampled data will be displayed after perf is stopped:
dump section data, addr: (0x8000000) length: (0x5000)
You can export the data using the JTAG interface and then use the IDE offline tool to analyze the data.
You can also call **LOS_PerfDataRead** to read data to a specified address for further analysis. In the example, **OsPrintBuff** is a test API, which prints the sampled data by byte. **num** indicates the sequence number of the byte, and **hex** indicates the value in the byte.
...@@ -3,34 +3,33 @@ ...@@ -3,34 +3,33 @@
## Basic Concepts ## Basic Concepts
The central processing unit percent \(CPUP\) includes the system CPUP, process CPUP, task CPUP, and interrupt CPUP. With the system CPUP, you can determine whether the current system load exceeds the designed specifications. With the CPUP of each task/process/interrupt, you can determine whether their CPU usage meets expectations of the design. The central processing unit percent (CPUP) includes the system CPUP, process CPUP, task CPUP, and interrupt CPUP. With the system CPUP, you can determine whether the current system load exceeds the designed specifications. With the CPUP of each task/process/interrupt, you can determine whether their CPU usage meets expectations of the design.
- System CPUP - System CPUP
System CPUP is the CPU usage of the system within a period of time. It reflects the CPU load and the system running status (idle or busy) in the given period of time. The valid range of the system CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the system runs with full load.
System CPUP is the CPU usage of the system within a period of time. It reflects the CPU load and the system running status \(idle or busy\) in the given period of time. The valid range of the system CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the system runs with full load.
- Process CPUP - Process CPUP
Process CPUP refers to the CPU usage of a single process. It reflects the process status, busy or idle, in a period of time. The valid range of the process CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the process is being executed for a period of time. Process CPUP refers to the CPU usage of a single process. It reflects the process status, busy or idle, in a period of time. The valid range of the process CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the process is being executed for a period of time.
- Task CPUP - Task CPUP
Task CPUP refers to the CPU usage of a single task. It reflects the task status, busy or idle, in a period of time. The valid range of task CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the task is being executed for the given period of time. Task CPUP refers to the CPU usage of a single task. It reflects the task status, busy or idle, in a period of time. The valid range of task CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the task is being executed for the given period of time.
- Interrupt CPUP - Interrupt CPUP
Interrupt CPUP refers to the CPU usage of a single interrupt. It reflects the interrupt status, busy or idle, in a period of time. The valid range of the interrupt CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the interrupt is being executed for a period of time. Interrupt CPUP refers to the CPU usage of a single interrupt. It reflects the interrupt status, busy or idle, in a period of time. The valid range of the interrupt CPUP is 0 to 100 in percentage. The precision can be adjusted through configuration. The value **100** indicates that the interrupt is being executed for a period of time.
## Working Principles<a name="section593718536227"></a> ## Working Principles
The OpenHarmony LiteOS-A kernel CPUP module records the CPU usage by process, task, and interrupt. When a process or task is switched, the start time of the process or task is recorded. When the process or task is switched out or exits, the system accumulates the CPU time of the entire process or task. When an interrupt is executed, the system accumulates and records the execution time of each interrupt. The OpenHarmony LiteOS-A kernel CPUP module records the CPU usage by process, task, and interrupt. When a process or task is switched, the start time of the process or task is recorded. When the process or task is switched out or exits, the system accumulates the CPU time of the entire process or task. When an interrupt is executed, the system accumulates and records the execution time of each interrupt.
OpenHarmony provides the following types of CPUP information: OpenHarmony provides the following types of CPUP information:
- System CPUP - System CPUP
- Process CPUP - Process CPUP
- Task CPUP - Task CPUP
- Interrupt CPUP - Interrupt CPUP
The CPUP is calculated as follows: The CPUP is calculated as follows:
...@@ -43,134 +42,109 @@ Task CPUP = Total running time of the task/Total running time of the system ...@@ -43,134 +42,109 @@ Task CPUP = Total running time of the task/Total running time of the system
Interrupt CPUP = Total running time of the interrupt/Total running time of the system Interrupt CPUP = Total running time of the interrupt/Total running time of the system
## Development Guidelines<a name="section11284210152311"></a>
## Development Guidelines
### Available APIs<a name="section3745151592312"></a>
**Table 1** CPUP module APIs ### Available APIs
<a name="table147491853163018"></a> **Table 1** CPUP module APIs
<table><thead align="left"><tr id="row10807205323013"><th class="cellrowborder" valign="top" width="28.3971602839716%" id="mcps1.2.4.1.1"><p id="p980714539304"><a name="p980714539304"></a><a name="p980714539304"></a>Function</p>
</th> | Category| API| Description|
<th class="cellrowborder" valign="top" width="36.47635236476353%" id="mcps1.2.4.1.2"><p id="p1780715533305"><a name="p1780715533305"></a><a name="p1780715533305"></a>API</p> | -------- | -------- | -------- |
</th> | System CPUP| LOS_HistorySysCpuUsage | Obtains the historical CPUP of the system.|
<th class="cellrowborder" valign="top" width="35.12648735126487%" id="mcps1.2.4.1.3"><p id="p18807185316301"><a name="p18807185316301"></a><a name="p18807185316301"></a>Description</p> | Process CPUP| LOS_HistoryProcessCpuUsage | Obtains the historical CPUP of a specified process.|
</th> | Process CPUP| LOS_GetAllProcessCpuUsage | Obtains the historical CPUP of all processes in the system.|
</tr> | Task CPUP| LOS_HistoryTaskCpuUsage | Obtains the historical CPUP of a specified task.|
</thead> | Interrupt CPUP| LOS_GetAllIrqCpuUsage | Obtains the historical CPUP of all interrupts in the system.|
<tbody><tr id="row3807145310300"><td class="cellrowborder" valign="top" width="28.3971602839716%" headers="mcps1.2.4.1.1 "><p id="p174011140141013"><a name="p174011140141013"></a><a name="p174011140141013"></a>System CPUP</p> | Reset| LOS_CpupReset | Resets CPUP data.|
</td>
<td class="cellrowborder" valign="top" width="36.47635236476353%" headers="mcps1.2.4.1.2 "><p id="p158071153133013"><a name="p158071153133013"></a><a name="p158071153133013"></a>LOS_HistorySysCpuUsage</p>
</td> ### How to Develop
<td class="cellrowborder" valign="top" width="35.12648735126487%" headers="mcps1.2.4.1.3 "><p id="p14808115353010"><a name="p14808115353010"></a><a name="p14808115353010"></a>Obtains the historical CPUP of the system.</p>
</td> The typical CPUP development process is as follows:
</tr>
<tr id="row147461859201016"><td class="cellrowborder" rowspan="2" valign="top" width="28.3971602839716%" headers="mcps1.2.4.1.1 "><p id="p374720596102"><a name="p374720596102"></a><a name="p374720596102"></a>Process CPUP</p> 1. Call **LOS_HistorySysCpuUsage** to obtain the historical CPUP of the system.
</td>
<td class="cellrowborder" valign="top" width="36.47635236476353%" headers="mcps1.2.4.1.2 "><p id="p3747859101010"><a name="p3747859101010"></a><a name="p3747859101010"></a>LOS_HistoryProcessCpuUsage</p> 2. Call **LOS_HistoryProcessCpuUsage** to obtain the historical CPUP of a specified process.
</td>
<td class="cellrowborder" valign="top" width="35.12648735126487%" headers="mcps1.2.4.1.3 "><p id="p1747959131016"><a name="p1747959131016"></a><a name="p1747959131016"></a>Obtains the historical CPUP of a specified process.</p>
</td>
</tr>
<tr id="row2075434812116"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17541648171114"><a name="p17541648171114"></a><a name="p17541648171114"></a>LOS_GetAllProcessCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1575419483116"><a name="p1575419483116"></a><a name="p1575419483116"></a>Obtains the historical CPUP of all processes in the system.</p>
</td>
</tr>
<tr id="row1480855311301"><td class="cellrowborder" valign="top" width="28.3971602839716%" headers="mcps1.2.4.1.1 "><p id="p1618792981018"><a name="p1618792981018"></a><a name="p1618792981018"></a>Task CPUP</p>
</td>
<td class="cellrowborder" valign="top" width="36.47635236476353%" headers="mcps1.2.4.1.2 "><p id="p9808185353016"><a name="p9808185353016"></a><a name="p9808185353016"></a>LOS_HistoryTaskCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" width="35.12648735126487%" headers="mcps1.2.4.1.3 "><p id="p12808653183016"><a name="p12808653183016"></a><a name="p12808653183016"></a>Obtains the historical CPUP of a specified task.</p>
</td>
</tr>
<tr id="row680812535306"><td class="cellrowborder" valign="top" width="28.3971602839716%" headers="mcps1.2.4.1.1 "><p id="p13808125314307"><a name="p13808125314307"></a><a name="p13808125314307"></a>Interrupt CPUP</p>
</td>
<td class="cellrowborder" valign="top" width="36.47635236476353%" headers="mcps1.2.4.1.2 "><p id="p1480835316303"><a name="p1480835316303"></a><a name="p1480835316303"></a>LOS_GetAllIrqCpuUsage</p>
</td>
<td class="cellrowborder" valign="top" width="35.12648735126487%" headers="mcps1.2.4.1.3 "><p id="p33741531163313"><a name="p33741531163313"></a><a name="p33741531163313"></a>Obtains the historical CPUP of all interrupts in the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section122901429182316"></a>
The typical CPUP development process is as follows.
1. Call **LOS\_HistorySysCpuUsage** to obtain the historical CPUP of the system.
2. Call **LOS\_HistoryProcessCpuUsage** to obtain the historical CPUP of a specified process.
- If the process has been created, disable interrupt, obtain the CPUP in different modes, and then enable interrupt. - If the process has been created, disable interrupt, obtain the CPUP in different modes, and then enable interrupt.
- If the process is not created, return an error code. - If the process is not created, return an error code.
3. Call **LOS\_GetAllProcessCpuUsage** to obtain the CPUP of all processes. 3. Call **LOS_GetAllProcessCpuUsage** to obtain the CPUP of all processes.
- If the CPUP has been initialized, disable interrupt, obtain the CPUP in different modes, and then enable interrupt. - If the CPUP is initialized, disable interrupt, obtain the CPUP in different modes, and then enable interrupt.
- If CPUP is not initialized or has invalid input parameters, return an error code. - If CPUP is not initialized or has invalid input parameters, return an error code.
4. Call **LOS\_HistoryTaskCpuUsage** to obtain the historical CPUP of a specified task. 4. Call **LOS_HistoryTaskCpuUsage** to obtain the historical CPUP of a specified task.
- If the task has been created, disable interrupt, obtain the CPUP in different modes, and then enable interrupt. - If the task has been created, disable interrupt, obtain the CPUP in different modes, and then enable interrupt.
- If the task is not created, return an error code. - If the task is not created, return an error code.
5. Call **LOS\_GetAllIrqCpuUsage** to obtain the CPUP of all interrupts. 5. Call **LOS_GetAllIrqCpuUsage** to obtain the CPUP of all interrupts.
- If the CPUP has been initialized, disable interrupt, obtain the CPUP in different modes, and then enable interrupt. - If the CPUP has been initialized, disable interrupt, obtain the CPUP in different modes, and then enable interrupt.
- If CPUP has not been initialized or has invalid input parameters, return an error code. - If CPUP is not initialized or has invalid input parameters, return an error code.
### Development Example<a name="section1765785212310"></a> ### Development Example
This example implements the following: This example implements the following:
1. Create a task for the CPUP test. 1. Create a task for the CPUP test.
2. Obtain the CPUP of the current system. 2. Obtain the CPUP of the current system.
3. Obtain the historical system CPUP in different modes. 3. Obtain the historical system CPUP in different modes.
4. Obtain the CPUP of the created test task. 4. Obtain the CPUP of the created test task.
5. Obtain the CPUP of the created test task in different modes. 5. Obtain the CPUP of the created test task in different modes.
Prerequisites Prerequisites:
The CPUP control is enabled in the **menuconfig** configuration. The CPUP control is enabled in the **menuconfig** configuration.
**Sample Code** **Sample Code**
You can compile and verify the sample code in **kernel/liteos_a/testsuites /kernel/src /osTest.c**. The **CpupTest** function is called in **TestTaskEntry**.
The sample code is as follows: The sample code is as follows:
```
```c
#include "los_task.h" #include "los_task.h"
#include "los_cpup.h" #include "los_cpup.h"
#define MODE 4 #define MODE 4
UINT32 g_cpuTestTaskID; UINT32 g_cpuTestTaskID;
VOID ExampleCpup(VOID) VOID ExampleCpup(VOID)
{ {
printf("entry cpup test example\n"); int i = 0;
while(1) { dprintf("entry cpup test example\n");
usleep(100); for (i = 0; i < 10; i++) {
usleep(100); // 100: delay for 100ms
} }
} }
UINT32 ItCpupTest(VOID) UINT32 CpupTest(VOID)
{ {
UINT32 ret; UINT32 ret;
UINT32 cpupUse; UINT32 cpupUse;
TSK_INIT_PARAM_S cpupTestTask = { 0 }; TSK_INIT_PARAM_S cpupTestTask = {0};
memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S)); memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S));
cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup; cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup;
cpupTestTask.pcName = "TestCpupTsk"; cpupTestTask.pcName = "TestCpupTsk";
cpupTestTask.uwStackSize = 0x800; cpupTestTask.uwStackSize = 0x800; // 0x800: cpup test task stack size
cpupTestTask.usTaskPrio = 5; cpupTestTask.usTaskPrio = 5; // 5: cpup test task priority
ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask); ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask);
if(ret != LOS_OK) { if (ret != LOS_OK) {
printf("cpupTestTask create failed .\n"); printf("cpupTestTask create failed .\n");
return LOS_NOK; return LOS_NOK;
} }
usleep(100); usleep(100); // 100: delay for 100ms
/* Obtain the historical CPUP of the system. */ /* Obtain the historical CPUP of the system. */
cpupUse = LOS_HistorySysCpuUsage(CPU_LESS_THAN_1S); cpupUse = LOS_HistorySysCpuUsage(CPUP_LAST_ONE_SECONDS);
printf("the history system cpu usage in all time: %u.%u\n", dprintf("the history system cpu usage in all time: %u.%u\n",
cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT);
/* Obtain the CPUP of the specified task (cpupTestTask in this example).*/ /* Obtain the CPUP of the specified task (cpupTestTask in this example). */
cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPU_LESS_THAN_1S); cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPUP_LAST_ONE_SECONDS);
printf("cpu usage of the cpupTestTask in all time:\n TaskID: %d\n usage: %u.%u\n", dprintf("cpu usage of the cpupTestTask in all time:\n TaskID: %d\n usage: %u.%u\n",
g_cpuTestTaskID, cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); g_cpuTestTaskID, cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT);
return LOS_OK; return LOS_OK;
} }
...@@ -180,9 +154,12 @@ UINT32 ItCpupTest(VOID) ...@@ -180,9 +154,12 @@ UINT32 ItCpupTest(VOID)
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
entry cpup test example entry cpup test example
the history system cpu usage in all time: 3.0 the history system cpu usage in all time: 3.0
cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0 cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0
The print information may vary depending on the running environment.
``` ```
# cpup # cpup
## Command Function<a name="section1842161614217"></a> ## Command Function
This command is used to query the CPU usage \(CPU percent\) of the system. This command is used to query the CPU percent (CPUP) of the system.
## Syntax<a name="section5629527427"></a>
cpup \[_mode_\] \[_taskID_\] ## Syntax
## Parameters<a name="section133651361023"></a> cpup [_mode_] [_taskID_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table3774mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row3780mcpsimp"><th class="cellrowborder" valign="top" width="16%" id="mcps1.2.4.1.1"><p id="p3782mcpsimp"><a name="p3782mcpsimp"></a><a name="p3782mcpsimp"></a>Parameter</p> | -------- | -------- | -------- |
</th> | mode | Displays the CPUP of the system within the last 10 seconds by default.<br>- **0**: displays the CPUP within the last 10 seconds.<br>- **1**: displays the CPUP within the last 1 second.<br>- Other numbers: display the total CPUP since the system starts.| [0, 0xFFFFFFFF] |
<th class="cellrowborder" valign="top" width="56.99999999999999%" id="mcps1.2.4.1.2"><p id="p3784mcpsimp"><a name="p3784mcpsimp"></a><a name="p3784mcpsimp"></a>Description</p> | taskID | Specifies the task ID.| [0, 0xFFFFFFFF] |
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p3786mcpsimp"><a name="p3786mcpsimp"></a><a name="p3786mcpsimp"></a>Value Range</p>
</th> ## Usage Guidelines
</tr>
</thead>
<tbody><tr id="row3787mcpsimp"><td class="cellrowborder" valign="top" width="16%" headers="mcps1.2.4.1.1 "><p id="p3789mcpsimp"><a name="p3789mcpsimp"></a><a name="p3789mcpsimp"></a>mode</p>
</td>
<td class="cellrowborder" valign="top" width="56.99999999999999%" headers="mcps1.2.4.1.2 "><a name="ul1530071303413"></a><a name="ul1530071303413"></a><ul id="ul1530071303413"><li>Displays the CPU usage of the system within the last 10 seconds by default.</li><li><strong id="b13709113084810"><a name="b13709113084810"></a><a name="b13709113084810"></a>0</strong>: displays the CPU usage within the last 10 seconds.</li><li><strong id="b10788133319480"><a name="b10788133319480"></a><a name="b10788133319480"></a>1</strong>: displays the CPU usage within the last 1 second.</li><li>Other value: displays the total CPU usage since the system is started.</li></ul>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3794mcpsimp"><a name="p3794mcpsimp"></a><a name="p3794mcpsimp"></a>[0,0xFFFFFFFF]</p>
</td>
</tr>
<tr id="row3795mcpsimp"><td class="cellrowborder" valign="top" width="16%" headers="mcps1.2.4.1.1 "><p id="p3797mcpsimp"><a name="p3797mcpsimp"></a><a name="p3797mcpsimp"></a>taskID</p>
</td>
<td class="cellrowborder" valign="top" width="56.99999999999999%" headers="mcps1.2.4.1.2 "><p id="p3799mcpsimp"><a name="p3799mcpsimp"></a><a name="p3799mcpsimp"></a>Specifies the task ID.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3802mcpsimp"><a name="p3802mcpsimp"></a><a name="p3802mcpsimp"></a>[0,0xFFFFFFFF]</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section156611948521"></a>
- If no parameter is specified, the CPU usage of the system within the last 10 seconds is displayed. - If no parameter is specified, the CPU usage of the system within the last 10 seconds is displayed.
- If only **mode** is specified, the CPU usage within the specified period is displayed. - If only **mode** is specified, the CPU usage within the specified period is displayed.
- If both **mode** and **taskID** are specified, the CPU usage of the specified task within the given period is displayed. - If both **mode** and **taskID** are specified, the CPU usage of the specified task within the given period is displayed.
## Example<a name="section68501605319"></a>
## Example
Run **cpup 1 5**. Run **cpup 1 5**.
## Output<a name="section19871522144219"></a>
## Output
CPU usage of task 5 in the last one second: CPU usage of task 5 in the last one second:
...@@ -58,4 +44,3 @@ OHOS # cpup 1 5pid 5 ...@@ -58,4 +44,3 @@ OHOS # cpup 1 5pid 5
CpuUsage in 1s: 0.0 CpuUsage in 1s: 0.0
``` ```
# date # date
## Command Function<a name="section56472016338"></a>
## Command Function
This command is used to query the system date and time. This command is used to query the system date and time.
## Syntax<a name="section16635112512316"></a>
## Syntax
- date - date
- date --help - date --help
- date +\[_Format_\]
- date +[_Format_]
- date -u - date -u
## Parameters<a name="section15896030039"></a>
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table3825mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row3831mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p3833mcpsimp"><a name="p3833mcpsimp"></a><a name="p3833mcpsimp"></a>Parameter</p> | ------- | ------------------------------ | ---------------------- |
</th> | --help | Displays help information. | N/A |
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.4.1.2"><p id="p3835mcpsimp"><a name="p3835mcpsimp"></a><a name="p3835mcpsimp"></a>Description</p> | +Format | Prints the date and time in the specified format.| Placeholders listed in **--help**|
</th> | -u | Displays UTC (not the current time zone). | N/A |
<th class="cellrowborder" valign="top" width="28.999999999999996%" id="mcps1.2.4.1.3"><p id="p3837mcpsimp"><a name="p3837mcpsimp"></a><a name="p3837mcpsimp"></a>Value Range</p>
</th>
</tr> ## Usage Guidelines
</thead>
<tbody><tr id="row14667120409"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p5628123402"><a name="p5628123402"></a><a name="p5628123402"></a>--help</p> - If no parameter is specified, the system date and time in UTC format are displayed by default.
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.4.1.2 "><p id="p1162201234017"><a name="p1162201234017"></a><a name="p1162201234017"></a>Displays help information.</p>
</td>
<td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.4.1.3 "><p id="p11621412194011"><a name="p11621412194011"></a><a name="p11621412194011"></a>N/A</p>
</td>
</tr>
<tr id="row1566191264014"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p186211254017"><a name="p186211254017"></a><a name="p186211254017"></a>+Format</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.4.1.2 "><p id="p26216124407"><a name="p26216124407"></a><a name="p26216124407"></a>Prints the date and time in the specified <strong id="b115041849185916"><a name="b115041849185916"></a><a name="b115041849185916"></a>Format</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.4.1.3 "><p id="p46251220409"><a name="p46251220409"></a><a name="p46251220409"></a>Placeholders listed in <strong id="b36588246116"><a name="b36588246116"></a><a name="b36588246116"></a>--help</strong></p>
</td>
</tr>
<tr id="row1766111218401"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p146291274011"><a name="p146291274011"></a><a name="p146291274011"></a>-u</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.4.1.2 "><p id="p136291219403"><a name="p136291219403"></a><a name="p136291219403"></a>Displays UTC instead of the current time zone.</p>
</td>
<td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.4.1.3 "><p id="p5628129407"><a name="p5628129407"></a><a name="p5628129407"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section116361036636"></a>
- If no parameter is specified, the system UTC date and time are displayed by default.
- The **--help**, **+Format**, and **-u** parameters are mutually exclusive. - The **--help**, **+Format**, and **-u** parameters are mutually exclusive.
- Currently, this command cannot be used to set the time or date. - Currently, this command cannot be used to set the time or date.
## Example<a name="section021711411237"></a> ## Note
The shell does not support **date -u**. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run **date +%Y--%m--%d**. Run **date +%Y--%m--%d**.
## Output<a name="section17950184414312"></a>
## Output
System date in the specified format: System date in the specified format:
``` ```
OHOS:/$ date +%Y--%m--%d OHOS:/$ date +%Y--%m--%d
1970--01--01 1970--01--01
``` ```
# dmesg # dmesg
## Command Function<a name="section4643204919313"></a>
## Command Function
This command is used to display system boot and running information. This command is used to display system boot and running information.
## Syntax<a name="section6553153635"></a>
## Syntax
dmesg dmesg
dmesg \[_-c/-C/-D/-E/-L/-U_\] dmesg [_-c/-C/-D/-E/-L/-U_]
dmesg -s [_size_]
dmesg -s \[_size_\] dmesg -l [_level_]
dmesg -l \[_level_\] dmesg &gt; [_fileA_]
dmesg \> \[_fileA_\]
## Parameters<a name="section208971157532"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table3900mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row3906mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p3908mcpsimp"><a name="p3908mcpsimp"></a><a name="p3908mcpsimp"></a>Parameter</p> | --------------- | ---------------------------------------- | --------------- |
</th> | -c | Prints content in the buffer and clears the buffer. | N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p3910mcpsimp"><a name="p3910mcpsimp"></a><a name="p3910mcpsimp"></a>Description</p> | -C | Clears the buffer. | N/A |
</th> | -D/-E | Disables or enables printing to the console. | N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p3912mcpsimp"><a name="p3912mcpsimp"></a><a name="p3912mcpsimp"></a>Value Range</p> | -L/-U | Disables or enables printing via the serial port. | N/A |
</th> | -s&nbsp;size | Sets the size of the buffer. size specifies the buffer size to set.| N/A |
</tr> | -l&nbsp;level | Sets the buffering level. | [0, 5] |
</thead> | &gt;&nbsp;fileA | Writes the content in the buffer to a file. | N/A |
<tbody><tr id="row3913mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3915mcpsimp"><a name="p3915mcpsimp"></a><a name="p3915mcpsimp"></a>-c</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3917mcpsimp"><a name="p3917mcpsimp"></a><a name="p3917mcpsimp"></a>Prints content in the buffer and clears the buffer.</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3919mcpsimp"><a name="p3919mcpsimp"></a><a name="p3919mcpsimp"></a>N/A</p> - This command can be used only after **LOSCFG_SHELL_DMESG** is enabled. To enable **LOSCFG_SHELL_DMESG**, run the **make menuconfig** command in **kernel/liteos_a**. In the displayed dialog box, locate the **Debug** option and set **Enable Shell dmesg** to **Yes**.
</td> Debug ---&gt; Enable a Debug Version ---&gt; Enable Shell ---&gt; Enable Shell dmesg
</tr>
<tr id="row3920mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3922mcpsimp"><a name="p3922mcpsimp"></a><a name="p3922mcpsimp"></a>-C</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3924mcpsimp"><a name="p3924mcpsimp"></a><a name="p3924mcpsimp"></a>Clears the buffer.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3926mcpsimp"><a name="p3926mcpsimp"></a><a name="p3926mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row3927mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3929mcpsimp"><a name="p3929mcpsimp"></a><a name="p3929mcpsimp"></a>-D/-E</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3931mcpsimp"><a name="p3931mcpsimp"></a><a name="p3931mcpsimp"></a>Disables or enables printing to the console.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3933mcpsimp"><a name="p3933mcpsimp"></a><a name="p3933mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row3934mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3936mcpsimp"><a name="p3936mcpsimp"></a><a name="p3936mcpsimp"></a>-L/-U</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3938mcpsimp"><a name="p3938mcpsimp"></a><a name="p3938mcpsimp"></a>Disables or enables printing via the serial port.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3940mcpsimp"><a name="p3940mcpsimp"></a><a name="p3940mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row3941mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3943mcpsimp"><a name="p3943mcpsimp"></a><a name="p3943mcpsimp"></a>-s size</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3945mcpsimp"><a name="p3945mcpsimp"></a><a name="p3945mcpsimp"></a>Sets the size of the buffer.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3947mcpsimp"><a name="p3947mcpsimp"></a><a name="p3947mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row3948mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3950mcpsimp"><a name="p3950mcpsimp"></a><a name="p3950mcpsimp"></a>-l level</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3952mcpsimp"><a name="p3952mcpsimp"></a><a name="p3952mcpsimp"></a>Sets the buffering level.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3954mcpsimp"><a name="p3954mcpsimp"></a><a name="p3954mcpsimp"></a>0 - 5</p>
</td>
</tr>
<tr id="row3955mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3957mcpsimp"><a name="p3957mcpsimp"></a><a name="p3957mcpsimp"></a>&gt; fileA</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p717417317512"><a name="p717417317512"></a><a name="p717417317512"></a>Writes the content in the buffer to the specified file.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3961mcpsimp"><a name="p3961mcpsimp"></a><a name="p3961mcpsimp"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section213115219413"></a>
- This command depends on **LOSCFG\_SHELL\_DMESG**. Before using this command, select **Enable Shell dmesg** on **menuconfig**.
Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg
- If no parameter is specified, all content in the buffer is printed. - If no parameter is specified, all content in the buffer is printed.
- The parameters followed by hyphens \(-\) are mutually exclusive.
- The parameters followed by hyphens (-) are mutually exclusive.
1. Before writing content to a file, ensure that the file system has been mounted. 1. Before writing content to a file, ensure that the file system has been mounted.
2. Disabling the serial port printing will adversely affect shell. You are advised to set up a connection using Telnet before disabling the serial port. 2. Disabling the serial port printing will adversely affect shell. You are advised to set up a connection using Telnet before disabling the serial port.
## Example<a name="section13736564418"></a> ## Example
Run **dmesg\> dmesg.log**. Run **dmesg> dmesg.log**.
## Output<a name="section194005101413"></a>
Writing the content in the buffer to the **dmesg.log** file: ## Output
Write the content in the buffer to the **dmesg.log** file.
``` ```
OHOS # dmesg > dmesg.log OHOS # dmesg > dmesg.log
Dmesg write log to dmesg.log success Dmesg write log to dmesg.log success
``` ```
# exec # exec
## Command Function<a name="section4643204919313"></a> ## Command Function
This command is a built-in shell command used to execute user-mode programs. This command is a built-in shell command used to execute basic user-mode programs.
## Syntax<a name="section6553153635"></a>
exec <_executable-file_\> ## Syntax
## Parameters<a name="section208971157532"></a> exec &lt;*executable-file*&gt;
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table3900mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row3906mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p3908mcpsimp"><a name="p3908mcpsimp"></a><a name="p3908mcpsimp"></a>Parameter</p> | --------------- | ------------------ |
</th> | executable-file | Specifies a valid executable file.|
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p3910mcpsimp"><a name="p3910mcpsimp"></a><a name="p3910mcpsimp"></a>Description</p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p3912mcpsimp"><a name="p3912mcpsimp"></a><a name="p3912mcpsimp"></a>Value Range</p> ## Usage Guidelines
</th>
</tr>
</thead>
<tbody><tr id="row3913mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3915mcpsimp"><a name="p3915mcpsimp"></a><a name="p3915mcpsimp"></a>executable-file</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3917mcpsimp"><a name="p3917mcpsimp"></a><a name="p3917mcpsimp"></a>Indicates a valid executable file.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3919mcpsimp"><a name="p3919mcpsimp"></a><a name="p3919mcpsimp"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section213115219413"></a>
Currently, this command supports only valid binary programs. The programs are successfully executed and then run in the background by default. However, the programs share the same device with the shell. As a result, the output of the programs and the shell may be interlaced. Currently, this command supports only valid binary programs. The programs are successfully executed and then run in the background by default. However, the programs share the same device with the shell. As a result, the output of the programs and the shell may be interlaced.
## Example<a name="section13736564418"></a>
Example: ## Example
Run **exec helloworld**. Run **exec helloworld**.
## Output<a name="section194005101413"></a>
## Output
``` ```
OHOS # exec helloworld OHOS # exec helloworld
OHOS # hello world! OHOS # hello world!
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > **NOTE**<br>
>After the executable file is executed, the prompt **OHOS \#** is printed first. The shell **exec** command is executed in the background, causing the prompt to be printed in advance. > After the executable file is executed, the prompt **OHOS #** is printed first. The shell **exec** command is executed in the background, causing the prompt to be printed in advance.
# free # free
## Command Function<a name="section175151514841"></a>
## Command Function
This command is used to display the memory usage in the system. This command is used to display the memory usage in the system.
## Syntax<a name="section8488721749"></a>
free \[_-b | -k | -m | -g | -t_\] ## Syntax
free [_-b | -k | -m | -g | -t_]
## Parameters<a name="section27272181949"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table110mcpsimp"></a> | Parameter| Description |
<table><thead align="left"><tr id="row116mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p118mcpsimp"><a name="p118mcpsimp"></a><a name="p118mcpsimp"></a>Parameter</p> | -------- | -------- |
</th> | No parameter| Displays the memory usage in bytes.|
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p120mcpsimp"><a name="p120mcpsimp"></a><a name="p120mcpsimp"></a>Description</p> | --help/-h | Displays the parameters supported by the **free** command.|
</th> | -b | Displays the memory usage in bytes.|
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p122mcpsimp"><a name="p122mcpsimp"></a><a name="p122mcpsimp"></a>Value Range</p> | -k | Display the memory waterline in KiB.|
</th> | -m | Display the memory waterline in MiB.|
</tr> | -g | Displays the memory usage in GiB.|
</thead> | -t | Displays the memory usage in TiB.|
<tbody><tr id="row1250317052114"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p44861016218"><a name="p44861016218"></a><a name="p44861016218"></a>No parameter</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p64861302212"><a name="p64861302212"></a><a name="p64861302212"></a>Displays the memory usage in bytes.</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1248619010215"><a name="p1248619010215"></a><a name="p1248619010215"></a>N/A</p> None.
</td>
</tr>
<tr id="row2503160182110"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1948618017215"><a name="p1948618017215"></a><a name="p1948618017215"></a>--help/-h</p> ## Example
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1648617012214"><a name="p1648617012214"></a><a name="p1648617012214"></a>Displays the parameters supported by the <strong id="b1247315411335"><a name="b1247315411335"></a><a name="b1247315411335"></a>free</strong> command.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p11486205219"><a name="p11486205219"></a><a name="p11486205219"></a>N/A</p>
</td>
</tr>
<tr id="row150318082111"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p164861709216"><a name="p164861709216"></a><a name="p164861709216"></a>-b</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p54864013214"><a name="p54864013214"></a><a name="p54864013214"></a>Displays the memory usage in bytes.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p124862014218"><a name="p124862014218"></a><a name="p124862014218"></a>N/A</p>
</td>
</tr>
<tr id="row750330162116"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1848615072110"><a name="p1848615072110"></a><a name="p1848615072110"></a>-k</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1648670192120"><a name="p1648670192120"></a><a name="p1648670192120"></a>Displays the memory usage in KiB.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p124861301216"><a name="p124861301216"></a><a name="p124861301216"></a>N/A</p>
</td>
</tr>
<tr id="row105021082114"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p20486100122114"><a name="p20486100122114"></a><a name="p20486100122114"></a>-m</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p134869022114"><a name="p134869022114"></a><a name="p134869022114"></a>Displays the memory usage in MiB.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p124868015219"><a name="p124868015219"></a><a name="p124868015219"></a>N/A</p>
</td>
</tr>
<tr id="row95021909216"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p114861408218"><a name="p114861408218"></a><a name="p114861408218"></a>-g</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p348680122118"><a name="p348680122118"></a><a name="p348680122118"></a>Displays the memory usage in GiB.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p64866011217"><a name="p64866011217"></a><a name="p64866011217"></a>N/A</p>
</td>
</tr>
<tr id="row125026092116"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p19486101218"><a name="p19486101218"></a><a name="p19486101218"></a>-t</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p18486140132118"><a name="p18486140132118"></a><a name="p18486140132118"></a>Displays the memory usage in TiB.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p048620142111"><a name="p048620142111"></a><a name="p048620142111"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section148661259410"></a>
None
## Example<a name="section68081530242"></a>
Run **free**, **free -k**, and **free -m**, respectively. Run **free**, **free -k**, and **free -m**, respectively.
## Output<a name="section171235517543"></a>
## Output
``` ```
OHOS:/$ free OHOS:/$ free
...@@ -101,40 +57,13 @@ Mem: 2 2 0 0 0 ...@@ -101,40 +57,13 @@ Mem: 2 2 0 0 0
Swap: 0 0 0 Swap: 0 0 0
``` ```
**Table 2** Output **Table 2** Output description
<a name="table633mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row638mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p640mcpsimp"><a name="p640mcpsimp"></a><a name="p640mcpsimp"></a>Parameter</p> | -------- | -------- |
</th> | total | Total size of the dynamic memory pool.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p642mcpsimp"><a name="p642mcpsimp"></a><a name="p642mcpsimp"></a>Description</p> | used | Size of the used memory.|
</th> | free | Size of the unallocated memory.|
</tr> | shared | Size of the shared memory.|
</thead> | buffers | Size of the buffer.|
<tbody><tr id="row3746215112211"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p57373157224"><a name="p57373157224"></a><a name="p57373157224"></a>total</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1737315202218"><a name="p1737315202218"></a><a name="p1737315202218"></a>Total size of the dynamic memory pool</p>
</td>
</tr>
<tr id="row16746161582219"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1173731512215"><a name="p1173731512215"></a><a name="p1173731512215"></a>used</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p197376156222"><a name="p197376156222"></a><a name="p197376156222"></a>Size of the used memory</p>
</td>
</tr>
<tr id="row174661542216"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p8737141519228"><a name="p8737141519228"></a><a name="p8737141519228"></a>free</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p97371915142218"><a name="p97371915142218"></a><a name="p97371915142218"></a>Size of the unallocated memory</p>
</td>
</tr>
<tr id="row1274520152227"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1073821542210"><a name="p1073821542210"></a><a name="p1073821542210"></a>shared</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1773801514223"><a name="p1773801514223"></a><a name="p1773801514223"></a>Size of the shared memory</p>
</td>
</tr>
<tr id="row07452153229"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p773811512229"><a name="p773811512229"></a><a name="p773811512229"></a>buffers</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p157381015192216"><a name="p157381015192216"></a><a name="p157381015192216"></a>Size of the buffer</p>
</td>
</tr>
</tbody>
</table>
# help # help
## Command Function<a name="section991211345413"></a>
## Command Function
This command is used to display all commands in the OS and some Toybox commands. This command is used to display all commands in the OS and some Toybox commands.
## Syntax<a name="section19103204016410"></a>
## Syntax
help help
## Parameters<a name="section1533416233432"></a>
None ## Parameters
None.
## Usage<a name="section4156445417"></a> ## Usage Guidelines
You can run **help** to display all commands in the current OS. You can run **help** to display all commands in the current OS.
## Example<a name="section12776124712417"></a>
## Example
Run **help**. Run **help**.
## Output<a name="section092662412544"></a>
## Output
All commands in the system: All commands in the system:
``` ```
After shell prompt "OHOS # ": After shell prompt "OHOS # ":
Use `<cmd> [args ...]` to run built-in shell commands listed above. Use `<cmd> [args ...]` to run built-in shell commands listed above.
Use `exec <cmd> [args ...]` or `./<cmd> [args ...]` to run external commands. Use `exec <cmd> [args ...]` or `./<cmd> [args ...]` to run external commands.
OHOS:/$ help OHOS:/$ help
*******************shell commands:************************* ***shell commands:*
arp cat cat_logmpp cd chgrp chmod arp cat cat_logmpp cd chgrp chmod
chown cp cpup date dhclient dmesg chown cp cpup date dhclient dmesg
dns format free help hi3881 hwi dns format free help hi3881 hwi
...@@ -44,11 +51,10 @@ watch writeproc ...@@ -44,11 +51,10 @@ watch writeproc
After shell prompt "OHOS # ": After shell prompt "OHOS # ":
Use `<cmd> [args ...]` to run built-in shell commands listed above. Use `<cmd> [args ...]` to run built-in shell commands listed above.
Use `exec <cmd> [args ...]` or `./<cmd> [args ...]` to run external commands. Use `exec <cmd> [args ...]` or `./<cmd> [args ...]` to run external commands.
*******************toybox commands:************************ ***toybox commands:
chgrp chmod chown cp date du free help ifconfig kill ls mkdir mount chgrp chmod chown cp date du free help ifconfig kill ls mkdir mount
mv ping ps reboot rm rmdir top touch umount uname mv ping ps reboot rm rmdir top touch umount uname
Use `toybox help [command]` to show usage information for a specific command. Use `toybox help [command]` to show usage information for a specific command.
Use `shell` to enter interactive legacy shell. Use `shell` to enter interactive legacy shell.
Use `alias` to display command aliases. Use `alias` to display command aliases.
``` ```
# hwi # hwi
## Command Function<a name="section445335110416"></a>
## Command Function
This command is used to query information about interrupts. This command is used to query information about interrupts.
## Syntax<a name="section1795712553416"></a>
## Syntax
hwi hwi
## Parameters<a name="section92544592410"></a>
None ## Parameters
None.
## Usage<a name="section104151141252"></a>
## Usage Guidelines
- Run **hwi** to display the interrupt IDs, count of interrupts, and registered interrupt names of the system. - Run **hwi** to display the interrupt IDs, count of interrupts, and registered interrupt names of the system.
- If **LOSCFG\_CPUP\_INCLUDE\_IRQ** is enabled, the interrupt handling time \(ATime\), CPU usage, and type of each interrupt are also displayed.
## Example<a name="section11545171957"></a> - If **LOSCFG_CPUP_INCLUDE_IRQ** is enabled, the interrupt handling time (ATime), CPU usage, and type of each interrupt are also displayed.
## Example
Run **hwi**. Run **hwi**.
## Output<a name="section075617368542"></a>
- Interrupt information \(**LOSCFG\_CPUP\_INCLUDE\_IRQ** disabled\): ## Output
- Interrupt information (**LOSCFG_CPUP_INCLUDE_IRQ** disabled):
``` ```
OHOS # hwi OHOS # hwi
...@@ -61,7 +68,7 @@ Run **hwi**. ...@@ -61,7 +68,7 @@ Run **hwi**.
102: 0: SPI_HI35XX 102: 0: SPI_HI35XX
``` ```
- Interrupt information \(**LOSCFG\_CPUP\_INCLUDE\_IRQ** enabled\): - Interrupt information (**LOSCFG_CPUP_INCLUDE_IRQ** enabled):
``` ```
OHOS # hwi OHOS # hwi
...@@ -99,57 +106,15 @@ Run **hwi**. ...@@ -99,57 +106,15 @@ Run **hwi**.
102: 0 0 0.0 0.0 0.0 normal SPI_HI35XX 102: 0 0 0.0 0.0 0.0 normal SPI_HI35XX
``` ```
**Table 1** Output **Table 1** Output description
<a name="table809mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row814mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p816mcpsimp"><a name="p816mcpsimp"></a><a name="p816mcpsimp"></a>Parameter</p> | -------- | -------- |
</th> | InterruptNo | Interrupt number.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p818mcpsimp"><a name="p818mcpsimp"></a><a name="p818mcpsimp"></a>Description</p> | Count | Number of interrupts.|
</th> | Name | Registered interrupt name.|
</tr> | ATime | Interrupt handling time.|
</thead> | CPUUSE | CPU usage.|
<tbody><tr id="row20360171311398"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p172391401402"><a name="p172391401402"></a><a name="p172391401402"></a>InterruptNo</p> | CPUUSE10s | CPU usage in the last 10s.|
</td> | CPUUSE1s | CPU usage in the last 1s.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p42381940174013"><a name="p42381940174013"></a><a name="p42381940174013"></a>Interrupt ID</p> | mode | Interrupt type, which can be any of the following:<br>- **normal**: non-shared interrupt.<br>- **shared**: shared interrupt.|
</td>
</tr>
<tr id="row262535153913"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1823824014402"><a name="p1823824014402"></a><a name="p1823824014402"></a>Count</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p14237040144018"><a name="p14237040144018"></a><a name="p14237040144018"></a>Number of interrupts</p>
</td>
</tr>
<tr id="row9683953153916"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p6236124084018"><a name="p6236124084018"></a><a name="p6236124084018"></a>Name</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p18235164014401"><a name="p18235164014401"></a><a name="p18235164014401"></a>Registered interrupt name</p>
</td>
</tr>
<tr id="row85721136402"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1123434017409"><a name="p1123434017409"></a><a name="p1123434017409"></a>ATime</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2023424094014"><a name="p2023424094014"></a><a name="p2023424094014"></a>Interrupt handling time</p>
</td>
</tr>
<tr id="row19180126151415"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p6233040164020"><a name="p6233040164020"></a><a name="p6233040164020"></a>CPUUSE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p5232840104015"><a name="p5232840104015"></a><a name="p5232840104015"></a>CPU usage</p>
</td>
</tr>
<tr id="row511517331702"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p14231040164014"><a name="p14231040164014"></a><a name="p14231040164014"></a>CPUUSE10s</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1323011409405"><a name="p1323011409405"></a><a name="p1323011409405"></a>CPU usage within the last 10 seconds</p>
</td>
</tr>
<tr id="row1868124415413"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p9681144414114"><a name="p9681144414114"></a><a name="p9681144414114"></a>CPUUSE1s</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p76814443417"><a name="p76814443417"></a><a name="p76814443417"></a>CPU usage within the last 1 second</p>
</td>
</tr>
<tr id="row7681164454112"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1968124412411"><a name="p1968124412411"></a><a name="p1968124412411"></a>mode</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p268134415419"><a name="p268134415419"></a><a name="p268134415419"></a>Interrupt type, which can be any of the following:</p>
<a name="ul682912412419"></a><a name="ul682912412419"></a><ul id="ul682912412419"><li><strong id="b35357873733839"><a name="b35357873733839"></a><a name="b35357873733839"></a>normal</strong>: non-shared interrupt.</li><li><strong id="b209107492433839"><a name="b209107492433839"></a><a name="b209107492433839"></a>shared</strong>: shared interrupt.</li></ul>
</td>
</tr>
</tbody>
</table>
# kill # kill
## Command Function<a name="section366714216619"></a>
This command is used to send a signal to a specified process. ## Command Function
## Syntax<a name="section8833164614615"></a> This command is used to send a signal to a process to terminate the abnormal application.
kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._
## Parameters<a name="section12809111019453"></a> ## Syntax
kill [-l [_signo_] | _-s signo_ | _-signo_] *pid...*
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table438mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row444mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p446mcpsimp"><a name="p446mcpsimp"></a><a name="p446mcpsimp"></a>Parameter</p> | ------ | -------------------------- | ----------- |
</th> | --help | Displays the parameters supported by the **kill** command.| N/A |
<th class="cellrowborder" valign="top" width="51.92%" id="mcps1.2.4.1.2"><p id="p448mcpsimp"><a name="p448mcpsimp"></a><a name="p448mcpsimp"></a>Description</p> | -l | Lists the names and numbers of signals. | N/A |
</th> | -s | Sends a signal. | N/A |
<th class="cellrowborder" valign="top" width="27.08%" id="mcps1.2.4.1.3"><p id="p450mcpsimp"><a name="p450mcpsimp"></a><a name="p450mcpsimp"></a>Value Range</p> | signo | Specifies the signal number. | [1, 30] |
</th> | pid | Specifies the process ID. | [1, MAX_INT] |
</tr>
</thead> > **NOTICE**<br>
<tbody><tr id="row6412714183316"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p940219144332"><a name="p940219144332"></a><a name="p940219144332"></a>--help</p> > The value range of **signo** is [0, 64]. The recommended value range is [1, 30], and other values in the value range are reserved.
</td>
<td class="cellrowborder" valign="top" width="51.92%" headers="mcps1.2.4.1.2 "><p id="p3402191493310"><a name="p3402191493310"></a><a name="p3402191493310"></a>Displays the parameters supported by the <strong id="b277973411569"><a name="b277973411569"></a><a name="b277973411569"></a>kill</strong> command.</p>
</td> ## Usage Guidelines
<td class="cellrowborder" valign="top" width="27.08%" headers="mcps1.2.4.1.3 "><p id="p4402161493316"><a name="p4402161493316"></a><a name="p4402161493316"></a>N/A</p>
</td>
</tr>
<tr id="row114122143330"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p0402314103315"><a name="p0402314103315"></a><a name="p0402314103315"></a>-l</p>
</td>
<td class="cellrowborder" valign="top" width="51.92%" headers="mcps1.2.4.1.2 "><p id="p640281413313"><a name="p640281413313"></a><a name="p640281413313"></a>Lists the names and numbers of signals.</p>
</td>
<td class="cellrowborder" valign="top" width="27.08%" headers="mcps1.2.4.1.3 "><p id="p19402191416337"><a name="p19402191416337"></a><a name="p19402191416337"></a>N/A</p>
</td>
</tr>
<tr id="row12412131493314"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1240220141335"><a name="p1240220141335"></a><a name="p1240220141335"></a>-s</p>
</td>
<td class="cellrowborder" valign="top" width="51.92%" headers="mcps1.2.4.1.2 "><p id="p8402131411331"><a name="p8402131411331"></a><a name="p8402131411331"></a>Sends signals</p>
</td>
<td class="cellrowborder" valign="top" width="27.08%" headers="mcps1.2.4.1.3 "><p id="p140211415339"><a name="p140211415339"></a><a name="p140211415339"></a>N/A</p>
</td>
</tr>
<tr id="row1441281443320"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p14402171410332"><a name="p14402171410332"></a><a name="p14402171410332"></a>signo</p>
</td>
<td class="cellrowborder" valign="top" width="51.92%" headers="mcps1.2.4.1.2 "><p id="p114023144336"><a name="p114023144336"></a><a name="p114023144336"></a>Specifies the signal number.</p>
</td>
<td class="cellrowborder" valign="top" width="27.08%" headers="mcps1.2.4.1.3 "><p id="p240212145333"><a name="p240212145333"></a><a name="p240212145333"></a>[1,30]</p>
</td>
</tr>
<tr id="row13411714143310"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p5402131463314"><a name="p5402131463314"></a><a name="p5402131463314"></a>pid</p>
</td>
<td class="cellrowborder" valign="top" width="51.92%" headers="mcps1.2.4.1.2 "><p id="p7402014113310"><a name="p7402014113310"></a><a name="p7402014113310"></a>Specifies the process ID.</p>
</td>
<td class="cellrowborder" valign="top" width="27.08%" headers="mcps1.2.4.1.3 "><p id="p24021514183317"><a name="p24021514183317"></a><a name="p24021514183317"></a>[1,MAX_INT]</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-notice.gif) **NOTICE:**
>The value range of **signo** is \[0, 64\]. The recommended value range is \[1, 30\], and other values in the value range are reserved.
## Usage<a name="section15935131220717"></a>
- The **signo** and **pid** parameters are mandatory. - The **signo** and **pid** parameters are mandatory.
- The **pid** value range varies depending on the system configuration. For example, if the maximum **pid** value supported by the system is **256**, this value range is \[1-256\].
## Example<a name="section79281818476"></a> - The **pid** value range varies depending on the system configuration. For example, if the maximum **pid** value supported by the system is **256**, this value range is [1, 256].
## Note
The **kill** command is not supported by the shell. mksh supports it. To switch to mksh, run **cd bin;** and **./mksh**.
## Example
- Query the process list before killing process 42. - Query the process list before killing process 42.
...@@ -83,6 +53,7 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._ ...@@ -83,6 +53,7 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._
6 1 6 0 Pending 0x688000 0x137000 0x11bca0 0.0 media_server 6 1 6 0 Pending 0x688000 0x137000 0x11bca0 0.0 media_server
7 1 7 0 Pending 0x9d2000 0x103000 0xa1cdf 0.88 wms_server 7 1 7 0 Pending 0x9d2000 0x103000 0xa1cdf 0.88 wms_server
8 1 8 2 Pending 0x1f5000 0x48000 0x47dc2 0.2 mksh 8 1 8 2 Pending 0x1f5000 0x48000 0x47dc2 0.2 mksh
10 5 5 101 Pending 0x11ec000 0x2f9000 0x206047 0.93 com.example.launcher
12 1 12 0 Pending 0x4d4000 0x112000 0xe0882 0.0 deviceauth_service 12 1 12 0 Pending 0x4d4000 0x112000 0xe0882 0.0 deviceauth_service
13 1 13 0 Pending 0x34f000 0xbd000 0x51799 0.0 sensor_service 13 1 13 0 Pending 0x34f000 0xbd000 0x51799 0.0 sensor_service
14 1 14 2 Pending 0x34e000 0xb3000 0x52184 0.0 ai_server 14 1 14 2 Pending 0x34e000 0xb3000 0x52184 0.0 ai_server
...@@ -91,7 +62,7 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._ ...@@ -91,7 +62,7 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._
43 8 43 2 Running 0x1d7000 0x3a000 0x1e577 0.0 toybox 43 8 43 2 Running 0x1d7000 0x3a000 0x1e577 0.0 toybox
``` ```
- Send signal 9 \(the default action of **SIGKILL** is to immediately terminate the process\) to process 42 test\_demo \(a user-mode process\). Then, check the current process list. The commands **kill -s 9 42** and **kill -9 42** have the same effect. - Send signal 9 (the default action of **SIGKILL** is to immediately terminate the process) to process 42 test_demo (a user-mode process). Then, check the current process list. The commands **kill -s 9 42** and **kill -9 42** have the same effect.
``` ```
OHOS:/$ kill -s 9 42 OHOS:/$ kill -s 9 42
...@@ -108,6 +79,7 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._ ...@@ -108,6 +79,7 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._
6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server
7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.89 wms_server 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.89 wms_server
8 1 8 2 Pending 0x1f5000 0x48000 0x482dc 0.2 mksh 8 1 8 2 Pending 0x1f5000 0x48000 0x482dc 0.2 mksh
10 5 5 101 Pending 0x11ec000 0x2f9000 0x206561 0.93 com.example.launcher
12 1 12 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_service 12 1 12 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_service
13 1 13 0 Pending 0x34f000 0xbd000 0x51cb3 0.0 sensor_service 13 1 13 0 Pending 0x34f000 0xbd000 0x51cb3 0.0 sensor_service
14 1 14 2 Pending 0x34e000 0xb3000 0x5269e 0.0 ai_server 14 1 14 2 Pending 0x34e000 0xb3000 0x5269e 0.0 ai_server
...@@ -117,9 +89,13 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._ ...@@ -117,9 +89,13 @@ kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._
- Run the **kill -100 31** command. - Run the **kill -100 31** command.
## Output<a name="section12742311179"></a>
**Example 1**: The signal is successfully sent to process 42. ## Output
The command output is as follows:
Example 1: The signal is successfully sent to process 42.
``` ```
OHOS:/$ kill -s 9 42 OHOS:/$ kill -s 9 42
...@@ -131,10 +107,10 @@ Process 42 is killed. ...@@ -131,10 +107,10 @@ Process 42 is killed.
**Example 2**: The signal fails to be sent to process 31. **Example 2**: The signal fails to be sent to process 31.
``` ```
OHOS:/$ kill -100 31 OHOS:/$ kill -100 31
kill: Unknown signal '(null)' kill: Unknown signal '(null)'
``` ```
**Unknown signal '\(null\)'** is displayed because the **signo** value **100** exceeds the value range \[0, 64\]. **Unknown signal '(null)'** is displayed because the **signo** value **100** exceeds the value range [0, 64].
# log # log
## Command Function<a name="section128219131856"></a>
## Command Function
This command is used to set and query log configuration. This command is used to set and query log configuration.
## Syntax<a name="section3894181710519"></a>
log level \[_levelNum_\] ## Syntax
log level [_levelNum_]
## Parameters<a name="section7693122310515"></a>
**Table 1** Parameter description
<a name="table237mcpsimp"></a> ## Parameters
<table><thead align="left"><tr id="row243mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p245mcpsimp"><a name="p245mcpsimp"></a><a name="p245mcpsimp"></a><strong id="b3369319192013"><a name="b3369319192013"></a><a name="b3369319192013"></a>Parameter</strong></p>
</th> **Table 1** Parameter description
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p247mcpsimp"><a name="p247mcpsimp"></a><a name="p247mcpsimp"></a><strong id="b12646112413211"><a name="b12646112413211"></a><a name="b12646112413211"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p249mcpsimp"><a name="p249mcpsimp"></a><a name="p249mcpsimp"></a><strong id="b13881153318285"><a name="b13881153318285"></a><a name="b13881153318285"></a>Value Range</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row250mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p252mcpsimp"><a name="p252mcpsimp"></a><a name="p252mcpsimp"></a>levelNum</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p254mcpsimp"><a name="p254mcpsimp"></a><a name="p254mcpsimp"></a>Specifies the level of logs to print.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2270121719813"><a name="p2270121719813"></a><a name="p2270121719813"></a>[0,5]</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section1982111281512"></a> | Parameter| Description| Value Range|
| -------- | -------- | -------- |
| levelNum | Specifies the level of logs to print.| [0, 5] |
- This command depends on **LOSCFG\_SHELL\_LK**. Before using this command, select **Enable Shell lk** on **menuconfig**.
**Debug** ---\> **Enable a Debug Version** ---\> **Enable Shell** ---\> **Enable Shell lK** ## Usage Guidelines
- The **log level** command is used to set the log level, which can be any of the following: - This command can be used only after **LOSCFG_SHELL_LK** is enabled. Before using this command, set **Enable Shell lk** to **Yes** on **menuconfig**.
**Debug** ---&gt; **Enable a Debug Version** ---&gt; **Enable Shell** ---&gt; **Enable Shell lK**
TRACE\_EMG = 0, - The **log level** command sets the log level, which can be any of the following:
TRACE_EMG = 0,
TRACE\_COMMON = 1, TRACE_COMMON = 1,
TRACE\_ERROR = 2, TRACE_ERROR = 2,
TRACE\_WARN = 3, TRACE_WARN = 3,
TRACE\_INFO = 4, TRACE_INFO = 4,
TRACE\_DEBUG = 5 TRACE_DEBUG = 5
If the log level specified is not within the value range, a message will be displayed. If the log level specified is not within the value range, a message will be displayed.
- If **\[levelNum\]** is not specified, this command queries the current log level. The usage method is also displayed. - If **[levelNum]** is not specified, this command displays the current log level and how to use it.
- If the log level is set to **4** or **5** in the source code of the open-source small system, a large number of logs will be printed.
## Example<a name="section176301333259"></a> - If the log level is set to **4** or **5** in the source code of an OpenHarmony small system, a large number of logs will be printed.
## Example
Run **log level 3**. Run **log level 3**.
## Output<a name="section14354765415"></a>
Setting the log print level to WARN: ## Output
The log print level is set to WARN.
``` ```
OHOS # log level 3 OHOS # log level 3
Set current log level WARN Set current log level WARN
``` ```
# memcheck # memcheck
## Command Function<a name="section191633812516"></a>
## Command Function
This command is used to check whether the dynamically allocated memory block is complete and whether nodes in the memory pool are damaged due to out-of-bounds memory access. This command is used to check whether the dynamically allocated memory block is complete and whether nodes in the memory pool are damaged due to out-of-bounds memory access.
## Syntax<a name="section428816435510"></a>
## Syntax
memcheck memcheck
## Parameters<a name="section1939943304411"></a>
None ## Parameters
None.
## Usage<a name="section228914491951"></a>
## Usage Guidelines
- If all nodes in the memory pool are complete, "system memcheck over, all passed!" is displayed. - If all nodes in the memory pool are complete, "system memcheck over, all passed!" is displayed.
- If a node in the memory pool is incomplete, information about the memory block of the corrupted node is displayed. - If a node in the memory pool is incomplete, information about the memory block of the corrupted node is displayed.
## Example<a name="section17373205314515"></a>
## Example
Run **memcheck**. Run **memcheck**.
## Output<a name="section13406205385413"></a> Run **memcheck**, and memory overwriting occurs.
Example 1: All nodes in the memory pool are complete. ## Output
Example 1: No error is detected.
``` ```
OHOS # memcheck OHOS # memcheck
system memcheck over, all passed! system memcheck over, all passed!
``` ```
Example 2: Out-of-bounds memory access is detected. Example 2: Memory overwriting is detected.
``` ```
[L0S DLnkCheckMenl 349, memory check [L0S DLnkCheckMenl 349, memory check
...@@ -43,7 +52,7 @@ puмExcBuffAddr pc = 0x803ad7a4 ...@@ -43,7 +52,7 @@ puмExcBuffAddr pc = 0x803ad7a4
puwExcBuffAddr lr = 0x803ad7a4 puwExcBuffAddr lr = 0x803ad7a4
puwExcBuffAddr sp = 0х80cb7de0 puwExcBuffAddr sp = 0х80cb7de0
puwExcBuffAddr fp = 0x80cb7dec puwExcBuffAddr fp = 0x80cb7dec
*******backtrace begin******* ***backtrace begin***
traceback 0 -- lr = 0х8037cb84 traceback 0 -- lr = 0х8037cb84
traceback 0 -- fp = 0х80cb7e1c traceback 0 -- fp = 0х80cb7e1c
traceback 1 -- lr = 0х8037033c traceback 1 -- lr = 0х8037033c
...@@ -55,4 +64,3 @@ traceback 3 -- fp = 0х80cb7ea4 ...@@ -55,4 +64,3 @@ traceback 3 -- fp = 0х80cb7ea4
traceback 4 -- lr = 0x803ad9e8 traceback 4 -- lr = 0x803ad9e8
traceback 4 -- fp = 9x11111111 traceback 4 -- fp = 9x11111111
``` ```
# oom # oom
## Command Function<a name="section366714216619"></a>
## Command Function
This command is used to query and set the low memory threshold and the PageCache reclaim threshold. This command is used to query and set the low memory threshold and the PageCache reclaim threshold.
## Syntax<a name="section8833164614615"></a>
## Syntax
oom oom
oom -i \[_interval_\] oom -i [_interval_]
oom -m \[_mem byte_\] oom -m [_mem byte_]
oom -r \[_mem byte_\] oom -r [_mem byte_]
oom -h | --help oom -h | --help
## Parameters<a name="section12809111019453"></a>
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table438mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row444mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p446mcpsimp"><a name="p446mcpsimp"></a><a name="p446mcpsimp"></a>Parameter</p> | ----------------------- | ------------------------------- | ------------------------------------------------------------ |
</th> | -i [interval] | Sets the interval (in ms) for checking the Out Of Memory (OOM) thread task.| [100, 10000] |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p448mcpsimp"><a name="p448mcpsimp"></a><a name="p448mcpsimp"></a>Description</p> | -m [mem byte] | Sets the low memory threshold (in MB). | 0 to 1<br>The value **0** means not to perform the low memory threshold check. |
</th> | -r [mem byte] | Sets the PageCache reclaim threshold. | Low memory threshold to the maximum available memory of the system<br>Generally, the size of a PageCache is 4 KB. Sometimes, it is 16 KB to 64 KB. |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p450mcpsimp"><a name="p450mcpsimp"></a><a name="p450mcpsimp"></a>Value Range</p> | -h \| --help | Displays help information. | N/A |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row451mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p5196112612119"><a name="p5196112612119"></a><a name="p5196112612119"></a>-i [interval]</p>
</td> If no parameter is specified, this command displays the current OOM configuration.
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1149945111817"><a name="p1149945111817"></a><a name="p1149945111817"></a>Sets the interval (in ms) for checking the Out Of Memory (OOM) thread task.</p>
</td> > **NOTE**<br>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p749810571812"><a name="p749810571812"></a><a name="p749810571812"></a>100 to 10000</p> > If the system memory is insufficient, the system displays a message indicating the insufficiency.
</td>
</tr>
<tr id="row18583553793"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p95841853292"><a name="p95841853292"></a><a name="p95841853292"></a>-m [mem byte]</p> ## Example
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2058485315912"><a name="p2058485315912"></a><a name="p2058485315912"></a>Sets the low memory threshold (in MB).</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1584105318917"><a name="p1584105318917"></a><a name="p1584105318917"></a>0 (disables the low memory check) to 1</p>
</td>
</tr>
<tr id="row17926124131218"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p49266245128"><a name="p49266245128"></a><a name="p49266245128"></a>-r [mem byte]</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p159263241121"><a name="p159263241121"></a><a name="p159263241121"></a>Sets the PageCache reclaim threshold.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p692642412121"><a name="p692642412121"></a><a name="p692642412121"></a>Ranging from the low memory threshold to the maximum available system memory</p>
</td>
</tr>
<tr id="row1176110379557"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p4762113745519"><a name="p4762113745519"></a><a name="p4762113745519"></a>-h | --help</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p9762113775517"><a name="p9762113775517"></a><a name="p9762113775517"></a>Displays help information.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p7762133765511"><a name="p7762133765511"></a><a name="p7762133765511"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section15935131220717"></a>
If no parameter is specified, this command displays the current OOM configuration.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>If the system memory is insufficient, the system displays a message indicating the insufficiency.
## Example<a name="section387104374416"></a>
Run the following commands: Run the following commands:
- oom - oom
- oom -i 100 - oom -i 100
## Output<a name="section12742311179"></a>
Example 1: displaying OOM configuration ## Output
Example 1: The OOM configuration is displayed by default.
``` ```
OHOS:/$ oom OHOS:/$ oom
...@@ -88,6 +62,7 @@ OHOS:/$ oom ...@@ -88,6 +62,7 @@ OHOS:/$ oom
Information displayed when the system memory is insufficient: Information displayed when the system memory is insufficient:
``` ```
T:20 Enter:IT MEM 00M 001 T:20 Enter:IT MEM 00M 001
[oom] OS is in low memory state [oom] OS is in low memory state
...@@ -124,7 +99,7 @@ R10 = 0xa0a0a0a ...@@ -124,7 +99,7 @@ R10 = 0xa0a0a0a
R11 = 0x20e20c8c R11 = 0x20e20c8c
R12 = 0х0 R12 = 0х0
CPSR = 0х80000010 CPSR = 0х80000010
*******backtrace beain******* ***backtrace beain***
traceback 0 -- lr = 0x9242e1c fp = 0х20e20cc4 lr in /usr/bin/testsuits apr 0x4be1c traceback 0 -- lr = 0x9242e1c fp = 0х20e20cc4 lr in /usr/bin/testsuits apr 0x4be1c
traceback 1 -- 1r = 0х92430cc fp = 0x20e20cdc lr in /usr/bin/testsuits app --> 0x4c0cc traceback 1 -- 1r = 0х92430cc fp = 0x20e20cdc lr in /usr/bin/testsuits app --> 0x4c0cc
traceback 2 -- 1r = 0x9396ab0 fp = 0x20e20cec lr in /usr/bin/testsuits app -> 0х19fab0 traceback 2 -- 1r = 0x9396ab0 fp = 0x20e20cec lr in /usr/bin/testsuits app -> 0х19fab0
...@@ -133,49 +108,23 @@ traceback 4 -- lr = 0x92427d4 fp = 0x20e20d44 lr in /usr/bin/testsuits app --> 0 ...@@ -133,49 +108,23 @@ traceback 4 -- lr = 0x92427d4 fp = 0x20e20d44 lr in /usr/bin/testsuits app --> 0
traceback 5 -- 1r = 0x20c4df50 fp = 0хb0b0b0b 1r in /1ib/libc.so - -> 0x62f50 traceback 5 -- 1r = 0x20c4df50 fp = 0хb0b0b0b 1r in /1ib/libc.so - -> 0x62f50
``` ```
Example 2: setting the OOM check interval to 100 ms
Example 2: The OOM check interval is set to 100 ms.
``` ```
OHOS:/$ oom -i 100 OHOS:/$ oom -i 100
[oom] set oom check interval (100)ms successful [oom] set oom check interval (100)ms successful
``` ```
**Table 2** Output
<a name="table487mcpsimp"></a>
<table><thead align="left"><tr id="row492mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p494mcpsimp"><a name="p494mcpsimp"></a><a name="p494mcpsimp"></a>Output</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p496mcpsimp"><a name="p496mcpsimp"></a><a name="p496mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row502mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p583513382179"><a name="p583513382179"></a><a name="p583513382179"></a>[oom] OS is in low memory state</p>
<p id="p636114453553"><a name="p636114453553"></a><a name="p636114453553"></a>total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p19833143819174"><a name="p19833143819174"></a><a name="p19833143819174"></a>The operating system has low memory.</p>
<p id="p83883291587"><a name="p83883291587"></a><a name="p83883291587"></a>The available physical memory in the operating system is <strong id="b15343050123397"><a name="b15343050123397"></a><a name="b15343050123397"></a>0x1bcf000</strong> bytes, <strong id="b18697901323397"><a name="b18697901323397"></a><a name="b18697901323397"></a>0x1b50000</strong> bytes have been used, and <strong id="b3252944373397"><a name="b3252944373397"></a><a name="b3252944373397"></a>0x7f000</strong> bytes are available. The current low memory threshold is <strong id="b13811086363397"><a name="b13811086363397"></a><a name="b13811086363397"></a>0x80000</strong> bytes.</p>
</td>
</tr>
<tr id="row1990234224612"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p3902144294612"><a name="p3902144294612"></a><a name="p3902144294612"></a>[oom] candidate victim process init pid: 1, actual phy mem byte: 82602</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p13903144284610"><a name="p13903144284610"></a><a name="p13903144284610"></a>Memory usage of each process. The physical memory occupied by the <strong id="b143686319910"><a name="b143686319910"></a><a name="b143686319910"></a>init</strong> process is 82602 bytes.</p>
</td>
</tr>
<tr id="row520212272335"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p172038278339"><a name="p172038278339"></a><a name="p172038278339"></a>[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p112034276331"><a name="p112034276331"></a><a name="p112034276331"></a>The actual memory used by the <strong id="b16405477923397"><a name="b16405477923397"></a><a name="b16405477923397"></a>UserProcess12</strong> process is <strong id="b10952024983397"><a name="b10952024983397"></a><a name="b10952024983397"></a>25951558</strong> bytes.</p>
</td>
</tr>
<tr id="row3273195033416"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p184989213512"><a name="p184989213512"></a><a name="p184989213512"></a>[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p112741750143417"><a name="p112741750143417"></a><a name="p112741750143417"></a>The process that uses the most memory currently is <strong id="b17770979863397"><a name="b17770979863397"></a><a name="b17770979863397"></a>UserProcess12</strong>.</p>
</td>
</tr>
<tr id="row16442089365"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p045148153618"><a name="p045148153618"></a><a name="p045148153618"></a>excFrom: User!</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p6452818367"><a name="p6452818367"></a><a name="p6452818367"></a>The system memory is low, and the <strong id="b4088490143397"><a name="b4088490143397"></a><a name="b4088490143397"></a>UserProcess12</strong> process fails to apply for memory and exits.</p>
</td>
</tr>
</tbody>
</table>
**Table 2** Output description
| Parameter | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| [oom] OS is in low memory state<br>total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte) | The OS has low memory.<br>The total physical memory is **0x1bcf000** bytes, **0x1b50000** bytes are used, and **0x7f000** bytes are left.<br/>The current lower memory threshold is **0x80000** bytes. |
| [oom] candidate victim process init pid: 1, actual phy mem byte: 82602 | The memory occupied by the **init** process is 82602 bytes. |
| [oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558 | The memory used by the **UserProcess12** process is **25951558** bytes. |
| [oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558 | The process that uses the most memory currently is **UserProcess12**. |
| excFrom: User! | The system memory is low, and the **UserProcess12** process fails to apply for memory and exits. |
# pmm # pmm
## Command Function<a name="section445335110416"></a>
## Command Function
This command is used to check the usage of the physical pages of the system memory and the page cache. This command is used to check the usage of the physical pages of the system memory and the page cache.
## Syntax<a name="section1795712553416"></a>
## Syntax
pmm pmm
## Parameters<a name="section92544592410"></a>
None ## Parameters
None.
## Usage<a name="section104151141252"></a>
## Usage Guidelines
This command is available only in the **Debug** version. This command is available only in the **Debug** version.
## Example<a name="section11545171957"></a>
## Example
Run **pmm**. Run **pmm**.
## Output<a name="section075617368542"></a>
## Output
Usage of physical pages: Usage of physical pages:
...@@ -49,62 +55,17 @@ Vnode number = 67 ...@@ -49,62 +55,17 @@ Vnode number = 67
Vnode memory size = 10720(B) Vnode memory size = 10720(B)
``` ```
**Table 1** Output **Table 1** Output description
<a name="table5579102611579"></a> | Parameter| Description|
<table><thead align="left"><tr id="row12579162613572"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p18579122619578"><a name="p18579122619578"></a><a name="p18579122619578"></a>Parameter</p> | -------- | -------- |
</th> | phys_seg | Address of the physical page control block.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p11579182635718"><a name="p11579182635718"></a><a name="p11579182635718"></a>Description</p> | base | First physical page address, that is, start address of the physical page memory.|
</th> | size | Size of the physical page memory.|
</tr> | free_pages | Number of free physical pages.|
</thead> | active&nbsp;anon | Number of active anonymous pages in the page cache.|
<tbody><tr id="row1457942675720"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2058042605713"><a name="p2058042605713"></a><a name="p2058042605713"></a>phys_seg</p> | inactive&nbsp;anon | Number of inactive anonymous pages in the page cache.|
</td> | active&nbsp;file | Number of active file pages in the page cache.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1058062614579"><a name="p1058062614579"></a><a name="p1058062614579"></a>Address of the physical page control block</p> | inactive&nbsp;file | Number of inactive file pages in the page cache.|
</td> | pmm&nbsp;pages | **total** indicates the total number of physical pages. <br/>**used** indicates the number of used physical pages. <br/>**free** indicates the number of idle physical pages. |
</tr>
<tr id="row14580192616575"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p858062615712"><a name="p858062615712"></a><a name="p858062615712"></a>base</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1858082617577"><a name="p1858082617577"></a><a name="p1858082617577"></a>First physical page address, that is, start address of the physical page memory</p>
</td>
</tr>
<tr id="row17580826115719"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p5580226155713"><a name="p5580226155713"></a><a name="p5580226155713"></a>size</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p85808262572"><a name="p85808262572"></a><a name="p85808262572"></a>Size of the physical page memory</p>
</td>
</tr>
<tr id="row161931831175912"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p201931631185913"><a name="p201931631185913"></a><a name="p201931631185913"></a>free_pages</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1919383125911"><a name="p1919383125911"></a><a name="p1919383125911"></a>Number of free physical pages</p>
</td>
</tr>
<tr id="row1397105119596"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p0397951175918"><a name="p0397951175918"></a><a name="p0397951175918"></a>active anon</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1139715117599"><a name="p1139715117599"></a><a name="p1139715117599"></a>Number of active anonymous pages in the page cache</p>
</td>
</tr>
<tr id="row16409173520010"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p941012351409"><a name="p941012351409"></a><a name="p941012351409"></a>inactive anon</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1341012355019"><a name="p1341012355019"></a><a name="p1341012355019"></a>Number of inactive anonymous pages in the page cache</p>
</td>
</tr>
<tr id="row467016386014"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p10670103818015"><a name="p10670103818015"></a><a name="p10670103818015"></a>active file</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1267012382019"><a name="p1267012382019"></a><a name="p1267012382019"></a>Number of active file pages in the page cache</p>
</td>
</tr>
<tr id="row18966641507"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p5966741706"><a name="p5966741706"></a><a name="p5966741706"></a>inactive file</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p17966174115018"><a name="p17966174115018"></a><a name="p17966174115018"></a>Number of inactive file pages in the page cache</p>
</td>
</tr>
<tr id="row13183445101"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p318394514018"><a name="p318394514018"></a><a name="p318394514018"></a>pmm pages</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1616375952018"><a name="p1616375952018"></a><a name="p1616375952018"></a><strong id="b161631659162014"><a name="b161631659162014"></a><a name="b161631659162014"></a>total</strong>: total number of physical pages.</p>
<p id="p2029802122113"><a name="p2029802122113"></a><a name="p2029802122113"></a><strong id="b429822122113"><a name="b429822122113"></a><a name="b429822122113"></a>used</strong>: number of used physical pages.</p>
<p id="p1218312452014"><a name="p1218312452014"></a><a name="p1218312452014"></a><strong id="b132798755433826"><a name="b132798755433826"></a><a name="b132798755433826"></a>free</strong>: number of free physical pages.</p>
</td>
</tr>
</tbody>
</table>
# reboot # reboot
## Command Function<a name="section20643141481314"></a>
## Command Function
This command is used to restart a device. This command is used to restart a device.
## Syntax<a name="section1075441721316"></a>
## Syntax
reboot reboot
## Parameters<a name="section1472810220135"></a>
None ## Parameters
None.
## Usage<a name="section186772414131"></a>
## Usage Guidelines
After the **reboot** command is executed, the device restarts immediately. After the **reboot** command is executed, the device restarts immediately.
## Example<a name="section4764192791314"></a>
## Example
reboot reboot
## Output<a name="section5791253155517"></a>
None ## Output
None.
# reset # reset
## Command Function<a name="section366714216619"></a>
## Command Function
This command is used to restart a device. This command is used to restart a device.
## Syntax<a name="section8833164614615"></a>
## Syntax
reset reset
## Parameters<a name="section12809111019453"></a>
None ## Parameters
None.
## Usage<a name="section15935131220717"></a>
## Usage Guidelines
After the **reset** command is executed, the device restarts immediately. After the **reset** command is executed, the device restarts immediately.
## Example<a name="section79281818476"></a>
## Example
Run **reset**. Run **reset**.
## Output<a name="section12742311179"></a>
None ## Output
None.
# sem # sem
## Command Function<a name="section366714216619"></a>
## Command Function
This command is used to query information about kernel semaphores. This command is used to query information about kernel semaphores.
## Syntax<a name="section8833164614615"></a>
sem \[_ID__ / fulldata_\] ## Syntax
sem [_ID__ / fulldata_]
## Parameters<a name="section12809111019453"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table438mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row444mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p446mcpsimp"><a name="p446mcpsimp"></a><a name="p446mcpsimp"></a>Parameter</p> | -------- | -------- | -------- |
</th> | ID | Specifies the semaphore ID.| [0, 1023] or [0x0, 0x3FF]|
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p448mcpsimp"><a name="p448mcpsimp"></a><a name="p448mcpsimp"></a>Parameters</p> | fulldata | Displays information about all semaphores in use. <br/>The displayed information includes **SemID**, **Count**, **Original Count**, **Creator TaskEntry**, and **Last Access Time**. | N/A |
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p450mcpsimp"><a name="p450mcpsimp"></a><a name="p450mcpsimp"></a>Value Range</p>
</th> ## Usage Guidelines
</tr>
</thead>
<tbody><tr id="row451mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p453mcpsimp"><a name="p453mcpsimp"></a><a name="p453mcpsimp"></a>ID</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p455mcpsimp"><a name="p455mcpsimp"></a><a name="p455mcpsimp"></a>Specifies the semaphore ID.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p14422125918562"><a name="p14422125918562"></a><a name="p14422125918562"></a>[0, 1023] or [0x0, 0x3FF]</p>
</td>
</tr>
<tr id="row458mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p460mcpsimp"><a name="p460mcpsimp"></a><a name="p460mcpsimp"></a>fulldata</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p462mcpsimp"><a name="p462mcpsimp"></a><a name="p462mcpsimp"></a>Queries information about all the semaphores in use. The information includes <strong id="b189454249533849"><a name="b189454249533849"></a><a name="b189454249533849"></a>SemID</strong>, <strong id="b162724654333849"><a name="b162724654333849"></a><a name="b162724654333849"></a>Count</strong>, <strong id="b111325307233849"><a name="b111325307233849"></a><a name="b111325307233849"></a>OriginalCount</strong>, <strong id="b182850346833849"><a name="b182850346833849"></a><a name="b182850346833849"></a>Creator(TaskEntry)</strong>, and <strong id="b213750533633849"><a name="b213750533633849"></a><a name="b213750533633849"></a>LastAccessTime</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="entry464mcpsimpp0"><a name="entry464mcpsimpp0"></a><a name="entry464mcpsimpp0"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section15935131220717"></a>
- If no parameter is specified, this command displays the semaphore IDs and the number of times that each semaphore is used. - If no parameter is specified, this command displays the semaphore IDs and the number of times that each semaphore is used.
- If **ID** is specified, the use of the specified semaphore is displayed. - If **ID** is specified, the use of the specified semaphore is displayed.
- The **fulldata** parameter depends on **LOSCFG\_DEBUG\_SEMAPHORE**. Before using this parameter, select **Enable Semaphore Debugging** on **menuconfig**.
Debug ---\> Enable a Debug Version ---\> Enable Debug LiteOS Kernel Resource ---\> Enable Semaphore Debugging - The **fulldata** parameter depends on **LOSCFG_DEBUG_SEMAPHORE**. Before using this parameter, set **Enable Semaphore Debugging** to **Yes** on **menuconfig**.
**Debug** ---&gt; **Enable a Debug Version** ---&gt; **Enable Debug LiteOS Kernel Resource** ---&gt; E**nable Semaphore Debugging**
## Example<a name="section79281818476"></a> ## Example
- Run **sem**. - Run **sem**.
- Configure **LOSCFG\_DEBUG\_SEMAPHORE** and run **sem fulldata**.
## Output<a name="section1975118519456"></a> - Configure **LOSCFG_DEBUG_SEMAPHORE** and run **sem fulldata**.
## Output
Example 1: brief semaphore information Example 1: brief semaphore information
...@@ -81,31 +67,17 @@ OHOS # sem ...@@ -81,31 +67,17 @@ OHOS # sem
0x00000006 0 0x00000006 0
``` ```
**Table 2** Output **Table 2** Output description
<a name="table487mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row492mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p494mcpsimp"><a name="p494mcpsimp"></a><a name="p494mcpsimp"></a>Parameter</p> | -------- | -------- |
</th> | SemID | Semaphore ID.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p496mcpsimp"><a name="p496mcpsimp"></a><a name="p496mcpsimp"></a>Description</p> | Count | Number of times that the semaphore is used.|
</th>
</tr> > **NOTE**<br>
</thead> > The **ID** value can be in decimal or hexadecimal format.
<tbody><tr id="row497mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p499mcpsimp"><a name="p499mcpsimp"></a><a name="p499mcpsimp"></a>SemID</p> >
</td> > When **ID** is a value within [0, 1023], semaphore information of the specified ID is displayed. If the specified semaphore is not used, a message is displayed to inform you of this case. For other values, a message is displayed indicating that the parameter is incorrect.
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p501mcpsimp"><a name="p501mcpsimp"></a><a name="p501mcpsimp"></a>Semaphore ID</p>
</td>
</tr>
<tr id="row502mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p504mcpsimp"><a name="p504mcpsimp"></a><a name="p504mcpsimp"></a>Count</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p506mcpsimp"><a name="p506mcpsimp"></a><a name="p506mcpsimp"></a>Number of times that the semaphore is used</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE**
>The **ID** value can be in decimal or hexadecimal format.
>When **ID** is a value within \[0, 1023\], semaphore information of the specified ID is displayed. If the specified semaphore is not used, a message is displayed to inform you of this case. For other values, a message is displayed indicating that the parameter is incorrect.
Example 2: detailed semaphore information Example 2: detailed semaphore information
...@@ -143,38 +115,10 @@ Used Semaphore List: ...@@ -143,38 +115,10 @@ Used Semaphore List:
**Table 3** Output description **Table 3** Output description
<a name="table57783201041"></a> | Parameter| Description|
<table><thead align="left"><tr id="row12778320943"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p153641444643"><a name="p153641444643"></a><a name="p153641444643"></a>Parameter</p> | -------- | -------- |
</th> | SemID | Semaphore ID.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p236413447414"><a name="p236413447414"></a><a name="p236413447414"></a>Description</p> | Count | Number of times that the semaphore is used.|
</th> | OriginalCount | Original count of the semaphore.|
</tr> | Creator | Address of the entry function of the thread used to create the semaphore.|
</thead> | LastAccessTime | Last time when the semaphore was accessed.|
<tbody><tr id="row14834640646"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p7829840647"><a name="p7829840647"></a><a name="p7829840647"></a>SemID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p118291440244"><a name="p118291440244"></a><a name="p118291440244"></a>Semaphore ID</p>
</td>
</tr>
<tr id="row78346401141"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p08292401349"><a name="p08292401349"></a><a name="p08292401349"></a>Count</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1829104012416"><a name="p1829104012416"></a><a name="p1829104012416"></a>Number of times that the semaphore is used</p>
</td>
</tr>
<tr id="row1883414404411"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p88291640847"><a name="p88291640847"></a><a name="p88291640847"></a>OriginalCount</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p282916401148"><a name="p282916401148"></a><a name="p282916401148"></a>Original count of the semaphore</p>
</td>
</tr>
<tr id="row148347401646"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1782914401646"><a name="p1782914401646"></a><a name="p1782914401646"></a>Creator</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p168298407419"><a name="p168298407419"></a><a name="p168298407419"></a>Address of the entry function of the thread used to create the semaphore</p>
</td>
</tr>
<tr id="row783415401340"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p18829640549"><a name="p18829640549"></a><a name="p18829640549"></a>LastAccessTime</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p198292406412"><a name="p198292406412"></a><a name="p198292406412"></a>Last time when the semaphore was accessed</p>
</td>
</tr>
</tbody>
</table>
# stack # stack
## Command Function<a name="section445335110416"></a> ## Command Function
This command is used to check the usage of each stack in the system. This command is used to check the usage of each stack in the system.
## Syntax<a name="section1795712553416"></a>
## Syntax
stack stack
## Parameters<a name="section92544592410"></a>
None ## Parameters
None.
## Usage<a name="section104151141252"></a> ## Usage Guidelines
None None.
## Example<a name="section11545171957"></a>
## Example
Run **stack**. Run **stack**.
## Output<a name="section075617368542"></a>
## Output
System stack usage: System stack usage:
...@@ -35,40 +40,12 @@ OHOS # stack ...@@ -35,40 +40,12 @@ OHOS # stack
exc_stack 0 0x405c9000 0x1000 0x0 exc_stack 0 0x405c9000 0x1000 0x0
``` ```
**Table 1** Output **Table 1** Output description
<a name="table633mcpsimp"></a>
<table><thead align="left"><tr id="row638mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p640mcpsimp"><a name="p640mcpsimp"></a><a name="p640mcpsimp"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p642mcpsimp"><a name="p642mcpsimp"></a><a name="p642mcpsimp"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row643mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p645mcpsimp"><a name="p645mcpsimp"></a><a name="p645mcpsimp"></a>stack name</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p647mcpsimp"><a name="p647mcpsimp"></a><a name="p647mcpsimp"></a>Name of the stack</p>
</td>
</tr>
<tr id="row648mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p650mcpsimp"><a name="p650mcpsimp"></a><a name="p650mcpsimp"></a>cpu id</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p652mcpsimp"><a name="p652mcpsimp"></a><a name="p652mcpsimp"></a>CPU ID</p>
</td>
</tr>
<tr id="row653mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p655mcpsimp"><a name="p655mcpsimp"></a><a name="p655mcpsimp"></a>stack addr</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p657mcpsimp"><a name="p657mcpsimp"></a><a name="p657mcpsimp"></a>Stack address</p>
</td>
</tr>
<tr id="row658mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p660mcpsimp"><a name="p660mcpsimp"></a><a name="p660mcpsimp"></a>total size</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p662mcpsimp"><a name="p662mcpsimp"></a><a name="p662mcpsimp"></a>Total stack size</p>
</td>
</tr>
<tr id="row10101624938"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p610724734"><a name="p610724734"></a><a name="p610724734"></a>used size</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1510024539"><a name="p1510024539"></a><a name="p1510024539"></a>Size of the stack used</p>
</td>
</tr>
</tbody>
</table>
| Parameter| Description|
| -------- | -------- |
| stack&nbsp;name | Name of the stack.|
| cpu&nbsp;id | CPU number.|
| stack&nbsp;addr | Stack address.|
| total&nbsp;size | Total stack size.|
| used&nbsp;size | Size of the stack used.|
# su # su
## Command Function<a name="section297810431676"></a>
## Command Function
This command is used to switch the user account. This command is used to switch the user account.
## Syntax<a name="section157131147876"></a>
su \[_uid_\] \[_gid_\] ## Syntax
su [_uid_] [_gid_]
## Parameters<a name="section04145521671"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1049mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row1055mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1057mcpsimp"><a name="p1057mcpsimp"></a><a name="p1057mcpsimp"></a>Parameter</p> | -------- | -------- | -------- |
</th> | uid | Specifies the ID of the target user.| - Left blank<br>- [0, 60000] |
<th class="cellrowborder" valign="top" width="51.93%" id="mcps1.2.4.1.2"><p id="p1059mcpsimp"><a name="p1059mcpsimp"></a><a name="p1059mcpsimp"></a>Description</p> | gid | Specifies the ID of the target user group.| - Left blank<br>- [0, 60000] |
</th>
<th class="cellrowborder" valign="top" width="27.07%" id="mcps1.2.4.1.3"><p id="p1061mcpsimp"><a name="p1061mcpsimp"></a><a name="p1061mcpsimp"></a>Value Range</p>
</th> ## Usage Guidelines
</tr>
</thead>
<tbody><tr id="row1062mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1064mcpsimp"><a name="p1064mcpsimp"></a><a name="p1064mcpsimp"></a>uid</p>
</td>
<td class="cellrowborder" valign="top" width="51.93%" headers="mcps1.2.4.1.2 "><p id="p14138191243"><a name="p14138191243"></a><a name="p14138191243"></a>Specifies the ID of the target user.</p>
</td>
<td class="cellrowborder" valign="top" width="27.07%" headers="mcps1.2.4.1.3 "><a name="ul14151675449"></a><a name="ul14151675449"></a><ul id="ul14151675449"><li>Left blank</li><li>[0,60000]</li></ul>
</td>
</tr>
<tr id="row172161126124218"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p12217026154215"><a name="p12217026154215"></a><a name="p12217026154215"></a>gid</p>
</td>
<td class="cellrowborder" valign="top" width="51.93%" headers="mcps1.2.4.1.2 "><p id="p48748461789"><a name="p48748461789"></a><a name="p48748461789"></a>Specifies the ID of the target user group.</p>
</td>
<td class="cellrowborder" valign="top" width="27.07%" headers="mcps1.2.4.1.3 "><a name="ul10433713134417"></a><a name="ul10433713134417"></a><ul id="ul10433713134417"><li>Left blank</li><li>[0,60000]</li></ul>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section14615155610719"></a>
- If no parameter is specified, the **su** command switches to user **root** by default. The **uid** and **gid** for user **root** are both **0**. - If no parameter is specified, the **su** command switches to user **root** by default. The **uid** and **gid** for user **root** are both **0**.
- If **uid** and **gid** are specified, this command allows commands to be executed as the user with the specified **uid** and **gid**. - If **uid** and **gid** are specified, this command allows commands to be executed as the user with the specified **uid** and **gid**.
- If the input parameter is out of the range, an error message will be printed. - If the input parameter is out of the range, an error message will be printed.
## Example<a name="section13338150985"></a>
## Example
Run **su 1000 1000**. Run **su 1000 1000**.
## Output<a name="section125021924194613"></a>
Switching to the user with both **uid** and **gid** of **1000**: ## Output
The user with both **uid** and **gid** of **1000** is switched.
``` ```
OHOS # ls OHOS # ls
...@@ -63,4 +50,3 @@ Directory /data/system/param: ...@@ -63,4 +50,3 @@ Directory /data/system/param:
-rw-r--r-- O u:1000 g:1000 hello 2.txt -rw-r--r-- O u:1000 g:1000 hello 2.txt
-гw-r--r-- 0 u:0 g:0 hello_1.txt -гw-r--r-- 0 u:0 g:0 hello_1.txt
``` ```
# swtmr # swtmr
## Command Function<a name="section166171064814"></a> ## Command Function
This command is used to query information about system software timers. This command is used to query information about system software timers.
## Syntax<a name="section424011111682"></a>
swtmr \[_ID_\] ## Syntax
## Parameters<a name="section1268410459465"></a> swtmr [_ID_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table517mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row523mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p525mcpsimp"><a name="p525mcpsimp"></a><a name="p525mcpsimp"></a>Parameter</p> | -------- | -------- | -------- |
</th> | ID | Specifies the ID of a software timer.| [0, 0xFFFFFFFF] |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p527mcpsimp"><a name="p527mcpsimp"></a><a name="p527mcpsimp"></a>Description</p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p529mcpsimp"><a name="p529mcpsimp"></a><a name="p529mcpsimp"></a>Value Range</p> ## Usage Guidelines
</th>
</tr>
</thead>
<tbody><tr id="row530mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p532mcpsimp"><a name="p532mcpsimp"></a><a name="p532mcpsimp"></a>ID</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p534mcpsimp"><a name="p534mcpsimp"></a><a name="p534mcpsimp"></a>Specifies the ID of a software timer.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p536mcpsimp"><a name="p536mcpsimp"></a><a name="p536mcpsimp"></a>[0,0xFFFFFFFF]</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section169806213815"></a>
- If no parameter is specified, information about all software timers is displayed. - If no parameter is specified, information about all software timers is displayed.
- If the **ID** parameter is specified, information about the specified software timer is displayed. - If the **ID** parameter is specified, information about the specified software timer is displayed.
## Example<a name="section16676026389"></a>
## Example
Run the following commands: Run the following commands:
- swtmr - swtmr
- swtmr 1 - swtmr 1
## Output<a name="section1541991614710"></a>
## Output
Example 1: information about all software timers Example 1: information about all software timers
...@@ -76,56 +68,19 @@ SwTmrID State Mode Interval Count Arg handlerAddr ...@@ -76,56 +68,19 @@ SwTmrID State Mode Interval Count Arg handlerAddr
0x00000001 Ticking Period 1000 841 0x00000000 0x4037fc04 0x00000001 Ticking Period 1000 841 0x00000000 0x4037fc04
``` ```
**Table 2** Output **Table 2** Output description
<a name="table551mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row556mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p558mcpsimp"><a name="p558mcpsimp"></a><a name="p558mcpsimp"></a>Parameter</p> | -------- | -------- |
</th> | SwTmrID | ID of the software timer.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p560mcpsimp"><a name="p560mcpsimp"></a><a name="p560mcpsimp"></a>Description</p> | State | Status of the software timer.<br>The status may be **UnUsed**, **Created**, or **Ticking**.|
</th> | Mode | Mode of the software timer.<br>The value can be **Once**, **Period**, or **NSD** (one-shot timer that will not be automatically deleted after the timer has expired).|
</tr> | Interval | Number of ticks for the software timer.|
</thead> | Count | Number of times that the software timer has been used.|
<tbody><tr id="row561mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p563mcpsimp"><a name="p563mcpsimp"></a><a name="p563mcpsimp"></a>SwTmrID</p> | Arg | Input parameter.|
</td> | handlerAddr | Address of the callback.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p565mcpsimp"><a name="p565mcpsimp"></a><a name="p565mcpsimp"></a>ID of the software timer</p>
</td> > **NOTE**<br>
</tr> > - The **ID** value can be in decimal or hexadecimal format.
<tr id="row566mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p568mcpsimp"><a name="p568mcpsimp"></a><a name="p568mcpsimp"></a>State</p> >
</td> > - If the **ID** value is within the range of [0, *Number of current software timers - 1*], the status of the specified software timer is returned. Otherwise, an error code is returned.
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p570mcpsimp"><a name="p570mcpsimp"></a><a name="p570mcpsimp"></a>Status of the software timer</p>
<p id="p88402543474"><a name="p88402543474"></a><a name="p88402543474"></a>The value can be <strong id="b164905263633836"><a name="b164905263633836"></a><a name="b164905263633836"></a>UnUsed</strong>, <strong id="b138979237833836"><a name="b138979237833836"></a><a name="b138979237833836"></a>Created</strong>, or <strong id="b3849463233836"><a name="b3849463233836"></a><a name="b3849463233836"></a>Ticking</strong>.</p>
</td>
</tr>
<tr id="row571mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p573mcpsimp"><a name="p573mcpsimp"></a><a name="p573mcpsimp"></a>Mode</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p575mcpsimp"><a name="p575mcpsimp"></a><a name="p575mcpsimp"></a>Mode of the software timer</p>
<p id="p657320204499"><a name="p657320204499"></a><a name="p657320204499"></a>The value can be <strong id="b201632419733836"><a name="b201632419733836"></a><a name="b201632419733836"></a>Once</strong>, <strong id="b45281151733836"><a name="b45281151733836"></a><a name="b45281151733836"></a>Period</strong>, or <strong id="b73443815433836"><a name="b73443815433836"></a><a name="b73443815433836"></a>NSD</strong> (one-shot timer that will not be automatically deleted after the timer has expired).</p>
</td>
</tr>
<tr id="row576mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p578mcpsimp"><a name="p578mcpsimp"></a><a name="p578mcpsimp"></a>Interval</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p580mcpsimp"><a name="p580mcpsimp"></a><a name="p580mcpsimp"></a>Number of ticks for the software timer</p>
</td>
</tr>
<tr id="row581mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p583mcpsimp"><a name="p583mcpsimp"></a><a name="p583mcpsimp"></a>Count</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p585mcpsimp"><a name="p585mcpsimp"></a><a name="p585mcpsimp"></a>Number of times that the software timer has been used</p>
</td>
</tr>
<tr id="row586mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p588mcpsimp"><a name="p588mcpsimp"></a><a name="p588mcpsimp"></a>Arg</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p590mcpsimp"><a name="p590mcpsimp"></a><a name="p590mcpsimp"></a>Input parameter</p>
</td>
</tr>
<tr id="row591mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p593mcpsimp"><a name="p593mcpsimp"></a><a name="p593mcpsimp"></a>handlerAddr</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p595mcpsimp"><a name="p595mcpsimp"></a><a name="p595mcpsimp"></a>Address of the callback</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>- The **ID** value can be in decimal or hexadecimal format.
>- If the **ID** value is within the range of \[0, _Number of current software timers - 1_\], the status of the specified software timer is returned. For other values, an error message is displayed.
# systeminfo # systeminfo
## Command Function<a name="section863016434820"></a>
## Command Function
This command is used to display the resource usage of the current operating system, including tasks, semaphores, mutexes, queues, and software timers. This command is used to display the resource usage of the current operating system, including tasks, semaphores, mutexes, queues, and software timers.
## Syntax<a name="section139791817795"></a>
## Syntax
systeminfo systeminfo
## Parameters<a name="section19472339164813"></a>
None ## Parameters
None.
## Usage<a name="section285522592"></a> ## Usage Guidelines
None None.
## Example<a name="section9471171015105"></a>
## Example
Run **systeminfo**. Run **systeminfo**.
## Output<a name="section1657011114915"></a>
## Output
Usage of system resources: Usage of system resources:
...@@ -34,60 +40,15 @@ OHOS:/$ systeminfo ...@@ -34,60 +40,15 @@ OHOS:/$ systeminfo
SwTmr 20 1024 YES SwTmr 20 1024 YES
``` ```
**Table 1** Output **Table 1** Output description
<a name="table633mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row638mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p640mcpsimp"><a name="p640mcpsimp"></a><a name="p640mcpsimp"></a>Parameter</p> | ------- | -------------- |
</th> | Module | Module name. |
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p642mcpsimp"><a name="p642mcpsimp"></a><a name="p642mcpsimp"></a>Description</p> | Used | Used resources. |
</th> | Total | Total resources. |
</tr> | Enabled | Whether the module is enabled.|
</thead> | Task | Task. |
<tbody><tr id="row643mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p645mcpsimp"><a name="p645mcpsimp"></a><a name="p645mcpsimp"></a>Module</p> | Sem | Semaphore. |
</td> | Queue | Using queues. |
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p647mcpsimp"><a name="p647mcpsimp"></a><a name="p647mcpsimp"></a>Module name</p> | SwTmr | Software timer. |
</td>
</tr>
<tr id="row648mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p650mcpsimp"><a name="p650mcpsimp"></a><a name="p650mcpsimp"></a>Used</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p652mcpsimp"><a name="p652mcpsimp"></a><a name="p652mcpsimp"></a>Used resources</p>
</td>
</tr>
<tr id="row653mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p655mcpsimp"><a name="p655mcpsimp"></a><a name="p655mcpsimp"></a>Total</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p657mcpsimp"><a name="p657mcpsimp"></a><a name="p657mcpsimp"></a>Total resources</p>
</td>
</tr>
<tr id="row658mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p660mcpsimp"><a name="p660mcpsimp"></a><a name="p660mcpsimp"></a>Enabled</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p662mcpsimp"><a name="p662mcpsimp"></a><a name="p662mcpsimp"></a>Whether the module is enabled</p>
</td>
</tr>
<tr id="row10101624938"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p610724734"><a name="p610724734"></a><a name="p610724734"></a>Task</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1510024539"><a name="p1510024539"></a><a name="p1510024539"></a>Task</p>
</td>
</tr>
<tr id="row207288271839"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p572872713317"><a name="p572872713317"></a><a name="p572872713317"></a>Sem</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p272852716315"><a name="p272852716315"></a><a name="p272852716315"></a>Semaphore</p>
</td>
</tr>
<tr id="row1774316321731"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p274343218317"><a name="p274343218317"></a><a name="p274343218317"></a>Mutex</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1974319321133"><a name="p1974319321133"></a><a name="p1974319321133"></a>Mutex</p>
</td>
</tr>
<tr id="row121618371536"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p0161183720314"><a name="p0161183720314"></a><a name="p0161183720314"></a>Queue</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p09295155511"><a name="p09295155511"></a><a name="p09295155511"></a>Message queue</p>
</td>
</tr>
<tr id="row4935152211518"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p13935222154"><a name="p13935222154"></a><a name="p13935222154"></a>SwTmr</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p0936182215515"><a name="p0936182215515"></a><a name="p0936182215515"></a>Software timer</p>
</td>
</tr>
</tbody>
</table>
# task # task
## Command Function<a name="section0533181714106"></a>
## Command Function
This command is used to query information about processes and threads. This command is used to query information about processes and threads.
## Syntax<a name="section1014412308101"></a>
## Syntax
task/task -a task/task -a
## Parameters<a name="section116057158506"></a>
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table672mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row678mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p680mcpsimp"><a name="p680mcpsimp"></a><a name="p680mcpsimp"></a>Parameter</p> | -------- | -------- | -------- |
</th> | -a | Displays all information.| N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p682mcpsimp"><a name="p682mcpsimp"></a><a name="p682mcpsimp"></a>Description</p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p684mcpsimp"><a name="p684mcpsimp"></a><a name="p684mcpsimp"></a>Value Range</p> ## Usage Guidelines
</th>
</tr>
</thead>
<tbody><tr id="row685mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p687mcpsimp"><a name="p687mcpsimp"></a><a name="p687mcpsimp"></a>-a</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p689mcpsimp"><a name="p689mcpsimp"></a><a name="p689mcpsimp"></a>Displays all information.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p691mcpsimp"><a name="p691mcpsimp"></a><a name="p691mcpsimp"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section2053502951112"></a>
If no parameter is specified, partial task information is displayed by default. If no parameter is specified, partial task information is displayed by default.
## Example<a name="section12629113381116"></a>
## Example
Run **task**. Run **task**.
## Output<a name="section19299103465015"></a>
Task information \(partial\): ## Output
Task information (partial):
``` ```
OHOS # task OHOS # task
...@@ -55,6 +46,7 @@ OHOS # task ...@@ -55,6 +46,7 @@ OHOS # task
6 1 6 0 Pending 0x688000 0x137000 0x11c518 0.0 media_server 6 1 6 0 Pending 0x688000 0x137000 0x11c518 0.0 media_server
7 1 7 0 Pending 0x9d2000 0x103000 0xa1ddf 0.89 wms_server 7 1 7 0 Pending 0x9d2000 0x103000 0xa1ddf 0.89 wms_server
8 1 1 1000 Running 0x2bf000 0x8f000 0x2a8c6 0.0 shell 8 1 1 1000 Running 0x2bf000 0x8f000 0x2a8c6 0.0 shell
9 5 5 101 Pending 0x11ea000 0x2f9000 0x20429d 0.97 com.example.launcher
11 1 11 0 Pending 0x4d4000 0x112000 0xe0ad7 0.0 deviceauth_service 11 1 11 0 Pending 0x4d4000 0x112000 0xe0ad7 0.0 deviceauth_service
12 1 12 0 Pending 0x34f000 0xbd000 0x519ee 0.0 sensor_service 12 1 12 0 Pending 0x34f000 0xbd000 0x519ee 0.0 sensor_service
13 1 13 2 Pending 0x34e000 0xb3000 0x523d9 0.0 ai_server 13 1 13 2 Pending 0x34e000 0xb3000 0x523d9 0.0 ai_server
...@@ -68,75 +60,19 @@ OHOS # task ...@@ -68,75 +60,19 @@ OHOS # task
7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread
``` ```
**Table 2** Output **Table 2** Output description
<a name="table809mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row814mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p816mcpsimp"><a name="p816mcpsimp"></a><a name="p816mcpsimp"></a>Parameter</p> | -------- | -------- |
</th> | PID | Process ID.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p818mcpsimp"><a name="p818mcpsimp"></a><a name="p818mcpsimp"></a>Description</p> | PPID | Parent process ID.|
</th> | PGID | Process group ID.|
</tr> | UID | User ID.|
</thead> | Status | Current task status.|
<tbody><tr id="row20360171311398"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p123611139397"><a name="p123611139397"></a><a name="p123611139397"></a>PID</p> | CPUUSE10s | CPU usage within last 10 seconds.|
</td> | PName | Name of the process.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p3361171333920"><a name="p3361171333920"></a><a name="p3361171333920"></a>Process ID</p> | TID | Task ID.|
</td> | StackSize | Size of the task stack.|
</tr> | WaterLine | Peak value of the stack used.|
<tr id="row262535153913"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p862625163918"><a name="p862625163918"></a><a name="p862625163918"></a>PPID</p> | MEMUSE | Memory usage.|
</td> | TaskName | Task name.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1062611511398"><a name="p1062611511398"></a><a name="p1062611511398"></a>Parent process ID</p>
</td>
</tr>
<tr id="row9683953153916"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p76831753103915"><a name="p76831753103915"></a><a name="p76831753103915"></a>PGID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2068355383916"><a name="p2068355383916"></a><a name="p2068355383916"></a>Process group ID</p>
</td>
</tr>
<tr id="row85721136402"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p8572151313402"><a name="p8572151313402"></a><a name="p8572151313402"></a>UID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p55721813164013"><a name="p55721813164013"></a><a name="p55721813164013"></a>User ID</p>
</td>
</tr>
<tr id="row19180126151415"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p836mcpsimp"><a name="p836mcpsimp"></a><a name="p836mcpsimp"></a>Status</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p838mcpsimp"><a name="p838mcpsimp"></a><a name="p838mcpsimp"></a>Current task status</p>
</td>
</tr>
<tr id="row511517331702"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2116833506"><a name="p2116833506"></a><a name="p2116833506"></a>CPUUSE10s</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2011611331604"><a name="p2011611331604"></a><a name="p2011611331604"></a>CPU usage within last 10 seconds</p>
</td>
</tr>
<tr id="row136191839311"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p66199397110"><a name="p66199397110"></a><a name="p66199397110"></a>PName</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p11619153916110"><a name="p11619153916110"></a><a name="p11619153916110"></a>Process name</p>
</td>
</tr>
<tr id="row824mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p826mcpsimp"><a name="p826mcpsimp"></a><a name="p826mcpsimp"></a>TID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p828mcpsimp"><a name="p828mcpsimp"></a><a name="p828mcpsimp"></a>Task ID</p>
</td>
</tr>
<tr id="row839mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p841mcpsimp"><a name="p841mcpsimp"></a><a name="p841mcpsimp"></a>StackSize</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p843mcpsimp"><a name="p843mcpsimp"></a><a name="p843mcpsimp"></a>Size of the task stack</p>
</td>
</tr>
<tr id="row844mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p846mcpsimp"><a name="p846mcpsimp"></a><a name="p846mcpsimp"></a>WaterLine</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p848mcpsimp"><a name="p848mcpsimp"></a><a name="p848mcpsimp"></a>Peak value of the stack used</p>
</td>
</tr>
<tr id="row10188146131813"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p218912671818"><a name="p218912671818"></a><a name="p218912671818"></a>MEMUSE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1518926151810"><a name="p1518926151810"></a><a name="p1518926151810"></a>Memory usage</p>
</td>
</tr>
<tr id="row45465584313"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p821mcpsimp"><a name="p821mcpsimp"></a><a name="p821mcpsimp"></a>TaskName</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p823mcpsimp"><a name="p823mcpsimp"></a><a name="p823mcpsimp"></a>Task name</p>
</td>
</tr>
</tbody>
</table>
# top # top
## Command Function<a name="section20643141481314"></a>
## Command Function
This command is used to query process and thread information. This command is used to query process and thread information.
## Syntax<a name="section1075441721316"></a>
top \[_-a_\] ## Syntax
top [_-a_]
## Parameters<a name="section1472810220135"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table966mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row973mcpsimp"><th class="cellrowborder" valign="top" width="19.801980198019802%" id="mcps1.2.5.1.1"><p id="p975mcpsimp"><a name="p975mcpsimp"></a><a name="p975mcpsimp"></a>Parameter</p> | ------ | --------------------------- |
</th> | --help | Displays the parameters supported by the **top** command.|
<th class="cellrowborder" valign="top" width="29.222922292229224%" id="mcps1.2.5.1.2"><p id="p977mcpsimp"><a name="p977mcpsimp"></a><a name="p977mcpsimp"></a>Description</p> | -a | Displays detailed information. |
</th>
<th class="cellrowborder" valign="top" width="22.26222622262226%" id="mcps1.2.5.1.3"><p id="p979mcpsimp"><a name="p979mcpsimp"></a><a name="p979mcpsimp"></a>Default Value</p>
</th> ## Usage Guidelines
<th class="cellrowborder" valign="top" width="28.712871287128717%" id="mcps1.2.5.1.4"><p id="p981mcpsimp"><a name="p981mcpsimp"></a><a name="p981mcpsimp"></a>Value Range</p>
</th> If no parameter is specified, partial task information is displayed by default.
</tr>
</thead> ## Note
<tbody><tr id="row1643213388538"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p11426113820531"><a name="p11426113820531"></a><a name="p11426113820531"></a>--help</p>
</td> Currently, the shell does not support this command. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p942673885313"><a name="p942673885313"></a><a name="p942673885313"></a>Displays the parameters supported by the <strong id="b2435956125215"><a name="b2435956125215"></a><a name="b2435956125215"></a>top</strong> command.</p>
</td> ## Example
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p9426538195319"><a name="p9426538195319"></a><a name="p9426538195319"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 ">&nbsp;&nbsp;</td>
</tr>
<tr id="row1943253865311"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p1542613812537"><a name="p1542613812537"></a><a name="p1542613812537"></a>-a</p>
</td>
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p1842663895320"><a name="p1842663895320"></a><a name="p1842663895320"></a>Displays detailed information.</p>
</td>
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p13426123815313"><a name="p13426123815313"></a><a name="p13426123815313"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 ">&nbsp;&nbsp;</td>
</tr>
</tbody>
</table>
## Usage<a name="section186772414131"></a>
If no parameter is specified, this command displays process and thread information of some tasks by default.
## Example<a name="section4764192791314"></a>
Run **top**. Run **top**.
## Output<a name="section5791253155517"></a>
## Output
Command output Command output
...@@ -99,73 +83,17 @@ OHOS:/$ top ...@@ -99,73 +83,17 @@ OHOS:/$ top
**Table 2** Output description **Table 2** Output description
<a name="table1522165195511"></a> | Parameter | Description |
<table><thead align="left"><tr id="row1952285165514"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p25224518556"><a name="p25224518556"></a><a name="p25224518556"></a>Parameter</p> | --------- | ----------------- |
</th> | PID | Process ID. |
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p16522852554"><a name="p16522852554"></a><a name="p16522852554"></a>Description</p> | PPID | Parent process ID. |
</th> | PGID | Process group ID. |
</tr> | UID | User ID. |
</thead> | Status | Current task status. |
<tbody><tr id="row207354303550"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p107238309551"><a name="p107238309551"></a><a name="p107238309551"></a>PID</p> | CPUUSE10s | CPU usage within last 10 seconds.|
</td> | PName | Name of the process. |
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p372373015515"><a name="p372373015515"></a><a name="p372373015515"></a>Process ID</p> | TID | Task ID. |
</td> | StackSize | Size of the task stack. |
</tr> | WaterLine | Peak value of the stack used. |
<tr id="row1373513035514"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p972343012551"><a name="p972343012551"></a><a name="p972343012551"></a>PPID</p> | MEMUSE | Memory usage. |
</td> | TaskName | Task name. |
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p19723153055519"><a name="p19723153055519"></a><a name="p19723153055519"></a>Parent process ID</p>
</td>
</tr>
<tr id="row16735133035518"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p14723153065514"><a name="p14723153065514"></a><a name="p14723153065514"></a>PGID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p117231630165519"><a name="p117231630165519"></a><a name="p117231630165519"></a>Process group ID</p>
</td>
</tr>
<tr id="row157354306558"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p3723430195510"><a name="p3723430195510"></a><a name="p3723430195510"></a>UID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1372373016559"><a name="p1372373016559"></a><a name="p1372373016559"></a>User ID</p>
</td>
</tr>
<tr id="row573515301555"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1472318308552"><a name="p1472318308552"></a><a name="p1472318308552"></a>Status</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p57231430165518"><a name="p57231430165518"></a><a name="p57231430165518"></a>Current task status</p>
</td>
</tr>
<tr id="row15735730135515"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p472363045510"><a name="p472363045510"></a><a name="p472363045510"></a>CPUUSE10s</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1172323019556"><a name="p1172323019556"></a><a name="p1172323019556"></a>CPU usage within last 10 seconds</p>
</td>
</tr>
<tr id="row16735163025519"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p10723183035516"><a name="p10723183035516"></a><a name="p10723183035516"></a>PName</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1472310309557"><a name="p1472310309557"></a><a name="p1472310309557"></a>Process name</p>
</td>
</tr>
<tr id="row973593017554"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p13724123075515"><a name="p13724123075515"></a><a name="p13724123075515"></a>TID</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p12724630135510"><a name="p12724630135510"></a><a name="p12724630135510"></a>Task ID</p>
</td>
</tr>
<tr id="row157341730135512"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p87241930135520"><a name="p87241930135520"></a><a name="p87241930135520"></a>StackSize</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p8724930135519"><a name="p8724930135519"></a><a name="p8724930135519"></a>Size of the task stack</p>
</td>
</tr>
<tr id="row187341330145517"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1172483055520"><a name="p1172483055520"></a><a name="p1172483055520"></a>WaterLine</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p10724103013559"><a name="p10724103013559"></a><a name="p10724103013559"></a>Peak value of the stack used</p>
</td>
</tr>
<tr id="row473473025513"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p87240306554"><a name="p87240306554"></a><a name="p87240306554"></a>MEMUSE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p10724123005519"><a name="p10724123005519"></a><a name="p10724123005519"></a>Memory usage</p>
</td>
</tr>
<tr id="row18734143035519"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p7724163011559"><a name="p7724163011559"></a><a name="p7724163011559"></a>TaskName</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p872414301552"><a name="p872414301552"></a><a name="p872414301552"></a>Task name</p>
</td>
</tr>
</tbody>
</table>
# uname # uname
## Command Function<a name="section107697383115"></a>
## Command Function
This command is used to display the name, version creation time, system name, and version information of the current operating system. This command is used to display the name, version creation time, system name, and version information of the current operating system.
## Syntax<a name="section162824341116"></a>
## Syntax
uname \[_-a | -s | -r | -m | -n | -v | --help_\]
uname [_-a | -s | -r | -m | -n | -v | --help_]
**Table 1** Parameters
<a name="table909mcpsimp"></a> **Table 1** Parameter description
<table><thead align="left"><tr id="row914mcpsimp"><th class="cellrowborder" valign="top" width="33.989999999999995%" id="mcps1.2.3.1.1"><p id="p916mcpsimp"><a name="p916mcpsimp"></a><a name="p916mcpsimp"></a>Parameter</p>
</th> | Parameter | Description |
<th class="cellrowborder" valign="top" width="66.01%" id="mcps1.2.3.1.2"><p id="p918mcpsimp"><a name="p918mcpsimp"></a><a name="p918mcpsimp"></a>Parameters</p> | ------ | ----------------------- |
</th> | --help | Displays help information.|
</tr> | No parameter| Displays the operating system name by default. |
</thead> | -a | Displays all data. |
<tbody><tr id="row7659172561412"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p9648112519147"><a name="p9648112519147"></a><a name="p9648112519147"></a>--help</p> | -s | Displays the operating system name. |
</td> | -r | Displays the kernel release version. |
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p1664862551411"><a name="p1664862551411"></a><a name="p1664862551411"></a>Displays help information.</p> | -m | Displays the operating system architecture name. |
</td> | -n | Displays the network domain name of the host. |
</tr> | -v | Displays version information. |
<tr id="row365962510147"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p26489259149"><a name="p26489259149"></a><a name="p26489259149"></a>No parameter</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p186484252141"><a name="p186484252141"></a><a name="p186484252141"></a>Displays the operating system name by default.</p> ## Usage Guidelines
</td>
</tr>
<tr id="row12659142511413"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p156481253140"><a name="p156481253140"></a><a name="p156481253140"></a>-a</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p864872512145"><a name="p864872512145"></a><a name="p864872512145"></a>Displays all information.</p>
</td>
</tr>
<tr id="row365917254143"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p136481625131417"><a name="p136481625131417"></a><a name="p136481625131417"></a>-s</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p1064852514149"><a name="p1064852514149"></a><a name="p1064852514149"></a>Displays the operating system name.</p>
</td>
</tr>
<tr id="row196591425101413"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p364814255144"><a name="p364814255144"></a><a name="p364814255144"></a>-r</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p1564872515145"><a name="p1564872515145"></a><a name="p1564872515145"></a>Displays the kernel release version.</p>
</td>
</tr>
<tr id="row10659202591419"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p11648162520146"><a name="p11648162520146"></a><a name="p11648162520146"></a>-m</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p136489251143"><a name="p136489251143"></a><a name="p136489251143"></a>Displays the operating system architecture name.</p>
</td>
</tr>
<tr id="row126582025111417"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p13648102551411"><a name="p13648102551411"></a><a name="p13648102551411"></a>-n</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p6648132512141"><a name="p6648132512141"></a><a name="p6648132512141"></a>Displays the network domain name of the host.</p>
</td>
</tr>
<tr id="row3658925151415"><td class="cellrowborder" valign="top" width="33.989999999999995%" headers="mcps1.2.3.1.1 "><p id="p9648152501414"><a name="p9648152501414"></a><a name="p9648152501414"></a>-v</p>
</td>
<td class="cellrowborder" valign="top" width="66.01%" headers="mcps1.2.3.1.2 "><p id="p46489250149"><a name="p46489250149"></a><a name="p46489250149"></a>Displays version information.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section2652124861114"></a>
- The **uname** command displays the name of the current operating system by default. - The **uname** command displays the name of the current operating system by default.
- Except **--help** and **-a**, other parameters can be used together. **uname -a** is equivalent to **uname -srmnv**. - Except **--help** and **-a**, other parameters can be used together. **uname -a** is equivalent to **uname -srmnv**.
## Example<a name="section0107995132"></a> ## Note
The **-r**, **-m**, and **-n** parameters are not supported currently. mksh supports these parameters. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run the following commands: Run the following commands:
- uname -a - uname -a
- uname -ms - uname -ms
## Output<a name="section1215113245511"></a>
## Output
Example 1: all information of the operating system Example 1: all information of the operating system
``` ```
OHOS:/$ uname -a OHOS:/$ uname -a
LiteOS hisilicon 2.0.x.x Huawei LiteOS 2.0.x.x Oct 21 2021 17:39:32 Cortex-A7 LiteOS hisilicon 2.0.0.37 LiteOS 2.0.0.37 Oct 21 2021 17:39:32 Cortex-A7
OHOS:/$ OHOS:/$
``` ```
...@@ -89,4 +61,3 @@ OHOS:/$ uname -ms ...@@ -89,4 +61,3 @@ OHOS:/$ uname -ms
LiteOS Cortex-A7 LiteOS Cortex-A7
OHOS:/$ OHOS:/$
``` ```
# vmm # vmm
## Command Function<a name="section445335110416"></a>
## Command Function
This command is used to query the virtual memory used by a process. This command is used to query the virtual memory used by a process.
## Syntax<a name="section1795712553416"></a>
- vmm \[_-a / -h / --help_\] ## Syntax
- vmm \[_pid_\]
- vmm [_-a / -h / --help_]
- vmm [_pid_]
## Parameters<a name="section92544592410"></a>
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table3900mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row3906mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p3908mcpsimp"><a name="p3908mcpsimp"></a><a name="p3908mcpsimp"></a>Parameter</p> | -------- | -------- | -------- |
</th> | -a | Displays the virtual memory usage of all processes.| N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p3910mcpsimp"><a name="p3910mcpsimp"></a><a name="p3910mcpsimp"></a>Description</p> | -h&nbsp;\|&nbsp;--help | Displays help information.| N/A |
</th> | pid | Specifies the ID of the process to query.| [0, 63] |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p3912mcpsimp"><a name="p3912mcpsimp"></a><a name="p3912mcpsimp"></a>Value Range</p>
</th>
</tr> ## Usage Guidelines
</thead>
<tbody><tr id="row3913mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p17944444181717"><a name="p17944444181717"></a><a name="p17944444181717"></a>-a</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p209441344121716"><a name="p209441344121716"></a><a name="p209441344121716"></a>Displays the virtual memory usage of all processes.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3919mcpsimp"><a name="p3919mcpsimp"></a><a name="p3919mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row3920mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1944124412171"><a name="p1944124412171"></a><a name="p1944124412171"></a>-h | --help</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1494494441713"><a name="p1494494441713"></a><a name="p1494494441713"></a>Displays help information.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3926mcpsimp"><a name="p3926mcpsimp"></a><a name="p3926mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row3934mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p5945444181720"><a name="p5945444181720"></a><a name="p5945444181720"></a>pid</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1594515442177"><a name="p1594515442177"></a><a name="p1594515442177"></a>Specifies the ID of the process to query.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p3940mcpsimp"><a name="p3940mcpsimp"></a><a name="p3940mcpsimp"></a>[0,63]</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section104151141252"></a>
By default, this command displays the virtual memory usage of all processes. By default, this command displays the virtual memory usage of all processes.
## Example<a name="section11545171957"></a>
## Example
Run **vmm 3**. Run **vmm 3**.
## Output<a name="section075617368542"></a>
## Output
Virtual memory usage of process 3: Virtual memory usage of process 3:
...@@ -84,90 +64,23 @@ OHOS # vmm 3 ...@@ -84,90 +64,23 @@ OHOS # vmm 3
**Table 2** Basic process information **Table 2** Basic process information
<a name="table17136143042317"></a> | Parameter| Description|
<table><thead align="left"><tr id="row1113611307232"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p17137173017232"><a name="p17137173017232"></a><a name="p17137173017232"></a>Parameter</p> | -------- | -------- |
</th> | PID | Process ID.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p171371302230"><a name="p171371302230"></a><a name="p171371302230"></a>Description</p> | aspace | Address of the virtual memory control block.|
</th> | name | Process name.|
</tr> | base | Start address of the virtual memory.|
</thead> | size | Total Virtual Memory.|
<tbody><tr id="row11371230202317"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p0137630122313"><a name="p0137630122313"></a><a name="p0137630122313"></a>PID</p> | pages | Number of used physical pages.|
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p513793016233"><a name="p513793016233"></a><a name="p513793016233"></a>Process ID</p> **Table 3** Virtual memory interval information
</td>
</tr> | Parameter| Description|
<tr id="row61371630112315"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p18137133019236"><a name="p18137133019236"></a><a name="p18137133019236"></a>aspace</p> | -------- | -------- |
</td> | region | Address of the control block in the virtual memory region.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p9137130122311"><a name="p9137130122311"></a><a name="p9137130122311"></a>Address of the virtual memory control block</p> | name | Name of the virtual memory region.|
</td> | base | Start address of the virtual memory region.|
</tr> | size | Size of the virtual memory region.|
<tr id="row613793015232"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p12137230172311"><a name="p12137230172311"></a><a name="p12137230172311"></a>name</p> | mmu_flags | MMU mapping attribute of the virtual memory region.|
</td> | pages | Number of used physical pages, including that of the shared memory.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p19137193018235"><a name="p19137193018235"></a><a name="p19137193018235"></a>Process name</p> | pg/ref | Number of used physical pages.|
</td>
</tr>
<tr id="row1613763019237"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1413723015233"><a name="p1413723015233"></a><a name="p1413723015233"></a>base</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1613783082319"><a name="p1613783082319"></a><a name="p1613783082319"></a>Start address of the virtual memory</p>
</td>
</tr>
<tr id="row141376308237"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p101371730162319"><a name="p101371730162319"></a><a name="p101371730162319"></a>size</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p18137143092313"><a name="p18137143092313"></a><a name="p18137143092313"></a>Size of virtual memory</p>
</td>
</tr>
<tr id="row19137163072316"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p16137183013235"><a name="p16137183013235"></a><a name="p16137183013235"></a>pages</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p5137130142314"><a name="p5137130142314"></a><a name="p5137130142314"></a>Number of used physical pages</p>
</td>
</tr>
</tbody>
</table>
**Table 3** Virtual memory region information
<a name="table1195314682418"></a>
<table><thead align="left"><tr id="row14953144632413"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1195314617242"><a name="p1195314617242"></a><a name="p1195314617242"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p13953174614243"><a name="p13953174614243"></a><a name="p13953174614243"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row18953114610242"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p09531746132417"><a name="p09531746132417"></a><a name="p09531746132417"></a>region</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1795344642412"><a name="p1795344642412"></a><a name="p1795344642412"></a>Address of the control block in the virtual memory region</p>
</td>
</tr>
<tr id="row1795384682411"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p199531846112417"><a name="p199531846112417"></a><a name="p199531846112417"></a>name</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p19539466245"><a name="p19539466245"></a><a name="p19539466245"></a>Name of the virtual memory region</p>
</td>
</tr>
<tr id="row99531446132410"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p139531946132417"><a name="p139531946132417"></a><a name="p139531946132417"></a>base</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p139536468242"><a name="p139536468242"></a><a name="p139536468242"></a>Start address of the virtual memory region</p>
</td>
</tr>
<tr id="row79531046122418"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p11953546102418"><a name="p11953546102418"></a><a name="p11953546102418"></a>size</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p89531246142419"><a name="p89531246142419"></a><a name="p89531246142419"></a>Size of the virtual memory region</p>
</td>
</tr>
<tr id="row1295315464240"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p7953154602419"><a name="p7953154602419"></a><a name="p7953154602419"></a>mmu_flags</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p395464620242"><a name="p395464620242"></a><a name="p395464620242"></a>MMU mapping attribute of the virtual memory region</p>
</td>
</tr>
<tr id="row10954154692413"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1195484642410"><a name="p1195484642410"></a><a name="p1195484642410"></a>pages</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p29541546112416"><a name="p29541546112416"></a><a name="p29541546112416"></a>Number of used physical pages, including that of the shared memory</p>
</td>
</tr>
<tr id="row1395411463246"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p14954146152418"><a name="p14954146152418"></a><a name="p14954146152418"></a>pg/ref</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p10954164642419"><a name="p10954164642419"></a><a name="p10954164642419"></a>Number of used physical pages</p>
</td>
</tr>
</tbody>
</table>
# watch # watch
## Command Function<a name="section20643141481314"></a>
## Command Function
This command is used to periodically run the specified command and display its execution result. This command is used to periodically run the specified command and display its execution result.
## Syntax<a name="section1075441721316"></a>
## Syntax
- watch - watch
- watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\]
- watch [_-c/-n/-t/--count/--interval/-no-title/--over_] [_command_]
## Parameters<a name="section1472810220135"></a>
**Table 1** Parameter description ## Parameters
<a name="table966mcpsimp"></a> **Table 1** Parameter description
<table><thead align="left"><tr id="row973mcpsimp"><th class="cellrowborder" valign="top" width="19.801980198019802%" id="mcps1.2.5.1.1"><p id="p975mcpsimp"><a name="p975mcpsimp"></a><a name="p975mcpsimp"></a>Parameter</p>
</th> | Parameter| Description| Default Value| Value Range|
<th class="cellrowborder" valign="top" width="29.222922292229224%" id="mcps1.2.5.1.2"><p id="p977mcpsimp"><a name="p977mcpsimp"></a><a name="p977mcpsimp"></a>Description</p> | -------- | -------- | -------- | -------- |
</th> | -c&nbsp;/&nbsp;--count | Specifies the number of times that the specified command is executed.| 0xFFFFFF | (0, 0xFFFFFF]|
<th class="cellrowborder" valign="top" width="22.26222622262226%" id="mcps1.2.5.1.3"><p id="p979mcpsimp"><a name="p979mcpsimp"></a><a name="p979mcpsimp"></a>Default Value</p> | -n&nbsp;/&nbsp;--interval | Specifies the interval for running the command, in seconds.| 1s | (0, 0xFFFFFF]|
</th> | -t&nbsp;/&nbsp;-no-title | Disables time display on the top.| N/A | N/A |
<th class="cellrowborder" valign="top" width="28.712871287128717%" id="mcps1.2.5.1.4"><p id="p981mcpsimp"><a name="p981mcpsimp"></a><a name="p981mcpsimp"></a>Value Range</p> | command | Specifies the command to be monitored.| N/A | N/A |
</th> | --over | Stops the current command monitoring.| N/A | N/A |
</tr>
</thead>
<tbody><tr id="row982mcpsimp"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p984mcpsimp"><a name="p984mcpsimp"></a><a name="p984mcpsimp"></a>-c / --count</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p986mcpsimp"><a name="p986mcpsimp"></a><a name="p986mcpsimp"></a>Specifies the number of times that the specified command is executed.</p>
</td>
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p988mcpsimp"><a name="p988mcpsimp"></a><a name="p988mcpsimp"></a>0xFFFFFF</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 "><p id="p990mcpsimp"><a name="p990mcpsimp"></a><a name="p990mcpsimp"></a>(0, 0xFFFFFF]</p>
</td>
</tr>
<tr id="row991mcpsimp"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p993mcpsimp"><a name="p993mcpsimp"></a><a name="p993mcpsimp"></a>-n / --interval</p>
</td>
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p995mcpsimp"><a name="p995mcpsimp"></a><a name="p995mcpsimp"></a>Specifies the interval (in seconds) for periodically running the specified command.</p>
</td>
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p997mcpsimp"><a name="p997mcpsimp"></a><a name="p997mcpsimp"></a>1s</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 "><p id="p999mcpsimp"><a name="p999mcpsimp"></a><a name="p999mcpsimp"></a>(0, 0xFFFFFF]</p>
</td>
</tr>
<tr id="row1000mcpsimp"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p1002mcpsimp"><a name="p1002mcpsimp"></a><a name="p1002mcpsimp"></a>-t / -no-title</p>
</td>
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p1004mcpsimp"><a name="p1004mcpsimp"></a><a name="p1004mcpsimp"></a>Disables time display on the top.</p>
</td>
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p1006mcpsimp"><a name="p1006mcpsimp"></a><a name="p1006mcpsimp"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 "><p id="p1008mcpsimp"><a name="p1008mcpsimp"></a><a name="p1008mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row1009mcpsimp"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p1011mcpsimp"><a name="p1011mcpsimp"></a><a name="p1011mcpsimp"></a>command</p>
</td>
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p1013mcpsimp"><a name="p1013mcpsimp"></a><a name="p1013mcpsimp"></a>Specifies the command to be monitored.</p>
</td>
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p1015mcpsimp"><a name="p1015mcpsimp"></a><a name="p1015mcpsimp"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 "><p id="p1017mcpsimp"><a name="p1017mcpsimp"></a><a name="p1017mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row1018mcpsimp"><td class="cellrowborder" valign="top" width="19.801980198019802%" headers="mcps1.2.5.1.1 "><p id="p1020mcpsimp"><a name="p1020mcpsimp"></a><a name="p1020mcpsimp"></a>--over</p>
</td>
<td class="cellrowborder" valign="top" width="29.222922292229224%" headers="mcps1.2.5.1.2 "><p id="p1022mcpsimp"><a name="p1022mcpsimp"></a><a name="p1022mcpsimp"></a>Stops the current command monitoring.</p>
</td>
<td class="cellrowborder" valign="top" width="22.26222622262226%" headers="mcps1.2.5.1.3 "><p id="p1024mcpsimp"><a name="p1024mcpsimp"></a><a name="p1024mcpsimp"></a>N/A</p>
</td>
<td class="cellrowborder" valign="top" width="28.712871287128717%" headers="mcps1.2.5.1.4 "><p id="p1026mcpsimp"><a name="p1026mcpsimp"></a><a name="p1026mcpsimp"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section186772414131"></a>
You can run the **watch --over** command to stop monitoring of the specified command. You can run the **watch --over** command to stop monitoring of the specified command.
## Example<a name="section4764192791314"></a>
## Example
Run **watch -n 2 -c 6 task**. Run **watch -n 2 -c 6 task**.
## Output<a name="section5791253155517"></a>
## Output
Example: The **task** command is executed six times at an interval of 2 seconds. Example: The **task** command is executed six times at an interval of 2 seconds.
...@@ -121,4 +77,3 @@ OHOS # ...@@ -121,4 +77,3 @@ OHOS #
17 2 0x3 0 Running 0x3000 0x73c 0.0 0 shellcmd_watch 17 2 0x3 0 Running 0x3000 0x73c 0.0 0 shellcmd_watch
18 2 0x3 -1 Pending 0x2710 0x3ac 0.0 0 GPIO_IRQ_TSK_0_4 18 2 0x3 -1 Pending 0x2710 0x3ac 0.0 0 GPIO_IRQ_TSK_0_4
``` ```
# cat # cat
## Command Function<a name="section16710153391315"></a>
## Command Function
This command is used to display the content of a text file. This command is used to display the content of a text file.
## Syntax<a name="section1699392313158"></a>
cat \[_pathname_\] ## Syntax
cat [_pathname_]
## Parameters<a name="section1677217374136"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1049mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row1055mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1057mcpsimp"><a name="p1057mcpsimp"></a><a name="p1057mcpsimp"></a><strong id="b2166111484619"><a name="b2166111484619"></a><a name="b2166111484619"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | pathname | Specifies the file path. | An existing file |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1059mcpsimp"><a name="p1059mcpsimp"></a><a name="p1059mcpsimp"></a><strong id="b17121718469"><a name="b17121718469"></a><a name="b17121718469"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1061mcpsimp"><a name="p1061mcpsimp"></a><a name="p1061mcpsimp"></a><strong id="b6990101716464"><a name="b6990101716464"></a><a name="b6990101716464"></a>Value Range</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1062mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1064mcpsimp"><a name="p1064mcpsimp"></a><a name="p1064mcpsimp"></a>pathname</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1066mcpsimp"><a name="p1066mcpsimp"></a><a name="p1066mcpsimp"></a>Specifies the file path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1068mcpsimp"><a name="p1068mcpsimp"></a><a name="p1068mcpsimp"></a>An existing file</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section186772414131"></a>
Run the **cat** \[_pathname_\] command to display the content of a text file. ## Usage Guidelines
## Example<a name="section12158131814561"></a> Run the **cat** [*pathname*] command to display the content of a text file.
Run **cat hello-harmony.txt**.
## Output<a name="section183926225561"></a> ## Example
Content of **hello-harmony.txt** Run **cat hello-openharmony.txt**.
## Output
Content of **hello-openharmony.txt**
``` ```
OHOS # cat hello-harmony.txt OHOS # cat hello-openharmony.txt
OHOS # Hello Harmony ;) OHOS # Hello openharmony ;)
``` ```
# cd # cd
## Command Function<a name="section11690184921316"></a> ## Command Function
This command is used to change the current working directory. This command is used to change the current working directory.
## Syntax<a name="section75695409569"></a>
cd \[_path_\] ## Syntax
## Parameters<a name="section71961353181311"></a> cd [_path_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1087mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row1093mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1095mcpsimp"><a name="p1095mcpsimp"></a><a name="p1095mcpsimp"></a><strong id="b76096875111729"><a name="b76096875111729"></a><a name="b76096875111729"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | path | Specifies the path of the new directory. | You must have the execution (search) permission on the specified directory.|
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1097mcpsimp"><a name="p1097mcpsimp"></a><a name="p1097mcpsimp"></a><strong id="b1343743615221"><a name="b1343743615221"></a><a name="b1343743615221"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1099mcpsimp"><a name="p1099mcpsimp"></a><a name="p1099mcpsimp"></a><strong id="b163024311311729"><a name="b163024311311729"></a><a name="b163024311311729"></a>Value Range</strong></p> ## Usage Guidelines
</th>
</tr>
</thead>
<tbody><tr id="row1100mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1102mcpsimp"><a name="p1102mcpsimp"></a><a name="p1102mcpsimp"></a>path</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1104mcpsimp"><a name="p1104mcpsimp"></a><a name="p1104mcpsimp"></a>Specifies the target file path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1106mcpsimp"><a name="p1106mcpsimp"></a><a name="p1106mcpsimp"></a>You must have the execution (search) permission for the specified directory.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section3629759111317"></a>
- If **path** is not specified, this command switches to the root directory. - If **path** is not specified, this command switches to the root directory.
- If **path** is specified, this command switches to the specified directory. - If **path** is specified, this command switches to the specified directory.
- The **path** value starting with a slash \(/\) represents the root directory.
- The **path** value starting with a dot \(.\) represents the current directory. - The **path** value starting with a slash (/) represents the root directory.
- The **path** value starting with two dots \(..\) represents the parent directory.
- The **path** value starting with a dot (.) represents the current directory.
- The **path** value starting with two dots (..) represents the parent directory.
- You can run **cd -** to alternate between two directories that are recently accessed. - You can run **cd -** to alternate between two directories that are recently accessed.
## Example<a name="section211620301412"></a>
## Example
Run **cd ..**. Run **cd ..**.
## Output<a name="section1968117214577"></a>
## Output
Parent directory information: Parent directory information:
...@@ -55,4 +50,3 @@ OHOS:/$ ls ...@@ -55,4 +50,3 @@ OHOS:/$ ls
bin etc nfs sdcard system tmp vendor bin etc nfs sdcard system tmp vendor
dev lib proc storage test usr dev lib proc storage test usr
``` ```
# chgrp # chgrp
## Command Function<a name="section6103119161418"></a>
## Command Function
This command is used to change the file group. This command is used to change the file group.
## Syntax<a name="section186958132141"></a>
chgrp \[_group_\] \[_pathname_\] ## Syntax
chgrp [_group_] [_pathname_]
## Parameters<a name="section81796174141"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1049mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row1055mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1057mcpsimp"><a name="p1057mcpsimp"></a><a name="p1057mcpsimp"></a><strong id="b152503343511626"><a name="b152503343511626"></a><a name="b152503343511626"></a>Parameter</strong></p> | -------- | ---------- | -------------- |
</th> | group | Specifies the target file group.| [0, 0xFFFFFFFF] |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1059mcpsimp"><a name="p1059mcpsimp"></a><a name="p1059mcpsimp"></a><strong id="b14728419275"><a name="b14728419275"></a><a name="b14728419275"></a>Description</strong></p> | pathname | Specifies the file path. | An existing file |
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1061mcpsimp"><a name="p1061mcpsimp"></a><a name="p1061mcpsimp"></a><strong id="b71533702411626"><a name="b71533702411626"></a><a name="b71533702411626"></a>Value Range</strong></p>
</th> ## Usage Guidelines
</tr>
</thead>
<tbody><tr id="row1062mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1064mcpsimp"><a name="p1064mcpsimp"></a><a name="p1064mcpsimp"></a>group</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1066mcpsimp"><a name="p1066mcpsimp"></a><a name="p1066mcpsimp"></a>Specifies the target file group.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1068mcpsimp"><a name="p1068mcpsimp"></a><a name="p1068mcpsimp"></a>[0, 0xFFFFFFFF]</p>
</td>
</tr>
<tr id="row172161126124218"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p12217026154215"><a name="p12217026154215"></a><a name="p12217026154215"></a>pathname</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p4218826194210"><a name="p4218826194210"></a><a name="p4218826194210"></a>Specifies the file path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p182181026104214"><a name="p182181026104214"></a><a name="p182181026104214"></a>An existing file</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section14330152417140"></a>
- Specify **group** to change the file group. - Specify **group** to change the file group.
- For the FAT file system, this command cannot be used to change user group IDs. - For the FAT file system, this command cannot be used to change user group IDs.
## Example<a name="section951823119149"></a> ## Note
Currently, the shell does not support this command.
## Example
Run **chgrp 100 testfile**. Run **chgrp 100 testfile**.
## Output<a name="section14271133125715"></a>
Changing the group ID of the **testfile** file in the **dev/** directory to **100** ## Output
Change the group ID of the **testfile** file in the **dev/** directory to **100**.
``` ```
OHOS:/dev$ ll testfile OHOS:/dev$ ll testfile
...@@ -59,4 +47,3 @@ OHOS:/dev$ ll testfile ...@@ -59,4 +47,3 @@ OHOS:/dev$ ll testfile
-rw-r--r-- 0 0 100 0 1970-01-01 00:00 testfile -rw-r--r-- 0 0 100 0 1970-01-01 00:00 testfile
OHOS:/dev$ OHOS:/dev$
``` ```
# chmod # chmod
## Command Function<a name="section13992936121418"></a>
## Command Function
This command is used to change file operation permissions. This command is used to change file operation permissions.
## Syntax<a name="section63342439147"></a>
## Syntax
chmod \[_mode_\] \[_filename_\]
chmod [_mode_] [_filename_]
## Parameter Description<a name="section894414671411"></a>
**Table 1** Parameters ## Parameters
<a name="table1049mcpsimp"></a> **Table 1** Parameter description
<table><thead align="left"><tr id="row1055mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1057mcpsimp"><a name="p1057mcpsimp"></a><a name="p1057mcpsimp"></a>Parameter</p>
</th> | Parameter | Description | Value Range |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1059mcpsimp"><a name="p1059mcpsimp"></a><a name="p1059mcpsimp"></a>Description</p> | -------- | ------------------------------------------------------------ | -------------- |
</th> | mode | Specifies the permissions for a file or directory. The value is an octal number, representing the permission of **User** (owner), **Group** (group), or **Others** (other groups).| [0, 777] |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1061mcpsimp"><a name="p1061mcpsimp"></a><a name="p1061mcpsimp"></a>Value Range</p> | filename | Specifies the file path. | An existing file |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row2981144101719"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p20916441173"><a name="p20916441173"></a><a name="p20916441173"></a>mode</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3911344161713"><a name="p3911344161713"></a><a name="p3911344161713"></a>Specifies the permissions for a file or directory. The value is an octal number, representing the permission of <strong id="b11602834153114"><a name="b11602834153114"></a><a name="b11602834153114"></a>User</strong> (owner), <strong id="b032113853120"><a name="b032113853120"></a><a name="b032113853120"></a>Group</strong> (group), or <strong id="b1980114418310"><a name="b1980114418310"></a><a name="b1980114418310"></a>Others</strong> (other groups).</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1591744161719"><a name="p1591744161719"></a><a name="p1591744161719"></a>[0,777]</p>
</td>
</tr>
<tr id="row15985440173"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p99124461717"><a name="p99124461717"></a><a name="p99124461717"></a>filename</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p149134481719"><a name="p149134481719"></a><a name="p149134481719"></a>Specifies the file name.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p0911144181712"><a name="p0911144181712"></a><a name="p0911144181712"></a>An existing file</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section182415221419"></a>
- Specify **mode** to change file permissions. - Specify **mode** to change file permissions.
- For the files created on the FAT file system, the file permission attributes are the same as those of the mounted nodes. Currently, the node permissions include only user read and write. The **group** and **others** permissions do not take effect. In addition, only the user read and write permissions can be modified. The read and write permissions are **rw** and **ro** only. There is no such restriction for other file systems. - For the files created on the FAT file system, the file permission attributes are the same as those of the mounted nodes. Currently, the node permissions include only user read and write. The **group** and **others** permissions do not take effect. In addition, only the user read and write permissions can be modified. The read and write permissions are **rw** and **ro** only. There is no such restriction for other file systems.
## Example<a name="section8518195718147"></a> ## Note
Currently, the shell does not support this command.
Change the permissions on the **hello-harmony.txt** file to **644** and **777**. ## Example
## Output<a name="section127391818158"></a> Change the permissions on the **hello-openharmony.txt** file to **644** and **777**.
Modifying the permissions on the **hello-harmony.txt** file in the **/dev** directory:
## Output
Modify the permissions on the **hello-openharmony.txt** file in the **/dev** directory.
``` ```
OHOS:/dev$ chmod 644 hello-harmony.txt OHOS:/dev$ chmod 644 hello-openharmony.txt
OHOS:/dev$ ll hello-harmony.txt OHOS:/dev$ ll hello-openharmony.txt
-rw-r--r-- 0 0 0 0 1970-01-01 00:00 hello-harmony.txt -rw-r--r-- 0 0 0 0 1970-01-01 00:00 hello-openharmony.txt
OHOS:/dev$ chmod 777 hello-harmony.txt OHOS:/dev$ chmod 777 hello-openharmony.txt
OHOS:/dev$ ll hello-harmony.txt OHOS:/dev$ ll hello-openharmony.txt
-rwxrwxrwx 0 0 0 0 1970-01-01 00:00 hello-harmony.txt -rwxrwxrwx 0 0 0 0 1970-01-01 00:00 hello-openharmony.txt
``` ```
# chown # chown
## Command Function<a name="section247414691513"></a>
## Command Function
This command is used to change the owner of a file. This command is used to change the owner of a file.
## Syntax<a name="section14773151018159"></a>
chown \[_owner_\] \[_pathname_\] ## Syntax
chown [_owner_] [_pathname_]
## Parameters<a name="section598731391517"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1049mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row1055mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1057mcpsimp"><a name="p1057mcpsimp"></a><a name="p1057mcpsimp"></a><strong id="b130925344111510"><a name="b130925344111510"></a><a name="b130925344111510"></a>Parameter</strong></p> | -------- | ------------ | -------------- |
</th> | owner | Specifies the file owner. | [0, 0xFFFFFFFF] |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1059mcpsimp"><a name="p1059mcpsimp"></a><a name="p1059mcpsimp"></a><strong id="b1226032904716"><a name="b1226032904716"></a><a name="b1226032904716"></a>Description</strong></p> | pathname | Specifies the file path. | An existing file |
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1061mcpsimp"><a name="p1061mcpsimp"></a><a name="p1061mcpsimp"></a><strong id="b34190246311510"><a name="b34190246311510"></a><a name="b34190246311510"></a>Value Range</strong></p>
</th> ## Usage Guidelines
</tr>
</thead>
<tbody><tr id="row1541931122113"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p84121716217"><a name="p84121716217"></a><a name="p84121716217"></a>owner</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p14126172111"><a name="p14126172111"></a><a name="p14126172111"></a>Specifies the file owner.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p24129113218"><a name="p24129113218"></a><a name="p24129113218"></a>[0,0xFFFFFFFF]</p>
</td>
</tr>
<tr id="row12419191192111"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p141215115212"><a name="p141215115212"></a><a name="p141215115212"></a>pathname</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p7412315218"><a name="p7412315218"></a><a name="p7412315218"></a>Specifies the file path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p134126102118"><a name="p134126102118"></a><a name="p134126102118"></a>An existing file</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section16524152071510"></a>
This command does not apply to the FAT file system. This command does not apply to the FAT file system.
## Example<a name="section17901152561510"></a> ## Note
Currently, the shell does not support this command.
## Example
Run **chown 100 testfile**. Run **chown 100 testfile**.
## Output<a name="section15513163115816"></a>
Changing the UID of the **testfile** file in **/dev** to **100**: ## Output
Change the UID of the **testfile** file in **/dev** to **100**.
``` ```
OHOS:/dev$ touch testfile OHOS:/dev$ touch testfile
...@@ -58,4 +46,3 @@ OHOS:/dev$ chown 100 testfile ...@@ -58,4 +46,3 @@ OHOS:/dev$ chown 100 testfile
OHOS:/dev$ ll testfile OHOS:/dev$ ll testfile
-rw-r--r-- 0 100 100 0 1970-01-01 00:00 testfile -rw-r--r-- 0 100 100 0 1970-01-01 00:00 testfile
``` ```
# cp # cp
## Command Function<a name="section6841203041513"></a>
## Command Function
This command is used to create a copy for a file. This command is used to create a copy for a file.
## Syntax<a name="section24286359150"></a>
## Syntax
cp \[_SOURCEFILE_\] \[_DESTFILE_\]
cp [_SOURCEFILE_] [_DESTFILE_]
## Parameters<a name="section558617385152"></a>
**Table 1** Parameter description ## Parameters
<a name="table1130mcpsimp"></a> **Table 1** Parameter description
<table><thead align="left"><tr id="row1136mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1138mcpsimp"><a name="p1138mcpsimp"></a><a name="p1138mcpsimp"></a><strong id="b203611832412"><a name="b203611832412"></a><a name="b203611832412"></a>Parameter</strong></p>
</th> | Parameter| Description| Value Range|
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1140mcpsimp"><a name="p1140mcpsimp"></a><a name="p1140mcpsimp"></a><strong id="b1170512342014"><a name="b1170512342014"></a><a name="b1170512342014"></a>Description</strong></p> | -------- | -------- | -------- |
</th> | --help | Displays help information.| N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1142mcpsimp"><a name="p1142mcpsimp"></a><a name="p1142mcpsimp"></a><strong id="b173835351418"><a name="b173835351418"></a><a name="b173835351418"></a>Value Range</strong></p> | SOURCEFILE | Specifies the file to copy.| This command does not support copy of a directory, but supports copy of multiple files at a time.|
</th> | DESTFILE | Specifies the file to create.| Both a directory and a file are supported.|
</tr>
</thead>
<tbody><tr id="row217620816236"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p181687832310"><a name="p181687832310"></a><a name="p181687832310"></a>--help</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p181687882317"><a name="p181687882317"></a><a name="p181687882317"></a>Displays help information.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p18168118182312"><a name="p18168118182312"></a><a name="p18168118182312"></a>N/A</p>
</td>
</tr>
<tr id="row1417648122313"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p516816822316"><a name="p516816822316"></a><a name="p516816822316"></a>SOURCEFILE</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p81686862314"><a name="p81686862314"></a><a name="p81686862314"></a>Specifies the path of the source file.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1016811862312"><a name="p1016811862312"></a><a name="p1016811862312"></a>This command does not support copy of a directory, but supports copy of multiple files at a time.</p>
</td>
</tr>
<tr id="row191761384231"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p13168880235"><a name="p13168880235"></a><a name="p13168880235"></a>DESTFILE</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p9168789231"><a name="p9168789231"></a><a name="p9168789231"></a>Specifies the destination file path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p316810810235"><a name="p316810810235"></a><a name="p316810810235"></a>Both a directory and a file are supported.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section16128156162"></a>
- The name of the source file cannot be the same as that of the destination file in the same path. - The name of the source file cannot be the same as that of the destination file in the same path.
- **SOURCEFILE** must exist and cannot be a directory. - **SOURCEFILE** must exist and cannot be a directory.
- **SOURCEFILE** supports wildcard characters \* and ?. The asterisk \(\*\) indicates any number of characters, and the question mark \(?\) represents a single character. **DESTFILE** does not support wildcard characters. If **SOURCEFILE** specifies multiple files, **DESTFILE** must be a directory.
- If **DESTFILE** specifies a directory, this directory must exist. In this case, the destination file is named after the source file. - The source file path supports asterisks (*) and question marks (?). The wildcard "\*" indicates any number of characters, and "?" indicates any single character. **DEST** does not support wildcard characters. If the specified **SOURCE** matches multiple files, **DEST** must be a directory.
- If **DESTFILE** specifies a file, the directory for this file must exist. In this case, the file copy is renamed.
- If **DEST** is a directory, this directory must exist. In this case, the destination file is named after the source file.
- If the destination file path is a file, the directory for this file must exist. In this case, the file copy is renamed.
- If the destination file does not exist, a new file is created. If the destination file already exists, the existing file is overwritten. - If the destination file does not exist, a new file is created. If the destination file already exists, the existing file is overwritten.
>![](../public_sys-resources/icon-notice.gif) **NOTICE:** > **NOTICE**<br>
>When important system resources are copied, unexpected results such as a system breakdown may occur. For example, when the **/dev/uartdev-1** file is copied, the system may stop responding. > When important system resources are copied, unexpected results such as a system breakdown may occur. For example, when the **/dev/uartdev-1** file is copied, the system may stop responding.
## Example<a name="section19354171211618"></a> ## Example
Run **cp hello-OHOS.txt hello-harmony.txt ./tmp/**. Run **cp hello-OHOS.txt hello-openharmony.txt ./tmp/**.
## Output<a name="section16754183195914"></a>
Copying **hello-OHOS.txt** and **hello-harmony.txt** to **/tmp/**: ## Output
Copy **hello-OHOS.txt** and **hello-openharmony.txt** to **/tmp/**.
``` ```
OHOS:/$ ls OHOS:/$ ls
bin hello-OHOS.txt proc system vendor bin hello-OHOS.txt proc system vendor
dev hello-harmony.txt sdcard userdata dev hello-openharmony.txt sdcard userdata
etc lib storage usr etc lib storage usr
OHOS:/$ mkdir tmp OHOS:/$ mkdir tmp
OHOS:/$ cp hello-OHOS.txt hello-harmony.txt tmp/ OHOS:/$ cp hello-OHOS.txt hello-openharmony.txt tmp/
OHOS:/$ ll tmp OHOS:/$ ll tmp
total 0 total 0
-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 hello-OHOS.txt* -rwxrwxrwx 1 0 0 0 1979-12-31 00:00 hello-OHOS.txt*
-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 hello-harmony.txt* -rwxrwxrwx 1 0 0 0 1979-12-31 00:00 hello-openharmony.txt*
``` ```
# du # du
## Command Function<a name="section201149459368"></a>
## Command Function
This command is used to query the disk space occupied by a file. This command is used to query the disk space occupied by a file.
## Syntax<a name="section579813484364"></a>
du \[_-kKmh_\] \[_file..._\] ## Syntax
du [_-kKmh_] [_file..._]
## Parameters<a name="section168065311366"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1845mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row1851mcpsimp"><th class="cellrowborder" valign="top" width="20.84%" id="mcps1.2.4.1.1"><p id="p1853mcpsimp"><a name="p1853mcpsimp"></a><a name="p1853mcpsimp"></a>Parameter</p> | ------ | ------------------------------------------------------------ |
</th> | --help | Displays the parameters supported by the **du** command. |
<th class="cellrowborder" valign="top" width="52.16%" id="mcps1.2.4.1.2"><p id="p1855mcpsimp"><a name="p1855mcpsimp"></a><a name="p1855mcpsimp"></a>Description</p> | -k | Displays the occupied blocks, each of which is 1024 bytes by default. |
</th> | -K | Displays the occupied blocks, each of which is 512 bytes (POSIX). |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1857mcpsimp"><a name="p1857mcpsimp"></a><a name="p1857mcpsimp"></a>Value Range</p> | -m | Displays the disk space in MB. |
</th> | -h | Displays the disk space in human-readable format K, M, and G, for example, **1K**, **243M**, or **2G**.|
</tr> | file | Specifies the target file. |
</thead>
<tbody><tr id="row10230133312716"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p1921613332713"><a name="p1921613332713"></a><a name="p1921613332713"></a>--help</p>
</td> ## Usage Guidelines
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p14216153332715"><a name="p14216153332715"></a><a name="p14216153332715"></a>Displays the parameters supported by the <strong id="b22402916307"><a name="b22402916307"></a><a name="b22402916307"></a>du</strong> command.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p20216173362720"><a name="p20216173362720"></a><a name="p20216173362720"></a>N/A</p>
</td>
</tr>
<tr id="row1223010339271"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p112161733202717"><a name="p112161733202717"></a><a name="p112161733202717"></a>-k</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p142161833172710"><a name="p142161833172710"></a><a name="p142161833172710"></a>Displays the occupied blocks, each of which is 1024 bytes by default.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p42161335276"><a name="p42161335276"></a><a name="p42161335276"></a>N/A</p>
</td>
</tr>
<tr id="row4230933182718"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p152161336278"><a name="p152161336278"></a><a name="p152161336278"></a>-K</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p13216103319274"><a name="p13216103319274"></a><a name="p13216103319274"></a>Displays the occupied blocks, each of which is 512 bytes (POSIX).</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p192169337273"><a name="p192169337273"></a><a name="p192169337273"></a>N/A</p>
</td>
</tr>
<tr id="row1230103352716"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p132161833192716"><a name="p132161833192716"></a><a name="p132161833192716"></a>-m</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p621673332720"><a name="p621673332720"></a><a name="p621673332720"></a>Displays the disk space in MB.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1321614336271"><a name="p1321614336271"></a><a name="p1321614336271"></a>N/A</p>
</td>
</tr>
<tr id="row10229133315272"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p14216153313276"><a name="p14216153313276"></a><a name="p14216153313276"></a>-h</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p2216533192717"><a name="p2216533192717"></a><a name="p2216533192717"></a>Displays the disk space in human-readable format K, M, and G, for example, <strong id="b1315823125013"><a name="b1315823125013"></a><a name="b1315823125013"></a>1K</strong>, <strong id="b385962710225"><a name="b385962710225"></a><a name="b385962710225"></a>243M</strong>, or <strong id="b1114122962214"><a name="b1114122962214"></a><a name="b1114122962214"></a>2G</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p162161333102720"><a name="p162161333102720"></a><a name="p162161333102720"></a>N/A</p>
</td>
</tr>
<tr id="row1322918333273"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p182160331270"><a name="p182160331270"></a><a name="p182160331270"></a>file</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p19216103310272"><a name="p19216103310272"></a><a name="p19216103310272"></a>Specifies the target file.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p182171332271"><a name="p182171332271"></a><a name="p182171332271"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section19190125723612"></a>
- The **du** command is used to obtain the disk usage of a file rather than a directory. - The **du** command is used to obtain the disk usage of a file rather than a directory.
- The value of **file** must be the file name. It cannot contain the directory where the file is located. - The value of **file** must be the file name. It cannot contain the directory where the file is located.
## Example<a name="section10383416372"></a> ## Note
Currently, the shell does not support this command. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run **du -h testfile**. Run **du -h testfile**.
## Output<a name="section16633113552815"></a>
Command output ## Output
Disk space occupied by **testfile**.
``` ```
OHOS:/$ du -h testfile OHOS:/$ du -h testfile
1.8K testfile 1.8K testfile
``` ```
# format # format
## Command Function<a name="section1922331919169"></a> ## Command Function
This command is used for disk formatting. This command is used for disk formatting.
## Syntax<a name="section249226169"></a>
format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] ## Syntax
## Parameters<a name="section985173416177"></a> format &lt;*dev*inodename_&gt; &lt;*sectors*&gt; &lt;*option*&gt; [_label_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1183mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row1188mcpsimp"><th class="cellrowborder" valign="top" width="34%" id="mcps1.2.3.1.1"><p id="p1190mcpsimp"><a name="p1190mcpsimp"></a><a name="p1190mcpsimp"></a><strong id="b101095916104"><a name="b101095916104"></a><a name="b101095916104"></a>Parameter</strong></p> | -------- | -------- |
</th> | dev_inodename | Specifies the device name. |
<th class="cellrowborder" valign="top" width="66%" id="mcps1.2.3.1.2"><p id="p1192mcpsimp"><a name="p1192mcpsimp"></a><a name="p1192mcpsimp"></a><strong id="b14213111171020"><a name="b14213111171020"></a><a name="b14213111171020"></a>Description</strong></p> | sectors | Specifies the size of the allocated memory unit or sector. <br/>The value must be **0** or a power of **2**.<br/>The value **0** means to leave this parameter blank. <br/>For FAT32, the maximum value is **128**. If the parameter is set to **0**, a proper cluster size is automatically selected. The available cluster size range varies depending on the partition size. If the cluster size is incorrectly specified, the formatting may fail. |
</th> | option | Specifies the file system type. The options are as follows:<br>- **0x01**: FMT_FAT<br>- **0x02**: FMT_FAT32<br>- **0x07**: FMT_ANY<br>- **0x08**: FMT_ERASE (USB does not support this option.)<br>If an invalid value is specified, the system automatically selects the formatting mode. If the low-level formatting bit is **1** during the formatting of a USB flash drive, an error message is printed.|
</tr> | label | Specifies the volume label name. This parameter is optional, and the value is a string. <br/>If **null** is specified for this parameter, the previously set volume label name is cleared. |
</thead>
<tbody><tr id="row1193mcpsimp"><td class="cellrowborder" valign="top" width="34%" headers="mcps1.2.3.1.1 "><p id="p1195mcpsimp"><a name="p1195mcpsimp"></a><a name="p1195mcpsimp"></a>dev_inodename</p>
</td> ## Usage Guidelines
<td class="cellrowborder" valign="top" width="66%" headers="mcps1.2.3.1.2 "><p id="p1197mcpsimp"><a name="p1197mcpsimp"></a><a name="p1197mcpsimp"></a>Specifies the device name.</p>
</td>
</tr>
<tr id="row1203mcpsimp"><td class="cellrowborder" valign="top" width="34%" headers="mcps1.2.3.1.1 "><p id="p1205mcpsimp"><a name="p1205mcpsimp"></a><a name="p1205mcpsimp"></a>sectors</p>
</td>
<td class="cellrowborder" valign="top" width="66%" headers="mcps1.2.3.1.2 "><p id="p1207mcpsimp"><a name="p1207mcpsimp"></a><a name="p1207mcpsimp"></a>Specifies the size of the allocated memory unit or sector. The value <strong id="b1574273871018"><a name="b1574273871018"></a><a name="b1574273871018"></a>0</strong> indicates null. (The value must be <strong id="b16428721113"><a name="b16428721113"></a><a name="b16428721113"></a>0</strong> or a power of <strong id="b1053419931111"><a name="b1053419931111"></a><a name="b1053419931111"></a>2</strong>. For FAT32, the maximum value is <strong id="b51473841110"><a name="b51473841110"></a><a name="b51473841110"></a>128</strong>. If the parameter is set to <strong id="b99547931214"><a name="b99547931214"></a><a name="b99547931214"></a>0</strong>, a proper cluster size is automatically selected. The available cluster size range varies depending on the partition size. If the cluster size is incorrectly specified, the formatting may fail.)</p>
</td>
</tr>
<tr id="row1208mcpsimp"><td class="cellrowborder" valign="top" width="34%" headers="mcps1.2.3.1.1 "><p id="p1210mcpsimp"><a name="p1210mcpsimp"></a><a name="p1210mcpsimp"></a>option</p>
</td>
<td class="cellrowborder" valign="top" width="66%" headers="mcps1.2.3.1.2 "><div class="p" id="p1212mcpsimp"><a name="p1212mcpsimp"></a><a name="p1212mcpsimp"></a>Specifies the file system type. The options are as follows:<a name="ul10971366369"></a><a name="ul10971366369"></a><ul id="ul10971366369"><li><strong id="b169384514517"><a name="b169384514517"></a><a name="b169384514517"></a>0x01</strong>: FMT_FAT</li><li><strong id="b143061510125114"><a name="b143061510125114"></a><a name="b143061510125114"></a>0x02</strong>: FMT_FAT32</li><li><strong id="b3245614165116"><a name="b3245614165116"></a><a name="b3245614165116"></a>0x07</strong>: FMT_ANY</li><li><strong id="b018121813512"><a name="b018121813512"></a><a name="b018121813512"></a>0x08</strong>: FMT_ERASE (not supported by the USB flash drive)</li></ul>
</div>
<p id="p28366459374"><a name="p28366459374"></a><a name="p28366459374"></a>If an invalid value is specified, the system automatically selects the formatting mode. If the low-level formatting bit is <strong id="b4634562520"><a name="b4634562520"></a><a name="b4634562520"></a>1</strong> during the formatting of a USB flash drive, an error message is printed.</p>
</td>
</tr>
<tr id="row1213mcpsimp"><td class="cellrowborder" valign="top" width="34%" headers="mcps1.2.3.1.1 "><p id="p1215mcpsimp"><a name="p1215mcpsimp"></a><a name="p1215mcpsimp"></a>label</p>
</td>
<td class="cellrowborder" valign="top" width="66%" headers="mcps1.2.3.1.2 "><p id="p1217mcpsimp"><a name="p1217mcpsimp"></a><a name="p1217mcpsimp"></a>Specifies the volume label name. This parameter is optional, and the value is a string. If <strong id="b16648426102713"><a name="b16648426102713"></a><a name="b16648426102713"></a>null</strong> is specified for this parameter, the previously set volume label name is cleared.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section1510162714162"></a>
- The **format** command is used for disk formatting. You can find the device name in the **dev** directory. A storage card must be installed before the formatting. - The **format** command is used for disk formatting. You can find the device name in the **dev** directory. A storage card must be installed before the formatting.
- The **format** command can be used to format the USB flash drive, SD card, and MMC, but not the NAND flash or NOR flash. - The **format** command can be used to format the USB flash drive, SD card, and MMC, but not the NAND flash or NOR flash.
- An invalid **sectors** value may cause exceptions. - An invalid **sectors** value may cause exceptions.
## Example<a name="section25691431161611"></a>
## Example
Run **format /dev/mmcblk0 128 2**. Run **format /dev/mmcblk0 128 2**.
## Output<a name="section17368112365920"></a>
Formatting an MMC: ## Output
Format an MMC.
``` ```
OHOS # format /dev/mmcblk1 128 2 OHOS # format /dev/mmcblk1 128 2
Format to FAT32, 128 sectors per cluster. Format to FAT32, 128 sectors per cluster.
format /dev/mmcblk1 Success format /dev/mmcblk1 Success
``` ```
# ls # ls
## Command Function<a name="section6538163771614"></a>
This command is used to display the content of a specified directory. ## Command Function
## Syntax<a name="section45881743111616"></a> This command is used to display the content of a directory.
ls \[_-ACHLSZacdfhiklmnopqrstux1_\] \[_--color_\[_=auto_\]\] \[_directory..._\]
>![](../public_sys-resources/icon-note.gif) **NOTE:** ## Syntax
>During the system boot process, **ls=toybox ls --color=auto**, **ll = ls -alF**, **la=ls -A**, and **l=ls -CF** commands have been enabled using **alias** so that the initial actions of these commands are the same as those on Linux. For details, see the output description. To view help information, run **toybox ls --help**.
## Parameters<a name="section17528148171617"></a> ls [_-ACHLSZacdfhiklmnopqrstux1_] [_--color_[_=auto_]] [_directory..._]
> **NOTE**<br>
> During the system boot process, **ls=toybox ls --color=auto**, **ll = ls -alF**, **la=ls -A**, and **l=ls -CF** commands have been enabled using **alias** so that the initial actions of these commands are the same as those on Linux. For details, see **Output**. To view help information, run **toybox ls --help**.
## Parameters
**Table 1** Command parameter description **Table 1** Command parameter description
<a name="table1244mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row1250mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1252mcpsimp"><a name="p1252mcpsimp"></a><a name="p1252mcpsimp"></a><strong id="b85851402216"><a name="b85851402216"></a><a name="b85851402216"></a>Parameter</strong></p> | ------ | ------------------------------------------------------------ | ----------------------------- |
</th> | --help | Displays parameters supported by the **ls** command and their usage. | N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1254mcpsimp"><a name="p1254mcpsimp"></a><a name="p1254mcpsimp"></a><strong id="b128175424215"><a name="b128175424215"></a><a name="b128175424215"></a>Description</strong></p> | -a | Displays all files, including hidden files. | N/A |
</th> | -b | Escapes non-graphical characters. | N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1256mcpsimp"><a name="p1256mcpsimp"></a><a name="p1256mcpsimp"></a><strong id="b184580431629"><a name="b184580431629"></a><a name="b184580431629"></a>Value Range</strong></p> | -c | Uses **ctime** as the file timestamp. This parameter must be used together with **-l**. | N/A |
</th> | -d | Displays only the directory, rather than listing the content of the directory. | N/A |
</tr> | -i | Displays the node ID of a file. | N/A |
</thead> | -p | Adds a slash (/) after the directory. | N/A |
<tbody><tr id="row1165411114303"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p16614161193017"><a name="p16614161193017"></a><a name="p16614161193017"></a>--help</p> | -q | Displays non-printable characters, such as "?". | N/A |
</td> | -s | Provides information about the memory occupied by the directory and its members, in 1024 bytes. | N/A |
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p161410110302"><a name="p161410110302"></a><a name="p161410110302"></a>Displays parameters supported by the <strong id="b05047195230"><a name="b05047195230"></a><a name="b05047195230"></a>ls</strong> command and their usage.</p> | -u | Uses the last access time of the file as the timestamp. This option is used together with **-l**. | N/A |
</td> | -A | Lists all files except implied . and .. | N/A |
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p196141211193014"><a name="p196141211193014"></a><a name="p196141211193014"></a>N/A</p> | -H | Follows symbolic links listed in the command line. | N/A |
</td> | -L | Follows symbolic links. | N/A |
</tr> | -Z | Displays security context. | N/A |
<tr id="row3653131173015"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p76141511123013"><a name="p76141511123013"></a><a name="p76141511123013"></a>-a</p> | path | Specifies the path of the target directory.<br/>If **path** is left blank, the content of the current directory is displayed.<br>If **path** is an invalid directory, "ls&nbsp;error:&nbsp;No&nbsp;such&nbsp;directory." is displayed.<br><br>If **path** is a valid directory, the content of the specified directory is displayed. | Left blank<br>A valid directory|
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p861431163012"><a name="p861431163012"></a><a name="p861431163012"></a>Displays all files, including .hidden files.</p> **Table 2** Output format parameters
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p161421153016"><a name="p161421153016"></a><a name="p161421153016"></a>N/A</p> | Parameter | Description |
</td> | ------- | --------------------------------------- |
</tr> | -1 | Lists one file per line. |
<tr id="row6653161163013"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p10614131116307"><a name="p10614131116307"></a><a name="p10614131116307"></a>-b</p> | -c | Lists entries by column. |
</td> | -g | Like **-l**, but do not list the owner. |
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p6614511113013"><a name="p6614511113013"></a><a name="p6614511113013"></a>Escapes non-graphical characters.</p> | -h | Displays the total size of files in the directory, in KiB.|
</td> | -l | Displays detailed information about files in the directory. |
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p16614161110307"><a name="p16614161110307"></a><a name="p16614161110307"></a>N/A</p> | -m | Fills width with a list of entries separated by a comma. |
</td> | -n | Like **-l**, but lists numeric user and group IDs.|
</tr> | -o | Like **-l**, but do not list group information. |
<tr id="row165311113302"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p761517119300"><a name="p761517119300"></a><a name="p761517119300"></a>-c</p> | -x | Lists entries by line, instead of by column. |
</td> | -ll | Lists the file time attribute as ns. |
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p6615121114307"><a name="p6615121114307"></a><a name="p6615121114307"></a>Uses ctime as the file timestamp. This parameter must be used together with <strong id="b644143217354"><a name="b644143217354"></a><a name="b644143217354"></a>-l</strong>.</p>
</td> **Table 3** Parameters for sorting (by the initial letter by default)
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p861561115308"><a name="p861561115308"></a><a name="p861561115308"></a>N/A</p>
</td> | Parameter| Description |
</tr> | ---- | ------------------------------------------ |
<tr id="row19652131193018"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1861591117301"><a name="p1861591117301"></a><a name="p1861591117301"></a>-d</p> | -f | Do not sort. |
</td> | -r | Sorts in reverse order. |
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p126151511193010"><a name="p126151511193010"></a><a name="p126151511193010"></a>Displays only the directory, rather than listing the content of the directory.</p> | -t | Sorts by time, newest first.|
</td> | -S | Sorts by file size, largest first. |
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p061521133020"><a name="p061521133020"></a><a name="p061521133020"></a>N/A</p>
</td> **Table 4** Color printing
</tr>
<tr id="row265212115302"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p12615151183012"><a name="p12615151183012"></a><a name="p12615151183012"></a>-i</p> | Parameter| Default Configuration |
</td> | ---- | ------------------------------------------ |
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p11615511193012"><a name="p11615511193012"></a><a name="p11615511193012"></a>Displays the node ID of a file.</p> | --color | device=yellow symlink=turquoise/red dir=blue socket=purple files: exe=green suid=red suidfile=redback stickydir=greenback=auto means detect if output is a tty. |
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1361591103015"><a name="p1361591103015"></a><a name="p1361591103015"></a>N/A</p> ## Usage Guidelines
</td>
</tr> The file node information of the FAT file system inherits from its parent node. The parent node ID is **0**. Therefore, if you run the **ls -i** command on the Hi3516D V300 development board, the file node IDs displayed are all **0**.
<tr id="row66529118309"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p9615211133012"><a name="p9615211133012"></a><a name="p9615211133012"></a>-p</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3615131103017"><a name="p3615131103017"></a><a name="p3615131103017"></a>Adds a slash (/) after the directory.</p> ## Note
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1361551112302"><a name="p1361551112302"></a><a name="p1361551112302"></a>N/A</p> The shell does not support **ls** parameters. mksh supports them. To switch to mksh, run **cd bin** and **./mksh**.
</td>
</tr> ## Example
<tr id="row13651111183016"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p186151811183010"><a name="p186151811183010"></a><a name="p186151811183010"></a>-q</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p19615511123011"><a name="p19615511123011"></a><a name="p19615511123011"></a>Displays non-printable characters, such as "?".</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p6615151111303"><a name="p6615151111303"></a><a name="p6615151111303"></a>N/A</p>
</td>
</tr>
<tr id="row26511711113018"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1861581111304"><a name="p1861581111304"></a><a name="p1861581111304"></a>-s</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p161511114303"><a name="p161511114303"></a><a name="p161511114303"></a>Provides information about the memory occupied by the directory and its members, in 1024 bytes.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1061514115307"><a name="p1061514115307"></a><a name="p1061514115307"></a>N/A</p>
</td>
</tr>
<tr id="row4650181183020"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p8615101133017"><a name="p8615101133017"></a><a name="p8615101133017"></a>-u</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p761501113306"><a name="p761501113306"></a><a name="p761501113306"></a>Uses the last access time of the file as the timestamp. This option is used together with <strong id="b83441545164512"><a name="b83441545164512"></a><a name="b83441545164512"></a>-l</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p86153111309"><a name="p86153111309"></a><a name="p86153111309"></a>N/A</p>
</td>
</tr>
<tr id="row1365021120308"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p36151011193016"><a name="p36151011193016"></a><a name="p36151011193016"></a>-A</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p56151511183019"><a name="p56151511183019"></a><a name="p56151511183019"></a>Lists all files except implied . and ..</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p8615411193019"><a name="p8615411193019"></a><a name="p8615411193019"></a>N/A</p>
</td>
</tr>
<tr id="row13650151114302"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p20615411183017"><a name="p20615411183017"></a><a name="p20615411183017"></a>-H</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p19615151118304"><a name="p19615151118304"></a><a name="p19615151118304"></a>Follows symbolic links listed in the command line.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p10615161112307"><a name="p10615161112307"></a><a name="p10615161112307"></a>N/A</p>
</td>
</tr>
<tr id="row1865071119306"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p206151911123017"><a name="p206151911123017"></a><a name="p206151911123017"></a>-L</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p5615911203017"><a name="p5615911203017"></a><a name="p5615911203017"></a>Follows symbolic links.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p16615111111307"><a name="p16615111111307"></a><a name="p16615111111307"></a>N/A</p>
</td>
</tr>
<tr id="row16649411173019"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1861581116309"><a name="p1861581116309"></a><a name="p1861581116309"></a>-Z</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p7616151112301"><a name="p7616151112301"></a><a name="p7616151112301"></a>Displays security context.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p12616411173010"><a name="p12616411173010"></a><a name="p12616411173010"></a>N/A</p>
</td>
</tr>
<tr id="row186497114307"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p17616211113010"><a name="p17616211113010"></a><a name="p17616211113010"></a>path</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1761611110307"><a name="p1761611110307"></a><a name="p1761611110307"></a>If <strong id="b115515262034"><a name="b115515262034"></a><a name="b115515262034"></a>path</strong> is left blank, the content of the current directory is displayed.</p>
<p id="p10616141117308"><a name="p10616141117308"></a><a name="p10616141117308"></a>If <strong id="b9593204114312"><a name="b9593204114312"></a><a name="b9593204114312"></a>path</strong> is an invalid file name, the following failure message is displayed:</p>
<p id="p1061631112303"><a name="p1061631112303"></a><a name="p1061631112303"></a><strong id="b19604131716416"><a name="b19604131716416"></a><a name="b19604131716416"></a>ls error: No such directory</strong></p>
<p id="p206161111143018"><a name="p206161111143018"></a><a name="p206161111143018"></a>If <strong id="b615314272412"><a name="b615314272412"></a><a name="b615314272412"></a>path</strong> is a valid directory, the content of that directory is displayed.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p761617115309"><a name="p761617115309"></a><a name="p761617115309"></a>Left blank or a valid directory</p>
</td>
</tr>
</tbody>
</table>
**Table 2** Output parameters
<a name="table197022663018"></a>
<table><thead align="left"><tr id="row7970172614303"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p8970122616304"><a name="p8970122616304"></a><a name="p8970122616304"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p197012633020"><a name="p197012633020"></a><a name="p197012633020"></a><strong id="b1961069541"><a name="b1961069541"></a><a name="b1961069541"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1397092603018"><a name="p1397092603018"></a><a name="p1397092603018"></a>Value Range</p>
</th>
</tr>
</thead>
<tbody><tr id="row106817566303"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p365845683010"><a name="p365845683010"></a><a name="p365845683010"></a>-1</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1865811565309"><a name="p1865811565309"></a><a name="p1865811565309"></a>Lists one file per line.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p0658195616305"><a name="p0658195616305"></a><a name="p0658195616305"></a>N/A</p>
</td>
</tr>
<tr id="row15680155633011"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p116585565301"><a name="p116585565301"></a><a name="p116585565301"></a>-c</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1065865611302"><a name="p1065865611302"></a><a name="p1065865611302"></a>Lists entries by column.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p06581456113013"><a name="p06581456113013"></a><a name="p06581456113013"></a>N/A</p>
</td>
</tr>
<tr id="row11680556173014"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p86581756193012"><a name="p86581756193012"></a><a name="p86581756193012"></a>-g</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p20658356183018"><a name="p20658356183018"></a><a name="p20658356183018"></a>Like <strong id="b206161282355"><a name="b206161282355"></a><a name="b206161282355"></a>-l</strong>, but do not list owner.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p7658165663019"><a name="p7658165663019"></a><a name="p7658165663019"></a>N/A</p>
</td>
</tr>
<tr id="row19680105614309"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p17658185612306"><a name="p17658185612306"></a><a name="p17658185612306"></a>-h</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p16581756143014"><a name="p16581756143014"></a><a name="p16581756143014"></a>Displays the total size of files in the directory, in KiB.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1865814565305"><a name="p1865814565305"></a><a name="p1865814565305"></a>N/A</p>
</td>
</tr>
<tr id="row46801356143016"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p11658056123016"><a name="p11658056123016"></a><a name="p11658056123016"></a>-l</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1465875603018"><a name="p1465875603018"></a><a name="p1465875603018"></a>Displays detailed information about files in the directory.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p10658105673015"><a name="p10658105673015"></a><a name="p10658105673015"></a>N/A</p>
</td>
</tr>
<tr id="row136791256203013"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p10658125616303"><a name="p10658125616303"></a><a name="p10658125616303"></a>-m</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p15658115620304"><a name="p15658115620304"></a><a name="p15658115620304"></a>Fills width with a list of entries separated by a comma.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p26584563301"><a name="p26584563301"></a><a name="p26584563301"></a>N/A</p>
</td>
</tr>
<tr id="row176791156163014"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p265875611309"><a name="p265875611309"></a><a name="p265875611309"></a>-n</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1465895663016"><a name="p1465895663016"></a><a name="p1465895663016"></a>Like <strong id="b88319189351"><a name="b88319189351"></a><a name="b88319189351"></a>-l</strong>, but lists numeric user and group IDs.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p9658135613011"><a name="p9658135613011"></a><a name="p9658135613011"></a>N/A</p>
</td>
</tr>
<tr id="row10679185653015"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p365815562303"><a name="p365815562303"></a><a name="p365815562303"></a>-o</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p12658956193017"><a name="p12658956193017"></a><a name="p12658956193017"></a>Like <strong id="b24118395354"><a name="b24118395354"></a><a name="b24118395354"></a>-l</strong>, but do not list group information.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p8658155610309"><a name="p8658155610309"></a><a name="p8658155610309"></a>N/A</p>
</td>
</tr>
<tr id="row176791656123015"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1765865643019"><a name="p1765865643019"></a><a name="p1765865643019"></a>-x</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p13658456123014"><a name="p13658456123014"></a><a name="p13658456123014"></a>Lists entries by line, instead of by column.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p196581256103015"><a name="p196581256103015"></a><a name="p196581256103015"></a>N/A</p>
</td>
</tr>
<tr id="row1467820567304"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p06584565305"><a name="p06584565305"></a><a name="p06584565305"></a>-ll</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p365855610302"><a name="p365855610302"></a><a name="p365855610302"></a>Lists the file time attribute as ns.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p365845653010"><a name="p365845653010"></a><a name="p365845653010"></a>N/A</p>
</td>
</tr>
<tr id="row176781456183019"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p11659256133013"><a name="p11659256133013"></a><a name="p11659256133013"></a>--color</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2659756123020"><a name="p2659756123020"></a><a name="p2659756123020"></a>Colorizes the output.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2659135633011"><a name="p2659135633011"></a><a name="p2659135633011"></a>Default value: device=yellow symlink=turquoise/red dir=blue socket=purple files: exe=green suid=red suidfile=redback stickydir=greenback=auto means detect if output is a tty.</p>
</td>
</tr>
</tbody>
</table>
**Table 3** Sorting parameters \(sorted by the initial letter by default\)
<a name="table164254153318"></a>
<table><thead align="left"><tr id="row2425191515317"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p74259156313"><a name="p74259156313"></a><a name="p74259156313"></a>Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p542501512317"><a name="p542501512317"></a><a name="p542501512317"></a><strong id="b237939680"><a name="b237939680"></a><a name="b237939680"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1342513154318"><a name="p1342513154318"></a><a name="p1342513154318"></a>Value Range</p>
</th>
</tr>
</thead>
<tbody><tr id="row10358027153118"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p83441727153114"><a name="p83441727153114"></a><a name="p83441727153114"></a>-f</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p18344132717315"><a name="p18344132717315"></a><a name="p18344132717315"></a>Do not sort.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1834402753112"><a name="p1834402753112"></a><a name="p1834402753112"></a>N/A</p>
</td>
</tr>
<tr id="row4357112714312"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p6344162773117"><a name="p6344162773117"></a><a name="p6344162773117"></a>-r</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p11344102743115"><a name="p11344102743115"></a><a name="p11344102743115"></a>Reverse order while sorting.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2344142719315"><a name="p2344142719315"></a><a name="p2344142719315"></a>N/A</p>
</td>
</tr>
<tr id="row133571827153114"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p2344152717318"><a name="p2344152717318"></a><a name="p2344152717318"></a>-t</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p10344727103114"><a name="p10344727103114"></a><a name="p10344727103114"></a>Sort by time, newest first.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p73441927123116"><a name="p73441927123116"></a><a name="p73441927123116"></a>N/A</p>
</td>
</tr>
<tr id="row4357102773115"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p83444274318"><a name="p83444274318"></a><a name="p83444274318"></a>-S</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1134452715312"><a name="p1134452715312"></a><a name="p1134452715312"></a>Sort by file size, largest first.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1344122717310"><a name="p1344122717310"></a><a name="p1344122717310"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section041212533166"></a>
None
>![](../public_sys-resources/icon-notice.gif) **NOTICE:**
>The file node information of the FAT file system inherits from its parent node. The parent node ID is **0**. Therefore, if you run the **ls -i** command on the Hi3516D V300 development board, the file node IDs displayed are all **0**.
## Example<a name="section986105716167"></a>
Run the following commands: Run the following commands:
- ls - ls
- ll - ll
## Output<a name="section2036124918592"></a>
## Output
Example 1: **ls** command output Example 1: **ls** command output
...@@ -310,4 +112,3 @@ drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 userdata/ ...@@ -310,4 +112,3 @@ drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 userdata/
drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 usr/ drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 usr/
drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 vendor/ drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 vendor/
``` ```
# lsfd # lsfd
## Command Function<a name="section2053406181716"></a> ## Command Function
This command is used to display the file descriptors and names of the files that are open. This command is used to display the file descriptors and names of the files that are open.
## Syntax<a name="section523771017172"></a>
## Syntax
lsfd lsfd
## Usage<a name="section27241213201719"></a>
## Usage Guidelines
Run the **lsfd** command to display file descriptors and names of the opened files. Run the **lsfd** command to display file descriptors and names of the opened files.
## Example<a name="section442617197173"></a>
## Example
Run **lsfd**. Run **lsfd**.
## Output<a name="section42491639151813"></a>
## Output
Example: **lsfd** command output Example: **lsfd** command output
...@@ -57,4 +61,3 @@ OHOS # lsfd ...@@ -57,4 +61,3 @@ OHOS # lsfd
33 /dev/lite_ipc 33 /dev/lite_ipc
34 /dev/lite_ipc 34 /dev/lite_ipc
``` ```
# mkdir # mkdir
## Command Function<a name="section1083613274175"></a> ## Command Function
This command is used to create a directory. This command is used to create a directory.
## Syntax<a name="section820913118178"></a>
mkdir \[_-vp_\] \[_-m mode_\] \[_dirname..._\] ## Syntax
## Parameters<a name="section1256834121718"></a> mkdir [_-vp_] [_-m mode_] [_dirname..._]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1299mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row1305mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1307mcpsimp"><a name="p1307mcpsimp"></a><a name="p1307mcpsimp"></a><strong id="b209289681211447"><a name="b209289681211447"></a><a name="b209289681211447"></a>Parameter</strong></p> | --------- | ------------------------------ |
</th> | --help | Displays the parameters supported by the **mkdir** command. |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1309mcpsimp"><a name="p1309mcpsimp"></a><a name="p1309mcpsimp"></a><strong id="b16886221330"><a name="b16886221330"></a><a name="b16886221330"></a>Description</strong></p> | -m | Sets the permissions on the directory to create. |
</th> | -p | Creates parent and child directories recursively. |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1311mcpsimp"><a name="p1311mcpsimp"></a><a name="p1311mcpsimp"></a><strong id="b163527968011447"><a name="b163527968011447"></a><a name="b163527968011447"></a>Value Range</strong></p> | -v | Prints detailed information about the directory creation process.|
</th> | directory | Specifies the directory to create. |
</tr>
</thead>
<tbody><tr id="row15431344183419"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p85331144163414"><a name="p85331144163414"></a><a name="p85331144163414"></a>--help</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2053354433413"><a name="p2053354433413"></a><a name="p2053354433413"></a>Displays the parameters supported by the <strong id="b1177313015559"><a name="b1177313015559"></a><a name="b1177313015559"></a>mkdir</strong> command.</p> For the files created on the FAT file system, the file permission attributes are the same as those of the mounted nodes. Currently, the node permissions include only user read and write. The **group** and **others** permissions do not take effect.
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p16533144473411"><a name="p16533144473411"></a><a name="p16533144473411"></a>N/A</p> In addition, only the user read and write permissions can be modified. The read and write permissions are **rw** and **ro** only. Therefore, when the **-m** option is specified in the **mkdir** command, only **777** and **555** permissions are available for the created directory, and the execute permission does not take effect.
</td>
</tr> ## Note
<tr id="row9543644193413"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p153374418344"><a name="p153374418344"></a><a name="p153374418344"></a>-m</p>
</td> Currently, the shell does not support this command. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p9533114416343"><a name="p9533114416343"></a><a name="p9533114416343"></a>Sets the permissions on the directory to create.</p>
</td> ## Example
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p553334414343"><a name="p553334414343"></a><a name="p553334414343"></a>N/A</p>
</td>
</tr>
<tr id="row654224463420"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p853334414347"><a name="p853334414347"></a><a name="p853334414347"></a>-p</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3533184493418"><a name="p3533184493418"></a><a name="p3533184493418"></a>Creates parent and child directories recursively.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p753313443344"><a name="p753313443344"></a><a name="p753313443344"></a>N/A</p>
</td>
</tr>
<tr id="row454234412343"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p153315440349"><a name="p153315440349"></a><a name="p153315440349"></a>-v</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p453344420349"><a name="p453344420349"></a><a name="p453344420349"></a>Prints detailed information about the directory creation process.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p553313444343"><a name="p553313444343"></a><a name="p553313444343"></a>N/A</p>
</td>
</tr>
<tr id="row17542644203418"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p853394453413"><a name="p853394453413"></a><a name="p853394453413"></a>directory</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p653315443342"><a name="p653315443342"></a><a name="p653315443342"></a>Specifies the directory to create.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1553344410344"><a name="p1553344410344"></a><a name="p1553344410344"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section1294234115172"></a>
>![](../public_sys-resources/icon-notice.gif) **NOTICE:**
>For the files created on the FAT file system, the file permission attributes are the same as those of the mounted nodes. Currently, the node permissions include only user read and write. The **group** and **others** permissions do not take effect.
>In addition, only the user read and write permissions can be modified. The read and write permissions are **rw** and **ro** only. Therefore, when the **-m** option is specified in the **mkdir** command, only **777** and **555** permissions are available for the created directory, and the execute permission does not take effect.
## Example<a name="section1113345211713"></a>
Run the following commands: Run the following commands:
- mkdir testpath - mkdir testpath
- mkdir -m 777 testpath - mkdir -m 777 testpath
- mkdir -pv testpath01/testpath02/testpath03 - mkdir -pv testpath01/testpath02/testpath03
## Output<a name="section10142201012"></a> ## Output
Example 1: Create a directory named **testpath**.
``` ```
OHOS:/tmp$ mkdir testpath OHOS:/tmp$ mkdir testpath
...@@ -83,7 +56,8 @@ total 2 ...@@ -83,7 +56,8 @@ total 2
drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/ drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/
``` ```
Example 2: creating a directory with specified permissions Example 2: Create a directory named **testpath** with specified permissions.
``` ```
OHOS:/tmp$ mkdir -m 777 testpath OHOS:/tmp$ mkdir -m 777 testpath
...@@ -92,7 +66,8 @@ total 2 ...@@ -92,7 +66,8 @@ total 2
drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/ drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/
``` ```
Example 3: creating directories recursively Example 3: Create directories recursively.
``` ```
OHOS:/tmp$ mkdir -pv testpath01/testpath02/testpath03 OHOS:/tmp$ mkdir -pv testpath01/testpath02/testpath03
...@@ -109,4 +84,3 @@ OHOS:/tmp$ ll testpath01/testpath02/ ...@@ -109,4 +84,3 @@ OHOS:/tmp$ ll testpath01/testpath02/
total 2 total 2
drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath03/ drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath03/
``` ```
# mount # mount
## Command Function<a name="section11631837182"></a> ## Command Function
This command is used to mount a device to a specified directory. This command is used to mount a device to a specified directory.
## Syntax<a name="section1697638111820"></a>
mount \[_-f_\] \[_-t TYPE_\] \[_-o OPTION,_\] \[\[_DEVICE_\] _DIR_\] ## Syntax
## Parameters<a name="section1650151221819"></a> mount [_-f_] [_-t TYPE_] [_-o OPTION,_] [[_DEVICE_] _DIR_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1338mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row1344mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1346mcpsimp"><a name="p1346mcpsimp"></a><a name="p1346mcpsimp"></a><strong id="b84913249612"><a name="b84913249612"></a><a name="b84913249612"></a>Parameter</strong></p> | ------ | ----------------------------------------------------------- | ------------------------------------------------------------ |
</th> | --help | Displays the parameters supported by the **mount** command. | N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1348mcpsimp"><a name="p1348mcpsimp"></a><a name="p1348mcpsimp"></a><strong id="b1136292612616"><a name="b1136292612616"></a><a name="b1136292612616"></a>Description</strong></p> | -f | Fakes mounting the file system (no mounting is actually performed). | N/A |
</th> | -t | Specifies the file system type. | vfat, yaffs, jffs, ramfs, nfs, procfs, romfs|
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1350mcpsimp"><a name="p1350mcpsimp"></a><a name="p1350mcpsimp"></a><strong id="b4385271067"><a name="b4385271067"></a><a name="b4385271067"></a>Value Range</strong></p> | -o | Specifies the mount options. | N/A |
</th> | DEVICE | Specifies the device to mount (in the format of the device directory). | A device in the system |
</tr> | DIR | Specifies the directory.<br>You must have the execution (search) permission on the specified directory.| N/A |
</thead>
<tbody><tr id="row081413014400"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p080318303407"><a name="p080318303407"></a><a name="p080318303407"></a>--help</p>
</td> ## Usage Guidelines
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p8804113024018"><a name="p8804113024018"></a><a name="p8804113024018"></a>Displays the parameters supported by the <strong id="b07421044122514"><a name="b07421044122514"></a><a name="b07421044122514"></a>mount</strong> command.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p280418307406"><a name="p280418307406"></a><a name="p280418307406"></a>N/A</p>
</td>
</tr>
<tr id="row1781443044019"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1580410305409"><a name="p1580410305409"></a><a name="p1580410305409"></a>-f</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1980419305409"><a name="p1980419305409"></a><a name="p1980419305409"></a>Fakes mounting the file system (no mounting is actually performed).</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p58041230114019"><a name="p58041230114019"></a><a name="p58041230114019"></a>N/A</p>
</td>
</tr>
<tr id="row1981411307404"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p11804143024013"><a name="p11804143024013"></a><a name="p11804143024013"></a>-t</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p680443010409"><a name="p680443010409"></a><a name="p680443010409"></a>Specifies the file system type.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p13804193034020"><a name="p13804193034020"></a><a name="p13804193034020"></a>vfat, yaffs, jffs, ramfs, nfs, procfs, romfs</p>
</td>
</tr>
<tr id="row20813330184020"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p168041330194012"><a name="p168041330194012"></a><a name="p168041330194012"></a>-o</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p280473015402"><a name="p280473015402"></a><a name="p280473015402"></a>Specifies the mount options.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p4804193020407"><a name="p4804193020407"></a><a name="p4804193020407"></a>N/A</p>
</td>
</tr>
<tr id="row0813730134015"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p38041030124019"><a name="p38041030124019"></a><a name="p38041030124019"></a>DEVICE</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p28045303401"><a name="p28045303401"></a><a name="p28045303401"></a>Specifies the device to mount (in the format of the device directory).</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p8804113084010"><a name="p8804113084010"></a><a name="p8804113084010"></a>A device in the system</p>
</td>
</tr>
<tr id="row1381383044011"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p7804133012406"><a name="p7804133012406"></a><a name="p7804133012406"></a>DIR</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1380419308409"><a name="p1380419308409"></a><a name="p1380419308409"></a>Specifies the directory.</p>
<p id="p14804153014011"><a name="p14804153014011"></a><a name="p14804153014011"></a>You must have the execution (search) permission on the specified directory.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1780403094017"><a name="p1780403094017"></a><a name="p1780403094017"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section124541520171912"></a>
By specifying the device to mount, directory, and file system format in the **mount** command, you can successfully mount the file system to the specified directory. By specifying the device to mount, directory, and file system format in the **mount** command, you can successfully mount the file system to the specified directory.
## Example<a name="section7424625171917"></a> ## Note
Currently, the shell does not support this command. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run **mount -t nfs 192.168.1.3:/nfs nfs**. Run **mount -t nfs 192.168.1.3:/nfs nfs**.
## Output<a name="section14757018116"></a>
Mounting the **nfs** directory on the server with IP address of **192.168.1.3** to the newly created **/nfs** directory in the current system ## Output
Mount the **nfs** directory on the server with IP address of **192.168.1.3** to the newly created **/nfs** directory in the current system.
``` ```
OHOS:/$ mkdir nfs OHOS:/$ mkdir nfs
...@@ -90,4 +53,3 @@ OHOS:/$ ls nfs/ ...@@ -90,4 +53,3 @@ OHOS:/$ ls nfs/
OHOS_Image.bin hello rootfs_vfat.img OHOS_Image.bin hello rootfs_vfat.img
dev_tools mksh_rootfs_vfat.img test_demo dev_tools mksh_rootfs_vfat.img test_demo
``` ```
# mv # mv
## Command Function<a name="section201149459368"></a> ## Command Function
This command is used to move files. This command is used to move files.
## Syntax<a name="section579813484364"></a>
mv \[_-fivn_\] _SOURCE... DEST_ ## Syntax
## Parameters<a name="section168065311366"></a> mv [_-fivn_] *SOURCE... DEST*
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1845mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row1851mcpsimp"><th class="cellrowborder" valign="top" width="20.84%" id="mcps1.2.4.1.1"><p id="p1853mcpsimp"><a name="p1853mcpsimp"></a><a name="p1853mcpsimp"></a>Parameter</p> | ------ | ------------------------------------------------------------ | ----------------------------------------------- |
</th> | -help | Displays help information. | N/A |
<th class="cellrowborder" valign="top" width="52.16%" id="mcps1.2.4.1.2"><p id="p1855mcpsimp"><a name="p1855mcpsimp"></a><a name="p1855mcpsimp"></a>Description</p> | -f | Forcibly overwrites the target file. | N/A |
</th> | -i | Provides information before moving a file that would overwrite an existing file or directory. Enter **y** to overwrite the file or directory, and enter **n** to cancel the operation.| N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1857mcpsimp"><a name="p1857mcpsimp"></a><a name="p1857mcpsimp"></a>Value Range</p> | -n | Do not overwrite any existing file or directory. | N/A |
</th> | -v | This parameter does not take effect although it is supported by the latest Toybox code. | N/A |
</tr> | SOURCE | Specifies the file to move. | This command cannot be used to move a directory. It can be used to move multiple files at a time.|
</thead> | DEST | Specifies the destination file path. | Both a directory and a file are supported. |
<tbody><tr id="row20678165916440"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p126571859174418"><a name="p126571859174418"></a><a name="p126571859174418"></a>-help</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p1165745918447"><a name="p1165745918447"></a><a name="p1165745918447"></a>Displays help information.</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p165725913441"><a name="p165725913441"></a><a name="p165725913441"></a>N/A</p> - **SOURCEFILE** supports wildcard characters * and ?. The asterisk (*) indicates any number of characters, and the question mark (?) represents a single character. **DEST** does not support wildcard characters. If the specified **SOURCE** matches multiple files, **DEST** must be a directory.
</td>
</tr>
<tr id="row12678159174418"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p166571959164412"><a name="p166571959164412"></a><a name="p166571959164412"></a>-f</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p8657859134412"><a name="p8657859134412"></a><a name="p8657859134412"></a>Forcibly overwrites the target file.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1965775904419"><a name="p1965775904419"></a><a name="p1965775904419"></a>N/A</p>
</td>
</tr>
<tr id="row126781259104418"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p5657115954414"><a name="p5657115954414"></a><a name="p5657115954414"></a>-i</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p7657105917445"><a name="p7657105917445"></a><a name="p7657105917445"></a>Provides a prompt before moving a file that would overwrite an existing file. Enter <strong id="b886564463218"><a name="b886564463218"></a><a name="b886564463218"></a>y</strong> to overwrite the file or enter <strong id="b16826758113218"><a name="b16826758113218"></a><a name="b16826758113218"></a>n</strong> to cancel the operation.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1165795924415"><a name="p1165795924415"></a><a name="p1165795924415"></a>N/A</p>
</td>
</tr>
<tr id="row186773599442"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p86571059114410"><a name="p86571059114410"></a><a name="p86571059114410"></a>-n</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p36572059164415"><a name="p36572059164415"></a><a name="p36572059164415"></a>Do not overwrite any existing file or directory.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1965715944417"><a name="p1965715944417"></a><a name="p1965715944417"></a>N/A</p>
</td>
</tr>
<tr id="row66771159124413"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p15657185964416"><a name="p15657185964416"></a><a name="p15657185964416"></a>-v</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p166571759124418"><a name="p166571759124418"></a><a name="p166571759124418"></a>This parameter does not take effect although it is supported by the latest Toybox code.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p12657059184418"><a name="p12657059184418"></a><a name="p12657059184418"></a>N/A</p>
</td>
</tr>
<tr id="row11677145964419"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p2657205924414"><a name="p2657205924414"></a><a name="p2657205924414"></a>SOURCE</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p3657205924416"><a name="p3657205924416"></a><a name="p3657205924416"></a>Specifies the path of the source file.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1365775904419"><a name="p1365775904419"></a><a name="p1365775904419"></a>This command cannot be used to move a directory. It can be used to move multiple files at a time.</p>
</td>
</tr>
<tr id="row1267615917447"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p1658459144411"><a name="p1658459144411"></a><a name="p1658459144411"></a>DEST</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p265810599448"><a name="p265810599448"></a><a name="p265810599448"></a>Specifies the destination file path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p7658105914449"><a name="p7658105914449"></a><a name="p7658105914449"></a>Both a directory and a file are supported.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section19190125723612"></a>
- **SOURCE** supports wildcard characters \* and ?. The asterisk \(\*\) indicates any number of characters, and the question mark \(?\) represents a single character. **DEST** does not support wildcard characters. If the specified **SOURCE** matches multiple files, **DEST** must be a directory.
- If **DEST** is a directory, this directory must exist. In this case, the destination file is named after the source file. - If **DEST** is a directory, this directory must exist. In this case, the destination file is named after the source file.
- If **DEST** is a file, the directory for this file must exist. - If **DEST** is a file, the directory for this file must exist.
- If the destination file already exists, it will be overwritten. - If the destination file already exists, it will be overwritten.
## Example<a name="section10383416372"></a> ## Note
Currently, the shell does not support this command. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run the following commands: Run the following commands:
- mv -i test.txt testpath/ - mv -i test.txt testpath/
- mv test?.txt testpath/ \(Move **test3.txt**, **testA.txt**, and **test\_.txt**\)
## Output<a name="section131601649114511"></a> - mv test?.txt testpath/ (Move **test3.txt**, **testA.txt**, and **test_.txt**)
## Output
Example 1: Move a file.
Example 1: moving a file
``` ```
OHOS:/$ touch test.txt OHOS:/$ touch test.txt
...@@ -112,7 +74,8 @@ bin etc proc storage test.txt userdata vendor ...@@ -112,7 +74,8 @@ bin etc proc storage test.txt userdata vendor
dev lib sdcard system testpath usr dev lib sdcard system testpath usr
``` ```
Example 2: moving files using wildcards Example 2: Move files.
``` ```
OHOS:/$ ls OHOS:/$ ls
...@@ -125,4 +88,3 @@ dev lib sdcard system testpath usr ...@@ -125,4 +88,3 @@ dev lib sdcard system testpath usr
OHOS:/$ ls testpath/ OHOS:/$ ls testpath/
test.txt test3.txt testA.txt test_.txt test.txt test3.txt testA.txt test_.txt
``` ```
# partinfo # partinfo
## Command Function<a name="section1777503617199"></a> ## Command Function
This command is used to query information about the partitions of a hard disk or SD card identified by the system. This command is used to query information about the partitions of a hard disk or SD card identified by the system.
## Syntax<a name="section185501447132114"></a>
partinfo <_dev\_inodename_\> ## Syntax
## Parameters<a name="section1304151212252"></a> partinfo &lt;*dev*inodename_&gt;
**Table 1** Parameter description
<a name="table1390mcpsimp"></a> ## Parameters
<table><thead align="left"><tr id="row1396mcpsimp"><th class="cellrowborder" valign="top" width="22%" id="mcps1.2.4.1.1"><p id="p1398mcpsimp"><a name="p1398mcpsimp"></a><a name="p1398mcpsimp"></a><strong id="b130786349111516"><a name="b130786349111516"></a><a name="b130786349111516"></a>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="51%" id="mcps1.2.4.1.2"><p id="p1400mcpsimp"><a name="p1400mcpsimp"></a><a name="p1400mcpsimp"></a><strong id="b1089142031013"><a name="b1089142031013"></a><a name="b1089142031013"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1402mcpsimp"><a name="p1402mcpsimp"></a><a name="p1402mcpsimp"></a><strong id="b17244395211516"><a name="b17244395211516"></a><a name="b17244395211516"></a>Value Range</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1403mcpsimp"><td class="cellrowborder" valign="top" width="22%" headers="mcps1.2.4.1.1 "><p id="p1405mcpsimp"><a name="p1405mcpsimp"></a><a name="p1405mcpsimp"></a>dev_inodename</p>
</td>
<td class="cellrowborder" valign="top" width="51%" headers="mcps1.2.4.1.2 "><p id="p1407mcpsimp"><a name="p1407mcpsimp"></a><a name="p1407mcpsimp"></a>Specifies the name of the partition to be queried.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1409mcpsimp"><a name="p1409mcpsimp"></a><a name="p1409mcpsimp"></a>A valid partition name</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section4566131982520"></a> **Table 1** Parameter description
None | Parameter| Description| Value Range|
| -------- | -------- | -------- |
| dev_inodename | Specifies the name of the partition to be queried.| A valid partition name|
## Example<a name="section4351134942514"></a>
## Usage Guidelines
None.
## Example
Run **partinfo /dev/mmcblk0p0**. Run **partinfo /dev/mmcblk0p0**.
## Output<a name="section66689331412"></a>
## Output
System partition information: System partition information:
``` ```
OHOS # partinfo /dev/mmcblk0p0 OHOS # partinfo /dev/mmcblk0p0
part info : part info :
...@@ -55,4 +46,3 @@ part filesystem : 00 ...@@ -55,4 +46,3 @@ part filesystem : 00
part sec start : 20480 part sec start : 20480
part sec count : 102400 part sec count : 102400
``` ```
# pwd # pwd
## Command Function<a name="section197737712267"></a> ## Command Function
This command is used to display the current path. This command is used to display the current path.
## Syntax<a name="section1544061016267"></a>
## Syntax
pwd pwd
## Parameters<a name="section599112120262"></a>
None ## Parameters
None.
## Usage Guidelines
## Usage<a name="section66901116152615"></a> The **pwd** command writes the full path (from the root directory) of the current directory to the standard output. The directories are separated by slashes (/). The directory following the first slash (/) indicates the root directory, and the last directory is the current directory.
The **pwd** command writes the full path \(from the root directory\) of the current directory to the standard output. The directories are separated by slashes \(/\). The directory following the first slash \(/\) indicates the root directory, and the last directory is the current directory.
## Example<a name="section7427181922612"></a> ## Example
Run **pwd**. Run **pwd**.
## Output<a name="section116313389418"></a>
## Output
Current path: Current path:
``` ```
OHOS:/sdcard/nfs$ pwd OHOS:/sdcard/nfs$ pwd
/sdcard/nfs /sdcard/nfs
``` ```
# rm # rm
## Command Function<a name="section181141523142613"></a> ## Command Function
This command is used to delete a file or folder. This command is used to delete a file or folder.
## Syntax<a name="section8800926132619"></a>
rm \[_-fv_\] _FILE or rm_ \[_-rv_\] \[_PATH_ | _filename_\]... ## Syntax
## Parameters<a name="section15476229152617"></a> rm [_-fv_] *FILE or rm* [_-rv_] [_PATH_ | _filename_]...
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1507mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row1513mcpsimp"><th class="cellrowborder" valign="top" width="22.220000000000002%" id="mcps1.2.4.1.1"><p id="p1515mcpsimp"><a name="p1515mcpsimp"></a><a name="p1515mcpsimp"></a><strong id="b8231115224817"><a name="b8231115224817"></a><a name="b8231115224817"></a>Parameter</strong></p> | ------------- | ------------------------------------------------ |
</th> | -r | Deletes empty or non-empty directories. |
<th class="cellrowborder" valign="top" width="51.519999999999996%" id="mcps1.2.4.1.2"><p id="p1517mcpsimp"><a name="p1517mcpsimp"></a><a name="p1517mcpsimp"></a><strong id="b1599275514488"><a name="b1599275514488"></a><a name="b1599275514488"></a>Description</strong></p> | -f | Deletes a file or directory forcibly without confirmation. No error will be reported when a file that does not exist is to be deleted.|
</th> | -v | Displays the deletion process. |
<th class="cellrowborder" valign="top" width="26.26%" id="mcps1.2.4.1.3"><p id="p1519mcpsimp"><a name="p1519mcpsimp"></a><a name="p1519mcpsimp"></a><strong id="b186611453114810"><a name="b186611453114810"></a><a name="b186611453114810"></a>Value Range</strong></p> | PATH/filename | Specifies the name of the file or directory to delete. The value can be a path. |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row231513373307"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.2.4.1.1 "><p id="p73091437173016"><a name="p73091437173016"></a><a name="p73091437173016"></a>-r</p>
</td>
<td class="cellrowborder" valign="top" width="51.519999999999996%" headers="mcps1.2.4.1.2 "><p id="p630917373307"><a name="p630917373307"></a><a name="p630917373307"></a>Deletes empty or non-empty directories.</p>
</td>
<td class="cellrowborder" valign="top" width="26.26%" headers="mcps1.2.4.1.3 "><p id="p1430943753016"><a name="p1430943753016"></a><a name="p1430943753016"></a>N/A</p>
</td>
</tr>
<tr id="row1231583773013"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.2.4.1.1 "><p id="p19309203763010"><a name="p19309203763010"></a><a name="p19309203763010"></a>-f</p>
</td>
<td class="cellrowborder" valign="top" width="51.519999999999996%" headers="mcps1.2.4.1.2 "><p id="p53092373308"><a name="p53092373308"></a><a name="p53092373308"></a>Deletes a file or directory forcibly without confirmation. No error will be reported when a file that does not exist is to be deleted.</p>
</td>
<td class="cellrowborder" valign="top" width="26.26%" headers="mcps1.2.4.1.3 "><p id="p8309937153018"><a name="p8309937153018"></a><a name="p8309937153018"></a>N/A</p>
</td>
</tr>
<tr id="row331513719302"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.2.4.1.1 "><p id="p5309103733013"><a name="p5309103733013"></a><a name="p5309103733013"></a>-v</p>
</td>
<td class="cellrowborder" valign="top" width="51.519999999999996%" headers="mcps1.2.4.1.2 "><p id="p1830913711300"><a name="p1830913711300"></a><a name="p1830913711300"></a>Displays the deletion process.</p>
</td>
<td class="cellrowborder" valign="top" width="26.26%" headers="mcps1.2.4.1.3 "><p id="p230933703015"><a name="p230933703015"></a><a name="p230933703015"></a>N/A</p>
</td>
</tr>
<tr id="row173147371301"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.2.4.1.1 "><p id="p14309143753012"><a name="p14309143753012"></a><a name="p14309143753012"></a>PATH/filename</p>
</td>
<td class="cellrowborder" valign="top" width="51.519999999999996%" headers="mcps1.2.4.1.2 "><p id="p193091637183016"><a name="p193091637183016"></a><a name="p193091637183016"></a>Specifies the name of the file or directory to delete. The value can be a path.</p>
</td>
<td class="cellrowborder" valign="top" width="26.26%" headers="mcps1.2.4.1.3 "><p id="p10309173711309"><a name="p10309173711309"></a><a name="p10309173711309"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section10578163215262"></a>
- The **rm** command can be used to delete multiple files or folders at a time. - The **rm** command can be used to delete multiple files or folders at a time.
- You can run **rm -r** to delete a non-empty directory. - You can run **rm -r** to delete a non-empty directory.
- If the **rm** command without **-f** is used to delete a file that does not exist, an error will be reported. - If the **rm** command without **-f** is used to delete a file that does not exist, an error will be reported.
## Example<a name="section18548133511263"></a> ## Note
The shell does not support **-v** or **-f**. mksh supports them. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run the following commands: Run the following commands:
- rm testfile - rm testfile
- rm -r testpath/ - rm -r testpath/
## Output<a name="section1565323814265"></a>
Example 1: deleting **testfile** ## Output
Example 1: Delete **testfile**.
``` ```
OHOS:/$ ls OHOS:/$ ls
...@@ -80,7 +59,8 @@ bin etc proc storage userdata vendor ...@@ -80,7 +59,8 @@ bin etc proc storage userdata vendor
dev lib sdcard system usr dev lib sdcard system usr
``` ```
Example 2: deleting **testpath**, a non-empty directory Example 2: Delete **testpath**, a non-empty directory.
``` ```
OHOS:/$ ls OHOS:/$ ls
...@@ -91,4 +71,3 @@ OHOS:/$ ls ...@@ -91,4 +71,3 @@ OHOS:/$ ls
bin etc proc storage userdata vendor bin etc proc storage userdata vendor
dev lib sdcard system usr dev lib sdcard system usr
``` ```
# rmdir # rmdir
## Command Function<a name="section1839611420266"></a> ## Command Function
This command is used to delete a directory. This command is used to delete a directory.
## Syntax<a name="section329574512266"></a>
rmdir \[_-p_\] \[_dirname..._\] ## Syntax
## Parameters<a name="section15865747102620"></a> rmdir [_-p_] [_dirname..._]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1557mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row1563mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1565mcpsimp"><a name="p1565mcpsimp"></a><a name="p1565mcpsimp"></a><strong id="b170710424141"><a name="b170710424141"></a><a name="b170710424141"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | --help | Displays the parameters supported by the **rmdir** command.| N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1567mcpsimp"><a name="p1567mcpsimp"></a><a name="p1567mcpsimp"></a><strong id="b10358846121415"><a name="b10358846121415"></a><a name="b10358846121415"></a>Description</strong></p> | -p | Deletes a path.| N/A |
</th> | --ignore-fail-on-non-empty | Suppresses the error message when a non-empty directory is to be deleted.| N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1569mcpsimp"><a name="p1569mcpsimp"></a><a name="p1569mcpsimp"></a><strong id="b171032047111410"><a name="b171032047111410"></a><a name="b171032047111410"></a>Value Range</strong></p> | dir | Specifies the name of the directory to delete. The directory must be empty. A path is supported.| N/A |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row17771161013316"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p19752111019336"><a name="p19752111019336"></a><a name="p19752111019336"></a>--help</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p18752121015338"><a name="p18752121015338"></a><a name="p18752121015338"></a>Displays the parameters supported by the <strong id="b101038101521"><a name="b101038101521"></a><a name="b101038101521"></a>rmdir</strong> command.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p127521810103316"><a name="p127521810103316"></a><a name="p127521810103316"></a>N/A</p>
</td>
</tr>
<tr id="row977061043317"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p67521810113316"><a name="p67521810113316"></a><a name="p67521810113316"></a>-p</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1475271013319"><a name="p1475271013319"></a><a name="p1475271013319"></a>Deletes a path.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p117525107338"><a name="p117525107338"></a><a name="p117525107338"></a>N/A</p>
</td>
</tr>
<tr id="row2769810133315"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p775211053314"><a name="p775211053314"></a><a name="p775211053314"></a>--ignore-fail-on-non-empty</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p77522010123314"><a name="p77522010123314"></a><a name="p77522010123314"></a>Suppresses the error message when a non-empty directory is to be deleted.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1475281014339"><a name="p1475281014339"></a><a name="p1475281014339"></a>N/A</p>
</td>
</tr>
<tr id="row1776918105337"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p5752141018337"><a name="p5752141018337"></a><a name="p5752141018337"></a>dir</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p3752161083313"><a name="p3752161083313"></a><a name="p3752161083313"></a>Specifies the name of the directory to delete. The directory must be empty. A path is supported.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p57521210113313"><a name="p57521210113313"></a><a name="p57521210113313"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section107857508261"></a>
- The **rmdir** command can only be used to delete directories. - The **rmdir** command can only be used to delete directories.
- The **rmdir** command can delete only one directory at a time. - The **rmdir** command can delete only one directory at a time.
- The **rmdir** command can delete only empty directories. - The **rmdir** command can delete only empty directories.
## Example<a name="section11196165315262"></a>
## Example
Run **rmdir dir**. Run **rmdir dir**.
## Output<a name="section1073811415613"></a>
Deleting the directory **dir**: ## Output
Delete the directory **dir**.
``` ```
OHOS:/test$ mkdir dir OHOS:/test$ mkdir dir
...@@ -74,4 +49,3 @@ dir ...@@ -74,4 +49,3 @@ dir
OHOS:/test$ rmdir dir/ OHOS:/test$ rmdir dir/
OHOS:/test$ ls OHOS:/test$ ls
``` ```
# statfs # statfs
## Command Function<a name="section153921657152613"></a> ## Command Function
This command is used to print information about a file system, such as the type, total size, and available size. This command is used to print information about a file system, such as the type, total size, and available size.
## Syntax<a name="section135391102717"></a>
statfs \[_directory_\] ## Syntax
## Parameters<a name="section074312314279"></a> statfs [_directory_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1597mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row1603mcpsimp"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p1605mcpsimp"><a name="p1605mcpsimp"></a><a name="p1605mcpsimp"></a><strong id="b156942710240"><a name="b156942710240"></a><a name="b156942710240"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | directory | Specifies the file system directory.| The file system must exist and support the **statfs** command. The supported file systems include JFFS2, FAT, and NFS.|
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p1607mcpsimp"><a name="p1607mcpsimp"></a><a name="p1607mcpsimp"></a><strong id="b1759110293240"><a name="b1759110293240"></a><a name="b1759110293240"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p1609mcpsimp"><a name="p1609mcpsimp"></a><a name="p1609mcpsimp"></a><strong id="b10264183019242"><a name="b10264183019242"></a><a name="b10264183019242"></a>Value Range</strong></p> ## Usage Guidelines
</th>
</tr>
</thead>
<tbody><tr id="row1610mcpsimp"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1612mcpsimp"><a name="p1612mcpsimp"></a><a name="p1612mcpsimp"></a>directory</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1615mcpsimp"><a name="p1615mcpsimp"></a><a name="p1615mcpsimp"></a>Specifies the file system directory.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1617mcpsimp"><a name="p1617mcpsimp"></a><a name="p1617mcpsimp"></a>The file system must exist and support the <strong id="b1635148125717"><a name="b1635148125717"></a><a name="b1635148125717"></a>statfs</strong> command. The supported file systems include JFFS2, FAT, and NFS.</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section133816772712"></a>
The printed information varies depending on the file system. The printed information varies depending on the file system.
## Example<a name="section526149182717"></a>
## Example
The following uses the NFS as an example: The following uses the NFS as an example:
...@@ -57,4 +46,3 @@ statfs got: ...@@ -57,4 +46,3 @@ statfs got:
total size: 808742490112 Bytes total size: 808742490112 Bytes
free size: 255618461696 Bytes free size: 255618461696 Bytes
``` ```
# sync # sync
## Command Function<a name="section1285017122274"></a> ## Command Function
This command is used to synchronize cached data \(data in the file system\) to an SD card. This command is used to synchronize cached data (data in the file system) to an SD card.
## Syntax<a name="section4731516162712"></a>
## Syntax
sync sync
## Parameters<a name="section9352418122714"></a>
None ## Parameters
None.
## Usage<a name="section10725192142717"></a> ## Usage Guidelines
- The **sync** command is used to refresh the cache. If no SD card is inserted, no operation will be performed. - The **sync** command is used to refresh the cache. If no SD card is inserted, no operation will be performed.
- When an SD card is inserted, the cache information is synchronized to the SD card. If the synchronization is successful, no information is displayed. - When an SD card is inserted, the cache information is synchronized to the SD card. If the synchronization is successful, no information is displayed.
## Example<a name="section414434814354"></a>
## Example
Run **sync**. Data will be synchronized to the SD card if an SD card is available, and no operation will be performed if no SD card is available. Run **sync**. Data will be synchronized to the SD card if an SD card is available, and no operation will be performed if no SD card is available.
## Output<a name="section19618121710317"></a>
None ## Output
None.
# touch # touch
## Command Function<a name="section17541924112716"></a> ## Command Function
- This command is used to create an empty file in a specified directory. - This command is used to create an empty file in a specified directory.
- If this command is executed to create an existing file, the execution will be successful but the timestamp will not be updated. - If this command is executed to create an existing file, the execution will be successful but the timestamp will not be updated.
## Syntax<a name="section866182711274"></a>
## Syntax
touch \[_filename_\]
touch [_filename_]
## Parameters<a name="section268912296270"></a>
**Table 1** Parameter description ## Parameters
<a name="table1635mcpsimp"></a> **Table 1** Parameter description
<table><thead align="left"><tr id="row1642mcpsimp"><th class="cellrowborder" valign="top" width="20.73%" id="mcps1.2.4.1.1"><p id="p1653mcpsimp"><a name="p1653mcpsimp"></a><a name="p1653mcpsimp"></a><strong id="b132581435193918"><a name="b132581435193918"></a><a name="b132581435193918"></a>Parameter</strong></p>
</th> | Parameter | Description | Value Range|
<th class="cellrowborder" valign="top" width="52.44%" id="mcps1.2.4.1.2"><p id="p1655mcpsimp"><a name="p1655mcpsimp"></a><a name="p1655mcpsimp"></a><strong id="b88661537163918"><a name="b88661537163918"></a><a name="b88661537163918"></a>Description</strong></p> | -------- | --------------------------- | -------- |
</th> | --help | Displays the parameters supported by the **touch** command.| N/A |
<th class="cellrowborder" valign="top" width="26.83%" id="mcps1.2.4.1.3"><p id="p1657mcpsimp"><a name="p1657mcpsimp"></a><a name="p1657mcpsimp"></a><strong id="b164851738193910"><a name="b164851738193910"></a><a name="b164851738193910"></a>Value Range</strong></p> | filename | Specifies the name of the file to create. | N/A |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row1323618419461"><td class="cellrowborder" valign="top" width="20.73%" headers="mcps1.2.4.1.1 "><p id="p1229443463"><a name="p1229443463"></a><a name="p1229443463"></a>--help</p>
</td>
<td class="cellrowborder" valign="top" width="52.44%" headers="mcps1.2.4.1.2 "><p id="p1122915417465"><a name="p1122915417465"></a><a name="p1122915417465"></a>Displays the parameters supported by the <strong id="b39321953125917"><a name="b39321953125917"></a><a name="b39321953125917"></a>touch</strong> command.</p>
</td>
<td class="cellrowborder" valign="top" width="26.83%" headers="mcps1.2.4.1.3 "><p id="p152291464613"><a name="p152291464613"></a><a name="p152291464613"></a>N/A</p>
</td>
</tr>
<tr id="row82356419461"><td class="cellrowborder" valign="top" width="20.73%" headers="mcps1.2.4.1.1 "><p id="p322913424613"><a name="p322913424613"></a><a name="p322913424613"></a>filename</p>
</td>
<td class="cellrowborder" valign="top" width="52.44%" headers="mcps1.2.4.1.2 "><p id="p162291494614"><a name="p162291494614"></a><a name="p162291494614"></a>Specifies the name of the file to create.</p>
</td>
<td class="cellrowborder" valign="top" width="26.83%" headers="mcps1.2.4.1.3 "><p id="p182291242462"><a name="p182291242462"></a><a name="p182291242462"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section412093332714"></a>
- The **touch** command creates an empty file that is readable and writeable. - The **touch** command creates an empty file that is readable and writeable.
- You can use the **touch** command to create multiple files at a time. - You can use the **touch** command to create multiple files at a time.
>![](../public_sys-resources/icon-notice.gif) **NOTICE:** > **NOTICE**<br>
>If you run the **touch** command to create a file in a directory storing important system resources, unexpected results such as a system breakdown may occur. For example, if you run the **touch uartdev-0** command in the **/dev** directory, the system may stop responding. > If you run the **touch** command to create a file in a directory storing important system resources, unexpected results such as a system breakdown may occur. For example, if you run the **touch uartdev-0** command in the **/dev** directory, the system may stop responding.
## Note
## Example<a name="section414434814354"></a> The shell does not support **--help** or creation of multiple files at the same time. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
## Example
Run the following commands: Run the following commands:
- touch file.c - touch file.c
- touch testfile1 testfile2 testfile3 - touch testfile1 testfile2 testfile3
## Output<a name="section1028419515711"></a>
Example 1: creating the **file.c** file ## Output
Example 1: Create a file named **file.c**.
``` ```
OHOS:/tmp$ ls OHOS:/tmp$ ls
...@@ -70,7 +60,8 @@ total 0 ...@@ -70,7 +60,8 @@ total 0
-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 file.c* -rwxrwxrwx 1 0 0 0 1979-12-31 00:00 file.c*
``` ```
Example 2: creating three files \(**testfile1**, **testfile2**, and **testfile3**\) Example 2: Create three files (**testfile1**, **testfile2**, and **testfile3**) at a time.
``` ```
*OHOS:/tmp$ *OHOS:/tmp$
...@@ -82,4 +73,3 @@ total 0 ...@@ -82,4 +73,3 @@ total 0
-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 testfile3* -rwxrwxrwx 1 0 0 0 1979-12-31 00:00 testfile3*
OHOS:/tmp$ OHOS:/tmp$
``` ```
# umount # umount
## Command Function<a name="section365125133520"></a> ## Command Function
This command is used to unmount a specified file system. This command is used to unmount a file system.
## Syntax<a name="section9615254123512"></a>
umount \[_-a \[-t TYPE\]_\] \[_dir_\] ## Syntax
## Parameters<a name="section63446577355"></a> umount [_-a [-t TYPE]_] [_dir_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1713mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row1719mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p1721mcpsimp"><a name="p1721mcpsimp"></a><a name="p1721mcpsimp"></a><strong id="b18608121184416"><a name="b18608121184416"></a><a name="b18608121184416"></a>Parameter</strong></p> | ------ | ------------------------------------------------------------ | -------------------------- |
</th> | --help | Displays the parameters supported by the **umount** command. | N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p1723mcpsimp"><a name="p1723mcpsimp"></a><a name="p1723mcpsimp"></a><strong id="b123794114417"><a name="b123794114417"></a><a name="b123794114417"></a>Description</strong></p> | -a | Unmounts all file systems mounted. | N/A |
</th> | -t | Used together with the **-a** option to restrict the file systems specified by **-a**, allowing only the file system specified by **-t** to be unmounted.| N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1725mcpsimp"><a name="p1725mcpsimp"></a><a name="p1725mcpsimp"></a><strong id="b8664446440"><a name="b8664446440"></a><a name="b8664446440"></a>Value Range</strong></p> | dir | Specifies the directory from which the file system is to be unmounted. | Directory mounted with the file system|
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row915417105016"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1299991675018"><a name="p1299991675018"></a><a name="p1299991675018"></a>--help</p>
</td> By specifying the **dir** parameter in the **unmount** command, you can unmount the specified file system.
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p5999201625017"><a name="p5999201625017"></a><a name="p5999201625017"></a>Displays the parameters supported by the <strong id="b15196112818310"><a name="b15196112818310"></a><a name="b15196112818310"></a>umount</strong> command.</p>
</td> ## Note
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1899981685020"><a name="p1899981685020"></a><a name="p1899981685020"></a>N/A</p>
</td> The shell does not support this command. mksh supports it. To switch to mksh, run **cd bin** and **./mksh**.
</tr>
<tr id="row17151317125011"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1399931616501"><a name="p1399931616501"></a><a name="p1399931616501"></a>-a</p> ## Example
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p159991716125019"><a name="p159991716125019"></a><a name="p159991716125019"></a>Unmounts all file systems mounted.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p999918167508"><a name="p999918167508"></a><a name="p999918167508"></a>N/A</p>
</td>
</tr>
<tr id="row21414171504"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p129997169509"><a name="p129997169509"></a><a name="p129997169509"></a>-t</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p49997167506"><a name="p49997167506"></a><a name="p49997167506"></a>Used together with the <strong id="b19922101571717"><a name="b19922101571717"></a><a name="b19922101571717"></a>-a</strong> option to restrict the file systems specified by <strong id="b1927154112172"><a name="b1927154112172"></a><a name="b1927154112172"></a>-a</strong>, allowing only the file system specified by <strong id="b99221198185"><a name="b99221198185"></a><a name="b99221198185"></a>-t</strong> to be unmounted.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p0999171695016"><a name="p0999171695016"></a><a name="p0999171695016"></a>N/A</p>
</td>
</tr>
<tr id="row131441775015"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p49990164502"><a name="p49990164502"></a><a name="p49990164502"></a>dir</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p129991162504"><a name="p129991162504"></a><a name="p129991162504"></a>Specifies the directory from which the file system is to be unmounted.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1499916164502"><a name="p1499916164502"></a><a name="p1499916164502"></a>Directory mounted with the file system</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section92931509368"></a>
By specifying the **dir** parameter in the **unmount** command, you can unmount the specified file system from the directory.
## Example<a name="section144311323616"></a>
Run the following commands: Run the following commands:
- umount ./nfs - umount ./nfs
- umount -a -t nfs - umount -a -t nfs
## Output<a name="section360525113611"></a>
**unmount** command output: ## Output
Example 1: Unmount the file system from **./nfs**.
Example 1: unmounting the file system from **./nfs**
``` ```
OHOS:/$ umount ./nfs/ OHOS:/$ umount ./nfs/
umount ok umount ok
``` ```
Example 2: unmounting all NFS directories Example 2: Unmount all NFS directories.
``` ```
OHOS:/$ umount -a -t nfs OHOS:/$ umount -a -t nfs
umount ok umount ok
``` ```
# writeproc # writeproc
## Command Function<a name="section366714216619"></a> ## Command Function
This command is used to write data to a specified proc file system. The proc file system supports the input of string parameters. Each file needs to implement its own method. This command is used to write data to the specified proc file system. The proc file system supports data of strings. The method for writing data needs to be implemented.
## Syntax<a name="section8833164614615"></a>
writeproc <_data_\> \>\> /proc/<_filename_\> ## Syntax
## Parameters<a name="section12809111019453"></a> writeproc &lt;*data*&gt; &gt;&gt; /proc/&lt;*filename*&gt;
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table438mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row444mcpsimp"><th class="cellrowborder" valign="top" width="21.000000000000004%" id="mcps1.2.4.1.1"><p id="p446mcpsimp"><a name="p446mcpsimp"></a><a name="p446mcpsimp"></a><strong id="b16354000851164"><a name="b16354000851164"></a><a name="b16354000851164"></a>Parameter</strong></p> | -------- | ---------------------------------------------------------- |
</th> | data | Specifies the string to write, which ends with a space. If you need to write a space, use **""** to enclose the space. |
<th class="cellrowborder" valign="top" width="52.970000000000006%" id="mcps1.2.4.1.2"><p id="p448mcpsimp"><a name="p448mcpsimp"></a><a name="p448mcpsimp"></a><strong id="b2720614204911"><a name="b2720614204911"></a><a name="b2720614204911"></a>Description</strong></p> | filename | Specifies the proc file to which **data** is to write. |
</th>
<th class="cellrowborder" valign="top" width="26.030000000000005%" id="mcps1.2.4.1.3"><p id="p450mcpsimp"><a name="p450mcpsimp"></a><a name="p450mcpsimp"></a><strong id="b3067324051164"><a name="b3067324051164"></a><a name="b3067324051164"></a>Value Range</strong></p>
</th> ## Usage Guidelines
</tr>
</thead> The proc file system implements its own **write()** function. Calling the **writeproc** command will pass input parameters to the **write()** function.
<tbody><tr id="row451mcpsimp"><td class="cellrowborder" valign="top" width="21.000000000000004%" headers="mcps1.2.4.1.1 "><p id="p2500105121818"><a name="p2500105121818"></a><a name="p2500105121818"></a>data</p>
</td> > **NOTE**<br>
<td class="cellrowborder" valign="top" width="52.970000000000006%" headers="mcps1.2.4.1.2 "><p id="p1149945111817"><a name="p1149945111817"></a><a name="p1149945111817"></a>Specifies the string to be entered, which ends with a space. If you need to enter a space, use <strong id="b11296145424918"><a name="b11296145424918"></a><a name="b11296145424918"></a>""</strong> to enclose the space.</p> > The procfs file system does not support multi-thread access.
</td>
<td class="cellrowborder" valign="top" width="26.030000000000005%" headers="mcps1.2.4.1.3 "><p id="p749810571812"><a name="p749810571812"></a><a name="p749810571812"></a>N/A</p> ## Note
</td>
</tr> Currently, the shell does not support this command.
<tr id="row155978258237"><td class="cellrowborder" valign="top" width="21.000000000000004%" headers="mcps1.2.4.1.1 "><p id="p195983258238"><a name="p195983258238"></a><a name="p195983258238"></a>filename</p>
</td> ## Example
<td class="cellrowborder" valign="top" width="52.970000000000006%" headers="mcps1.2.4.1.2 "><p id="p25985252238"><a name="p25985252238"></a><a name="p25985252238"></a>Specifies the proc file to which <strong id="b1319518261507"><a name="b1319518261507"></a><a name="b1319518261507"></a>data</strong> is to be passed.</p>
</td> Run **writeproc test >> /proc/uptime**.
<td class="cellrowborder" valign="top" width="26.030000000000005%" headers="mcps1.2.4.1.3 "><p id="p10598425112312"><a name="p10598425112312"></a><a name="p10598425112312"></a>N/A</p>
</td>
</tr> ## Output
</tbody>
</table> ```
OHOS \# writeproc test &gt;&gt; /proc/uptime
## Usage<a name="section15935131220717"></a>
[INFO]write buf is: test
The proc file implements its own **write** command. Calling the **writeproc** command will pass the input parameters to the **write** command.
test &gt;&gt; /proc/uptime
>![](../public_sys-resources/icon-note.gif) **NOTE:** ```
>The procfs file system does not support multi-thread access.
> **NOTE**<br>
## Example<a name="section79281818476"></a> > The **uptime** proc file temporarily implements the **write()** function. The **INFO** log is generated by the **test()** function.
Run **writeproc test \>\> /proc/uptime**.
## Output<a name="section12742311179"></a>
OHOS \# writeproc test \>\> /proc/uptime
\[INFO\]write buf is: test
test \>\> /proc/uptime
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>The uptime proc file temporarily implements the **write** command. The **INFO** log is generated by the implemented **test** command.
...@@ -3,22 +3,28 @@ ...@@ -3,22 +3,28 @@
## When to Use ## When to Use
When the system does not respond, you can use the magic key function to check whether the system is suspended by an interrupt lock (the magic key also does not respond) or view the system task running status. When the system does not respond, you can use the magic key to check whether the system is suspended by an interrupt lock or view the system task running status.
If interrupts are responded, you can use the magic key to check the task CPU usage (**cpup**) and find out the task with the highest CPU usage. Generally, the task with a higher priority preempts the CPU resources. If interrupts are responded, you can use the magic key to check the task CPU percent (CPUP) and locate the task with the highest CPUP. Generally, the task with a higher priority preempts the CPU resources.
## How to Use ## How to Configure
The magic key depends on the macro **LOSCFG_ENABLE_MAGICKEY**.
To configure **LOSCFG_ENABLE_MAGICKEY**:
1. Configure the macro **LOSCFG_ENABLE_MAGICKEY**. 1. Run the **make menuconfig** command in **kernel/liteos_a**.
2. Locate the **Debug** option and select **Enable MAGIC KEY**.
The magic key depends on the **LOSCFG_ENABLE_MAGICKEY** macro. Before using the magic key, select **Enable MAGIC KEY** (**Debug** ---> **Enable MAGIC KEY**) on **menuconfig**. The magic key cannot be used if this option is disabled. This option is selected by default. If it is not selected, the magic key is invalid.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** > **NOTE**<br>
> > On **menuconfig**, you can move the cursor to **LOSCFG_ENABLE_MAGICKEY** and enter a question mark (?) to view help information.
> On **menuconfig**, you can move the cursor to **LOSCFG_ENABLE_MAGICKEY** and enter a question mark (?) to view help Information.
## How to Use
2. Press **Ctrl+R** to enable the magic key. 1. Press **Ctrl+R** to enable the magic key.
When the UART or USB-to-virtual serial port is connected, press **Ctrl+R**. If "Magic key on" is displayed, the magic key is enabled. To disable it, press **Ctrl+R** again. If "Magic key off" is displayed, the magic key is disabled. When the UART or USB-to-virtual serial port is connected, press **Ctrl+R**. If "Magic key on" is displayed, the magic key is enabled. To disable it, press **Ctrl+R** again. If "Magic key off" is displayed, the magic key is disabled.
...@@ -32,5 +38,5 @@ If interrupts are responded, you can use the magic key to check the task CPU usa ...@@ -32,5 +38,5 @@ If interrupts are responded, you can use the magic key to check the task CPU usa
- **Ctrl+E**: Checks the integrity of the memory pool. If an error is detected, the system displays an error message. If no error is detected, the system displays "system memcheck over, all passed!". - **Ctrl+E**: Checks the integrity of the memory pool. If an error is detected, the system displays an error message. If no error is detected, the system displays "system memcheck over, all passed!".
> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **NOTICE**<br> > **NOTE**<br>
> If magic key is enabled, when special characters need to be entered through the UART or USB-to-virtual serial port, avoid using characters the same as the magic keys. Otherwise, the magic key may be triggered by mistake, causing errors in the original design. > If magic key is enabled, when special characters need to be entered through the UART or USB-to-virtual serial port, avoid using characters the same as the magic keys. Otherwise, the magic key may be triggered by mistake, causing errors in design.
# arp # arp
## Command Function<a name="section201149459368"></a> ## Command Function
Hosts on an Ethernet communicate with each other using MAC addresses. IP addresses must be converted into MAC addresses to enable communication between hosts on a LAN \(Ethernet\). To achieve this purpose, the host stores a table containing the mapping between IP addresses and MAC addresses. This table is called an Address Resolution Protocol \(ARP\) cache table. Before sending an IP packet to a LAN, the host looks up the destination MAC address in the ARP cache table. The ARP cache table is maintained by the TCP/IP stack. You can run the **arp** command to view and modify the ARP cache table. Hosts on an Ethernet communicate with each other using MAC addresses. IP addresses must be converted into MAC addresses to enable communication between hosts on a LAN (Ethernet). To achieve this purpose, the host stores a table containing the mapping between IP addresses and MAC addresses. This table is called an Address Resolution Protocol (ARP) cache table. Before sending an IP packet to a LAN, the host looks up the destination MAC address in the ARP cache table. The ARP cache table is maintained by the TCP/IP stack. You can run the **arp** command to view and modify the ARP cache table.
## Syntax<a name="section579813484364"></a>
## Syntax
arp arp
arp \[_-i IF_\] -s _IPADDR HWADDR_ arp [_-i IF_] -s *IPADDR HWADDR*
arp [_-i IF_] -d *IPADDR*
arp \[_-i IF_\] -d _IPADDR_
## Parameters<a name="section168065311366"></a> ## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table1845mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row1851mcpsimp"><th class="cellrowborder" valign="top" width="20.84%" id="mcps1.2.4.1.1"><p id="p1853mcpsimp"><a name="p1853mcpsimp"></a><a name="p1853mcpsimp"></a><strong id="b24438529911613"><a name="b24438529911613"></a><a name="b24438529911613"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | No parameter| Prints the content of the ARP cache table.| N/A |
<th class="cellrowborder" valign="top" width="52.16%" id="mcps1.2.4.1.2"><p id="p1855mcpsimp"><a name="p1855mcpsimp"></a><a name="p1855mcpsimp"></a><strong id="b665518251701"><a name="b665518251701"></a><a name="b665518251701"></a>Description</strong></p> | -i&nbsp;IF | Specifies the network port. This parameter is optional.| N/A |
</th> | -s&nbsp;IPADDR<br>HWADDR | Adds an ARP entry. The second parameter is the IP address and MAC address of the other host on the LAN.| N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p1857mcpsimp"><a name="p1857mcpsimp"></a><a name="p1857mcpsimp"></a><strong id="b169031044911613"><a name="b169031044911613"></a><a name="b169031044911613"></a>Value Range</strong></p> | -d&nbsp;IPADDR | Deletes an ARP entry.| N/A |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row1858mcpsimp"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p1860mcpsimp"><a name="p1860mcpsimp"></a><a name="p1860mcpsimp"></a>No parameter</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p1862mcpsimp"><a name="p1862mcpsimp"></a><a name="p1862mcpsimp"></a>Queries the content of the ARP cache table.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1864mcpsimp"><a name="p1864mcpsimp"></a><a name="p1864mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row1865mcpsimp"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p1867mcpsimp"><a name="p1867mcpsimp"></a><a name="p1867mcpsimp"></a>-i IF</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p1869mcpsimp"><a name="p1869mcpsimp"></a><a name="p1869mcpsimp"></a>Specifies the network port. This parameter is optional.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1871mcpsimp"><a name="p1871mcpsimp"></a><a name="p1871mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row1872mcpsimp"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p1874mcpsimp"><a name="p1874mcpsimp"></a><a name="p1874mcpsimp"></a>-s IPADDR</p>
<p id="p1875mcpsimp"><a name="p1875mcpsimp"></a><a name="p1875mcpsimp"></a>HWADDR</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p1877mcpsimp"><a name="p1877mcpsimp"></a><a name="p1877mcpsimp"></a>Adds an ARP entry. The second parameter is the IP address and MAC address of the other host on the LAN.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1879mcpsimp"><a name="p1879mcpsimp"></a><a name="p1879mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row1880mcpsimp"><td class="cellrowborder" valign="top" width="20.84%" headers="mcps1.2.4.1.1 "><p id="p1882mcpsimp"><a name="p1882mcpsimp"></a><a name="p1882mcpsimp"></a>-d IPADDR</p>
</td>
<td class="cellrowborder" valign="top" width="52.16%" headers="mcps1.2.4.1.2 "><p id="p1884mcpsimp"><a name="p1884mcpsimp"></a><a name="p1884mcpsimp"></a>Deletes an ARP entry.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1886mcpsimp"><a name="p1886mcpsimp"></a><a name="p1886mcpsimp"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section19190125723612"></a>
- The **arp** command is used to query and modify the ARP cache table of the TCP/IP stack. If ARP entries for IP addresses on different subnets are added, the protocol stack returns a failure message. - The **arp** command is used to query and modify the ARP cache table of the TCP/IP stack. If ARP entries for IP addresses on different subnets are added, the protocol stack returns a failure message.
- This command can be used only after the TCP/IP stack is enabled.
## Example<a name="section10383416372"></a> - This command can be used only after the TCP/IP protocol stack is enabled.
## Example
Run the **arp** command. Run **arp**.
ARP cache table: ARP cache table information:
``` ```
OHOS # arp OHOS # arp
...@@ -75,35 +46,11 @@ Address HWaddress Iface Type ...@@ -75,35 +46,11 @@ Address HWaddress Iface Type
192.168.1.10 E6:2B:99:2C:4B:20 eth0 static 192.168.1.10 E6:2B:99:2C:4B:20 eth0 static
``` ```
**Table 2** Output description **Table 2** Parameter description
<a name="table1901mcpsimp"></a>
<table><thead align="left"><tr id="row1906mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1908mcpsimp"><a name="p1908mcpsimp"></a><a name="p1908mcpsimp"></a><strong id="b38103410311613"><a name="b38103410311613"></a><a name="b38103410311613"></a>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p1910mcpsimp"><a name="p1910mcpsimp"></a><a name="p1910mcpsimp"></a><strong id="b6623104464810"><a name="b6623104464810"></a><a name="b6623104464810"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1911mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1913mcpsimp"><a name="p1913mcpsimp"></a><a name="p1913mcpsimp"></a>Address</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1915mcpsimp"><a name="p1915mcpsimp"></a><a name="p1915mcpsimp"></a>IPv4 address of a network device.</p>
</td>
</tr>
<tr id="row1916mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1918mcpsimp"><a name="p1918mcpsimp"></a><a name="p1918mcpsimp"></a>HWaddress</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1920mcpsimp"><a name="p1920mcpsimp"></a><a name="p1920mcpsimp"></a>MAC address of a network device.</p>
</td>
</tr>
<tr id="row1921mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1923mcpsimp"><a name="p1923mcpsimp"></a><a name="p1923mcpsimp"></a>Iface</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1925mcpsimp"><a name="p1925mcpsimp"></a><a name="p1925mcpsimp"></a>Name of the port used by the ARP entry.</p>
</td>
</tr>
<tr id="row1926mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1928mcpsimp"><a name="p1928mcpsimp"></a><a name="p1928mcpsimp"></a>Type</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1930mcpsimp"><a name="p1930mcpsimp"></a><a name="p1930mcpsimp"></a>Indicates whether the ARP entry is dynamic or static. A dynamic ARP entry is automatically created by the protocol stack, and a static ARP entry is added by the user.</p>
</td>
</tr>
</tbody>
</table>
| Parameter| Description|
| -------- | -------- |
| Address | IPv4 address of the network device.|
| HWaddress | MAC address of the network device.|
| Iface | Name of the port used by the ARP entry.|
| Type | Whether the ARP entry is dynamic or static. A dynamic ARP entry is automatically created by the protocol stack, and a static ARP entry is added by the user. |
# dhclient # dhclient
## Command Function<a name="section366714216619"></a> ## Command Function
This command is used to set and query **dhclient** parameters. This command is used to set and query **dhclient** parameters.
## Syntax<a name="section8833164614615"></a>
- dhclient <_netif name_\> ## Syntax
- dhclient -x <_netif name_\>
## Parameters<a name="section12809111019453"></a> - dhclient &lt;*netif name*&gt;
- dhclient -x &lt;*netif name*&gt;
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table438mcpsimp"></a> | Parameter | Description | Value Range |
<table><thead align="left"><tr id="row444mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p446mcpsimp"><a name="p446mcpsimp"></a><a name="p446mcpsimp"></a><strong id="b20999054421160"><a name="b20999054421160"></a><a name="b20999054421160"></a>Parameter</strong></p> | ------------------------------- | -------------------------------------------- | ---------------- |
</th> | -h&nbsp;\|&nbsp;--help | Displays parameters supported by the **dhclient** command and their usage.| N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p448mcpsimp"><a name="p448mcpsimp"></a><a name="p448mcpsimp"></a><strong id="b16991513175018"><a name="b16991513175018"></a><a name="b16991513175018"></a>Description</strong></p> | &lt;netif&nbsp;name&gt; | Enables Dynamic Host Configuration Protocol (DHCP) for a network interface card (NIC). | NIC name, **eth0**|
</th> | -x&nbsp;&lt;netif&nbsp;name&gt; | Disables DHCP for a NIC. | NIC name, **eth0**|
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p450mcpsimp"><a name="p450mcpsimp"></a><a name="p450mcpsimp"></a><strong id="b9837196561160"><a name="b9837196561160"></a><a name="b9837196561160"></a>Value Range</strong></p>
</th>
</tr> ## Usage Guidelines
</thead>
<tbody><tr id="row15810322374"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p108030222712"><a name="p108030222712"></a><a name="p108030222712"></a>-h | --help</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p14803132214716"><a name="p14803132214716"></a><a name="p14803132214716"></a>Displays parameters supported by the <strong id="b71961312874"><a name="b71961312874"></a><a name="b71961312874"></a>dhclient</strong> command and their usage.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p28038222716"><a name="p28038222716"></a><a name="p28038222716"></a>N/A</p>
</td>
</tr>
<tr id="row880917225712"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p6803162212717"><a name="p6803162212717"></a><a name="p6803162212717"></a>&lt;netif name&gt;</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p980352211712"><a name="p980352211712"></a><a name="p980352211712"></a>Enables Dynamic Host Configuration Protocol (DHCP) for a network interface card (NIC).</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p48031822276"><a name="p48031822276"></a><a name="p48031822276"></a>NIC name, <strong id="b178511243205513"><a name="b178511243205513"></a><a name="b178511243205513"></a>eth0</strong></p>
</td>
</tr>
<tr id="row78092222716"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p108032221379"><a name="p108032221379"></a><a name="p108032221379"></a>-x &lt;netif name&gt;</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1180318222710"><a name="p1180318222710"></a><a name="p1180318222710"></a>Disables DHCP for a NIC.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p78034222072"><a name="p78034222072"></a><a name="p78034222072"></a>NIC name, <strong id="b41988451673"><a name="b41988451673"></a><a name="b41988451673"></a>eth0</strong></p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section15935131220717"></a>
Run the following commands: Run the following commands:
- dhclient eth0 - dhclient eth0
- dhclient -x eth0 - dhclient -x eth0
## Example<a name="section79281818476"></a> ## Note
Currently, the shell does not support this command.
## Example
Example 1: Enable DHCP for eth0.
Example 1: enabling DHCP for eth0
``` ```
OHOS:/$ dhclient eth0 OHOS:/$ dhclient eth0
...@@ -69,7 +52,9 @@ eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 ...@@ -69,7 +52,9 @@ eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1
OHOS:/$ OHOS:/$
``` ```
Example 2: disabling DHCP for eth0
Example 2: Disable DHCP for eth0.
``` ```
OHOS:/$ dhclient -x eth0 OHOS:/$ dhclient -x eth0
...@@ -81,4 +66,3 @@ lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 ...@@ -81,4 +66,3 @@ lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1
eth0 ip:0.0.0.0 netmask:0.0.0.0 gateway:0.0.0.0 eth0 ip:0.0.0.0 netmask:0.0.0.0 gateway:0.0.0.0
HWaddr 42:da:81:bc:58:94 MTU:1500 Running Default Link UP HWaddr 42:da:81:bc:58:94 MTU:1500 Running Default Link UP
``` ```
# ifconfig # ifconfig
## Command Function<a name="section174940284379"></a> ## Command Function
This command can be used to: This command can be used to:
- Query and set parameters of a network interface card \(NIC\), such as the IP address, network mask, gateway, and MAC address. - Query and set parameters of a network interface card (NIC), such as the IP address, network mask, gateway, and MAC address.
- Enable or disable a NIC. - Enable or disable a NIC.
## Syntax<a name="section136073203715"></a>
ifconfig \[option\] ## Syntax
ifconfig [option]
option: option:
- \[_-a_\] - [_-a_]
- <_interface_\> <_address_\> \[_netmask <mask\>_\] \[_gateway <address\>_\]
- \[_hw ether <address\>_\] \[_mtu <size\>_\] - &lt;*interface*&gt; &lt;*address*&gt; [_netmask &lt;mask&gt;_] [_gateway &lt;address&gt;_]
- \[_inet6 add <address\>_\]
- \[_inet6 del <address\>_\] - [_hw ether &lt;address&gt;_] [_mtu &lt;size&gt;_]
- \[_up|down_\]
- [_inet6 add &lt;address&gt;_]
- [_inet6 del &lt;address&gt;_]
- [_up|down_]
## Parameters<a name="section6493235203710"></a>
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table2005mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row2011mcpsimp"><th class="cellrowborder" valign="top" width="17.93%" id="mcps1.2.4.1.1"><p id="p2013mcpsimp"><a name="p2013mcpsimp"></a><a name="p2013mcpsimp"></a><strong id="b207545880811653"><a name="b207545880811653"></a><a name="b207545880811653"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | No parameter| Displays all NIC information, which includes the IP address, network mask, gateway, MAC address, maximum transmission unit (MTUs), and running status of each NIC.| N/A |
<th class="cellrowborder" valign="top" width="53.669999999999995%" id="mcps1.2.4.1.2"><p id="p2015mcpsimp"><a name="p2015mcpsimp"></a><a name="p2015mcpsimp"></a><strong id="b519711279124"><a name="b519711279124"></a><a name="b519711279124"></a>Description</strong></p> | -a | Displays data sent and received by the protocol stack.| N/A |
</th> | interface | Specifies the NIC name, for example, **eth0**.| N/A |
<th class="cellrowborder" valign="top" width="28.4%" id="mcps1.2.4.1.3"><p id="p2017mcpsimp"><a name="p2017mcpsimp"></a><a name="p2017mcpsimp"></a><strong id="b19371475311653"><a name="b19371475311653"></a><a name="b19371475311653"></a>Value Range</strong></p> | address | Specifies the IP address, for example, **192.168.1.10**. The NIC name must be specified.| N/A |
</th> | netmask | Specifies the subnet mask, for example, **255.255.255.0**.| N/A |
</tr> | gateway | Specifies the gateway, for example, **192.168.1.1**.| N/A |
</thead> | hw&nbsp;ether | Specifies the MAC address, for example, **00:11:22:33:44:55**. Currently, only the **ether** hardware type is supported.| N/A |
<tbody><tr id="row71475414535"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p11941141534"><a name="p11941141534"></a><a name="p11941141534"></a>No parameter</p> | mtu | Specifies the MTU size, for example, **1000**.| - IPv4: [68, 1500]<br>- IPv6:[1280, 1500] |
</td> | add | Specifies the IPv6 address, for example, **2001:a:b:c:d:e:f:d**. The NIC name and **inet6** must be specified.| N/A |
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p1594124175315"><a name="p1594124175315"></a><a name="p1594124175315"></a>Displays all NIC information, which includes the IP address, network mask, gateway, MAC address, maximum transmission unit (MTUs), and running status of each NIC.</p> | del | Deletes an IPv6 address. You need to specify the NIC name and add the **inet6** option. For details, see the example.| N/A |
</td> | up | Enables the data processing function of the NIC. The NIC name must be specified.| N/A |
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p1194174145311"><a name="p1194174145311"></a><a name="p1194174145311"></a>N/A</p> | down | Disables the data processing function of the NIC. The NIC name must be specified.| N/A |
</td>
</tr>
<tr id="row1814615495314"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p194144135316"><a name="p194144135316"></a><a name="p194144135316"></a>-a</p> ## Usage Guidelines
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p13941445534"><a name="p13941445534"></a><a name="p13941445534"></a>Displays data sent and received by the protocol stack.</p> - This command can be used only after the TCP/IP stack is enabled.
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p1294154155314"><a name="p1294154155314"></a><a name="p1294154155314"></a>N/A</p>
</td>
</tr>
<tr id="row31466417533"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p199410445319"><a name="p199410445319"></a><a name="p199410445319"></a>interface</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p139415485312"><a name="p139415485312"></a><a name="p139415485312"></a>Specifies the NIC name, for example, <strong id="b1368975571410"><a name="b1368975571410"></a><a name="b1368975571410"></a>eth0</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p9944415315"><a name="p9944415315"></a><a name="p9944415315"></a>N/A</p>
</td>
</tr>
<tr id="row9145114165319"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p7947412538"><a name="p7947412538"></a><a name="p7947412538"></a>address</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p119454165313"><a name="p119454165313"></a><a name="p119454165313"></a>Specifies the IP address, for example, <strong id="b530715731519"><a name="b530715731519"></a><a name="b530715731519"></a>192.168.1.10</strong>. The NIC name must be specified.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p99424185316"><a name="p99424185316"></a><a name="p99424185316"></a>N/A</p>
</td>
</tr>
<tr id="row1614415418534"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p1694942532"><a name="p1694942532"></a><a name="p1694942532"></a>netmask</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p194749536"><a name="p194749536"></a><a name="p194749536"></a>Specifies the subnet mask, for example, <strong id="b1625513191514"><a name="b1625513191514"></a><a name="b1625513191514"></a>255.255.255.0</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p094124175316"><a name="p094124175316"></a><a name="p094124175316"></a>N/A</p>
</td>
</tr>
<tr id="row13144942537"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p1494174125316"><a name="p1494174125316"></a><a name="p1494174125316"></a>gateway</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p109413413534"><a name="p109413413534"></a><a name="p109413413534"></a>Specifies the gateway, for example, <strong id="b52931945195112"><a name="b52931945195112"></a><a name="b52931945195112"></a>192.168.1.1</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p19946465313"><a name="p19946465313"></a><a name="p19946465313"></a>N/A</p>
</td>
</tr>
<tr id="row914313405310"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p169415455310"><a name="p169415455310"></a><a name="p169415455310"></a>hw ether</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p20946412532"><a name="p20946412532"></a><a name="p20946412532"></a>Specifies the MAC address, for example, <strong id="b85669109525"><a name="b85669109525"></a><a name="b85669109525"></a>00:11:22:33:44:55</strong>. Currently, only the <strong id="b534492414613"><a name="b534492414613"></a><a name="b534492414613"></a>ether</strong> hardware type is supported.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p19948418537"><a name="p19948418537"></a><a name="p19948418537"></a>N/A</p>
</td>
</tr>
<tr id="row141421142532"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p13941049535"><a name="p13941049535"></a><a name="p13941049535"></a>mtu</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p159418414536"><a name="p159418414536"></a><a name="p159418414536"></a>Specifies the MTU size, for example, <strong id="b2852192012261"><a name="b2852192012261"></a><a name="b2852192012261"></a>1000</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><a name="ul7956417536"></a><a name="ul7956417536"></a><ul id="ul7956417536"><li>IPv4:<p id="p29519485319"><a name="p29519485319"></a><a name="p29519485319"></a>[68,1500]</p>
</li><li>IPv6:<p id="p69524195316"><a name="p69524195316"></a><a name="p69524195316"></a>[1280, 1500]</p>
</li></ul>
</td>
</tr>
<tr id="row1914214419532"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p119554125313"><a name="p119554125313"></a><a name="p119554125313"></a>add</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p1952046539"><a name="p1952046539"></a><a name="p1952046539"></a>Specifies the IPv6 address, for example, <strong id="b12509153516279"><a name="b12509153516279"></a><a name="b12509153516279"></a>2001:a:b:c:d:e:f:d</strong>. The NIC name and <strong id="b912123842916"><a name="b912123842916"></a><a name="b912123842916"></a>inet6</strong> must be specified.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p49516418533"><a name="p49516418533"></a><a name="p49516418533"></a>N/A</p>
</td>
</tr>
<tr id="row17141144175319"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p4952445318"><a name="p4952445318"></a><a name="p4952445318"></a>del</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p1556618562119"><a name="p1556618562119"></a><a name="p1556618562119"></a>Deletes an IPv6 address. You need to specify the NIC name and add the <strong id="b166212197409"><a name="b166212197409"></a><a name="b166212197409"></a>inet6</strong> option. For details, see the example.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p1995248536"><a name="p1995248536"></a><a name="p1995248536"></a>N/A</p>
</td>
</tr>
<tr id="row714064175312"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p12951849536"><a name="p12951849536"></a><a name="p12951849536"></a>up</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p119510455314"><a name="p119510455314"></a><a name="p119510455314"></a>Enables the data processing function of the NIC. The NIC name must be specified.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p695944533"><a name="p695944533"></a><a name="p695944533"></a>N/A</p>
</td>
</tr>
<tr id="row31405465313"><td class="cellrowborder" valign="top" width="17.93%" headers="mcps1.2.4.1.1 "><p id="p49516455316"><a name="p49516455316"></a><a name="p49516455316"></a>down</p>
</td>
<td class="cellrowborder" valign="top" width="53.669999999999995%" headers="mcps1.2.4.1.2 "><p id="p1795164105312"><a name="p1795164105312"></a><a name="p1795164105312"></a>Disables the data processing function of the NIC. The NIC name must be specified.</p>
</td>
<td class="cellrowborder" valign="top" width="28.4%" headers="mcps1.2.4.1.3 "><p id="p12951644532"><a name="p12951644532"></a><a name="p12951644532"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section05763403371"></a>
- The **ifconfig** command can be used only after the TCP/IP stack is enabled.
- Detecting an IP address conflict takes time. Each time you run the **ifconfig** command to set an IP address, there is a delay of about 2 seconds. - Detecting an IP address conflict takes time. Each time you run the **ifconfig** command to set an IP address, there is a delay of about 2 seconds.
## Example<a name="section168802042123717"></a>
## Example
- ifconfig eth0 192.168.100.31 netmask 255.255.255.0 gateway 192.168.100.1 hw ether 00:49:cb:6c:a1:31 - ifconfig eth0 192.168.100.31 netmask 255.255.255.0 gateway 192.168.100.1 hw ether 00:49:cb:6c:a1:31
- ifconfig -a - ifconfig -a
- ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d - ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d
- ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d - ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d
## Output<a name="section124638211109"></a>
- Example 1: setting network parameters ## Output
- Example 1: Set network parameters.
``` ```
OHOS:/$ ifconfig eth0 192.168.100.31 netmask 255.255.255.0 gateway 192.168.100.1 hw ether 00:49:cb:6c:a1:31 OHOS:/$ ifconfig eth0 192.168.100.31 netmask 255.255.255.0 gateway 192.168.100.1 hw ether 00:49:cb:6c:a1:31
...@@ -149,61 +81,22 @@ option: ...@@ -149,61 +81,22 @@ option:
HWaddr 00:49:cb:6c:a1:31 MTU:1500 Running Default Link UP HWaddr 00:49:cb:6c:a1:31 MTU:1500 Running Default Link UP
``` ```
The following table describes the output parameters.
**Table 2** Output description **Table 2** Parameter description
<a name="table2147mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row2152mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p2154mcpsimp"><a name="p2154mcpsimp"></a><a name="p2154mcpsimp"></a><strong id="b211311219311653"><a name="b211311219311653"></a><a name="b211311219311653"></a>Parameter</strong></p> | -------- | -------- |
</th> | ip | IP address of the board.|
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p2156mcpsimp"><a name="p2156mcpsimp"></a><a name="p2156mcpsimp"></a><strong id="b336412763515"><a name="b336412763515"></a><a name="b336412763515"></a>Description</strong></p> | netmask | Subnet mask.|
</th> | gateway | Gateway.|
</tr> | HWaddr | MAC address of the board.|
</thead> | MTU | Maximum transmission unit.|
<tbody><tr id="row17361516205420"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p107151611546"><a name="p107151611546"></a><a name="p107151611546"></a>ip</p> | Running/Stop | Whether the NIC is running.|
</td> | Default | Indicates that the NIC is connected to the default gateway.|
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p117111610549"><a name="p117111610549"></a><a name="p117111610549"></a>IP address of the board</p> | Link&nbsp;UP/Down | Connection status of the NIC.|
</td>
</tr> - Example 2: Obtain protocol stack statistics.
<tr id="row4363166543"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p15731635412"><a name="p15731635412"></a><a name="p15731635412"></a>netmask</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p187161616540"><a name="p187161616540"></a><a name="p187161616540"></a>Subnet mask</p>
</td>
</tr>
<tr id="row435161665419"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1714162546"><a name="p1714162546"></a><a name="p1714162546"></a>gateway</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1471216175420"><a name="p1471216175420"></a><a name="p1471216175420"></a>Gateway</p>
</td>
</tr>
<tr id="row93541615542"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p671167547"><a name="p671167547"></a><a name="p671167547"></a>HWaddr</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p157111665412"><a name="p157111665412"></a><a name="p157111665412"></a>MAC address of the board</p>
</td>
</tr>
<tr id="row13421645418"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p487161543"><a name="p487161543"></a><a name="p487161543"></a>MTU</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p78016195415"><a name="p78016195415"></a><a name="p78016195415"></a>Maximum transmission unit</p>
</td>
</tr>
<tr id="row433181615412"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p10821612543"><a name="p10821612543"></a><a name="p10821612543"></a>Running/Stop</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p281516205410"><a name="p281516205410"></a><a name="p281516205410"></a>Indicates whether the NIC is running.</p>
</td>
</tr>
<tr id="row33320167543"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p5821685419"><a name="p5821685419"></a><a name="p5821685419"></a>Default</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p881516145415"><a name="p881516145415"></a><a name="p881516145415"></a>Indicates that the NIC is connected to the default gateway.</p>
</td>
</tr>
<tr id="row1321166546"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p3881695417"><a name="p3881695417"></a><a name="p3881695417"></a>Link UP/Down</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p18201614546"><a name="p18201614546"></a><a name="p18201614546"></a>Connection status of the NIC</p>
</td>
</tr>
</tbody>
</table>
- Example 2: obtaining protocol stack statistics
``` ```
OHOS # ifconfig -a OHOS # ifconfig -a
...@@ -213,71 +106,24 @@ option: ...@@ -213,71 +106,24 @@ option:
TX packets(ip6):3 errors:0 overrun:0 bytes:0(0.0 B) TX packets(ip6):3 errors:0 overrun:0 bytes:0(0.0 B)
``` ```
The following table describes the output parameters.
**Table 3** ifconfig -a output description **Table 3** ifconfig -a parameter description
<a name="table2209mcpsimp"></a> | Parameter| Description|
<table><thead align="left"><tr id="row2214mcpsimp"><th class="cellrowborder" valign="top" width="28.999999999999996%" id="mcps1.2.3.1.1"><p id="p2216mcpsimp"><a name="p2216mcpsimp"></a><a name="p2216mcpsimp"></a><strong id="b120972048811653"><a name="b120972048811653"></a><a name="b120972048811653"></a>Parameter</strong></p> | -------- | -------- |
</th> | RX&nbsp;packets | Number of normal packets received at the IP layer.|
<th class="cellrowborder" valign="top" width="71%" id="mcps1.2.3.1.2"><p id="p2218mcpsimp"><a name="p2218mcpsimp"></a><a name="p2218mcpsimp"></a><strong id="b8227191303719"><a name="b8227191303719"></a><a name="b8227191303719"></a>Description</strong></p> | RX&nbsp;error | Number of error packets received at the IP layer. The errors include the length error, verification error, IP option error, and IP header protocol error.|
</th> | RX&nbsp;dropped | Number of packets discarded at the IP layer. Packets are discarded due to packet errors, packet forwarding failures, and disabled local NICs.|
</tr> | RX&nbsp;overrun | Number of packets that the MAC layer fails to deliver to the upper-layer protocol stack. The failure is caused by resource insufficiency at the protocol stack.|
</thead> | RX&nbsp;bytes | Total length of normal packets received at the IP layer, excluding the length of the fragments that are not reassembled.|
<tbody><tr id="row6921834553"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p117413375517"><a name="p117413375517"></a><a name="p117413375517"></a>RX packets</p> | TX&nbsp;packets | Number of packets that have been normally sent or forwarded at the IP layer.|
</td> | TX&nbsp;error | Number of packets that the IP layer fails to send. Packets may fail to be sent because the packets cannot be routed or the packets fail to be processed in the protocol stack.|
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p1174183145516"><a name="p1174183145516"></a><a name="p1174183145516"></a>Number of normal packets received at the IP layer.</p> | TX&nbsp;dropped | Number of packets that the MAC layer discards due to delivery failures, for example, the NIC driver fails to process the packets.|
</td> | TX&nbsp;overrun | Not used currently.|
</tr> | TX&nbsp;bytes | Total length of the packets successfully sent or forwarded at the IP layer.|
<tr id="row209212315518"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p274938554"><a name="p274938554"></a><a name="p274938554"></a>RX error</p>
</td> - Example 3: Set an IPv6 address.
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p1274133195513"><a name="p1274133195513"></a><a name="p1274133195513"></a>Number of error packets received at the IP layer. The errors include the length error, verification error, IP option error, and IP header protocol error.</p>
</td>
</tr>
<tr id="row692832556"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p474234551"><a name="p474234551"></a><a name="p474234551"></a>RX dropped</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p13741637551"><a name="p13741637551"></a><a name="p13741637551"></a>Number of packets discarded at the IP layer. Packets are discarded due to packet errors, packet forwarding failures, and disabled local NICs.</p>
</td>
</tr>
<tr id="row199215312556"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p1674530552"><a name="p1674530552"></a><a name="p1674530552"></a>RX overrun</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p17742305517"><a name="p17742305517"></a><a name="p17742305517"></a>Number of packets that the MAC layer fails to deliver to the upper-layer protocol stack. The failure is caused by resource insufficiency at the protocol stack.</p>
</td>
</tr>
<tr id="row69193145519"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p157417310551"><a name="p157417310551"></a><a name="p157417310551"></a>RX bytes</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p9741385519"><a name="p9741385519"></a><a name="p9741385519"></a>Total length of normal packets received at the IP layer, excluding the length of the fragments that are not reassembled.</p>
</td>
</tr>
<tr id="row091333559"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p1741336554"><a name="p1741336554"></a><a name="p1741336554"></a>TX packets</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p19745375513"><a name="p19745375513"></a><a name="p19745375513"></a>Number of packets that have been normally sent or forwarded at the IP layer.</p>
</td>
</tr>
<tr id="row5914345515"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p147443125513"><a name="p147443125513"></a><a name="p147443125513"></a>TX error</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p9756312553"><a name="p9756312553"></a><a name="p9756312553"></a>Number of packets that the IP layer fails to send. Packets may fail to be sent because the packets cannot be routed or the packets fail to be processed in the protocol stack.</p>
</td>
</tr>
<tr id="row7911032557"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p13752316555"><a name="p13752316555"></a><a name="p13752316555"></a>TX dropped</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p87519395520"><a name="p87519395520"></a><a name="p87519395520"></a>Number of packets that the MAC layer discards due to delivery failures, for example, the NIC driver fails to process the packets.</p>
</td>
</tr>
<tr id="row9901345510"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p27523205513"><a name="p27523205513"></a><a name="p27523205513"></a>TX overrun</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p107512325514"><a name="p107512325514"></a><a name="p107512325514"></a>Reserved.</p>
</td>
</tr>
<tr id="row39016318552"><td class="cellrowborder" valign="top" width="28.999999999999996%" headers="mcps1.2.3.1.1 "><p id="p1475933554"><a name="p1475933554"></a><a name="p1475933554"></a>TX bytes</p>
</td>
<td class="cellrowborder" valign="top" width="71%" headers="mcps1.2.3.1.2 "><p id="p7759375512"><a name="p7759375512"></a><a name="p7759375512"></a>Total length of the packets successfully sent or forwarded at the IP layer.</p>
</td>
</tr>
</tbody>
</table>
- Example 3: setting an IPv6 address
``` ```
OHOS:/$ ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d OHOS:/$ ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d
...@@ -297,7 +143,7 @@ option: ...@@ -297,7 +143,7 @@ option:
HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP
``` ```
- Example 4: deleting an IPv6 address - Example 4: Delete an IPv6 address.
``` ```
OHOS:/$ ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d OHOS:/$ ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d
...@@ -309,5 +155,3 @@ option: ...@@ -309,5 +155,3 @@ option:
eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1
HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP
``` ```
# ipdebug # ipdebug
## Command Function<a name="section10191115553720"></a> ## Command Function
**ipdebug** is a console command and is used for IPv6 debugging. It can display IPv6 address prefixes, neighbor entries, destination entries, and default route entries. **ipdebug** is a console command and is used for IPv6 debugging. It can display IPv6 address prefixes, neighbor entries, destination entries, and default route entries.
## Syntax<a name="section124061758123713"></a>
## Syntax
ipdebug ipdebug
## Example<a name="section171837113810"></a>
## Example
Run the **ipdebug** command. Run the **ipdebug** command.
## Output<a name="section561416467104"></a>
## Output
**ipdebug** command output: **ipdebug** command output:
...@@ -52,4 +55,3 @@ FE80::4639:C4FF:FE94:5D44 FE80::4639:C4FF:FE94:5D44 pmtu 1500 age 6 ...@@ -52,4 +55,3 @@ FE80::4639:C4FF:FE94:5D44 FE80::4639:C4FF:FE94:5D44 pmtu 1500 age 6
FE80::4639:C4FF:FE94:5D44 invalidation_timer 1784 flags 0 FE80::4639:C4FF:FE94:5D44 invalidation_timer 1784 flags 0
-------------------------------------------------------------------- --------------------------------------------------------------------
``` ```
# netstat # netstat
## Command Function<a name="section13469162113816"></a> ## Command Function
The **netstat** command is a console command and is used for monitoring the TCP/IP network. It can display the actual network connections and the status of each network interface device. This command displays statistics related to TCP and UDP and can be used to check the network connection to each port on the device \(board\). The **netstat** command is a console command and is used for monitoring the TCP/IP network. It can display the actual network connections and the status of each network interface device. This command displays statistics related to TCP and UDP connections and can be used to check the network connection to each port on a device (board).
## Syntax<a name="section795712373812"></a>
## Syntax
netstat netstat
## Parameters<a name="section17629431193817"></a>
None ## Parameters
## Usage<a name="section5277153519380"></a> None.
netstat
## Example<a name="section108141437163820"></a> ## Usage Guidelines
None.
## Note
Currently, the shell does not support this command.
## Example
Run **netstat**. Run **netstat**.
## Output<a name="section1357015107117"></a>
**netstat** print information ## Output
**netstat** output information:
``` ```
OHOS # netstat OHOS # netstat
...@@ -43,48 +51,14 @@ udp 0 0 127.0.0.1:62178 127.0.0.1:62177 ...@@ -43,48 +51,14 @@ udp 0 0 127.0.0.1:62178 127.0.0.1:62177
**Table 1** Output description **Table 1** Output description
<a name="table2526mcpsimp"></a> | Parameter | Description |
<table><thead align="left"><tr id="row2531mcpsimp"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p2533mcpsimp"><a name="p2533mcpsimp"></a><a name="p2533mcpsimp"></a>Parameter</p> | -------------------- | ------------------------------------------------------------ |
</th> | Proto | Protocol type. |
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p2535mcpsimp"><a name="p2535mcpsimp"></a><a name="p2535mcpsimp"></a>Description</p> | Recv-Q | Amount of data that is not read by the user.<br>For Listen TCP, the value indicates the number of TCP connections that have finished the three-way handshake but are not accepted by users. |
</th> | Send-Q | For a TCP connection, this value indicates the amount of data that has been sent but not acknowledged.<br>For a UDP connection, this value indicates the amount of data buffered before IP address resolution is complete.|
</tr> | Local&nbsp;Address | Local IP address and port number. |
</thead> | Foreign&nbsp;Address | Remote IP address and port number. |
<tbody><tr id="row2536mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2538mcpsimp"><a name="p2538mcpsimp"></a><a name="p2538mcpsimp"></a>Proto</p> | State | TCP connection status. This parameter is meaningless for UDP. |
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2540mcpsimp"><a name="p2540mcpsimp"></a><a name="p2540mcpsimp"></a>Protocol type.</p> > **NOTE**<br>
</td> > The command output like "========== total sockets 32 ====== unused sockets 22 BootTime 27 s ==========" indicates that there are 32 sockets in total, 22 sockets are not used, and it has been 27 seconds since the system starts.
</tr>
<tr id="row2546mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2548mcpsimp"><a name="p2548mcpsimp"></a><a name="p2548mcpsimp"></a>Recv-Q</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2550mcpsimp"><a name="p2550mcpsimp"></a><a name="p2550mcpsimp"></a>Amount of data that is not read by the user.</p>
<p id="p2551mcpsimp"><a name="p2551mcpsimp"></a><a name="p2551mcpsimp"></a>For Listen TCP, the value indicates the number of TCP connections that have finished three-way handshake but are not accepted by users.</p>
</td>
</tr>
<tr id="row2553mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2555mcpsimp"><a name="p2555mcpsimp"></a><a name="p2555mcpsimp"></a>Send-Q</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1250715415473"><a name="p1250715415473"></a><a name="p1250715415473"></a>For a TCP connection, this value indicates the amount of data that has been sent but not acknowledged.</p>
<p id="p1080412214470"><a name="p1080412214470"></a><a name="p1080412214470"></a>For a UDP connection, this value indicates the amount of data buffered before IP address resolution is complete.</p>
</td>
</tr>
<tr id="row2558mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2560mcpsimp"><a name="p2560mcpsimp"></a><a name="p2560mcpsimp"></a>Local Address</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2562mcpsimp"><a name="p2562mcpsimp"></a><a name="p2562mcpsimp"></a>Local IP address and port number.</p>
</td>
</tr>
<tr id="row2563mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2565mcpsimp"><a name="p2565mcpsimp"></a><a name="p2565mcpsimp"></a>Foreign Address</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2567mcpsimp"><a name="p2567mcpsimp"></a><a name="p2567mcpsimp"></a>Remote IP address and port number.</p>
</td>
</tr>
<tr id="row2568mcpsimp"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p2570mcpsimp"><a name="p2570mcpsimp"></a><a name="p2570mcpsimp"></a>State</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p2572mcpsimp"><a name="p2572mcpsimp"></a><a name="p2572mcpsimp"></a>TCP connection status. This parameter is meaningless for UDP.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>The command output like "========== total sockets 32 ====== unused sockets 22 BootTime 27 s ==========" indicates that there are 32 sockets in total, 22 sockets are not used, and it has been 27 seconds since the system starts.
# ntpdate # ntpdate
## Command Function<a name="section38494293815"></a> ## Command Function
This command is used to synchronize system time from the server. This command is used to synchronize system time from the server.
## Syntax<a name="section5503114413387"></a>
ntpdate \[_SERVER\_IP1_\] \[_SERVER\_IP2_\]... ## Syntax
## Parameters<a name="section136934472383"></a> ntpdate [_SERVER_IP1_] [_SERVER_IP2_]...
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table2616mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row2622mcpsimp"><th class="cellrowborder" valign="top" width="20.79%" id="mcps1.2.4.1.1"><p id="p2624mcpsimp"><a name="p2624mcpsimp"></a><a name="p2624mcpsimp"></a><strong id="b156978804711722"><a name="b156978804711722"></a><a name="b156978804711722"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | SERVER_IP | Specifies the IP address of the NTP server.| N/A |
<th class="cellrowborder" valign="top" width="52.480000000000004%" id="mcps1.2.4.1.2"><p id="p2626mcpsimp"><a name="p2626mcpsimp"></a><a name="p2626mcpsimp"></a><strong id="b53501572310"><a name="b53501572310"></a><a name="b53501572310"></a>Description</strong></p>
</th>
<th class="cellrowborder" valign="top" width="26.729999999999997%" id="mcps1.2.4.1.3"><p id="p2628mcpsimp"><a name="p2628mcpsimp"></a><a name="p2628mcpsimp"></a><strong id="b88462564511722"><a name="b88462564511722"></a><a name="b88462564511722"></a>Value Range</strong></p> ## Usage Guidelines
</th>
</tr> Run the **ntpdate [_SERVER_IP1_] [_SERVER_IP2_]...** command to obtain and display the time of the first server with a valid IP address.
</thead>
<tbody><tr id="row2629mcpsimp"><td class="cellrowborder" valign="top" width="20.79%" headers="mcps1.2.4.1.1 "><p id="p2631mcpsimp"><a name="p2631mcpsimp"></a><a name="p2631mcpsimp"></a>SERVER_IP</p>
</td> ## Example
<td class="cellrowborder" valign="top" width="52.480000000000004%" headers="mcps1.2.4.1.2 "><p id="p2633mcpsimp"><a name="p2633mcpsimp"></a><a name="p2633mcpsimp"></a>Specifies the IP address of the NTP server.</p>
</td>
<td class="cellrowborder" valign="top" width="26.729999999999997%" headers="mcps1.2.4.1.3 "><p id="entry2634mcpsimpp0"><a name="entry2634mcpsimpp0"></a><a name="entry2634mcpsimpp0"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section121401651173816"></a>
Run the **ntpdate **\[_SERVER\_IP1_\] \[_SERVER\_IP2_\]... command. **ntpdate** obtains and displays the time of the first server with a valid IP address.
## Example<a name="section3431554203811"></a>
Run **ntpdate 192.168.1.3 **to update the system time. Run **ntpdate 192.168.1.3 **to update the system time.
## Output<a name="section18638194610115"></a>
## Output
``` ```
OHOS # ntpdate 192.168.1.3 OHOS # ntpdate 192.168.1.3
time server 192.168.1.3: Mon Jun 13 09:24:25 2016 time server 192.168.1.3: Mon Jun 13 09:24:25 2016
``` ```
If the time zone of the board is different from that of the server, the displayed time may be several hours different from the obtained server time. If the time zone of the board is different from that of the server, the displayed time may be several hours different from the server time obtained.
# ping # ping
## Command Function<a name="section119672573385"></a> ## Command Function
This command is used to test an IPv4 connection. This command is used to test an IPv4 connection.
## Syntax<a name="section869419010390"></a>
ping _\[-4\] \[-c cnt\] \[-f\] \[-i interval\] \[-q\] \[-s size\] <IP\>_ ## Syntax
## Parameters<a name="section9877183173918"></a> ping *[-4] [-c cnt] [-f] [-i interval] [-q] [-s size] &lt;IP&gt;*
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table2664mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row2670mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p2672mcpsimp"><a name="p2672mcpsimp"></a><a name="p2672mcpsimp"></a><strong id="b8570451611622"><a name="b8570451611622"></a><a name="b8570451611622"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | --help | Displays the parameters supported by the **ping** command.| N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p2674mcpsimp"><a name="p2674mcpsimp"></a><a name="p2674mcpsimp"></a><strong id="b18214141162620"><a name="b18214141162620"></a><a name="b18214141162620"></a>Description</strong></p> | -4 | Forcibly pings the destination address using the IPv4 protocol.| 0-65500 |
</th> | -c&nbsp;CNT | Specifies the number of execution times. The default value is **3**.| 1-65535 |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p2676mcpsimp"><a name="p2676mcpsimp"></a><a name="p2676mcpsimp"></a><strong id="b54224635611622"><a name="b54224635611622"></a><a name="b54224635611622"></a>Value Range</strong></p> | -f | Pings an IPv4 address in implicit mode. The default parameter configuration is equivalent to **-c 15 -i 0.2**.| N/A |
</th> | -i&nbsp;interval | Specifies the interval (in ms) for sending a ping packet.| 1-200 |
</tr> | -q | Implicitly pings an IPv4 address. If the host is still alive, the ping stops after **true** is returned.| N/A |
</thead> | -s&nbsp;SIZE | Specifies the size of a ping packet, in bytes. The default size is **56** bytes.| 0-4088 |
<tbody><tr id="row02916415585"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1028111418588"><a name="p1028111418588"></a><a name="p1028111418588"></a>--help</p> | IP | Specifies the IPv4 address of the network to test.| N/A |
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p122810445818"><a name="p122810445818"></a><a name="p122810445818"></a>Displays the parameters supported by the <strong id="b1796144112279"><a name="b1796144112279"></a><a name="b1796144112279"></a>ping</strong> command.</p>
</td> ## Usage Guidelines
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1028118410584"><a name="p1028118410584"></a><a name="p1028118410584"></a>N/A</p>
</td>
</tr>
<tr id="row15291104105819"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p3281747588"><a name="p3281747588"></a><a name="p3281747588"></a>-4</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p16281846585"><a name="p16281846585"></a><a name="p16281846585"></a>Forcibly pings the destination address using the IPv4 protocol.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p202811548588"><a name="p202811548588"></a><a name="p202811548588"></a>0-65500</p>
</td>
</tr>
<tr id="row82911540582"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p18281646583"><a name="p18281646583"></a><a name="p18281646583"></a>-c CNT</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p1281248583"><a name="p1281248583"></a><a name="p1281248583"></a>Specifies the number of execution times. The default value is <strong id="b209506262288"><a name="b209506262288"></a><a name="b209506262288"></a>3</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p528111412581"><a name="p528111412581"></a><a name="p528111412581"></a>1-65535</p>
</td>
</tr>
<tr id="row112911545588"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p1028154135811"><a name="p1028154135811"></a><a name="p1028154135811"></a>-f</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p22811642583"><a name="p22811642583"></a><a name="p22811642583"></a>Pings an IPv4 address in implicit mode. The default parameter configuration is equivalent to <strong id="b12261222102915"><a name="b12261222102915"></a><a name="b12261222102915"></a>-c 15 -i 0.2</strong>.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p628118425815"><a name="p628118425815"></a><a name="p628118425815"></a>N/A</p>
</td>
</tr>
<tr id="row192917495812"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p02811416589"><a name="p02811416589"></a><a name="p02811416589"></a>-i interval</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p15281184125813"><a name="p15281184125813"></a><a name="p15281184125813"></a>Specifies the interval (in ms) for sending a ping packet.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p5281144195811"><a name="p5281144195811"></a><a name="p5281144195811"></a>1-200</p>
</td>
</tr>
<tr id="row182911647586"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p17281840587"><a name="p17281840587"></a><a name="p17281840587"></a>-q</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p13281124155815"><a name="p13281124155815"></a><a name="p13281124155815"></a>Implicitly pings an IPv4 address. If the host is active, the ping stops after <strong id="b3813112783011"><a name="b3813112783011"></a><a name="b3813112783011"></a>true</strong> is received.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p182811240582"><a name="p182811240582"></a><a name="p182811240582"></a>N/A</p>
</td>
</tr>
<tr id="row92900485818"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p5281124125815"><a name="p5281124125815"></a><a name="p5281124125815"></a>-s SIZE</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p12281154165819"><a name="p12281154165819"></a><a name="p12281154165819"></a>Specifies the size of a ping packet, in bytes. The default size is <strong id="b145002224316"><a name="b145002224316"></a><a name="b145002224316"></a>56</strong> bytes.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p13281341582"><a name="p13281341582"></a><a name="p13281341582"></a>0-4088</p>
</td>
</tr>
<tr id="row1529016465815"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p202818413586"><a name="p202818413586"></a><a name="p202818413586"></a>IP</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p4282545588"><a name="p4282545588"></a><a name="p4282545588"></a>Specifies the IPv4 address to test.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p1928284155810"><a name="p1928284155810"></a><a name="p1928284155810"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section1097046193914"></a>
- The **ping** command is used to check whether the destination IP address is reachable. - The **ping** command is used to check whether the destination IP address is reachable.
- If the destination IP address is unreachable, the system displays a message indicating that the request times out. - If the destination IP address is unreachable, the system displays a message indicating that the request times out.
- If no route is available to the destination IP address, an error message is displayed. - If no route is available to the destination IP address, an error message is displayed.
- This command can be used only after the TCP/IP stack is enabled.
## Example<a name="section14564129113911"></a> - This command can be used only after the TCP/IP protocol stack is enabled.
## Example
Run **ping 192.168.1.3**. Run **ping 192.168.1.3**.
## Output<a name="section1621732891215"></a>
Pinging a TFTP server IP address: ## Output
Ping a TFTP server IP address.
``` ```
OHOS:/$ ping 192.168.1.3 OHOS:/$ ping 192.168.1.3
...@@ -106,4 +57,3 @@ Ping 192.168.1.3 (192.168.1.3): 56(84) bytes. ...@@ -106,4 +57,3 @@ Ping 192.168.1.3 (192.168.1.3): 56(84) bytes.
3 packets transmitted, 3 received, 0% packet loss 3 packets transmitted, 3 received, 0% packet loss
round-trip min/avg/max = 0/0/0 ms round-trip min/avg/max = 0/0/0 ms
``` ```
# ping6 # ping6
## Command Function<a name="section1057291313393"></a> ## Command Function
This command is used to test an IPv6 network connection. This command is used to test an IPv6 network connection.
## Syntax<a name="section199901315123919"></a>
ping6 _\[-c count\] \[-I interface / sourceAddress\] destination_ ## Syntax
## Parameters<a name="section4679319113919"></a> ping6 *[-c count] [-I interface / sourceAddress] destination*
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table2742mcpsimp"></a> | Parameter | Description | Value Range|
<table><thead align="left"><tr id="row2748mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p2750mcpsimp"><a name="p2750mcpsimp"></a><a name="p2750mcpsimp"></a><strong id="b9059409211170"><a name="b9059409211170"></a><a name="b9059409211170"></a>Parameter</strong></p> | --------------------- | ----------------------------------- | -------- |
</th> | -c&nbsp;count | Specifies the number of execution times. If this parameter is not specified, the default value is **4**.| [1, 65535] |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p2752mcpsimp"><a name="p2752mcpsimp"></a><a name="p2752mcpsimp"></a><strong id="b189621522143614"><a name="b189621522143614"></a><a name="b189621522143614"></a>Description</strong></p> | -I&nbsp;interface | Specifies the NIC for performing the ping operation. | N/A |
</th> | -I&nbsp;sourceAddress | Specifies the source IPv6 address. | N/A |
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p2754mcpsimp"><a name="p2754mcpsimp"></a><a name="p2754mcpsimp"></a><strong id="b1322365521170"><a name="b1322365521170"></a><a name="b1322365521170"></a>Value Range</strong></p> | destination | Specifies the IP address of the destination host. | N/A |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row2755mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p2757mcpsimp"><a name="p2757mcpsimp"></a><a name="p2757mcpsimp"></a>-c count</p>
</td> - If the destination IPv6 address is unreachable, "Request Timed Out" will be displayed.
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2759mcpsimp"><a name="p2759mcpsimp"></a><a name="p2759mcpsimp"></a>Specifies the number of execution times. If this parameter is not specified, the default value is <strong id="b1769545815488"><a name="b1769545815488"></a><a name="b1769545815488"></a>4</strong>.</p>
</td> - If no route is available to the destination IPv6 address, "Destinatin Host Unreachable" will be displayed.
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2761mcpsimp"><a name="p2761mcpsimp"></a><a name="p2761mcpsimp"></a>1~65535</p>
</td> - This command can be used only after the TCP/IP stack is enabled.
</tr>
<tr id="row2762mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p2764mcpsimp"><a name="p2764mcpsimp"></a><a name="p2764mcpsimp"></a>-I interface</p> ## Note
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2766mcpsimp"><a name="p2766mcpsimp"></a><a name="p2766mcpsimp"></a>Performs an IPv6 ping operation for a specified NIC.</p> Currently, the shell does not support this command.
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2768mcpsimp"><a name="p2768mcpsimp"></a><a name="p2768mcpsimp"></a>N/A</p> ## Example
</td>
</tr>
<tr id="row2769mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p2771mcpsimp"><a name="p2771mcpsimp"></a><a name="p2771mcpsimp"></a>-I sourceAddress</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2773mcpsimp"><a name="p2773mcpsimp"></a><a name="p2773mcpsimp"></a>Specifies the source IPv6 address.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2775mcpsimp"><a name="p2775mcpsimp"></a><a name="p2775mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row84173618410"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p141163619410"><a name="p141163619410"></a><a name="p141163619410"></a>destination</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p134111362417"><a name="p134111362417"></a><a name="p134111362417"></a>Specifies the IP address of the destination host.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p134173611412"><a name="p134173611412"></a><a name="p134173611412"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section1127917226399"></a>
- If the destination IPv6 address is unreachable, the system displays a message indicating that the request times out.
- If no route is available to the destination IPv6 address, an error message is displayed.
- This command can be used only after the TCP/IP protocol stack is enabled.
## Example<a name="section7211192553917"></a>
- ping6 2001:a:b:c:d:e:f:b - ping6 2001:a:b:c:d:e:f:b
- ping6 -c 3 2001:a:b:c:d:e:f:b - ping6 -c 3 2001:a:b:c:d:e:f:b
- ping6 -I eth0 2001:a:b:c:d:e:f:b - ping6 -I eth0 2001:a:b:c:d:e:f:b
- ping6 -I 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b - ping6 -I 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b
## Output<a name="section4846145221215"></a>
## Output
1. Output of **ping6 2001:a:b:c:d:e:f:b**: 1. Output of **ping6 2001:a:b:c:d:e:f:b**:
...@@ -116,5 +96,3 @@ ping6 _\[-c count\] \[-I interface / sourceAddress\] destination_ ...@@ -116,5 +96,3 @@ ping6 _\[-c count\] \[-I interface / sourceAddress\] destination_
--- 2001:a:b:c:d:e:f:b/64 ping statistics --- --- 2001:a:b:c:d:e:f:b/64 ping statistics ---
4 packets transmitted, 4 received, 0.00% packet loss, time 20msrtt min/avg/max = 0/0.00/0 ms 4 packets transmitted, 4 received, 0.00% packet loss, time 20msrtt min/avg/max = 0/0.00/0 ms
``` ```
# telnet # telnet
## Command Function<a name="section3551830123913"></a> ## Command Function
This command is used to enable or disable the Telnet server service. This command is used to enable or disable the Telnet server service.
## Syntax<a name="section14897133233918"></a>
telnet \[_on | off_\] ## Syntax
## Parameters<a name="section977718353392"></a> telnet [_on | off_]
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table2844mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row2850mcpsimp"><th class="cellrowborder" valign="top" width="21%" id="mcps1.2.4.1.1"><p id="p2852mcpsimp"><a name="p2852mcpsimp"></a><a name="p2852mcpsimp"></a><strong id="b980352831178"><a name="b980352831178"></a><a name="b980352831178"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | on | Enables the telnet server service.| N/A |
<th class="cellrowborder" valign="top" width="52%" id="mcps1.2.4.1.2"><p id="p2854mcpsimp"><a name="p2854mcpsimp"></a><a name="p2854mcpsimp"></a><strong id="b385431525416"><a name="b385431525416"></a><a name="b385431525416"></a>Description</strong></p> | off | Disables the telnet server service.| N/A |
</th>
<th class="cellrowborder" valign="top" width="27%" id="mcps1.2.4.1.3"><p id="p2856mcpsimp"><a name="p2856mcpsimp"></a><a name="p2856mcpsimp"></a><strong id="b19001516841178"><a name="b19001516841178"></a><a name="b19001516841178"></a>Value Range</strong></p>
</th> ## Usage Guidelines
</tr>
</thead>
<tbody><tr id="row2857mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p2859mcpsimp"><a name="p2859mcpsimp"></a><a name="p2859mcpsimp"></a>on</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2861mcpsimp"><a name="p2861mcpsimp"></a><a name="p2861mcpsimp"></a>Enables the Telnet server service.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2863mcpsimp"><a name="p2863mcpsimp"></a><a name="p2863mcpsimp"></a>N/A</p>
</td>
</tr>
<tr id="row2864mcpsimp"><td class="cellrowborder" valign="top" width="21%" headers="mcps1.2.4.1.1 "><p id="p2866mcpsimp"><a name="p2866mcpsimp"></a><a name="p2866mcpsimp"></a>off</p>
</td>
<td class="cellrowborder" valign="top" width="52%" headers="mcps1.2.4.1.2 "><p id="p2868mcpsimp"><a name="p2868mcpsimp"></a><a name="p2868mcpsimp"></a>Disables the Telnet server service.</p>
</td>
<td class="cellrowborder" valign="top" width="27%" headers="mcps1.2.4.1.3 "><p id="p2870mcpsimp"><a name="p2870mcpsimp"></a><a name="p2870mcpsimp"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section134991538183916"></a>
- Before enabling Telnet, ensure that the network driver and network protocol stack have been initialized and the NIC of the board is in the **link up** state. - Before enabling Telnet, ensure that the network driver and network protocol stack have been initialized and the NIC of the board is in the **link up** state.
- Currently, multiple clients \(Telnet + IP\) cannot connect to the development board at the same time.
>![](../public_sys-resources/icon-notice.gif) **NOTICE:** - Currently, multiple clients (Telnet + IP) cannot connect to the development board at the same time.
>Telnet is used for debugging and is disabled by default. Do not use it in formal products. > **NOTICE**<br>
> Telnet is used for debugging and is disabled by default. Do not use it in formal products.
## Example<a name="section1097414426398"></a> ## Example
Run **telnet on**. Run **telnet on**.
## Output<a name="section11846624191310"></a>
## Output
Command output: Command output:
``` ```
OHOS # telnet on OHOS # telnet on
OHOS # start telnet server successfully, waiting for connection. OHOS # start telnet server successfully, waiting for connection.
``` ```
# tftp # tftp
## Command Function<a name="section15142134573911"></a> ## Command Function
Trivial File Transfer Protocol \(TFTP\) is a protocol in the TCP/IP protocol suite for transferring files between clients and servers. TFTP provides simple and low-overhead file transfer services. The port number is 69. Trivial File Transfer Protocol (TFTP) is a protocol in the TCP/IP protocol suite for transferring files between clients and servers. TFTP provides simple and low-overhead file transfer services. The port number is 69.
The **tftp** command is used to transfer files with a TFTP server. The **tftp** command is used to transfer files with a TFTP server.
## Syntax<a name="section20958174917394"></a>
./bin/tftp _<-g/-p\>_ _-l_ _\[FullPathLocalFile\] -r \[RemoteFile\] \[Host\]_ ## Syntax
## Parameters<a name="section576613532395"></a> ./bin/tftp *&lt;-g/-p&gt;**-l**[FullPathLocalFile] -r [RemoteFile] [Host]*
## Parameters
**Table 1** Parameter description **Table 1** Parameter description
<a name="table2894mcpsimp"></a> | Parameter| Description| Value Range|
<table><thead align="left"><tr id="row2900mcpsimp"><th class="cellrowborder" valign="top" width="20.79%" id="mcps1.2.4.1.1"><p id="p2902mcpsimp"><a name="p2902mcpsimp"></a><a name="p2902mcpsimp"></a><strong id="b116998706011737"><a name="b116998706011737"></a><a name="b116998706011737"></a>Parameter</strong></p> | -------- | -------- | -------- |
</th> | -g/-p | Specifies the file transfer direction.<br>- **-g**: obtains a file from the TFTP server.<br>- **-p**: uploads a file to the TFTP server.| N/A |
<th class="cellrowborder" valign="top" width="52.480000000000004%" id="mcps1.2.4.1.2"><p id="p2904mcpsimp"><a name="p2904mcpsimp"></a><a name="p2904mcpsimp"></a><strong id="b13511135745719"><a name="b13511135745719"></a><a name="b13511135745719"></a>Description</strong></p> | -l&nbsp;FullPathLocalFile | Specifies the complete path of a local file.| N/A |
</th> | -r&nbsp;RemoteFile | Specifies the file name on the server.| N/A |
<th class="cellrowborder" valign="top" width="26.729999999999997%" id="mcps1.2.4.1.3"><p id="p2906mcpsimp"><a name="p2906mcpsimp"></a><a name="p2906mcpsimp"></a><strong id="b174218805911737"><a name="b174218805911737"></a><a name="b174218805911737"></a>Value Range</strong></p> | Host | Specifies the server IP address.| N/A |
</th>
</tr>
</thead> ## Usage Guidelines
<tbody><tr id="row2907mcpsimp"><td class="cellrowborder" valign="top" width="20.79%" headers="mcps1.2.4.1.1 "><p id="p2909mcpsimp"><a name="p2909mcpsimp"></a><a name="p2909mcpsimp"></a>-g/-p</p>
</td>
<td class="cellrowborder" valign="top" width="52.480000000000004%" headers="mcps1.2.4.1.2 "><p id="p2911mcpsimp"><a name="p2911mcpsimp"></a><a name="p2911mcpsimp"></a>Specifies the file transfer direction.</p>
<a name="ul73571240131312"></a><a name="ul73571240131312"></a><ul id="ul73571240131312"><li><strong id="b0778214125818"><a name="b0778214125818"></a><a name="b0778214125818"></a>-g</strong>: downloads files from the TFTP server.</li><li><strong id="b7168132555814"><a name="b7168132555814"></a><a name="b7168132555814"></a>-p</strong>: uploads files to the TFTP server.</li></ul>
</td>
<td class="cellrowborder" valign="top" width="26.729999999999997%" headers="mcps1.2.4.1.3 "><p id="p14399194271310"><a name="p14399194271310"></a><a name="p14399194271310"></a>N/A</p>
</td>
</tr>
<tr id="row2921mcpsimp"><td class="cellrowborder" valign="top" width="20.79%" headers="mcps1.2.4.1.1 "><p id="p2923mcpsimp"><a name="p2923mcpsimp"></a><a name="p2923mcpsimp"></a>-l FullPathLocalFile</p>
</td>
<td class="cellrowborder" valign="top" width="52.480000000000004%" headers="mcps1.2.4.1.2 "><p id="p2925mcpsimp"><a name="p2925mcpsimp"></a><a name="p2925mcpsimp"></a>Specifies the complete path of a local file.</p>
</td>
<td class="cellrowborder" valign="top" width="26.729999999999997%" headers="mcps1.2.4.1.3 "><p id="entry2926mcpsimpp0"><a name="entry2926mcpsimpp0"></a><a name="entry2926mcpsimpp0"></a>N/A</p>
</td>
</tr>
<tr id="row2927mcpsimp"><td class="cellrowborder" valign="top" width="20.79%" headers="mcps1.2.4.1.1 "><p id="p2929mcpsimp"><a name="p2929mcpsimp"></a><a name="p2929mcpsimp"></a>-r RemoteFile</p>
</td>
<td class="cellrowborder" valign="top" width="52.480000000000004%" headers="mcps1.2.4.1.2 "><p id="p2931mcpsimp"><a name="p2931mcpsimp"></a><a name="p2931mcpsimp"></a>Specifies the file name on the server.</p>
</td>
<td class="cellrowborder" valign="top" width="26.729999999999997%" headers="mcps1.2.4.1.3 "><p id="entry2932mcpsimpp0"><a name="entry2932mcpsimpp0"></a><a name="entry2932mcpsimpp0"></a>N/A</p>
</td>
</tr>
<tr id="row2933mcpsimp"><td class="cellrowborder" valign="top" width="20.79%" headers="mcps1.2.4.1.1 "><p id="p2935mcpsimp"><a name="p2935mcpsimp"></a><a name="p2935mcpsimp"></a>Host</p>
</td>
<td class="cellrowborder" valign="top" width="52.480000000000004%" headers="mcps1.2.4.1.2 "><p id="p2937mcpsimp"><a name="p2937mcpsimp"></a><a name="p2937mcpsimp"></a>Specifies the server IP address.</p>
</td>
<td class="cellrowborder" valign="top" width="26.729999999999997%" headers="mcps1.2.4.1.3 "><p id="entry2938mcpsimpp0"><a name="entry2938mcpsimpp0"></a><a name="entry2938mcpsimpp0"></a>N/A</p>
</td>
</tr>
</tbody>
</table>
## Usage<a name="section149795134408"></a>
1. Deploy a TFTP server on the server and configure the TFTP server correctly. 1. Deploy a TFTP server on the server and configure the TFTP server correctly.
2. Use the **tftp** command to upload and download files on the OpenHarmony board.
3. The size of the file to be transferred cannot exceed 32 MB.
>![](../public_sys-resources/icon-notice.gif) **NOTICE:** 2. Use the **tftp** command to upload files from or download files to an OpenHarmony board.
>TFTP is used for debugging and disabled by default. Do not use it in formal products.
3. The size of the file to be transferred cannot exceed 32 MB.
> **NOTICE**<br>
> TFTP is used for debugging and disabled by default. Do not use it in formal products.
## Example<a name="section148921918114015"></a> ## Example
Download the **out** file from the server. Download the **out** file from the server.
## Output<a name="section7872155631313"></a>
## Output
``` ```
OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2 OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2
...@@ -78,4 +50,3 @@ TFTP transfer finish ...@@ -78,4 +50,3 @@ TFTP transfer finish
``` ```
After the **tftp** command is executed, **TFTP transfer finish** is displayed if the file transfer is complete. If the file transfer fails, other information is displayed to help locate the fault. After the **tftp** command is executed, **TFTP transfer finish** is displayed if the file transfer is complete. If the file transfer fails, other information is displayed to help locate the fault.
...@@ -28,20 +28,18 @@ The online mode must be used with the integrated development environment (IDE). ...@@ -28,20 +28,18 @@ The online mode must be used with the integrated development environment (IDE).
The trace module of the OpenHarmony LiteOS-A kernel provides the following APIs. For more details, see [API reference](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h). The trace module of the OpenHarmony LiteOS-A kernel provides the following APIs. For more details, see [API reference](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h).
**Table 1** APIs of the trace module **Table 1** APIs of the trace module
| Category| Description| | Category| Description|
| -------- | -------- | | -------- | -------- |
| Starting/Stopping trace| **LOS_TraceStart**: starts trace.<br>**LOS_TraceStop**: stops trace. | | Starting/Stopping trace| **LOS_TraceStart**: starts trace.<br>**LOS_TraceStop**: stops trace.|
| Managing trace records| **LOS_TraceRecordDump**: dumps data from the trace buffer.<br>**LOS_TraceRecordGet**: obtains the start address of the trace buffer.<br>**LOS_TraceReset**: clears events in the trace buffer. | | Managing trace records| **LOS_TraceRecordDump**: dumps data from the trace buffer.<br>**LOS_TraceRecordGet**: obtains the start address of the trace buffer.<br>**LOS_TraceReset**: clears events in the trace buffer.|
| Filtering trace records| **LOS_TraceEventMaskSet**: sets the event mask to trace only events of the specified modules.| | Filtering trace records| **LOS_TraceEventMaskSet**: sets the event mask to trace only events of the specified modules.|
| Masking events of specified interrupt IDs| **LOS_TraceHwiFilterHookReg**: registers a hook to filter out events of specified interrupt IDs.| | Masking events of specified interrupt IDs| **LOS_TraceHwiFilterHookReg**: registers a hook to filter out events of specified interrupt IDs.|
| Performing function instrumentation| **LOS_TRACE_EASY**: performs simple instrumentation.<br>**LOS_TRACE**: performs standard instrumentation. | | Performing function instrumentation| **LOS_TRACE_EASY**: performs simple instrumentation.<br>**LOS_TRACE**: performs standard instrumentation.|
You can perform function instrumentation in the source code to trace specific events. The system provides the following APIs for instrumentation:
- **LOS_TRACE_EASY(TYPE, IDENTITY, params...)** for simple instrumentation
- You can perform function instrumentation in the source code to trace specific events. The system provides the following APIs for instrumentation:
- **LOS_TRACE_EASY(TYPE, IDENTITY, params...)** for simple instrumentation
- You only need to insert this API into the source code. - You only need to insert this API into the source code.
- **TYPE** specifies the event type. The value range is 0 to 0xF. The meaning of each value is user-defined. - **TYPE** specifies the event type. The value range is 0 to 0xF. The meaning of each value is user-defined.
- **IDENTITY** specifies the object of the event operation. The value is of the **UIntPtr** type. - **IDENTITY** specifies the object of the event operation. The value is of the **UIntPtr** type.
...@@ -60,7 +58,7 @@ You can perform function instrumentation in the source code to trace specific ev ...@@ -60,7 +58,7 @@ You can perform function instrumentation in the source code to trace specific ev
Insert the following in the position where the fd2 file is written: Insert the following in the position where the fd2 file is written:
LOS_TRACE_EASY(2, fd2, flag, size); LOS_TRACE_EASY(2, fd2, flag, size);
``` ```
- **LOS_TRACE(TYPE, IDENTITY, params...)** for standard instrumentation. - **LOS_TRACE(TYPE, IDENTITY, params...)** for standard instrumentation.
- Compared with simple instrumentation, standard instrumentation supports dynamic event filtering and parameter tailoring. However, you need to extend the functions based on rules. - Compared with simple instrumentation, standard instrumentation supports dynamic event filtering and parameter tailoring. However, you need to extend the functions based on rules.
- **TYPE** specifies the event type. You can define the event type in **enum LOS_TRACE_TYPE** in the header file **los_trace.h**. For details about methods and rules for defining events, see other event types. - **TYPE** specifies the event type. You can define the event type in **enum LOS_TRACE_TYPE** in the header file **los_trace.h**. For details about methods and rules for defining events, see other event types.
- The **IDENTITY** and **Params** are the same as those of simple instrumentation. - The **IDENTITY** and **Params** are the same as those of simple instrumentation.
...@@ -86,34 +84,33 @@ You can perform function instrumentation in the source code to trace specific ev ...@@ -86,34 +84,33 @@ You can perform function instrumentation in the source code to trace specific ev
4. Insert a code stub in a proper position. 4. Insert a code stub in a proper position.
Format: LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...)) Format: LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...))
LOS_TRACE(FS_READ, fp, fd, flag, size); // Code stub for reading files. LOS_TRACE(FS_READ, fp, fd, flag, size); // Code stub for reading files.
The parameters following #TYPE# are the input parameter of the **FS_READ_PARAMS** function in step 3. #The parameters following #TYPE# are the input parameter of the **FS_READ_PARAMS** function in step 3.
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > **NOTE**<br>
> The trace event types and parameters can be modified as required. For details about the parameters, see **kernel\include\los_trace.h**. > The preset trace events and parameters can be tailored in the same way. For details about the parameters, see [kernel\include\los_trace.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h).
For **LOS_TraceEventMaskSet(UINT32 mask)**, only the most significant 28 bits (corresponding to the enable bit of the module in **LOS_TRACE_MASK**) of the mask take effect and are used only for module-based tracing. Currently, fine-grained event-based tracing is not supported. For example, in **LOS_TraceEventMaskSet(0x202)**, the effective mask is **0x200 (TRACE_QUE_FLAG)** and all events of the QUE module are collected. The recommended method is **LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG);**.
To enable trace of only simple instrumentation events, set **Trace Mask** to **TRACE_MAX_FLAG**. - For **LOS_TraceEventMaskSet(UINT32 mask)**, only the most significant 28 bits (corresponding to the enable bit of the module in **LOS_TRACE_MASK**) of the mask take effect and are used only for module-based tracing. Currently, fine-grained event-based tracing is not supported. For example, in **LOS_TraceEventMaskSet(0x202)**, the effective mask is **0x200 (TRACE_QUE_FLAG)** and all events of the QUE module are collected. The recommended method is **LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG);**.
The trace buffer has limited capacity. When the trace buffer is full, events will be overwritten. You can use **LOS_TraceRecordDump** to export data from the trace buffer and locate the latest records by **CurEvtIndex**. - To enable trace of only simple instrumentation events, set **Trace Mask** to **TRACE_MAX_FLAG**.
The typical trace operation process includes **LOS_TraceStart**, **LOS_TraceStop**, and **LOS_TraceRecordDump**. - The trace buffer has limited capacity. When the trace buffer is full, events will be overwritten. You can use **LOS_TraceRecordDump** to export data from the trace buffer and locate the latest records by **CurEvtIndex**.
You can filter out interrupt events by interrupt ID to prevent other events from being overwritten due to frequent triggering of a specific interrupt in some scenarios. You can customize interrupt filtering rules. - The typical trace operation process includes **LOS_TraceStart**, **LOS_TraceStop**, and **LOS_TraceRecordDump**.
Example: - You can filter out interrupt events by interrupt ID to prevent other events from being overwritten due to frequent triggering of a specific interrupt in some scenarios. You can customize interrupt filtering rules.
Example:
``` ```c
BOOL Example_HwiNumFilter(UINT32 hwiNum) BOOL Example_HwiNumFilter(UINT32 hwiNum)
{ {
if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) {
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); LOS_TraceHwiFilterHookReg(Example_HwiNumFilter);
``` ```
The interrupt events with interrupt ID of **TIMER_INT** or **DMA_INT** are not traced. The interrupt events with interrupt ID of **TIMER_INT** or **DMA_INT** are not traced.
...@@ -129,7 +126,7 @@ The trace character device is added in **/dev/trace**. You can use **read()**, * ...@@ -129,7 +126,7 @@ The trace character device is added in **/dev/trace**. You can use **read()**, *
- **ioctl()**: performs user-mode trace operations, including: - **ioctl()**: performs user-mode trace operations, including:
``` ```c
#define TRACE_IOC_MAGIC 'T' #define TRACE_IOC_MAGIC 'T'
#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) #define TRACE_START _IO(TRACE_IOC_MAGIC, 1)
#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) #define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2)
...@@ -151,25 +148,24 @@ For details, see [User-Mode Development Example](kernel-small-debug-trace.md#use ...@@ -151,25 +148,24 @@ For details, see [User-Mode Development Example](kernel-small-debug-trace.md#use
The typical trace process is as follows: The typical trace process is as follows:
1. Configure the macro related to the trace module. 1. Configure the macro related to the trace module.
Configure the macro **LOSCFG_KERNEL_TRACE**, which is disabled by default. Run the **make update_config** command in the **kernel/liteos_a** directory, choose **Kernel** > **Enable Hook Feature**, and set **Enable Trace Feature** to **YES**. Configure the macro **LOSCFG_KERNEL_TRACE**, which is disabled by default. Run the **make update_config** command in the **kernel/liteos_a** directory, choose **Kernel** > **Enable Hook Feature**, and set **Enable Trace Feature** to **YES**.
| Configuration Item | menuconfig Option| Description| Value| | Item| menuconfig Option| Description| Value|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| LOSCFG_KERNEL_TRACE | Enable&nbsp;Trace&nbsp;Feature | Specifies whether to enable the trace feature.| YES/NO | | LOSCFG_KERNEL_TRACE | Enable Trace Feature | Specifies whether to enable the trace feature.| YES/NO |
| LOSCFG_RECORDER_MODE_OFFLINE | Trace&nbsp;work&nbsp;mode&nbsp;-&gt;Offline&nbsp;mode | Specifies whether to enable the online trace mode.| YES/NO | | LOSCFG_RECORDER_MODE_OFFLINE | Trace work mode -> Offline mode | Specifies whether to enable the online trace mode.| YES/NO |
| LOSCFG_RECORDER_MODE_ONLINE | Trace&nbsp;work&nbsp;mode&nbsp;-&gt;Online&nbsp;mode | Specifies whether to enable the offline trace mode.| YES/NO | | LOSCFG_RECORDER_MODE_ONLINE | Trace work mode -> Online mode | Specifies whether to enable the offline trace mode.| YES/NO |
| LOSCFG_TRACE_CLIENT_INTERACT | Enable&nbsp;Trace&nbsp;Client&nbsp;Visualization&nbsp;and&nbsp;Control | Enables interaction with Trace IDE (dev tools), including data visualization and process control.| YES/NO | | LOSCFG_TRACE_CLIENT_INTERACT | Enable Trace Client Visualization and Control | Enables interaction with Trace IDE (dev tools), including data visualization and process control.| YES/NO |
| LOSCFG_TRACE_FRAME_CORE_MSG | Enable&nbsp;Record&nbsp;more&nbsp;extended&nbsp;content&nbsp;-<br>&gt;Record&nbsp;cpuid,&nbsp;hardware&nbsp;interrupt<br>&nbsp;status,&nbsp;task&nbsp;lock&nbsp;status | Specifies whether to enable recording of the CPU ID, interruption state, and lock task state.| YES/NO | | LOSCFG_TRACE_FRAME_CORE_MSG | Enable Record more extended content -> Record cpuid, hardware interrupt status, task lock status | Specifies whether to enable recording of the CPU ID, interruption state, and lock task state.| YES/NO |
| LOSCFG_TRACE_FRAME_EVENT_COUNT | Enable&nbsp;Record&nbsp;more&nbsp;extended&nbsp;content<br>&nbsp;-&gt;Record&nbsp;event&nbsp;count,<br>&nbsp;which&nbsp;indicate&nbsp;the&nbsp;sequence&nbsp;of&nbsp;happend&nbsp;events | Specifies whether to enables recording of the event sequence number.| YES/NO | | LOSCFG_TRACE_FRAME_EVENT_COUNT | Enable Record more extended content -> Record event count, which indicate the sequence of happend events | Specifies whether to enables recording of the event sequence number.| YES/NO |
| LOSCFG_TRACE_FRAME_MAX_PARAMS | Record&nbsp;max&nbsp;params | Specifies the maximum number of parameters for event recording.| INT | | LOSCFG_TRACE_FRAME_MAX_PARAMS | Record max params | Specifies the maximum number of parameters for event recording.| INT |
| LOSCFG_TRACE_BUFFER_SIZE | Trace&nbsp;record&nbsp;buffer&nbsp;size | Specifies the trace buffer size.| INT | | LOSCFG_TRACE_BUFFER_SIZE | Trace record buffer size | Specifies the trace buffer size.| INT |
2. (Optional) Preset event parameters and stubs (or use the default event parameter settings and event stubs). 2. (Optional) Preset event parameters and stubs (or use the default event parameter settings and event stubs).
3. (Optional) Call **LOS_TraceStop** to stop trace and call **LOS_TraceReset** to clear the trace buffer. (Trace is started by default.) 3. (Optional) Call **LOS_TraceStop** to stop trace and call **LOS_TraceReset** to clear the trace buffer. (Trace is started by default.)
4. (Optional) Call **LOS_TraceEventMaskSet** to set the event mask for trace (only the interrupts and task events are enabled by default). For details about the event mask, see **LOS_TRACE_MASK** in **los_trace.h**. 4. (Optional) Call **LOS_TraceEventMaskSet** to set the mask of the events to be traced. The default event mask enables only trace of interrupts and task events. For details about the event masks, see **LOS_TRACE_MASK** in [los_trace.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h).
5. Call **LOS_TraceStart** at the start of the code where the event needs to be traced. 5. Call **LOS_TraceStart** at the start of the code where the event needs to be traced.
...@@ -177,7 +173,7 @@ The typical trace process is as follows: ...@@ -177,7 +173,7 @@ The typical trace process is as follows:
7. Call **LOS_TraceRecordDump** to output the data in the buffer. (The input parameter of the function is of the Boolean type. The value **FALSE** means to output data in the specified format, and the value **TRUE** means to output data to Trace IDE.) 7. Call **LOS_TraceRecordDump** to output the data in the buffer. (The input parameter of the function is of the Boolean type. The value **FALSE** means to output data in the specified format, and the value **TRUE** means to output data to Trace IDE.)
The methods in steps 3 to 7 are encapsulated with shell commands. You can run these commands on shell. The mappings between the functions and commands are as follows: The methods in steps 3 to 7 are encapsulated with shell commands. You can run these commands on shell. The mappings between the methods and commands are as follows:
- LOS_TraceReset —— trace_reset - LOS_TraceReset —— trace_reset
...@@ -207,10 +203,12 @@ This example implements the following: ...@@ -207,10 +203,12 @@ This example implements the following:
### Kernel-Mode Sample Code ### Kernel-Mode Sample Code
You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites /kernel /src/osTest.c** for testing.
The sample code is as follows: The sample code is as follows:
``` ```c
#include "los_trace.h" #include "los_trace.h"
UINT32 g_traceTestTaskId; UINT32 g_traceTestTaskId;
VOID Example_Trace(VOID) VOID Example_Trace(VOID)
...@@ -231,18 +229,19 @@ VOID Example_Trace(VOID) ...@@ -231,18 +229,19 @@ VOID Example_Trace(VOID)
LOS_TraceStop(); LOS_TraceStop();
LOS_TraceRecordDump(FALSE); LOS_TraceRecordDump(FALSE);
} }
UINT32 Example_Trace_test(VOID){ UINT32 Example_Trace_test(VOID)
{
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S traceTestTask; TSK_INIT_PARAM_S traceTestTask;
/* Create a trace task. */ /* Create a trace task. */
memset(&traceTestTask, 0, sizeof(TSK_INIT_PARAM_S)); memset(&traceTestTask, 0, sizeof(TSK_INIT_PARAM_S));
traceTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Trace; traceTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Trace;
traceTestTask.pcName = "TestTraceTsk"; /* Test task name. */ traceTestTask.pcName = "TestTraceTsk"; /* Test task name. */
traceTestTask.uwStackSize = 0x800; traceTestTask.uwStackSize = 0x800; // 0x800: trace test task stack size
traceTestTask.usTaskPrio = 5; traceTestTask.usTaskPrio = 5; // 5: trace test task priority
traceTestTask.uwResved = LOS_TASK_STATUS_DETACHED; traceTestTask.uwResved = LOS_TASK_STATUS_DETACHED;
ret = LOS_TaskCreate(&g_traceTestTaskId, &traceTestTask); ret = LOS_TaskCreate(&g_traceTestTaskId, &traceTestTask);
if(ret != LOS_OK){ if (ret != LOS_OK) {
dprintf("TraceTestTask create failed .\n"); dprintf("TraceTestTask create failed .\n");
return LOS_NOK; return LOS_NOK;
} }
...@@ -280,13 +279,13 @@ Index Time(cycles) EventType CurTask Identity params ...@@ -280,13 +279,13 @@ Index Time(cycles) EventType CurTask Identity params
The output event information includes the occurrence time, event type, task in which the event occurs, object of the event operation, and other parameters of the event. The output event information includes the occurrence time, event type, task in which the event occurs, object of the event operation, and other parameters of the event.
- **EventType**: event type. For details, see **enum LOS_TRACE_TYPE** in the header file **los_trace.h**. - **EventType**: type of the event. For details, see **enum LOS_TRACE_TYPE** in [los_trace.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h).
- **CurrentTask**: ID of the running task. - **CurrentTask**: ID of the running task.
- **Identity**: object of the event operation. For details, see **#TYPE#_PARAMS** in the header file **los_trace.h**. - **Identity**: object of the event operation. For details, see **\#TYPE\#_PARAMS** in [los_trace.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h).
- **params**: event parameters. For details, see **#TYPE#_PARAMS** in the header file **los_trace.h**. - **params**: event parameters. For details, see **\#TYPE\#_PARAMS** in [los_trace.h](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h).
The following uses output No. 0 as an example. The following uses output No. 0 as an example.
...@@ -302,14 +301,15 @@ Index Time(cycles) EventType CurTask Identity params ...@@ -302,14 +301,15 @@ Index Time(cycles) EventType CurTask Identity params
- For details about the meanings of **Identity** and **params**, see the **TASK_SWITCH_PARAMS** macro. - For details about the meanings of **Identity** and **params**, see the **TASK_SWITCH_PARAMS** macro.
``` ```c
#define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ #define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \
taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus
``` ```
Because of **#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ...**, **Identity** is **taskId (0x0)** and the first parameter is **oldPriority (0x1f)**. Because of **#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ...**, **Identity** is **taskId (0x0)** and the first parameter is **oldPriority (0x1f)**.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** > **NOTE**
>
> The number of parameters in **params** is specified by **LOSCFG_TRACE_FRAME_MAX_PARAMS**. The default value is **3**. Excess parameters are not recorded. You need to set **LOSCFG_TRACE_FRAME_MAX_PARAMS** based on service requirements. > The number of parameters in **params** is specified by **LOSCFG_TRACE_FRAME_MAX_PARAMS**. The default value is **3**. Excess parameters are not recorded. You need to set **LOSCFG_TRACE_FRAME_MAX_PARAMS** based on service requirements.
Task 0x1 is switched to Task 0x0. The priority of task 0x1 is **0x1f**, and the state is **0x4**. The priority of the task 0x0 is **0x0**. Task 0x1 is switched to Task 0x0. The priority of task 0x1 is **0x1f**, and the state is **0x4**. The priority of the task 0x0 is **0x0**.
# User-Mode Memory Debugging # User-Mode Memory Debugging
## Basic Concepts ## Basic Concepts
The musl libc library of the debug version provides mechanisms, such as memory leak check, heap memory statistics, memory corruption check, and backtrace, to improve the efficiency in locating memory problems in user space.
The musl libc library of the debug version provides maintenance and test methods, such as memory leak check, heap memory statistics, memory corruption check, and backtrace, to improve the efficiency of locating memory problems in user space.
Instrumentation is performed in the **malloc** and **free** APIs to log key node information. The memory node integrity is checked when memory is requested and released by an application. When the application ends, memory statistics are provided to help identifying memory leaks.
Instrumentation is performed on the **malloc** and **free** APIs to log key node information. When memory is requested and released by a program, the memory node integrity is checked. When the program ends, memory statistics are provided for identifying memory leaks.
## Working Principles ## Working Principles
...@@ -18,15 +17,15 @@ When memory is requested, key information is saved to the memory node control bl ...@@ -18,15 +17,15 @@ When memory is requested, key information is saved to the memory node control bl
When memory is released, the system matches the memory node control block based on the memory address to be released and deletes the control block. When memory is released, the system matches the memory node control block based on the memory address to be released and deletes the control block.
**Figure 1** Heap memory node linked list **Figure 1** Heap memory node linked list
![](figures/heap-memory-node-linked-list.png "heap-memory-node-linked-list") ![](figures/heap-memory-node-linked-list.png "heap-memory-node-linked-list")
When memory is allocated, the returned address is saved in a link register (LR). During the process running, the system adds information, such as the LR corresponding to the suspected leak, to the memory node control block. <xref href="#fig716011269106" idp:producemode_text="auto" class="- topic/xref " id="xref106398301961"></xref> shows the heap memory node information. When memory is allocated, the returned address is saved in a link register (LR). During the process running, the system adds information, such as the LR corresponding to the suspected leak, to the memory node control block. The following figure shows the heap memory node information.
**Figure 2** Heap memory node information **Figure 2** Heap memory node information
![](figures/heap-memory-node-information.png "heap-memory-node-information") ![](figures/heap-memory-node-information.png "heap-memory-node-information")
**TID** indicates the thread ID; **PID** indicates the process ID; **ptr** indicates the address of the memory requested; **size** indicates the size of the requested memory; **lr[*n*]** indicates the address of the call stack, and *n* is configurable. **TID** indicates the thread ID; **PID** indicates the process ID; **ptr** indicates the address of the memory requested; **size** indicates the size of the requested memory; **lr[*n*]** indicates the address of the call stack, and *n* is configurable.
...@@ -34,9 +33,9 @@ When memory is released, the input parameter pointer in the **free** API is used ...@@ -34,9 +33,9 @@ When memory is released, the input parameter pointer in the **free** API is used
You can export the memory debugging information of each process through the serial port or file, and use the addr2line tool to convert the exported information into the code lines that cause memory leaks. In this way, the memory leakage problem can be solved. You can export the memory debugging information of each process through the serial port or file, and use the addr2line tool to convert the exported information into the code lines that cause memory leaks. In this way, the memory leakage problem can be solved.
**Figure 3** Process of locating the code line for a memory leak **Figure 3** Process of locating the code line for a memory leak
![](figures/process-of-locating-the-code-lines-for-a-memory-leak.png "process-of-locating-the-code-lines-for-a-memory-leak") ![](figures/process-of-locating-the-code-lines-for-a-memory-leak.png "process-of-locating-the-code-lines-for-a-memory-leak")
### Heap Memory Statistics ### Heap Memory Statistics
...@@ -46,21 +45,29 @@ You can collect statistics on the percentage of heap memory requested by each th ...@@ -46,21 +45,29 @@ You can collect statistics on the percentage of heap memory requested by each th
### Memory Integrity Check ### Memory Integrity Check
- If the memory requested by using **malloc** is less than or equal to 0x1c000 bytes, the heap allocation algorithm is used to allocate memory. - Requested memory less than or equal to 0x1c000 bytes
When the requested memory is less than or equal to 0x1c000 bytes, **malloc** uses the heap allocation algorithm to allocate memory.
When a user program requests heap memory, information such as the check value is added to the heap memory node. If the check value is abnormal, it is probably that the previous heap memory block is overwritten. Currently, the scenario where the check value is damaged by a wild pointer cannot be identified. When memory is allocated or released, the memory node check value is verified. If the memory node is corrupted and the verification fails, the following information is output: TID, PID, and call stack information saved when the previous heap memory block of the corrupted node is allocated. You can use the addr2line tool to obtain the specific code line and rectify the fault. When a user program requests heap memory, information such as the check value is added to the heap memory node. If the check value is abnormal, it is probably that the previous heap memory block is overwritten. Currently, the scenario where the check value is damaged by a wild pointer cannot be identified. When memory is allocated or released, the memory node check value is verified. If the memory node is corrupted and the verification fails, the following information is output: TID, PID, and call stack information saved when the previous heap memory block of the corrupted node is allocated. You can use the addr2line tool to obtain the specific code line and rectify the fault.
**Figure 4** Adding a check value to the node header information **Figure 4** Adding a check value to the node header information
![](figures/adding-a-check-value-to-the-node-header-information.png "adding-a-check-value-to-the-node-header-information") ![](figures/adding-a-check-value-to-the-node-header-information.png "adding-a-check-value-to-the-node-header-information")
When heap memory is released by using **free**, the memory block is not released immediately. Instead, the magic number 0xFE is written into the memory block, which is then placed in the free queue to prevent the memory block from being allocated by **malloc** within a certain period of time. When a wild pointer or **use-after-free** operation is performed to read the memory, an exception can be detected. However, this mechanism does not apply to write operations. When heap memory is released by **free**, the memory block is not released immediately. Instead, the magic number 0xFE is written into the memory block, which is then placed in the free queue to prevent the memory block from being allocated by **malloc** within a certain period of time. When a wild pointer or **use-after-free** operation is performed to read the memory, an exception can be detected. However, this mechanism does not apply to write operations.
**Figure 5** Process of releasing memory **Figure 5** Process of releasing memory
![](figures/process-of-releasing-memory.png "process-of-releasing-memory") ![](figures/process-of-releasing-memory.png "process-of-releasing-memory")
- If the memory requested by using **malloc** is greater than 0x1c000 bytes, **mmap** is used to allocate memory.
When **mmap** is used to request a large memory block, one more page is allocated at the start and end of the memory region. The current **PAGE_SIZE** of each page is **0x1000**. The permissions of the two pages are set to **PROT_NONE** (no read or write permission) by using the **mprotect** API to prevent out-of-bounds read and write of memory. If out-of-bounds read and write of memory occurs, the user program becomes abnormal because the user does not have the read or write permission. The code logic can be identified based on the abnormal call stack information.
- Requested memory greater than 0x1c000 bytes
When the requested memory is greater than 0x1c000 bytes, **malloc** uses **mmap** to allocate memory.
When **mmap** is used to allocate a large memory block, one more page is allocated at the start and end of the memory region. The current **PAGE_SIZE** of each page is **0x1000**. The permissions of the two pages are set to **PROT_NONE** (no read or write permission) by using the **mprotect** API to prevent out-of-bounds read and write of memory. If out-of-bounds read and write of memory occurs, the user program becomes abnormal because the user does not have the read or write permission. The code logic can be identified based on the abnormal call stack information.
**Figure 6** Layout of the memory allocated by using the **mmap** mechanism of **malloc** **Figure 6** Layout of the memory allocated by using the **mmap** mechanism of **malloc**
...@@ -105,7 +112,7 @@ You can perform heap memory debugging by using either of the following: ...@@ -105,7 +112,7 @@ You can perform heap memory debugging by using either of the following:
- CLI: By using the CLI, you do not need to modify user code. However, you cannot accurately check the heap memory information of a specific logic segment. - CLI: By using the CLI, you do not need to modify user code. However, you cannot accurately check the heap memory information of a specific logic segment.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > **NOTE**<br>
> After memory debugging is enabled, a heap memory leak check and a heap memory integrity check will be performed by default when a process exits. If memory debugging is disabled, the heap memory statistics, heap memory leak check, and heap memory integrity check cannot be enabled, and there is no response to the calling of any debug API. > After memory debugging is enabled, a heap memory leak check and a heap memory integrity check will be performed by default when a process exits. If memory debugging is disabled, the heap memory statistics, heap memory leak check, and heap memory integrity check cannot be enabled, and there is no response to the calling of any debug API.
...@@ -119,7 +126,7 @@ You can perform heap memory debugging by using either of the following: ...@@ -119,7 +126,7 @@ You can perform heap memory debugging by using either of the following:
The sample code explicitly calls the related APIs of the memory debugging module to check the memory. The sample code explicitly calls the related APIs of the memory debugging module to check the memory.
``` ```c
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
...@@ -127,7 +134,8 @@ The sample code explicitly calls the related APIs of the memory debugging module ...@@ -127,7 +134,8 @@ The sample code explicitly calls the related APIs of the memory debugging module
#define MALLOC_LEAK_SIZE 0x300 #define MALLOC_LEAK_SIZE 0x300
void func(void) { void func(void)
{
char *ptr = malloc(MALLOC_LEAK_SIZE); char *ptr = malloc(MALLOC_LEAK_SIZE);
memset(ptr, '3', MALLOC_LEAK_SIZE); memset(ptr, '3', MALLOC_LEAK_SIZE);
} }
...@@ -156,7 +164,8 @@ $ clang -o mem_check mem_check.c -funwind-tables -rdynamic -g -mfloat-abi=softfp ...@@ -156,7 +164,8 @@ $ clang -o mem_check mem_check.c -funwind-tables -rdynamic -g -mfloat-abi=softfp
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > **NOTE**
>
> - In this example, the compiler path is written into an environment variable in the **.bashrc** file. > - In this example, the compiler path is written into an environment variable in the **.bashrc** file.
> >
> - When compiling user programs and required libraries, add the option **-funwind-tables -rdynamic -g** for stack backtracking. > - When compiling user programs and required libraries, add the option **-funwind-tables -rdynamic -g** for stack backtracking.
...@@ -293,14 +302,15 @@ kill -37 <pid> # Check whether the head node of the heap memory is complete. ...@@ -293,14 +302,15 @@ kill -37 <pid> # Check whether the head node of the heap memory is complete.
The sample code constructs a memory problem and uses the command line to perform memory debugging. The sample code constructs a memory problem and uses the command line to perform memory debugging.
``` ```c
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#define MALLOC_LEAK_SIZE 0x300 #define MALLOC_LEAK_SIZE 0x300
void func(void) { void func(void)
{
char *ptr = malloc(MALLOC_LEAK_SIZE); char *ptr = malloc(MALLOC_LEAK_SIZE);
memset(ptr, '3', MALLOC_LEAK_SIZE); memset(ptr, '3', MALLOC_LEAK_SIZE);
} }
...@@ -317,7 +327,7 @@ int main() ...@@ -317,7 +327,7 @@ int main()
##### Compilation ##### Compilation
For details, see [Compilation](kernel-small-debug-user.md#compilation). For details, see [Compilation](#compilation).
##### Running the mwatch Command ##### Running the mwatch Command
...@@ -497,25 +507,26 @@ Now using addr2line ... ...@@ -497,25 +507,26 @@ Now using addr2line ...
==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s).
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > **NOTE**<br>
> The preceding information recorded gradually is added to the file specified during initialization. Therefore, running the **cat** command can also display the historical information in the file. > The preceding information recorded gradually is added to the file specified during initialization. Therefore, running the **cat** command can also display the historical information in the file.
## Common Problems ## Common Problems
### Use After Free (UAF) ### Use After Free (UAF)
- Requested memory block less than or equal to 0x1c000 bytes: - Requested memory less than or equal to 0x1c000 bytes:
After the memory is released:
Read operation: If the magic number (0xFEFEFEFE) is read from the memory block released, UAF occurs. Read operation: If the magic number (0xFEFEFEFE) is read from the memory block released, UAF occurs.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > **NOTE**
>
> After **free** is called, the heap memory will not be released to the heap memory pool immediately. Instead, the heap memory is placed in a queue with a fixed length and filled with the magic number 0xFE. When the queue is full, the memory block first placed in the queue is released to the heap memory pool first. > After **free** is called, the heap memory will not be released to the heap memory pool immediately. Instead, the heap memory is placed in a queue with a fixed length and filled with the magic number 0xFE. When the queue is full, the memory block first placed in the queue is released to the heap memory pool first.
Write operation: The memory debugging module cannot detect UAF errors from write operations. Write operation: The memory debugging module cannot detect UAF errors from write operations.
- Requested memory block greater than 0x1c000 bytes: - Requested memory block greater than 0x1c000 bytes:
The heap memory greater than 0x1c000 bytes must be requested by calling the **mmap** API via **malloc**. If the heap memory is accessed after being released, the user program will become abnormal (because the memory region has been unmapped). The heap memory greater than 0x1c000 bytes must be requested by calling the **mmap** API via **malloc**. If the heap memory is accessed after being released, the user program will become abnormal (because the memory region has been unmapped).
...@@ -527,6 +538,7 @@ Double free errors occur when **free()** is called more than once with the same ...@@ -527,6 +538,7 @@ Double free errors occur when **free()** is called more than once with the same
### Heap Memory Node Corrupted ### Heap Memory Node Corrupted
- Requested memory block less than or equal to 0x1c000 bytes: - Requested memory block less than or equal to 0x1c000 bytes:
When a heap memory node is corrupted, the user program exits unexpectedly, and the call stack that requests the heap memory of the node corrupted is output. The memory debugging module, however, cannot debug the memory corrupted by a wild pointer. For example, if the user program mem_check has heap memory overwriting, you can use the command line to obtain the possible location of the memory corruption. When a heap memory node is corrupted, the user program exits unexpectedly, and the call stack that requests the heap memory of the node corrupted is output. The memory debugging module, however, cannot debug the memory corrupted by a wild pointer. For example, if the user program mem_check has heap memory overwriting, you can use the command line to obtain the possible location of the memory corruption.
......
...@@ -59,10 +59,9 @@ The user mode provides only the LMS check library. It does not provide external ...@@ -59,10 +59,9 @@ The user mode provides only the LMS check library. It does not provide external
The typical process for enabling LMS is as follows: The typical process for enabling LMS is as follows:
1. Configure the macros related to the LMS module. 1. Configure the macros related to the LMS module.
Configure the LMS macro **LOSCFG_KERNEL_LMS**, which is disabled by default. Run the **make update_config** command in the **kernel/liteos_a** directory, choose **Kernel**, and select **Enable Lite Memory Sanitizer**. Configure the LMS macro **LOSCFG_KERNEL_LMS**, which is disabled by default. Run the **make update_config** command in the **kernel/liteos_a** directory, choose **Kernel**, and select **Enable Lite Memory Sanitizer**.
| Macro| menuconfig Option| Description| Value:| | Macro| menuconfig Option| Description| Value |
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| LOSCFG_KERNEL_LMS | Enable Lms Feature | Whether to enable LMS.| YES/NO | | LOSCFG_KERNEL_LMS | Enable Lms Feature | Whether to enable LMS.| YES/NO |
| LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms check pool max num | Maximum number of memory pools that can be checked by LMS.| INT | | LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms check pool max num | Maximum number of memory pools that can be checked by LMS.| INT |
...@@ -70,9 +69,7 @@ The typical process for enabling LMS is as follows: ...@@ -70,9 +69,7 @@ The typical process for enabling LMS is as follows:
| LOSCFG_LMS_STORE_CHECK | Enable lms write check | Whether to enable LMS write check.| YES/NO | | LOSCFG_LMS_STORE_CHECK | Enable lms write check | Whether to enable LMS write check.| YES/NO |
| LOSCFG_LMS_CHECK_STRICT | Enable lms strict check, byte-by-byte | Whether to enable LMS byte-by-byte check.| YES/NO | | LOSCFG_LMS_CHECK_STRICT | Enable lms strict check, byte-by-byte | Whether to enable LMS byte-by-byte check.| YES/NO |
2. Modify the build script of the target module. 2. Modify the build script of the target module.
Add **-fsanitize=kernel-address** to insert memory access checks, and add the **-O0** option to disable optimization performed by the compiler. Add **-fsanitize=kernel-address** to insert memory access checks, and add the **-O0** option to disable optimization performed by the compiler.
The modifications vary depending on the compiler (GCC or Clang) used. The following is an example: The modifications vary depending on the compiler (GCC or Clang) used. The following is an example:
...@@ -113,9 +110,10 @@ This example implements the following: ...@@ -113,9 +110,10 @@ This example implements the following:
#### Kernel-Mode Sample Code #### Kernel-Mode Sample Code
The sample code is as follows: The functions of the sample code can be added to **TestTaskEntry** in **kernel /liteos_a/testsuites /kernel /src /osTest.c** for testing.
The sample code is as follows:
``` ```c
#define PAGE_SIZE (0x1000U) #define PAGE_SIZE (0x1000U)
#define INDEX_MAX 20 #define INDEX_MAX 20
UINT32 g_lmsTestTaskId; UINT32 g_lmsTestTaskId;
...@@ -141,7 +139,7 @@ static VOID LmsTestUseAfterFree(VOID) ...@@ -141,7 +139,7 @@ static VOID LmsTestUseAfterFree(VOID)
PRINTK("\n######%s start ######\n", __FUNCTION__); PRINTK("\n######%s start ######\n", __FUNCTION__);
UINT32 i; UINT32 i;
CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX);
LOS_MemFree(g_testLmsPool, str); (VOID)LOS_MemFree(g_testLmsPool, str);
PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */ PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */
PRINTK("\n######%s stop ######\n", __FUNCTION__); PRINTK("\n######%s stop ######\n", __FUNCTION__);
} }
...@@ -151,18 +149,19 @@ VOID LmsTestCaseTask(VOID) ...@@ -151,18 +149,19 @@ VOID LmsTestCaseTask(VOID)
LmsTestOsmallocOverflow(); LmsTestOsmallocOverflow();
LmsTestUseAfterFree(); LmsTestUseAfterFree();
} }
UINT32 Example_Lms_test(VOID){ UINT32 Example_Lms_test(VOID)
{
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S lmsTestTask; TSK_INIT_PARAM_S lmsTestTask;
/* Create a task for LMS. */ /* Create a task for LMS. */
memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S)); memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S));
lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask; lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask;
lmsTestTask.pcName = "TestLmsTsk"; /* Test task name. */ lmsTestTask.pcName = "TestLmsTsk"; /* Test task name. */
lmsTestTask.uwStackSize = 0x800; lmsTestTask.uwStackSize = 0x800; // 0x800: LMS test task stack size
lmsTestTask.usTaskPrio = 5; lmsTestTask.usTaskPrio = 5; // 5: LMS test task priority
lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED; lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED;
ret = LOS_TaskCreate(&g_lmsTestTaskId, &lmsTestTask); ret = LOS_TaskCreate(&g_lmsTestTaskId, &lmsTestTask);
if(ret != LOS_OK){ if (ret != LOS_OK) {
PRINT_ERR("LmsTestTask create failed .\n"); PRINT_ERR("LmsTestTask create failed .\n");
return LOS_NOK; return LOS_NOK;
} }
...@@ -260,7 +259,7 @@ The key output information is as follows: ...@@ -260,7 +259,7 @@ The key output information is as follows:
### User-Mode Development Process ### User-Mode Development Process
Add the following to the build script of the app to be checked. For details about the complete code, see **/kernel/liteos_a/apps/lms/BUILD.gn**. Add the following to the app build script to be checked. For details about the sample code, see [/kernel/liteos_a/apps/lms/BUILD.gn](https://gitee.com/openharmony/kernel_liteos_a/blob/master/apps/lms/BUILD.gn).
``` ```
...@@ -318,7 +317,7 @@ This example implements the following: ...@@ -318,7 +317,7 @@ This example implements the following:
The code is as follows: The code is as follows:
``` ```c
static void BufWriteTest(void *buf, int start, int end) static void BufWriteTest(void *buf, int start, int end)
{ {
for (int i = start; i <= end; i++) { for (int i = start; i <= end; i++) {
...@@ -335,7 +334,7 @@ static void BufReadTest(void *buf, int start, int end) ...@@ -335,7 +334,7 @@ static void BufReadTest(void *buf, int start, int end)
static void LmsMallocTest(void) static void LmsMallocTest(void)
{ {
printf("\n-------- LmsMallocTest Start --------\n"); printf("\n-------- LmsMallocTest Start --------\n");
char *buf = (char *)malloc(16); char *buf = (char *)malloc(16); // 16: buffer size for test
BufReadTest(buf, -1, 16); BufReadTest(buf, -1, 16);
free(buf); free(buf);
printf("\n-------- LmsMallocTest End --------\n"); printf("\n-------- LmsMallocTest End --------\n");
...@@ -343,7 +342,7 @@ static void LmsMallocTest(void) ...@@ -343,7 +342,7 @@ static void LmsMallocTest(void)
static void LmsFreeTest(void) static void LmsFreeTest(void)
{ {
printf("\n-------- LmsFreeTest Start --------\n"); printf("\n-------- LmsFreeTest Start --------\n");
char *buf = (char *)malloc(16); char *buf = (char *)malloc(16); // 16: buffer size for test
free(buf); free(buf);
BufReadTest(buf, 1, 1); BufReadTest(buf, 1, 1);
free(buf); free(buf);
...@@ -352,7 +351,7 @@ static void LmsFreeTest(void) ...@@ -352,7 +351,7 @@ static void LmsFreeTest(void)
int main(int argc, char * const * argv) int main(int argc, char * const * argv)
{ {
printf("\n############### Lms Test start ###############\n"); printf("\n############### Lms Test start ###############\n");
char *tmp = (char *)malloc(5000); char *tmp = (char *)malloc(5000); // 5000: temp buffer size
LmsMallocTest(); LmsMallocTest();
LmsFreeTest(); LmsFreeTest();
printf("\n############### Lms Test End ###############\n"); printf("\n############### Lms Test End ###############\n");
......
...@@ -3,20 +3,22 @@ ...@@ -3,20 +3,22 @@
## Kernel Startup Process ## Kernel Startup Process
The kernel startup process consists of the assembly startup and C language startup, as shown in the following figure. The kernel startup process consists of the assembly startup and C language startup, as shown in **Figure 1**.
The assembly startup involves the following operations: initializing CPU settings, disabling dCache/iCache, enabling the FPU and NEON, setting the MMU to establish the virtual-physical address mapping, setting the system stack, clearing the BSS segment, and calling the main function of the C language. The assembly startup involves the following operations: initializing CPU settings, disabling dCache/iCache, enabling the FPU and NEON, setting the MMU to establish the virtual-physical address mapping, setting the system stack, clearing the BSS segment, and calling the main function of the C language.
The C language startup involves the following operations: starting the **OsMain** function and starting scheduling. As shown in the following figure, the **OsMain** function is used for basic kernel initialization and architecture- and board-level initialization. The kernel startup framework leads the initialization process. The right part of the figure shows the phase in which external modules can register with the kernel startup framework and starts. The table below describes each phase. The C language startup involves the following operations: starting the **OsMain** function and starting scheduling.
**OsMain()** is used for basic kernel initialization and architecture- and board-level initialization. The kernel startup framework leads the initialization process. The right part of the figure shows the phase in which external modules can register with the kernel startup framework and starts. **Table 1** describes each phase.
**Figure 1** Kernel startup process<br> **Figure 1** Kernel startup process
![](figures/kernel-startup-process-2.png "kernel-startup-process-2")
![](figures/kernel-startup-process-2.png "kernel-startup-process-2")
**Table 1** Start framework
| Level | Startup Description | **Table 1** Kernel startup framework
| API| Description|
| -------- | -------- | | -------- | -------- |
| LOS_INIT_LEVEL_EARLIEST | Earliest initialization.<br>The initialization is architecture-independent. The board and subsequent modules initialize the pure software modules on which they depend.<br>Example: trace module| | LOS_INIT_LEVEL_EARLIEST | Earliest initialization.<br>The initialization is architecture-independent. The board and subsequent modules initialize the pure software modules on which they depend.<br>Example: trace module|
| LOS_INIT_LEVEL_ARCH_EARLY | Early initialization of the architecture.<br>The initialization is architecture-dependent. Subsequent modules initialize the modules on which they depend. It is recommended that functions not required for startup be placed at **LOS_INIT_LEVEL_ARCH**.| | LOS_INIT_LEVEL_ARCH_EARLY | Early initialization of the architecture.<br>The initialization is architecture-dependent. Subsequent modules initialize the modules on which they depend. It is recommended that functions not required for startup be placed at **LOS_INIT_LEVEL_ARCH**.|
...@@ -28,54 +30,52 @@ The C language startup involves the following operations: starting the **OsMain* ...@@ -28,54 +30,52 @@ The C language startup involves the following operations: starting the **OsMain*
| LOS_INIT_LEVEL_KMOD_BASIC | Initialization of the kernel basic modules.<br>Initialize the basic modules that can be detached from the kernel.<br>Example: VFS initialization| | LOS_INIT_LEVEL_KMOD_BASIC | Initialization of the kernel basic modules.<br>Initialize the basic modules that can be detached from the kernel.<br>Example: VFS initialization|
| LOS_INIT_LEVEL_KMOD_EXTENDED | Initialization of the kernel extended modules.<br>Initialize the extended modules that can be detached from the kernel.<br>Example: initialization of system call, ProcFS, Futex, HiLog, HiEvent, and LiteIPC| | LOS_INIT_LEVEL_KMOD_EXTENDED | Initialization of the kernel extended modules.<br>Initialize the extended modules that can be detached from the kernel.<br>Example: initialization of system call, ProcFS, Futex, HiLog, HiEvent, and LiteIPC|
| LOS_INIT_LEVEL_KMOD_TASK | Kernel task creation.<br>Create kernel tasks (kernel tasks and software timer tasks).<br>Example: creation of the resident resource reclaiming task, SystemInit task, and CPU usage statistics task| | LOS_INIT_LEVEL_KMOD_TASK | Kernel task creation.<br>Create kernel tasks (kernel tasks and software timer tasks).<br>Example: creation of the resident resource reclaiming task, SystemInit task, and CPU usage statistics task|
| LOS_INIT_LEVEL_FINISH | Complete of the kernel initialization.|
## Programming Example ## Development Example
**Example Description** **Example Description**
Add a kernel module and register the initialization function of the module to the kernel startup process through the kernel startup framework, so as to complete the module initialization during the kernel initialization process. Add a kernel module and register the initialization function of the module to the kernel startup process through the kernel startup framework, so as to complete the module initialization during the kernel initialization process.
You can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**.
**Sample Code** **Sample Code**
```c
```
/* Header file of the kernel startup framework */ /* Header file of the kernel startup framework */
#include "los_init.h" #include "los_init.h"
...
/* Initialization function of the new module */ /* Initialization function of the new module */
unsigned int OsSampleModInit(void) unsigned int OsSampleModInit(void)
{ {
PRINTK("OsSampleModInit SUCCESS!\n"); PRINTK("OsSampleModInit SUCCESS!\n");
......
} }
...
/* Register the new module at the target level of the kernel startup framework. */ /* Register the new module at the target level of the kernel startup framework. */
LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED); LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
``` ```
**Verification** **Verification**
``` ```
main core booting up... main core booting up...
/* The print information may vary depending on the running environment. */
...
/* Print the initialization function of the new module in the test code. */
OsSampleModInit SUCCESS! OsSampleModInit SUCCESS!
releasing 1 secondary cores
cpu 1 entering scheduler
cpu 0 entering scheduler
``` ```
According to the information displayed during the system startup, the kernel has called the initialization function of the registered module during the startup to initialize the module. According to the information displayed during the system startup, the kernel calls the initialization function of the registered module during the startup to initialize the module.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** > **NOTE**
> >
> Modules at the same level cannot depend on each other. It is recommended that a new module be split based on the preceding startup phase and be registered and started as required. > Modules of the same level cannot depend on each other. It is recommended that a new module be split based on the preceding startup phase and be registered and started as required.
> >
> You can view the symbol table in the **.rodata.init.kernel.*** segment of the **OHOS_Image.map** file generated after the build is complete, so as to learn about the initialization entry of each module that has been registered with the kernel startup framework and check whether the newly registered initialization entry has taken effect. > You can view the symbol table in the **.rodata.init.kernel.*** segment of the **OHOS_Image.map** file generated after the build is complete, so as to learn about the initialization entry of each module that has been registered with the kernel startup framework and check whether the newly registered initialization entry has taken effect.
# Startup in User Mode # Startup in User Mode
## Startup of the Root Process in User Mode<a name="section79911135647"></a>
## Startup of the Root Process in User Mode
The root process is the first user-mode process in the system. The process ID is 1. The root process is the ancestor of all user-mode processes. The root process is the first user-mode process in the system. The process ID is 1. The root process is the ancestor of all user-mode processes.
**Figure 1** Process tree<a name="fig427516409375"></a> **Figure 1** Process tree
![](figures/process-tree.png "process-tree") ![](figures/process-tree.png "process-tree")
### Startup Process of the Root Process<a name="section1184317581349"></a>
### Startup Process of the Root Process
Use the link script to place the following init startup code to the specified location in the system image. Use the link script to place the following init startup code to the specified location in the system image.
```
```c
#define LITE_USER_SEC_ENTRY __attribute__((section(".user.entry"))) #define LITE_USER_SEC_ENTRY __attribute__((section(".user.entry")))
LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args)
{ {
...@@ -23,28 +27,31 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) ...@@ -23,28 +27,31 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args)
} }
``` ```
During system startup, **OsUserInitProcess** is called to start the **init** process. The procedure is as follows: > **NOTE**
>
> The preceeding code is in **kernel/liteos_a/kernel/user/src/los_user_init.c**. The value of **g_initPath** can be **/dev/shm/init** or **/bin/init**, depending on the startup settings.
1. The kernel calls **OsLoadUserInit** to load the code. Use **OsUserInitProcess** to start the **init** process. The procedure is as follows:
2. A process space is created to start the **/bin/init** process.
### Responsibilities of the Root Process<a name="section1590220321759"></a> 1. The kernel calls **OsLoadUserInit** to load the code for startup.
2. A process space is created to start the **/bin/init** process.
- Starts key system programs or services, such as shell.
>![](../public_sys-resources/icon-note.gif) **NOTE** ### Responsibilities of the Root Process
>
>In OpenHarmony, the **init** process reads the **/etc/init.cfg** file and runs specified commands or starts specified processes based on configurations. For details, see [init Module](../subsystems/subsys-boot-init-cfg.md).
- The root process starts key system programs or services, such as shell.
> **NOTE**
> In OpenHarmony, the **init** process reads **/etc/init.cfg** and runs commands or starts processes based on the configuration. For details, see [init Configuration File](../subsystems/subsys-boot-init-cfg.md).
- Monitors the process for reclaiming the orphan process and clears the zombie processes in child processes. - The root process monitors the process for reclaiming the orphan process and clears the zombie processes in child processes.
## Running Programs in User Mode<a name="section194576310611"></a>
## Running Programs in User Mode
A user-mode program can be started in either of the following ways: A user-mode program can be started in either of the following ways:
- Run the shell command to start the process. - Using shell commands
``` ```
OHOS $ exec helloworld OHOS $ exec helloworld
...@@ -52,9 +59,6 @@ A user-mode program can be started in either of the following ways: ...@@ -52,9 +59,6 @@ A user-mode program can be started in either of the following ways:
OHOS $ /bin/helloworld OHOS $ /bin/helloworld
``` ```
- Using POSIX APIs
- Start a new process by calling the POSIX API. Use **Fork()** to create a process, and call **exec()** to execute a process.
Use the **Fork\(\)** method to create a process, and call the **exec\(\)** method to execute a new process.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册