From 73170dc7e4066ed8508c422ed35ecd0a6a73f530 Mon Sep 17 00:00:00 2001 From: duangavin123 Date: Thu, 17 Feb 2022 20:04:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=85=E6=A0=B8=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: duangavin123 --- en/device-dev/Readme-EN.md | 2 +- en/device-dev/kernel/Readme-EN.md | 362 ++-- .../kernel/figure/changing-the-directory.png | Bin 9998 -> 0 bytes ...p-of-the-hello-harmony-txt-file-to-100.png | Bin 8850 -> 0 bytes ...y-txt-file-to-100-and-200-respectively.png | Bin 8164 -> 0 bytes ...-for-the-hello-harmony-txt-file-to-666.png | Bin 8193 -> 0 bytes .../kernel/figure/command-output-24.png | Bin 4898 -> 0 bytes .../kernel/figure/command-output.png | Bin 21005 -> 0 bytes en/device-dev/kernel/figure/cpu-usage.png | Bin 2559 -> 0 bytes .../kernel/figure/creating-file-c.png | Bin 4757 -> 0 bytes .../figure/creating-the-share-directory.png | Bin 8323 -> 0 bytes .../kernel/figure/deleting-directory-dir.png | Bin 4577 -> 0 bytes .../figure/deleting-the-log1-txt-file.png | Bin 3797 -> 0 bytes .../figure/deleting-the-sd-directory.png | Bin 4935 -> 0 bytes ...aying-content-of-the-current-directory.png | Bin 6572 -> 0 bytes ...aying-the-content-of-hello-harmony-txt.png | Bin 2160 -> 0 bytes .../figure/displaying-the-current-path.png | Bin 1091 -> 0 bytes ...laying-the-memory-usage-in-three-units.png | Bin 17505 -> 0 bytes .../figure/en-us_image_0000001127519136.png | Bin 43891 -> 0 bytes .../figure/en-us_image_0000001127520662.png | Bin 25309 -> 0 bytes .../figure/en-us_image_0000001132778524.png | Bin 48620 -> 0 bytes .../figure/en-us_image_0000001133848164.png | Bin 20243 -> 0 bytes .../figure/en-us_image_0000001133848370.png | Bin 38993 -> 0 bytes .../figure/en-us_image_0000001133848906.png | Bin 8094 -> 0 bytes .../figure/en-us_image_0000001134008030.png | Bin 45947 -> 0 bytes .../figure/en-us_image_0000001134008686.png | Bin 4263 -> 0 bytes .../figure/en-us_image_0000001134008688.png | Bin 3407 -> 0 bytes .../figure/en-us_image_0000001173449871.png | Bin 45096 -> 0 bytes .../figure/en-us_image_0000001176974089.png | Bin 52119 -> 0 bytes .../figure/en-us_image_0000001179847649.png | Bin 1894 -> 0 bytes .../figure/en-us_image_0000001179848349.png | Bin 4571 -> 0 bytes .../figure/en-us_image_0000001179848731.png | Bin 10721 -> 0 bytes .../figure/en-us_image_0000001179967527.png | Bin 4180 -> 0 bytes .../figure/en-us_image_0000001179967909.png | Bin 3337 -> 0 bytes .../figure/en-us_image_0000001191018697.png | Bin 28182 -> 0 bytes .../kernel/figure/event-working-mechanism.png | Bin 33007 -> 0 bytes .../kernel/figure/file-copying-result.png | Bin 11218 -> 0 bytes .../figure/heap-memory-core-algorithm.png | Bin 51453 -> 0 bytes .../kernel/figure/kernel-architecture.png | Bin 26242 -> 0 bytes .../kernel/figure/mutex-working-mechanism.png | Bin 39810 -> 0 bytes .../figure/no-out-of-bounds-memory-access.png | Bin 2156 -> 0 bytes .../figure/out-of-bounds-memory-access.png | Bin 291809 -> 0 bytes .../kernel/figure/output-of-telnet-on.png | Bin 3436 -> 0 bytes .../figure/output-of-the-statfs-command.png | Bin 9019 -> 0 bytes .../figure/process-of-creating-a-vnode.png | Bin 38518 -> 0 bytes .../figure/process-of-locating-a-file.png | Bin 51389 -> 0 bytes .../figure/program-execution-process.png | Bin 82026 -> 0 bytes ...nformation-about-all-semaphores-in-use.png | Bin 12931 -> 0 bytes ...-information-about-all-software-timers.png | Bin 14879 -> 0 bytes ...ing-information-about-software-timer-1.png | Bin 5787 -> 0 bytes .../querying-partial-task-information.png | Bin 51379 -> 0 bytes en/device-dev/kernel/figure/querying-pids.png | Bin 15377 -> 0 bytes .../reading-and-writing-data-in-a-queue.png | Bin 14495 -> 0 bytes .../figure/semaphore-working-mechanism.png | Bin 41616 -> 0 bytes ...ending-a-signal-to-a-specified-process.png | Bin 3423 -> 0 bytes .../kernel/figure/signal-sending-failure.png | Bin 3171 -> 0 bytes .../snipaste_2021-01-26_10-38-58-25.png | Bin 6943 -> 0 bytes .../snipaste_2021-01-26_10-38-58-26.png | Bin 5006 -> 0 bytes .../figure/snipaste_2021-01-26_10-38-58.png | Bin 2702 -> 0 bytes .../figure/stack-analysis-mechanism.png | Bin 42471 -> 0 bytes en/device-dev/kernel/figure/static-memory.png | Bin 11527 -> 0 bytes ...e-user-whose-uid-and-gid-are-both-1000.png | Bin 8877 -> 0 bytes ...-printed-based-on-the-specified-format.png | Bin 2014 -> 0 bytes .../figure/task-command-monitoring-result.png | Bin 53999 -> 0 bytes .../kernel/figure/task-state-transition.png | Bin 12567 -> 0 bytes .../kernel/figure/unmounting-result.png | Bin 1641 -> 0 bytes .../figure/usage-of-system-resources.png | Bin 7206 -> 0 bytes .../viewing-the-usage-of-physical-pages.png | Bin 5973 -> 0 bytes ...memory-usage-of-the-process-with-pid-3.png | Bin 29236 -> 0 bytes .../writing-dmesg-content-to-a-file.png | Bin 3198 -> 0 bytes ...k-value-to-the-node-header-information.png | Bin ...ure-of-the-openharmony-liteos-a-kernel.png | Bin 0 -> 24845 bytes ...cpu-accessing-the-memory-or-peripheral.png | Bin .../cpu-accessing-the-memory.png | Bin .../dynamic-loading-process.png | Bin ...mic-memory-algorithm-for-mini-systems.png} | Bin ...mic-memory-algorithm-for-small-systems.png | Bin ...management-structure-for-mini-systems.png} | Bin ...nagement-structure-for-system-systems.png} | Bin .../elf-file-linking-process.png | Bin ...ent-working-mechanism-for-mini-systems.png | Bin 0 -> 22255 bytes ...t-working-mechanism-for-small-systems.png} | Bin .../exception-information.png} | Bin .../exported-symbol-table-information.png | Bin .../{figure => figures}/futex-design.jpg | Bin .../heap-memory-node-information.png | Bin .../heap-memory-node-linked-list.png | Bin .../kernel/figures/how-to-develop.png | Bin 0 -> 33266 bytes ...tegrating-discontiguous-memory-regions.png | Bin .../kernel/figures/interrupt-vector-table.png | Bin 0 -> 23554 bytes .../kernel/figures/kernel-architecture.png | Bin 0 -> 18365 bytes .../figures/kernel-small-mode-process-4.png | Bin 0 -> 12813 bytes .../kernel-small-mode-process.png} | Bin .../kernel-startup-process-2.png} | Bin .../kernel-startup-process.png | Bin ...-by-using-the-mmap-mechanism-of-malloc.png | Bin ...-m-kernel-dynamic-loading-architecture.png | Bin ...-virtual-and-physical-memory-addresses.png | Bin ...tex-working-mechanism-for-mini-systems.png | Bin 0 -> 39258 bytes ...x-working-mechanism-for-small-systems.png} | Bin .../overall-file-system-architecture.png | Bin .../physical-memory-usage-distribution.png | Bin .../{figure => figures}/posix-framework.png | Bin .../kernel/figures/process-management.png | Bin 0 -> 25001 bytes .../figures/process-of-creating-a-vnode.png | Bin 0 -> 38532 bytes .../process-of-loading-an-elf-file.png | Bin .../figures/process-of-locating-a-file.png | Bin 0 -> 51175 bytes ...ating-the-code-lines-for-a-memory-leak.png | Bin .../process-of-releasing-memory.png | Bin .../process-state-transition.png | Bin .../{figure => figures}/process-tree.png | Bin .../figures/program-execution-process.png | Bin 0 -> 70099 bytes ...reading-and-writing-data-in-a-queue-3.png} | Bin .../reading-and-writing-data-in-a-queue.png | Bin 0 -> 17038 bytes .../{figure => figures}/releasing-memory.png | Bin .../{figure => figures}/requesting-memory.png | Bin .../scheduling-priority-bucket-queue.png | Bin 0 -> 19900 bytes .../kernel/figures/scheduling-process.png | Bin 0 -> 29019 bytes ...ore-working-mechanism-for-mini-systems.png | Bin 0 -> 40600 bytes ...e-working-mechanism-for-small-systems.png} | Bin .../figures/stack-analysis-mechanism.png | Bin 0 -> 27103 bytes .../kernel/figures/static-memory.png | Bin 0 -> 10728 bytes .../{figure => figures}/system-call.png | Bin .../task-state-transition.png} | Bin .../kernel/figures/task-state-transitions.png | Bin 0 -> 8558 bytes .../vdso-system-design.jpg | Bin .../kernel/kernel-basic-mini-time.md | 175 +- en/device-dev/kernel/kernel-mini-appx-code.md | 17 +- .../kernel/kernel-mini-appx-data-list.md | 11 +- .../kernel/kernel-mini-appx-lib-cmsis.md | 13 +- .../kernel/kernel-mini-appx-lib-posix.md | 16 +- .../kernel-mini-basic-interrupt-concept.md | 37 - .../kernel-mini-basic-interrupt-guide.md | 124 -- .../kernel/kernel-mini-basic-interrupt.md | 162 +- .../kernel-mini-basic-ipc-event-basic.md | 45 - .../kernel-mini-basic-ipc-event-guide.md | 186 -- .../kernel/kernel-mini-basic-ipc-event.md | 241 ++- .../kernel-mini-basic-ipc-mutex-basic.md | 17 - .../kernel-mini-basic-ipc-mutex-guide.md | 197 -- .../kernel/kernel-mini-basic-ipc-mutex.md | 221 +- .../kernel-mini-basic-ipc-queue-basic.md | 62 - .../kernel-mini-basic-ipc-queue-guide.md | 190 -- .../kernel/kernel-mini-basic-ipc-queue.md | 263 ++- .../kernel/kernel-mini-basic-ipc-sem-basic.md | 48 - .../kernel/kernel-mini-basic-ipc-sem-guide.md | 198 -- .../kernel/kernel-mini-basic-ipc-sem.md | 256 ++- .../kernel-mini-basic-memory-dynamic.md | 72 +- .../kernel/kernel-mini-basic-memory-static.md | 17 +- .../kernel/kernel-mini-basic-soft-basic.md | 49 - .../kernel/kernel-mini-basic-soft-guide.md | 211 -- .../kernel/kernel-mini-basic-soft.md | 274 ++- .../kernel/kernel-mini-basic-task-basic.md | 93 - .../kernel/kernel-mini-basic-task-guide.md | 300 --- .../kernel/kernel-mini-basic-task.md | 410 +++- .../kernel/kernel-mini-basic-time-basic.md | 21 - .../kernel/kernel-mini-basic-time-guide.md | 149 -- ...l-memory-inner.md => kernel-mini-debug.md} | 4 +- .../kernel/kernel-mini-extend-cpup-basic.md | 29 - .../kernel/kernel-mini-extend-cpup-guide.md | 155 -- .../kernel/kernel-mini-extend-cpup.md | 191 +- ...ernel-mini-extend-dynamic-loading-basic.md | 81 - ...ernel-mini-extend-dynamic-loading-guide.md | 183 -- .../kernel-mini-extend-dynamic-loading.md | 91 +- .../kernel/kernel-mini-extend-file-fat.md | 13 +- .../kernel/kernel-mini-extend-file-lit.md | 102 +- .../kernel-mini-extend-file-littlefs-basic.md | 6 - .../kernel-mini-extend-file-littlefs-guide.md | 93 - .../kernel/kernel-mini-extend-file.md | 6 +- .../kernel/kernel-mini-extend-support.md | 10 +- en/device-dev/kernel/kernel-mini-extend.md | 2 +- .../kernel/kernel-mini-imemory-debug-det.md | 15 +- .../kernel/kernel-mini-memory-debug-cet.md | 15 +- .../kernel/kernel-mini-memory-debug-mes.md | 16 +- .../kernel/kernel-mini-memory-exception.md | 54 +- .../kernel/kernel-mini-memory-lms.md | 328 +++ .../kernel/kernel-mini-memory-perf.md | 535 +++++ .../kernel/kernel-mini-memory-trace.md | 420 +++- en/device-dev/kernel/kernel-mini-overview.md | 21 +- en/device-dev/kernel/kernel-mini.md | 4 +- .../kernel/kernel-small-apx-bitwise.md | 13 +- en/device-dev/kernel/kernel-small-apx-dll.md | 16 +- .../kernel/kernel-small-apx-library.md | 26 +- .../kernel/kernel-small-basic-atomic.md | 14 +- .../kernel-small-basic-inner-reflect.md | 19 +- .../kernel/kernel-small-basic-interrupt.md | 30 +- .../kernel/kernel-small-basic-memory-heap.md | 32 +- .../kernel-small-basic-memory-physical.md | 21 +- .../kernel-small-basic-memory-virtual.md | 60 +- .../kernel-small-basic-process-process.md | 53 +- .../kernel-small-basic-process-scheduler.md | 23 +- .../kernel-small-basic-process-thread.md | 170 +- .../kernel/kernel-small-basic-process.md | 2 +- .../kernel/kernel-small-basic-softtimer.md | 16 +- .../kernel/kernel-small-basic-time.md | 11 +- .../kernel/kernel-small-basic-trans-event.md | 43 +- .../kernel/kernel-small-basic-trans-mutex.md | 22 +- .../kernel/kernel-small-basic-trans-queue.md | 21 +- .../kernel/kernel-small-basic-trans-rwlock.md | 13 +- .../kernel-small-basic-trans-semaphore.md | 31 +- .../kernel-small-basic-trans-user-mutex.md | 21 +- .../kernel-small-basic-trans-user-signal.md | 13 +- .../kernel/kernel-small-bundles-fs-new.md | 19 +- .../kernel-small-bundles-fs-support-fat.md | 16 +- .../kernel-small-bundles-fs-support-jffs2.md | 10 +- .../kernel-small-bundles-fs-support-nfs.md | 4 + .../kernel-small-bundles-fs-support-procfs.md | 14 +- .../kernel-small-bundles-fs-support-ramfs.md | 8 +- .../kernel/kernel-small-bundles-fs-virtual.md | 26 +- .../kernel/kernel-small-bundles-fs.md | 4 +- .../kernel/kernel-small-bundles-ipc.md | 12 +- .../kernel/kernel-small-bundles-linking.md | 55 +- .../kernel/kernel-small-bundles-share.md | 11 +- .../kernel/kernel-small-bundles-system.md | 27 +- en/device-dev/kernel/kernel-small-bundles.md | 2 +- .../kernel-small-debug-memory-corrupt.md | 9 +- .../kernel/kernel-small-debug-memory-info.md | 7 + .../kernel/kernel-small-debug-memory-leak.md | 24 +- .../kernel/kernel-small-debug-memory.md | 2 +- .../kernel/kernel-small-debug-process-cpu.md | 32 +- .../kernel/kernel-small-debug-shell-build.md | 8 +- .../kernel-small-debug-shell-cmd-cpup.md | 26 +- .../kernel-small-debug-shell-cmd-date.md | 71 +- .../kernel-small-debug-shell-cmd-dmesg.md | 31 +- .../kernel-small-debug-shell-cmd-exec.md | 9 +- .../kernel-small-debug-shell-cmd-free.md | 113 +- .../kernel-small-debug-shell-cmd-help.md | 44 +- .../kernel-small-debug-shell-cmd-hwi.md | 107 +- .../kernel-small-debug-shell-cmd-kill.md | 130 +- .../kernel-small-debug-shell-cmd-log.md | 33 +- .../kernel-small-debug-shell-cmd-memcheck.md | 44 +- .../kernel-small-debug-shell-cmd-oom.md | 93 +- .../kernel-small-debug-shell-cmd-pmm.md | 45 +- .../kernel-small-debug-shell-cmd-reboot.md | 33 + .../kernel-small-debug-shell-cmd-reset.md | 9 +- .../kernel-small-debug-shell-cmd-sem.md | 121 +- .../kernel-small-debug-shell-cmd-stack.md | 22 +- .../kernel/kernel-small-debug-shell-cmd-su.md | 28 +- .../kernel-small-debug-shell-cmd-swtmr.md | 52 +- .../kernel-small-debug-shell-cmd-sysinfo.md | 24 +- .../kernel-small-debug-shell-cmd-task.md | 38 +- .../kernel-small-debug-shell-cmd-top.md | 179 ++ .../kernel-small-debug-shell-cmd-uname.md | 68 +- .../kernel-small-debug-shell-cmd-vmm.md | 45 +- .../kernel-small-debug-shell-cmd-watch.md | 75 +- .../kernel/kernel-small-debug-shell-cmd.md | 4 + .../kernel/kernel-small-debug-shell-error.md | 8 +- .../kernel-small-debug-shell-file-cat.md | 15 +- .../kernel-small-debug-shell-file-cd.md | 26 +- .../kernel-small-debug-shell-file-chgrp.md | 32 +- .../kernel-small-debug-shell-file-chmod.md | 46 +- .../kernel-small-debug-shell-file-chown.md | 49 +- .../kernel-small-debug-shell-file-cp.md | 56 +- .../kernel-small-debug-shell-file-du.md | 93 + .../kernel-small-debug-shell-file-format.md | 29 +- .../kernel-small-debug-shell-file-ls.md | 298 ++- .../kernel-small-debug-shell-file-lsfd.md | 46 +- .../kernel-small-debug-shell-file-mkdir.md | 89 +- .../kernel-small-debug-shell-file-mount.md | 68 +- .../kernel-small-debug-shell-file-mv.md | 134 ++ .../kernel-small-debug-shell-file-partinfo.md | 21 +- ...kernel-small-debug-shell-file-partition.md | 18 +- .../kernel-small-debug-shell-file-pwd.md | 17 +- .../kernel-small-debug-shell-file-rm.md | 74 +- .../kernel-small-debug-shell-file-rmdir.md | 47 +- .../kernel-small-debug-shell-file-statfs.md | 25 +- .../kernel-small-debug-shell-file-sync.md | 7 + .../kernel-small-debug-shell-file-touch.md | 55 +- .../kernel-small-debug-shell-file-umount.md | 58 +- .../kernel-small-debug-shell-file-write.md | 9 +- .../kernel/kernel-small-debug-shell-file.md | 4 + .../kernel/kernel-small-debug-shell-guide.md | 2 + .../kernel-small-debug-shell-magickey.md | 11 +- .../kernel-small-debug-shell-net-arp.md | 94 +- .../kernel-small-debug-shell-net-dhclient.md | 134 +- .../kernel-small-debug-shell-net-dns.md | 86 - .../kernel-small-debug-shell-net-ifconfig.md | 252 +-- .../kernel-small-debug-shell-net-ipdebug.md | 11 +- .../kernel-small-debug-shell-net-netstat.md | 34 +- .../kernel-small-debug-shell-net-ntpdate.md | 7 + .../kernel-small-debug-shell-net-ping.md | 87 +- .../kernel-small-debug-shell-net-ping6.md | 7 + .../kernel-small-debug-shell-net-telnet.md | 17 +- .../kernel-small-debug-shell-net-tftp.md | 7 + .../kernel/kernel-small-debug-shell-net.md | 2 - .../kernel-small-debug-shell-overview.md | 10 +- .../kernel/kernel-small-debug-shell.md | 2 +- .../kernel-small-debug-trace-other-faqs.md | 15 +- ...ernel-small-debug-trace-other-lastwords.md | 11 +- .../kernel/kernel-small-debug-trace.md | 423 +++- .../kernel/kernel-small-debug-user-faqs.md | 4 + .../kernel-small-debug-user-function.md | 16 +- .../kernel-small-debug-user-guide-use-api.md | 5 + .../kernel-small-debug-user-guide-use-cli.md | 6 + en/device-dev/kernel/kernel-small-debug.md | 8 +- .../kernel/kernel-small-memory-lms.md | 499 +++++ en/device-dev/kernel/kernel-small-overview.md | 46 +- .../kernel/kernel-small-start-kernel.md | 21 +- .../kernel/kernel-small-start-user.md | 30 +- en/device-dev/kernel/kernel-small-start.md | 4 +- en/device-dev/kernel/kernel-small.md | 2 +- en/device-dev/kernel/kernel-standard-build.md | 15 +- .../kernel/kernel-standard-overview.md | 6 +- en/device-dev/kernel/kernel-standard-patch.md | 74 +- en/device-dev/kernel/kernel-standard.md | 2 +- en/device-dev/kernel/kernel.md | 2 +- en/readme.md | 4 +- zh-cn/device-dev/kernel/Readme-CN.md | 374 ++-- .../figure/zh-cn_image_0000001134008688.png | Bin 3407 -> 0 bytes ...45\277\203\347\256\227\346\263\225-19.png" | Bin 51453 -> 0 bytes ...0\345\277\203\347\256\227\346\263\225.png" | Bin 58123 -> 0 bytes ...5\345\255\230\350\266\212\347\225\214.png" | Bin 2156 -> 0 bytes ...3\347\244\272\346\204\217\345\233\276.png" | Bin 5872 -> 0 bytes .../figures/zh-cn_image_0000001125101908.png | Bin .../figures/zh-cn_image_0000001127393126.png | Bin .../figures/zh-cn_image_0000001127535690.jpg | Bin .../figures/zh-cn_image_0000001132774752.png | Bin .../figures/zh-cn_image_0000001132856572.png | Bin .../figures/zh-cn_image_0000001132875772.png | Bin .../figures/zh-cn_image_0000001132936268.png | Bin .../figures/zh-cn_image_0000001133104502.png | Bin .../figures/zh-cn_image_0000001133263576.png | Bin .../figures/zh-cn_image_0000001133264664.png | Bin .../figures/zh-cn_image_0000001143739220.png | Bin .../figures/zh-cn_image_0000001146437734.png | Bin 0 -> 43346 bytes .../figures/zh-cn_image_0000001153313284.png | Bin .../zh-cn_image_0000001153823524.png} | Bin .../zh-cn_image_0000001153832492.png} | Bin .../zh-cn_image_0000001153834574.png} | Bin .../zh-cn_image_0000001160018656.png} | Bin .../figures/zh-cn_image_0000001160338832.png | Bin .../figures/zh-cn_image_0000001165730464.png | Bin .../figures/zh-cn_image_0000001165890158.png | Bin .../figures/zh-cn_image_0000001165890518.png | Bin .../figures/zh-cn_image_0000001165890904.png | Bin .../zh-cn_image_0000001168711762.png} | Bin .../figures/zh-cn_image_0000001172904117.png | Bin .../figures/zh-cn_image_0000001173399977.png | Bin .../figures/zh-cn_image_0000001173586763.jpg | Bin .../figures/zh-cn_image_0000001175795145.png | Bin .../figures/zh-cn_image_0000001177654887.png | Bin .../figures/zh-cn_image_0000001178108019.png | Bin .../figures/zh-cn_image_0000001179103451.png | Bin .../figures/zh-cn_image_0000001179140185.png | Bin .../figures/zh-cn_image_0000001179142959.png | Bin .../figures/zh-cn_image_0000001180855455.png | Bin .../figures/zh-cn_image_0000001180952545.png | Bin .../figures/zh-cn_image_0000001189778871.png | Bin .../figures/zh-cn_image_0000001198253551.png | Bin 0 -> 75294 bytes .../figures/zh-cn_image_0000001199351155.png | Bin .../figures/zh-cn_image_0000001199352039.png | Bin .../figures/zh-cn_image_0000001199352445.png | Bin 0 -> 43346 bytes .../zh-cn_image_0000001199705711.png} | Bin .../zh-cn_image_0000001199706239.png} | Bin .../zh-cn_image_0000001199713709.png} | Bin .../zh-cn_image_0000001199736949.png} | Bin .../figures/zh-cn_image_0000001200292052.png | Bin .../zh-cn_image_0000001200452026.png} | Bin .../figures/zh-cn_image_0000001200612002.png | Bin .../figures/zh-cn_image_0000001200612006.png | Bin .../figures/zh-cn_image_0000001200771972.png | Bin .../figures/zh-cn_image_0000001211130993.png | Bin .../figures/zh-cn_image_0000001211449151.png | Bin .../figures/zh-cn_image_0000001214329013.png | Bin 0 -> 16523 bytes .../figures/zh-cn_image_0000001219007317.png | Bin .../figures/zh-cn_image_0000001245051881.png | Bin .../figures/zh-cn_image_0000001245171875.png | Bin .../figures/zh-cn_image_0000001245251887.png | Bin .../figures/zh-cn_image_0000001245411845.png | Bin .../kernel/kernel-basic-mini-time.md | 134 +- .../device-dev/kernel/kernel-memory-inner.md | 9 - zh-cn/device-dev/kernel/kernel-mini-app.md | 9 +- .../kernel/kernel-mini-appx-code.md | 174 +- .../kernel/kernel-mini-appx-data-list.md | 187 +- .../kernel/kernel-mini-appx-data.md | 5 +- .../kernel/kernel-mini-appx-lib-cmsis.md | 559 +---- .../kernel/kernel-mini-appx-lib-posix.md | 1806 ++--------------- .../device-dev/kernel/kernel-mini-appx-lib.md | 7 +- .../kernel-mini-basic-interrupt-concept.md | 37 - .../kernel-mini-basic-interrupt-guide.md | 130 -- .../kernel/kernel-mini-basic-interrupt.md | 135 +- .../kernel-mini-basic-ipc-event-basic.md | 50 - .../kernel-mini-basic-ipc-event-guide.md | 194 -- .../kernel/kernel-mini-basic-ipc-event.md | 215 +- .../kernel-mini-basic-ipc-mutex-basic.md | 19 - .../kernel-mini-basic-ipc-mutex-guide.md | 205 -- .../kernel/kernel-mini-basic-ipc-mutex.md | 204 +- .../kernel-mini-basic-ipc-queue-basic.md | 67 - .../kernel-mini-basic-ipc-queue-guide.md | 198 -- .../kernel/kernel-mini-basic-ipc-queue.md | 244 ++- .../kernel/kernel-mini-basic-ipc-sem-basic.md | 53 - .../kernel/kernel-mini-basic-ipc-sem-guide.md | 206 -- .../kernel/kernel-mini-basic-ipc-sem.md | 233 ++- .../kernel/kernel-mini-basic-ipc.md | 11 +- .../kernel/kernel-mini-basic-memory-basic.md | 17 +- .../kernel-mini-basic-memory-dynamic.md | 247 +-- .../kernel/kernel-mini-basic-memory-static.md | 146 +- .../kernel/kernel-mini-basic-memory.md | 9 +- .../kernel/kernel-mini-basic-soft-basic.md | 54 - .../kernel/kernel-mini-basic-soft-guide.md | 219 -- .../kernel/kernel-mini-basic-soft.md | 259 ++- .../kernel/kernel-mini-basic-task-basic.md | 96 - .../kernel/kernel-mini-basic-task-guide.md | 324 --- .../kernel/kernel-mini-basic-task.md | 314 ++- .../kernel/kernel-mini-basic-time-basic.md | 23 - .../kernel/kernel-mini-basic-time-guide.md | 157 -- zh-cn/device-dev/kernel/kernel-mini-basic.md | 15 +- .../kernel/kernel-mini-debug-lms.md | 293 --- zh-cn/device-dev/kernel/kernel-mini-debug.md | 10 + .../kernel/kernel-mini-extend-cpup-basic.md | 31 - .../kernel/kernel-mini-extend-cpup-guide.md | 163 -- .../kernel/kernel-mini-extend-cpup.md | 164 +- ...ernel-mini-extend-dynamic-loading-basic.md | 91 - ...ernel-mini-extend-dynamic-loading-guide.md | 187 -- .../kernel-mini-extend-dynamic-loading.md | 100 +- .../kernel/kernel-mini-extend-file-fat.md | 121 +- .../kernel/kernel-mini-extend-file-lit.md | 104 +- .../kernel-mini-extend-file-littlefs-basic.md | 6 - .../kernel-mini-extend-file-littlefs-guide.md | 95 - .../kernel/kernel-mini-extend-file.md | 223 +- .../kernel/kernel-mini-extend-support.md | 105 +- zh-cn/device-dev/kernel/kernel-mini-extend.md | 11 +- .../kernel/kernel-mini-imemory-debug-det.md | 73 +- .../kernel/kernel-mini-memory-debug-cet.md | 59 +- .../kernel/kernel-mini-memory-debug-mes.md | 56 +- .../kernel/kernel-mini-memory-debug.md | 9 +- .../kernel/kernel-mini-memory-exception.md | 557 +++-- .../kernel/kernel-mini-memory-lms.md | 251 +++ .../kernel/kernel-mini-memory-perf.md | 439 ++++ .../kernel/kernel-mini-memory-trace.md | 351 ++-- .../device-dev/kernel/kernel-mini-overview.md | 79 +- zh-cn/device-dev/kernel/kernel-mini.md | 13 +- .../kernel/kernel-small-apx-bitwise.md | 108 +- .../device-dev/kernel/kernel-small-apx-dll.md | 233 +-- .../kernel/kernel-small-apx-library.md | 80 +- .../kernel/kernel-small-apx-structure.md | 7 +- zh-cn/device-dev/kernel/kernel-small-apx.md | 7 +- .../kernel/kernel-small-basic-atomic.md | 251 +-- .../kernel-small-basic-inner-reflect.md | 125 +- .../kernel/kernel-small-basic-interrupt.md | 117 +- .../kernel/kernel-small-basic-memory-heap.md | 201 +- .../kernel-small-basic-memory-physical.md | 157 +- .../kernel-small-basic-memory-virtual.md | 400 +--- .../kernel/kernel-small-basic-memory.md | 11 +- .../kernel-small-basic-process-process.md | 215 +- .../kernel-small-basic-process-scheduler.md | 61 +- .../kernel-small-basic-process-thread.md | 266 +-- .../kernel/kernel-small-basic-process.md | 9 +- .../kernel/kernel-small-basic-softtimer.md | 179 +- .../kernel/kernel-small-basic-time.md | 112 +- .../kernel/kernel-small-basic-trans-event.md | 200 +- .../kernel/kernel-small-basic-trans-mutex.md | 232 +-- .../kernel/kernel-small-basic-trans-queue.md | 241 +-- .../kernel/kernel-small-basic-trans-rwlock.md | 157 +- .../kernel-small-basic-trans-semaphore.md | 185 +- .../kernel-small-basic-trans-user-mutex.md | 65 +- .../kernel-small-basic-trans-user-signal.md | 133 +- .../kernel/kernel-small-basic-trans.md | 17 +- .../device-dev/kernel/kernel-small-basics.md | 17 +- .../kernel/kernel-small-bundles-fs-new.md | 64 +- .../kernel-small-bundles-fs-support-fat.md | 53 +- .../kernel-small-bundles-fs-support-jffs2.md | 80 +- .../kernel-small-bundles-fs-support-nfs.md | 73 +- .../kernel-small-bundles-fs-support-procfs.md | 23 +- .../kernel-small-bundles-fs-support-ramfs.md | 24 +- .../kernel/kernel-small-bundles-fs-support.md | 13 +- .../kernel/kernel-small-bundles-fs-virtual.md | 719 +------ .../kernel/kernel-small-bundles-fs.md | 14 +- .../kernel/kernel-small-bundles-ipc.md | 76 +- .../kernel/kernel-small-bundles-linking.md | 95 +- .../kernel/kernel-small-bundles-share.md | 30 +- .../kernel/kernel-small-bundles-system.md | 292 +-- .../device-dev/kernel/kernel-small-bundles.md | 13 +- .../kernel-small-debug-memory-corrupt.md | 52 +- .../kernel/kernel-small-debug-memory-info.md | 56 +- .../kernel/kernel-small-debug-memory-leak.md | 74 +- .../kernel/kernel-small-debug-memory.md | 9 +- .../kernel/kernel-small-debug-other.md | 7 +- .../kernel/kernel-small-debug-perf.md | 506 ----- .../kernel/kernel-small-debug-process-cpu.md | 162 +- .../kernel/kernel-small-debug-process.md | 5 +- .../kernel/kernel-small-debug-shell-build.md | 191 +- .../kernel-small-debug-shell-cmd-cpup.md | 94 +- .../kernel-small-debug-shell-cmd-date.md | 96 +- .../kernel-small-debug-shell-cmd-dmesg.md | 175 +- .../kernel-small-debug-shell-cmd-exec.md | 61 +- .../kernel-small-debug-shell-cmd-free.md | 163 +- .../kernel-small-debug-shell-cmd-help.md | 52 +- .../kernel-small-debug-shell-cmd-hwi.md | 252 +-- .../kernel-small-debug-shell-cmd-kill.md | 206 +- .../kernel-small-debug-shell-cmd-log.md | 85 +- .../kernel-small-debug-shell-cmd-memcheck.md | 48 +- .../kernel-small-debug-shell-cmd-oom.md | 177 +- .../kernel-small-debug-shell-cmd-pmm.md | 105 +- .../kernel-small-debug-shell-cmd-reboot.md | 70 +- .../kernel-small-debug-shell-cmd-reset.md | 32 +- .../kernel-small-debug-shell-cmd-sem.md | 165 +- .../kernel-small-debug-shell-cmd-stack.md | 82 +- .../kernel/kernel-small-debug-shell-cmd-su.md | 90 +- .../kernel-small-debug-shell-cmd-swtmr.md | 145 +- .../kernel-small-debug-shell-cmd-sysinfo.md | 104 +- .../kernel-small-debug-shell-cmd-task.md | 154 +- .../kernel-small-debug-shell-cmd-top.md | 278 +-- .../kernel-small-debug-shell-cmd-uname.md | 106 +- .../kernel-small-debug-shell-cmd-vmm.md | 202 +- .../kernel-small-debug-shell-cmd-watch.md | 121 +- .../kernel/kernel-small-debug-shell-cmd.md | 51 +- .../kernel-small-debug-shell-details.md | 10 +- .../kernel/kernel-small-debug-shell-error.md | 147 +- .../kernel-small-debug-shell-file-cat.md | 60 +- .../kernel-small-debug-shell-file-cd.md | 78 +- .../kernel-small-debug-shell-file-chgrp.md | 79 +- .../kernel-small-debug-shell-file-chmod.md | 80 +- .../kernel-small-debug-shell-file-chown.md | 78 +- .../kernel-small-debug-shell-file-cp.md | 110 +- .../kernel-small-debug-shell-file-du.md | 145 +- .../kernel-small-debug-shell-file-format.md | 108 +- .../kernel-small-debug-shell-file-ls.md | 339 +--- .../kernel-small-debug-shell-file-lsfd.md | 33 +- .../kernel-small-debug-shell-file-mkdir.md | 121 +- .../kernel-small-debug-shell-file-mount.md | 111 +- .../kernel-small-debug-shell-file-mv.md | 226 +-- .../kernel-small-debug-shell-file-partinfo.md | 64 +- ...kernel-small-debug-shell-file-partition.md | 86 +- .../kernel-small-debug-shell-file-pwd.md | 36 +- .../kernel-small-debug-shell-file-rm.md | 111 +- .../kernel-small-debug-shell-file-rmdir.md | 106 +- .../kernel-small-debug-shell-file-statfs.md | 60 +- .../kernel-small-debug-shell-file-sync.md | 37 +- .../kernel-small-debug-shell-file-touch.md | 84 +- .../kernel-small-debug-shell-file-umount.md | 106 +- .../kernel-small-debug-shell-file-write.md | 89 +- .../kernel/kernel-small-debug-shell-file.md | 49 +- .../kernel/kernel-small-debug-shell-guide.md | 237 +-- .../kernel-small-debug-shell-magickey.md | 34 +- .../kernel-small-debug-shell-net-arp.md | 147 +- .../kernel-small-debug-shell-net-dhclient.md | 97 +- .../kernel-small-debug-shell-net-ifconfig.md | 443 ++-- .../kernel-small-debug-shell-net-ipdebug.md | 25 +- .../kernel-small-debug-shell-net-netstat.md | 98 +- .../kernel-small-debug-shell-net-ntpdate.md | 59 +- .../kernel-small-debug-shell-net-ping.md | 141 +- .../kernel-small-debug-shell-net-ping6.md | 209 +- .../kernel-small-debug-shell-net-telnet.md | 76 +- .../kernel-small-debug-shell-net-tftp.md | 110 +- .../kernel/kernel-small-debug-shell-net.md | 22 +- .../kernel-small-debug-shell-overview.md | 35 +- .../kernel/kernel-small-debug-shell.md | 15 +- .../kernel-small-debug-trace-other-faqs.md | 28 +- ...ernel-small-debug-trace-other-lastwords.md | 124 +- .../kernel/kernel-small-debug-trace.md | 495 ++--- .../kernel/kernel-small-debug-user-concept.md | 4 +- .../kernel/kernel-small-debug-user-faqs.md | 59 +- .../kernel-small-debug-user-function.md | 55 +- .../kernel-small-debug-user-guide-api.md | 64 +- .../kernel-small-debug-user-guide-use-api.md | 44 +- .../kernel-small-debug-user-guide-use-cli.md | 248 +-- .../kernel-small-debug-user-guide-use.md | 18 +- .../kernel/kernel-small-debug-user-guide.md | 7 +- .../kernel/kernel-small-debug-user.md | 17 +- zh-cn/device-dev/kernel/kernel-small-debug.md | 17 +- ...ebug-lms.md => kernel-small-memory-lms.md} | 314 ++- .../kernel/kernel-small-overview.md | 124 +- .../kernel/kernel-small-start-kernel.md | 135 +- .../kernel/kernel-small-start-user.md | 78 +- zh-cn/device-dev/kernel/kernel-small-start.md | 7 +- zh-cn/device-dev/kernel/kernel-small.md | 15 +- .../kernel/kernel-standard-build.md | 11 +- .../kernel/kernel-standard-overview.md | 16 +- .../kernel/kernel-standard-patch.md | 47 +- zh-cn/device-dev/kernel/kernel-standard.md | 8 +- zh-cn/device-dev/kernel/kernel.md | 9 +- .../public_sys-resources/icon-caution.gif | Bin 0 -> 580 bytes .../public_sys-resources/icon-danger.gif | Bin 0 -> 580 bytes .../kernel/public_sys-resources/icon-note.gif | Bin 0 -> 394 bytes .../public_sys-resources/icon-notice.gif | Bin 0 -> 406 bytes .../kernel/public_sys-resources/icon-tip.gif | Bin 0 -> 253 bytes .../public_sys-resources/icon-warning.gif | Bin 0 -> 580 bytes 577 files changed, 18156 insertions(+), 21053 deletions(-) delete mode 100644 en/device-dev/kernel/figure/changing-the-directory.png delete mode 100644 en/device-dev/kernel/figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png delete mode 100644 en/device-dev/kernel/figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png delete mode 100644 en/device-dev/kernel/figure/changing-the-permission-for-the-hello-harmony-txt-file-to-666.png delete mode 100644 en/device-dev/kernel/figure/command-output-24.png delete mode 100644 en/device-dev/kernel/figure/command-output.png delete mode 100644 en/device-dev/kernel/figure/cpu-usage.png delete mode 100644 en/device-dev/kernel/figure/creating-file-c.png delete mode 100644 en/device-dev/kernel/figure/creating-the-share-directory.png delete mode 100644 en/device-dev/kernel/figure/deleting-directory-dir.png delete mode 100644 en/device-dev/kernel/figure/deleting-the-log1-txt-file.png delete mode 100644 en/device-dev/kernel/figure/deleting-the-sd-directory.png delete mode 100644 en/device-dev/kernel/figure/displaying-content-of-the-current-directory.png delete mode 100644 en/device-dev/kernel/figure/displaying-the-content-of-hello-harmony-txt.png delete mode 100644 en/device-dev/kernel/figure/displaying-the-current-path.png delete mode 100644 en/device-dev/kernel/figure/displaying-the-memory-usage-in-three-units.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001127519136.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001127520662.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001132778524.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001133848164.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001133848370.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001133848906.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001134008030.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001134008686.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001134008688.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001173449871.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001176974089.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001179847649.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001179848349.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001179848731.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001179967527.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001179967909.png delete mode 100644 en/device-dev/kernel/figure/en-us_image_0000001191018697.png delete mode 100644 en/device-dev/kernel/figure/event-working-mechanism.png delete mode 100644 en/device-dev/kernel/figure/file-copying-result.png delete mode 100644 en/device-dev/kernel/figure/heap-memory-core-algorithm.png delete mode 100644 en/device-dev/kernel/figure/kernel-architecture.png delete mode 100644 en/device-dev/kernel/figure/mutex-working-mechanism.png delete mode 100644 en/device-dev/kernel/figure/no-out-of-bounds-memory-access.png delete mode 100644 en/device-dev/kernel/figure/out-of-bounds-memory-access.png delete mode 100644 en/device-dev/kernel/figure/output-of-telnet-on.png delete mode 100644 en/device-dev/kernel/figure/output-of-the-statfs-command.png delete mode 100644 en/device-dev/kernel/figure/process-of-creating-a-vnode.png delete mode 100644 en/device-dev/kernel/figure/process-of-locating-a-file.png delete mode 100644 en/device-dev/kernel/figure/program-execution-process.png delete mode 100644 en/device-dev/kernel/figure/querying-information-about-all-semaphores-in-use.png delete mode 100644 en/device-dev/kernel/figure/querying-information-about-all-software-timers.png delete mode 100644 en/device-dev/kernel/figure/querying-information-about-software-timer-1.png delete mode 100644 en/device-dev/kernel/figure/querying-partial-task-information.png delete mode 100644 en/device-dev/kernel/figure/querying-pids.png delete mode 100644 en/device-dev/kernel/figure/reading-and-writing-data-in-a-queue.png delete mode 100644 en/device-dev/kernel/figure/semaphore-working-mechanism.png delete mode 100644 en/device-dev/kernel/figure/sending-a-signal-to-a-specified-process.png delete mode 100644 en/device-dev/kernel/figure/signal-sending-failure.png delete mode 100644 en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58-25.png delete mode 100644 en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58-26.png delete mode 100644 en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58.png delete mode 100644 en/device-dev/kernel/figure/stack-analysis-mechanism.png delete mode 100644 en/device-dev/kernel/figure/static-memory.png delete mode 100644 en/device-dev/kernel/figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png delete mode 100644 en/device-dev/kernel/figure/system-date-printed-based-on-the-specified-format.png delete mode 100644 en/device-dev/kernel/figure/task-command-monitoring-result.png delete mode 100644 en/device-dev/kernel/figure/task-state-transition.png delete mode 100644 en/device-dev/kernel/figure/unmounting-result.png delete mode 100644 en/device-dev/kernel/figure/usage-of-system-resources.png delete mode 100644 en/device-dev/kernel/figure/viewing-the-usage-of-physical-pages.png delete mode 100644 en/device-dev/kernel/figure/virtual-memory-usage-of-the-process-with-pid-3.png delete mode 100644 en/device-dev/kernel/figure/writing-dmesg-content-to-a-file.png rename en/device-dev/kernel/{figure => figures}/adding-a-check-value-to-the-node-header-information.png (100%) create mode 100644 en/device-dev/kernel/figures/architecture-of-the-openharmony-liteos-a-kernel.png rename en/device-dev/kernel/{figure => figures}/cpu-accessing-the-memory-or-peripheral.png (100%) rename en/device-dev/kernel/{figure => figures}/cpu-accessing-the-memory.png (100%) rename en/device-dev/kernel/{figure => figures}/dynamic-loading-process.png (100%) rename en/device-dev/kernel/{figure/dynamic-memory-core-algorithm.png => figures/dynamic-memory-algorithm-for-mini-systems.png} (100%) rename "zh-cn/device-dev/kernel/figure/\350\275\273\351\207\217\347\263\273\347\273\237\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" => en/device-dev/kernel/figures/dynamic-memory-algorithm-for-small-systems.png (100%) rename en/device-dev/kernel/{figure/dynamic-memory-management-structure.png => figures/dynamic-memory-management-structure-for-mini-systems.png} (100%) rename en/device-dev/kernel/{figure/dynamic-memory-management-structure-20.png => figures/dynamic-memory-management-structure-for-system-systems.png} (100%) rename en/device-dev/kernel/{figure => figures}/elf-file-linking-process.png (100%) create mode 100644 en/device-dev/kernel/figures/event-working-mechanism-for-mini-systems.png rename en/device-dev/kernel/{figure/event-working-mechanism-21.png => figures/event-working-mechanism-for-small-systems.png} (100%) rename en/device-dev/kernel/{figure/en-us_image_0000001173429547.png => figures/exception-information.png} (100%) rename en/device-dev/kernel/{figure => figures}/exported-symbol-table-information.png (100%) rename en/device-dev/kernel/{figure => figures}/futex-design.jpg (100%) rename en/device-dev/kernel/{figure => figures}/heap-memory-node-information.png (100%) rename en/device-dev/kernel/{figure => figures}/heap-memory-node-linked-list.png (100%) create mode 100644 en/device-dev/kernel/figures/how-to-develop.png rename "zh-cn/device-dev/kernel/figure/\351\235\236\350\277\236\347\273\255\346\200\247\345\206\205\345\255\230\345\220\210\344\270\200\347\244\272\346\204\217\345\233\276.png" => en/device-dev/kernel/figures/integrating-discontiguous-memory-regions.png (100%) create mode 100644 en/device-dev/kernel/figures/interrupt-vector-table.png create mode 100644 en/device-dev/kernel/figures/kernel-architecture.png create mode 100644 en/device-dev/kernel/figures/kernel-small-mode-process-4.png rename en/device-dev/kernel/{figure/en-us_image_0000001127390512.png => figures/kernel-small-mode-process.png} (100%) rename en/device-dev/kernel/{figure/en-us_image_0000001178856385.png => figures/kernel-startup-process-2.png} (100%) rename en/device-dev/kernel/{figure => figures}/kernel-startup-process.png (100%) rename en/device-dev/kernel/{figure => figures}/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png (100%) rename en/device-dev/kernel/{figure => figures}/liteos-m-kernel-dynamic-loading-architecture.png (100%) rename en/device-dev/kernel/{figure => figures}/mapping-between-the-virtual-and-physical-memory-addresses.png (100%) create mode 100644 en/device-dev/kernel/figures/mutex-working-mechanism-for-mini-systems.png rename en/device-dev/kernel/{figure/mutex-working-mechanism-23.png => figures/mutex-working-mechanism-for-small-systems.png} (100%) rename en/device-dev/kernel/{figure => figures}/overall-file-system-architecture.png (100%) rename en/device-dev/kernel/{figure => figures}/physical-memory-usage-distribution.png (100%) rename en/device-dev/kernel/{figure => figures}/posix-framework.png (100%) create mode 100644 en/device-dev/kernel/figures/process-management.png create mode 100644 en/device-dev/kernel/figures/process-of-creating-a-vnode.png rename en/device-dev/kernel/{figure => figures}/process-of-loading-an-elf-file.png (100%) create mode 100644 en/device-dev/kernel/figures/process-of-locating-a-file.png rename en/device-dev/kernel/{figure => figures}/process-of-locating-the-code-lines-for-a-memory-leak.png (100%) rename en/device-dev/kernel/{figure => figures}/process-of-releasing-memory.png (100%) rename en/device-dev/kernel/{figure => figures}/process-state-transition.png (100%) rename en/device-dev/kernel/{figure => figures}/process-tree.png (100%) create mode 100644 en/device-dev/kernel/figures/program-execution-process.png rename en/device-dev/kernel/{figure/en-us_image_0000001132935054.png => figures/reading-and-writing-data-in-a-queue-3.png} (100%) create mode 100644 en/device-dev/kernel/figures/reading-and-writing-data-in-a-queue.png rename en/device-dev/kernel/{figure => figures}/releasing-memory.png (100%) rename en/device-dev/kernel/{figure => figures}/requesting-memory.png (100%) create mode 100644 en/device-dev/kernel/figures/scheduling-priority-bucket-queue.png create mode 100644 en/device-dev/kernel/figures/scheduling-process.png create mode 100644 en/device-dev/kernel/figures/semaphore-working-mechanism-for-mini-systems.png rename en/device-dev/kernel/{figure/semaphore-working-mechanism-22.png => figures/semaphore-working-mechanism-for-small-systems.png} (100%) create mode 100644 en/device-dev/kernel/figures/stack-analysis-mechanism.png create mode 100644 en/device-dev/kernel/figures/static-memory.png rename en/device-dev/kernel/{figure => figures}/system-call.png (100%) rename en/device-dev/kernel/{figure/thread-state-transition.png => figures/task-state-transition.png} (100%) create mode 100644 en/device-dev/kernel/figures/task-state-transitions.png rename en/device-dev/kernel/{figure => figures}/vdso-system-design.jpg (100%) delete mode 100644 en/device-dev/kernel/kernel-mini-basic-interrupt-concept.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-interrupt-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-soft-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-soft-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-task-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-task-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-time-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-basic-time-guide.md rename en/device-dev/kernel/{kernel-memory-inner.md => kernel-mini-debug.md} (67%) delete mode 100644 en/device-dev/kernel/kernel-mini-extend-cpup-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-extend-cpup-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md delete mode 100644 en/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md delete mode 100644 en/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md create mode 100644 en/device-dev/kernel/kernel-mini-memory-lms.md create mode 100644 en/device-dev/kernel/kernel-mini-memory-perf.md create mode 100644 en/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md create mode 100644 en/device-dev/kernel/kernel-small-debug-shell-cmd-top.md create mode 100644 en/device-dev/kernel/kernel-small-debug-shell-file-du.md create mode 100644 en/device-dev/kernel/kernel-small-debug-shell-file-mv.md delete mode 100644 en/device-dev/kernel/kernel-small-debug-shell-net-dns.md create mode 100644 en/device-dev/kernel/kernel-small-memory-lms.md delete mode 100644 zh-cn/device-dev/kernel/figure/zh-cn_image_0000001134008688.png delete mode 100644 "zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225-19.png" delete mode 100644 "zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" delete mode 100755 "zh-cn/device-dev/kernel/figure/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" delete mode 100755 "zh-cn/device-dev/kernel/figure/\347\272\277\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" rename "zh-cn/device-dev/kernel/figure/\346\226\207\344\273\266\347\263\273\347\273\237\347\232\204\346\200\273\344\275\223\347\273\223\346\236\204.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001125101908.png (100%) rename "zh-cn/device-dev/kernel/figure/Vnode\345\210\233\345\273\272\346\265\201\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001127393126.png (100%) rename "zh-cn/device-dev/kernel/figure/Futex\350\256\276\350\256\241\345\233\276.jpg" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001127535690.jpg (100%) rename "zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276-22.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001132774752.png (100%) rename "zh-cn/device-dev/kernel/figure/\347\263\273\347\273\237\350\260\203\347\224\250\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001132856572.png (100%) rename "zh-cn/device-dev/kernel/figure/\351\230\237\345\210\227\350\257\273\345\206\231\346\225\260\346\215\256\346\223\215\344\275\234\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001132875772.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\240\206\346\240\210\345\210\206\346\236\220\345\216\237\347\220\206\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001132936268.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\212\240\350\275\275\346\265\201\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001133104502.png (100%) rename "zh-cn/device-dev/kernel/figure/CPU\350\256\277\351\227\256\345\206\205\345\255\230\346\210\226\345\244\226\350\256\276\347\232\204\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001133263576.png (100%) rename "zh-cn/device-dev/kernel/figure/\347\250\213\345\272\217\346\211\247\350\241\214\346\265\201\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001133264664.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\206\205\345\255\230\351\207\212\346\224\276\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001143739220.png (100%) create mode 100644 zh-cn/device-dev/kernel/figures/zh-cn_image_0000001146437734.png rename "zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001153313284.png (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001173429547.png => figures/zh-cn_image_0000001153823524.png} (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001178856385.png => figures/zh-cn_image_0000001153832492.png} (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001132778524.png => figures/zh-cn_image_0000001153834574.png} (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001191018697.png => figures/zh-cn_image_0000001160018656.png} (100%) rename "zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\345\220\257\345\212\250\346\265\201\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001160338832.png (100%) rename "zh-cn/device-dev/kernel/figure/\346\263\204\346\274\217\347\202\271\344\273\243\347\240\201\350\241\214\345\256\232\344\275\215\346\265\201\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001165730464.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\240\206\345\206\205\345\255\230\350\212\202\347\202\271\344\277\241\346\201\257\351\223\276\350\241\250.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001165890158.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\240\206\345\206\205\345\255\230\350\212\202\347\202\271\344\277\241\346\201\257.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001165890518.png (100%) rename "zh-cn/device-dev/kernel/figure/free\346\265\201\347\250\213\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001165890904.png (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001127390512.png => figures/zh-cn_image_0000001168711762.png} (100%) rename "zh-cn/device-dev/kernel/figure/POSIX\346\216\245\345\217\243\346\241\206\346\236\266.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001172904117.png (100%) mode change 100755 => 100644 rename "zh-cn/device-dev/kernel/figure/\344\273\273\345\212\241\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001173399977.png (100%) rename "zh-cn/device-dev/kernel/figure/VDSO\347\263\273\347\273\237\350\256\276\350\256\241.jpg" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001173586763.jpg (100%) rename "zh-cn/device-dev/kernel/figure/\346\226\207\344\273\266\346\237\245\346\211\276\346\265\201\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001175795145.png (100%) rename "zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276-23.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001177654887.png (100%) rename "zh-cn/device-dev/kernel/figure/\350\277\233\347\250\213\346\240\221\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001178108019.png (100%) rename "zh-cn/device-dev/kernel/figure/CPU\350\256\277\351\227\256\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001179103451.png (100%) rename "zh-cn/device-dev/kernel/figure/\347\211\251\347\220\206\345\206\205\345\255\230\344\275\277\347\224\250\345\210\206\345\270\203\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001179140185.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\206\205\345\255\230\346\230\240\345\260\204\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001179142959.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\347\256\241\347\220\206\347\273\223\346\236\204\345\233\276-20.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001180855455.png (100%) rename "zh-cn/device-dev/kernel/figure/\344\272\213\344\273\266\350\277\220\344\275\234\345\216\237\347\220\206\345\233\276-21.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001180952545.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\206\205\345\255\230\347\224\263\350\257\267\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001189778871.png (100%) create mode 100644 zh-cn/device-dev/kernel/figures/zh-cn_image_0000001198253551.png rename "zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199351155.png (100%) rename "zh-cn/device-dev/kernel/figure/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199352039.png (100%) create mode 100644 zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199352445.png rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001127520662.png => figures/zh-cn_image_0000001199705711.png} (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001176974089.png => figures/zh-cn_image_0000001199706239.png} (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001173449871.png => figures/zh-cn_image_0000001199713709.png} (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001127519136.png => figures/zh-cn_image_0000001199736949.png} (100%) rename "zh-cn/device-dev/kernel/figure/LiteOS-M\345\206\205\346\240\270\345\212\250\346\200\201\345\212\240\350\275\275\346\236\266\346\236\204\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001200292052.png (100%) rename zh-cn/device-dev/kernel/{figure/zh-cn_image_0000001132935054.png => figures/zh-cn_image_0000001200452026.png} (100%) rename "zh-cn/device-dev/kernel/figure/\344\273\273\345\212\241\347\212\266\346\200\201\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001200612002.png (100%) rename "zh-cn/device-dev/kernel/figure/ELF\346\226\207\344\273\266\347\232\204\351\223\276\346\216\245\350\277\207\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001200612006.png (100%) rename "zh-cn/device-dev/kernel/figure/\344\272\213\344\273\266\350\277\220\344\275\234\345\216\237\347\220\206\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001200771972.png (100%) rename "zh-cn/device-dev/kernel/figure/malloc\351\200\232\350\277\207mmap\346\234\272\345\210\266\347\224\263\350\257\267\345\206\205\345\255\230\347\232\204\345\206\205\345\255\230\345\270\203\345\261\200.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001211130993.png (100%) rename "zh-cn/device-dev/kernel/figure/node\350\212\202\347\202\271\345\244\264\344\277\241\346\201\257\346\267\273\345\212\240\346\240\241\351\252\214\345\200\274.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001211449151.png (100%) create mode 100644 zh-cn/device-dev/kernel/figures/zh-cn_image_0000001214329013.png rename "zh-cn/device-dev/kernel/figure/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001219007317.png (100%) mode change 100755 => 100644 rename "zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245051881.png (100%) rename "zh-cn/device-dev/kernel/figure/\345\257\274\345\207\272\347\232\204\347\254\246\345\217\267\350\241\250\344\277\241\346\201\257.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245171875.png (100%) rename "zh-cn/device-dev/kernel/figure/ELF\346\226\207\344\273\266\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245251887.png (100%) rename "zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" => zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245411845.png (100%) delete mode 100644 zh-cn/device-dev/kernel/kernel-memory-inner.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-concept.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-soft-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-soft-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-task-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-task-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-time-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-basic-time-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-debug-lms.md create mode 100644 zh-cn/device-dev/kernel/kernel-mini-debug.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-extend-cpup-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-extend-cpup-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md delete mode 100644 zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md create mode 100644 zh-cn/device-dev/kernel/kernel-mini-memory-lms.md create mode 100644 zh-cn/device-dev/kernel/kernel-mini-memory-perf.md delete mode 100644 zh-cn/device-dev/kernel/kernel-small-debug-perf.md rename zh-cn/device-dev/kernel/{kernel-small-debug-lms.md => kernel-small-memory-lms.md} (59%) create mode 100644 zh-cn/device-dev/kernel/public_sys-resources/icon-caution.gif create mode 100644 zh-cn/device-dev/kernel/public_sys-resources/icon-danger.gif create mode 100644 zh-cn/device-dev/kernel/public_sys-resources/icon-note.gif create mode 100644 zh-cn/device-dev/kernel/public_sys-resources/icon-notice.gif create mode 100644 zh-cn/device-dev/kernel/public_sys-resources/icon-tip.gif create mode 100644 zh-cn/device-dev/kernel/public_sys-resources/icon-warning.gif diff --git a/en/device-dev/Readme-EN.md b/en/device-dev/Readme-EN.md index 91e7aa031b..1668634117 100644 --- a/en/device-dev/Readme-EN.md +++ b/en/device-dev/Readme-EN.md @@ -66,7 +66,7 @@ In addition, OpenHarmony provides a series of optional system components that ca

Using basic capabilities of OpenHarmony

- +

Advanced development

diff --git a/en/device-dev/kernel/Readme-EN.md b/en/device-dev/kernel/Readme-EN.md index 3ef7872307..db98e9eb28 100644 --- a/en/device-dev/kernel/Readme-EN.md +++ b/en/device-dev/kernel/Readme-EN.md @@ -1,197 +1,175 @@ # Kernel -- [Kernel for Mini and Small Systems](kernel-lite.md) - - [Kernel for Mini Systems](kernel-lite-mini.md) - - [Kernel Overview](kernel-mini-overview.md) - - [Basic Kernel](kernel-mini-basic.md) - - [Interrupt Management](kernel-mini-basic-interrupt.md) - - [Basic Concepts](kernel-mini-basic-interrupt-concept.md) - - [Development Guidelines](kernel-mini-basic-interrupt-guide.md) - - [Task Management](kernel-mini-basic-task.md) - - [Basic Concepts](kernel-mini-basic-task-basic.md) - - [Development Guidelines](kernel-mini-basic-task-guide.md) - - [Memory Management](kernel-mini-basic-memory.md) - - [Basic Concepts](kernel-mini-basic-memory-basic.md) - - [Static Memory](kernel-mini-basic-memory-static.md) - - [Dynamic Memory](kernel-mini-basic-memory-dynamic.md) - - [Kernel Communication Mechanisms](kernel-mini-basic-ipc.md) - - [Event](kernel-mini-basic-ipc-event.md) - - [Basic Concepts](kernel-mini-basic-ipc-event-basic.md) - - [Development Guidelines](kernel-mini-basic-ipc-event-guide.md) - - [Mutex](kernel-mini-basic-ipc-mutex.md) - - [Basic Concepts](kernel-mini-basic-ipc-mutex-basic.md) - - [Development Guidelines](kernel-mini-basic-ipc-mutex-guide.md) - - [Queue](kernel-mini-basic-ipc-queue.md) - - [Basic Concepts](kernel-mini-basic-ipc-queue-basic.md) - - [Development Guidelines](kernel-mini-basic-ipc-queue-guide.md) - - [Semaphore](kernel-mini-basic-ipc-sem.md) - - [Basic Concepts](kernel-mini-basic-ipc-sem-basic.md) - - [Development Guidelines](kernel-mini-basic-ipc-sem-guide.md) - - [Time Management](kernel-basic-mini-time.md) - - [Basic Concepts](kernel-mini-basic-time-basic.md) - - [Development Guidelines](kernel-mini-basic-time-guide.md) - - [Software Timer](kernel-mini-basic-soft.md) - - [Basic Concepts](kernel-mini-basic-soft-basic.md) - - [Development Guidelines](kernel-mini-basic-soft-guide.md) - - [Extension Components](kernel-mini-extend.md) - - [C++ Support](kernel-mini-extend-support.md) - - [CPUP](kernel-mini-extend-cpup.md) - - [Basic Concepts](kernel-mini-extend-cpup-basic.md) - - [Development Guidelines](kernel-mini-extend-cpup-guide.md) - - [Dynamic Loading](kernel-mini-extend-dynamic-loading.md) - - [Basic Concepts](kernel-mini-extend-dynamic-loading-basic.md) - - [Development Guidelines](kernel-mini-extend-dynamic-loading-guide.md) - - [File System](kernel-mini-extend-file.md) - - [FAT](kernel-mini-extend-file-fat.md) - - [LittleFS](kernel-mini-extend-file-lit.md) - - [Basic Concepts](kernel-mini-extend-file-littlefs-basic.md) - - [Development Guidelines](kernel-mini-extend-file-littlefs-guide.md) - - [Kernel Debugging](kernel-memory-inner.md) - - [Memory Debugging](kernel-mini-memory-debug.md) - - [Memory Information Statistics](kernel-mini-memory-debug-mes.md) - - [Memory Leak Check](kernel-mini-imemory-debug-det.md) - - [Memory Corruption Check](kernel-mini-memory-debug-cet.md) - - [Exception Debugging](kernel-mini-memory-exception.md) - - [Trace](kernel-mini-memory-trace.md) - - [LMS](kernel-mini-debug-lms.md) - - [Appendix](kernel-mini-app.md) - - [Kernel Coding Specification](kernel-mini-appx-code.md) - - [Basic Data Structure](kernel-mini-appx-data.md) - - [Doubly Linked List](kernel-mini-appx-data-list.md) - - [Standard Libraries](kernel-mini-appx-lib.md) - - [CMSIS Support](kernel-mini-appx-lib-cmsis.md) - - [POSIX Support](kernel-mini-appx-lib-posix.md) - - [Kernel for Small Systems](kernel-lite-small.md) - - [Kernel Overview](kernel-small-overview.md) - - [Kernel Startup](kernel-small-start.md) - - [Startup in Kernel Space](kernel-small-start-kernel.md) - - [Startup in User Space](kernel-small-start-user.md) - - [Basic Kernel](kernel-small-basics.md) - - [Interrupt and Exception Handling](kernel-small-basic-interrupt.md) - - [Process Management](kernel-small-basic-process.md) - - [Process](kernel-small-basic-process-process.md) - - [Task](kernel-small-basic-process-thread.md) - - [Scheduler](kernel-small-basic-process-scheduler.md) - - [Memory Management](kernel-small-basic-memory.md) - - [Heap Memory Management](kernel-small-basic-memory-heap.md) - - [Physical Memory Management](kernel-small-basic-memory-physical.md) - - [Virtual Memory Management](kernel-small-basic-memory-virtual.md) - - [Virtual-to-Physical Mapping](kernel-small-basic-inner-reflect.md) - - [Kernel Communication Mechanisms](kernel-small-basic-trans.md) - - [Event](kernel-small-basic-trans-event.md) - - [Semaphore](kernel-small-basic-trans-semaphore.md) - - [Mutex](kernel-small-basic-trans-mutex.md) - - [Queue](kernel-small-basic-trans-queue.md) - - [RW Lock](kernel-small-basic-trans-rwlock.md) - - [Futex](kernel-small-basic-trans-user-mutex.md) - - [Signal](kernel-small-basic-trans-user-signal.md) - - [Time Management](kernel-small-basic-time.md) - - [Software Timer](kernel-small-basic-softtimer.md) - - [Atomic Operation](kernel-small-basic-atomic.md) - - [Extension Components](kernel-small-bundles.md) - - [System Call](kernel-small-bundles-system.md) - - [Dynamic Loading and Linking](kernel-small-bundles-linking.md) - - [Virtual Dynamic Shared Object](kernel-small-bundles-share.md) - - [LiteIPC](kernel-small-bundles-ipc.md) - - [File Systems](kernel-small-bundles-fs.md) - - [Virtual File System](kernel-small-bundles-fs-virtual.md) - - [Supported File Systems](kernel-small-bundles-fs-support.md) - - [FAT](kernel-small-bundles-fs-support-fat.md) - - [JFFS2](kernel-small-bundles-fs-support-jffs2.md) - - [NFS](kernel-small-bundles-fs-support-nfs.md) - - [Ramfs](kernel-small-bundles-fs-support-ramfs.md) - - [procfs](kernel-small-bundles-fs-support-procfs.md) - - [File System Adaptation](kernel-small-bundles-fs-new.md) - - [Debugging and Tools](kernel-small-debug.md) - - [Shell](kernel-small-debug-shell.md) - - [Introduction to the Shell](kernel-small-debug-shell-overview.md) - - [Shell Command Development Guidelines](kernel-small-debug-shell-guide.md) - - [Shell Command Programming Example](kernel-small-debug-shell-build.md) - - [Shell Command Reference](kernel-small-debug-shell-details.md) - - [System Commands](kernel-small-debug-shell-cmd.md) - - [cpup](kernel-small-debug-shell-cmd-cpup.md) - - [date](kernel-small-debug-shell-cmd-date.md) - - [dmesg](kernel-small-debug-shell-cmd-dmesg.md) - - [exec](kernel-small-debug-shell-cmd-exec.md) - - [free](kernel-small-debug-shell-cmd-free.md) - - [help](kernel-small-debug-shell-cmd-help.md) - - [hwi](kernel-small-debug-shell-cmd-hwi.md) - - [kill](kernel-small-debug-shell-cmd-kill.md) - - [log](kernel-small-debug-shell-cmd-log.md) - - [memcheck](kernel-small-debug-shell-cmd-memcheck.md) - - [oom](kernel-small-debug-shell-cmd-oom.md) - - [pmm](kernel-small-debug-shell-cmd-pmm.md) - - [reset](kernel-small-debug-shell-cmd-reset.md) - - [sem](kernel-small-debug-shell-cmd-sem.md) - - [stack](kernel-small-debug-shell-cmd-stack.md) - - [su](kernel-small-debug-shell-cmd-su.md) - - [swtmr](kernel-small-debug-shell-cmd-swtmr.md) - - [systeminfo](kernel-small-debug-shell-cmd-sysinfo.md) - - [task](kernel-small-debug-shell-cmd-task.md) - - [uname](kernel-small-debug-shell-cmd-uname.md) - - [vmm](kernel-small-debug-shell-cmd-vmm.md) - - [watch](kernel-small-debug-shell-cmd-watch.md) - - [File Commands](kernel-small-debug-shell-file.md) - - [cat](kernel-small-debug-shell-file-cat.md) - - [cd](kernel-small-debug-shell-file-cd.md) - - [chgrp](kernel-small-debug-shell-file-chgrp.md) - - [chmod](kernel-small-debug-shell-file-chmod.md) - - [chown](kernel-small-debug-shell-file-chown.md) - - [cp](kernel-small-debug-shell-file-cp.md) - - [format](kernel-small-debug-shell-file-format.md) - - [ls](kernel-small-debug-shell-file-ls.md) - - [lsfd](kernel-small-debug-shell-file-lsfd.md) - - [mkdir](kernel-small-debug-shell-file-mkdir.md) - - [mount](kernel-small-debug-shell-file-mount.md) - - [partinfo](kernel-small-debug-shell-file-partinfo.md) - - [partition](kernel-small-debug-shell-file-partition.md) - - [pwd](kernel-small-debug-shell-file-pwd.md) - - [rm](kernel-small-debug-shell-file-rm.md) - - [rmdir](kernel-small-debug-shell-file-rmdir.md) - - [statfs](kernel-small-debug-shell-file-statfs.md) - - [sync](kernel-small-debug-shell-file-sync.md) - - [touch](kernel-small-debug-shell-file-touch.md) - - [writeproc](kernel-small-debug-shell-file-write.md) - - [umount](kernel-small-debug-shell-file-umount.md) - - [Network Commands](kernel-small-debug-shell-net.md) - - [arp](kernel-small-debug-shell-net-arp.md) - - [dhclient](kernel-small-debug-shell-net-dhclient.md) - - [ifconfig](kernel-small-debug-shell-net-ifconfig.md) - - [ipdebug](kernel-small-debug-shell-net-ipdebug.md) - - [netstat](kernel-small-debug-shell-net-netstat.md) - - [ntpdate](kernel-small-debug-shell-net-ntpdate.md) - - [ping](kernel-small-debug-shell-net-ping.md) - - [ping6](kernel-small-debug-shell-net-ping6.md) - - [telnet](kernel-small-debug-shell-net-telnet.md) - - [tftp](kernel-small-debug-shell-net-tftp.md) - - [Magic Key](kernel-small-debug-shell-magickey.md) - - [User-Space Exception Information](kernel-small-debug-shell-error.md) - - [Trace](kernel-small-debug-trace.md) - - [perf](kernel-small-debug-perf.md) - - [LMS](kernel-small-debug-lms.md) - - [Process Commissioning](kernel-small-debug-process.md) - - [CPUP](kernel-small-debug-process-cpu.md) - - [Memory Debugging](kernel-small-debug-memory.md) - - [Memory Information Statistics](kernel-small-debug-memory-info.md) - - [Memory Leak Check](kernel-small-debug-memory-leak.md) - - [Memory Corruption Check](kernel-small-debug-memory-corrupt.md) - - [User-Mode Memory Debugging](kernel-small-debug-user.md) - - [Basic Concepts](kernel-small-debug-user-concept.md) - - [Working Principles](kernel-small-debug-user-function.md) - - [Usage](kernel-small-debug-user-guide.md) - - [API Description](kernel-small-debug-user-guide-api.md) - - [How to Use](kernel-small-debug-user-guide-use.md) - - [Calling APIs](kernel-small-debug-user-guide-use-api.md) - - [Using the CLI](kernel-small-debug-user-guide-use-cli.md) - - [Typical Memory Problems](kernel-small-debug-user-faqs.md) - - [Other Kernel Debugging Methods](kernel-small-debug-other.md) - - [Dying Gasp](kernel-small-debug-trace-other-lastwords.md) - - [Common Fault Locating Methods](kernel-small-debug-trace-other-faqs.md) - - [Appendix](kernel-small-apx.md) - - [Basic Data Structure](kernel-small-apx-structure.md) - - [Doubly Linked List](kernel-small-apx-dll.md) - - [Bitwise Operation](kernel-small-apx-bitwise.md) - - [Standard Library](kernel-small-apx-library.md) +- [Kernel for Mini Systems](kernel-mini.md) + - [Kernel Overview](kernel-mini-overview.md) + - [Basic Kernel](kernel-mini-basic.md) + - [Interrupt Management](kernel-mini-basic-interrupt.md) + - [Task Management](kernel-mini-basic-task.md) + - [Memory Management](kernel-mini-basic-memory.md) + - [Basic Concepts](kernel-mini-basic-memory-basic.md) + - [Static Memory](kernel-mini-basic-memory-static.md) + - [Dynamic Memory](kernel-mini-basic-memory-dynamic.md) + - [Kernel Communication Mechanisms](kernel-mini-basic-ipc.md) + - [Event](kernel-mini-basic-ipc-event.md) + - [Mutex](kernel-mini-basic-ipc-mutex.md) + - [Queue](kernel-mini-basic-ipc-queue.md) + - [Semaphore](kernel-mini-basic-ipc-sem.md) + - [Time Management](kernel-basic-mini-time.md) + - [Software Timer](kernel-mini-basic-soft.md) + - [Extended Components](kernel-mini-extend.md) + - [C++ Support](kernel-mini-extend-support.md) + - [CPUP](kernel-mini-extend-cpup.md) + - [Dynamic Loading](kernel-mini-extend-dynamic-loading.md) + - [File System](kernel-mini-extend-file.md) + - [FAT](kernel-mini-extend-file-fat.md) + - [LittleFS](kernel-mini-extend-file-lit.md) + - [Kernel Debugging](kernel-mini-debug.md) + - [Memory Debugging](kernel-mini-memory-debug.md) + - [Memory Information Statistics](kernel-mini-memory-debug-mes.md) + - [Memory Leak Check](kernel-mini-imemory-debug-det.md) + - [Memory Corruption Check](kernel-mini-memory-debug-cet.md) + - [Exception Debugging](kernel-mini-memory-exception.md) + - [Trace](kernel-mini-memory-trace.md) + - [LMS](kernel-mini-memory-lms.md) + - [Appendix](kernel-mini-app.md) + - [Kernel Coding Specification](kernel-mini-appx-code.md) + - [Basic Data Structure](kernel-mini-appx-data.md) + - [Doubly Linked List](kernel-mini-appx-data-list.md) + - [Standard Libraries](kernel-mini-appx-lib.md) + - [CMSIS Support](kernel-mini-appx-lib-cmsis.md) + - [POSIX Support](kernel-mini-appx-lib-posix.md) +- [Kernel for Small Systems](kernel-small.md) + - [Kernel Overview](kernel-small-overview.md) + - [Kernel Startup](kernel-small-start.md) + - [Startup in Kernel Space](kernel-small-start-kernel.md) + - [Startup in User Space](kernel-small-start-user.md) + - [Basic Kernel](kernel-small-basics.md) + - [Interrupt and Exception Handling](kernel-small-basic-interrupt.md) + - [Process Management](kernel-small-basic-process.md) + - [Process](kernel-small-basic-process-process.md) + - [Task](kernel-small-basic-process-thread.md) + - [Scheduler](kernel-small-basic-process-scheduler.md) + - [Memory Management](kernel-small-basic-memory.md) + - [Heap Memory Management](kernel-small-basic-memory-heap.md) + - [Physical Memory Management](kernel-small-basic-memory-physical.md) + - [Virtual Memory Management](kernel-small-basic-memory-virtual.md) + - [Virtual-to-Physical Mapping](kernel-small-basic-inner-reflect.md) + - [Kernel Communication Mechanisms](kernel-small-basic-trans.md) + - [Event](kernel-small-basic-trans-event.md) + - [Semaphore](kernel-small-basic-trans-semaphore.md) + - [Mutex](kernel-small-basic-trans-mutex.md) + - [Queue](kernel-small-basic-trans-queue.md) + - [RW Lock](kernel-small-basic-trans-rwlock.md) + - [Futex](kernel-small-basic-trans-user-mutex.md) + - [Signal](kernel-small-basic-trans-user-signal.md) + - [Time Management](kernel-small-basic-time.md) + - [Software Timer](kernel-small-basic-softtimer.md) + - [Atomic Operation](kernel-small-basic-atomic.md) + - [Extension Components](kernel-small-bundles.md) + - [System Call](kernel-small-bundles-system.md) + - [Dynamic Loading and Linking](kernel-small-bundles-linking.md) + - [Virtual Dynamic Shared Object](kernel-small-bundles-share.md) + - [LiteIPC](kernel-small-bundles-ipc.md) + - [File Systems](kernel-small-bundles-fs.md) + - [Virtual File System](kernel-small-bundles-fs-virtual.md) + - [Supported File Systems](kernel-small-bundles-fs-support.md) + - [FAT](kernel-small-bundles-fs-support-fat.md) + - [JFFS2](kernel-small-bundles-fs-support-jffs2.md) + - [NFS](kernel-small-bundles-fs-support-nfs.md) + - [Ramfs](kernel-small-bundles-fs-support-ramfs.md) + - [procfs](kernel-small-bundles-fs-support-procfs.md) + - [File System Adaptation](kernel-small-bundles-fs-new.md) + - [Debugging and Tools](kernel-small-debug.md) + - [Shell](kernel-small-debug-shell.md) + - [Introduction to the Shell](kernel-small-debug-shell-overview.md) + - [Shell Command Development Guidelines](kernel-small-debug-shell-guide.md) + - [Shell Command Programming Example](kernel-small-debug-shell-build.md) + - [Shell Command Reference](kernel-small-debug-shell-details.md) + - [System Commands](kernel-small-debug-shell-cmd.md) + - [cpup](kernel-small-debug-shell-cmd-cpup.md) + - [date](kernel-small-debug-shell-cmd-date.md) + - [dmesg](kernel-small-debug-shell-cmd-dmesg.md) + - [exec](kernel-small-debug-shell-cmd-exec.md) + - [free](kernel-small-debug-shell-cmd-free.md) + - [help](kernel-small-debug-shell-cmd-help.md) + - [hwi](kernel-small-debug-shell-cmd-hwi.md) + - [kill](kernel-small-debug-shell-cmd-kill.md) + - [log](kernel-small-debug-shell-cmd-log.md) + - [memcheck](kernel-small-debug-shell-cmd-memcheck.md) + - [oom](kernel-small-debug-shell-cmd-oom.md) + - [pmm](kernel-small-debug-shell-cmd-pmm.md) + - [reset](kernel-small-debug-shell-cmd-reset.md) + - [sem](kernel-small-debug-shell-cmd-sem.md) + - [stack](kernel-small-debug-shell-cmd-stack.md) + - [su](kernel-small-debug-shell-cmd-su.md) + - [swtmr](kernel-small-debug-shell-cmd-swtmr.md) + - [systeminfo](kernel-small-debug-shell-cmd-sysinfo.md) + - [task](kernel-small-debug-shell-cmd-task.md) + - [uname](kernel-small-debug-shell-cmd-uname.md) + - [vmm](kernel-small-debug-shell-cmd-vmm.md) + - [watch](kernel-small-debug-shell-cmd-watch.md) + - [File Commands](kernel-small-debug-shell-file.md) + - [cat](kernel-small-debug-shell-file-cat.md) + - [cd](kernel-small-debug-shell-file-cd.md) + - [chgrp](kernel-small-debug-shell-file-chgrp.md) + - [chmod](kernel-small-debug-shell-file-chmod.md) + - [chown](kernel-small-debug-shell-file-chown.md) + - [cp](kernel-small-debug-shell-file-cp.md) + - [format](kernel-small-debug-shell-file-format.md) + - [ls](kernel-small-debug-shell-file-ls.md) + - [lsfd](kernel-small-debug-shell-file-lsfd.md) + - [mkdir](kernel-small-debug-shell-file-mkdir.md) + - [mount](kernel-small-debug-shell-file-mount.md) + - [partinfo](kernel-small-debug-shell-file-partinfo.md) + - [partition](kernel-small-debug-shell-file-partition.md) + - [pwd](kernel-small-debug-shell-file-pwd.md) + - [rm](kernel-small-debug-shell-file-rm.md) + - [rmdir](kernel-small-debug-shell-file-rmdir.md) + - [statfs](kernel-small-debug-shell-file-statfs.md) + - [sync](kernel-small-debug-shell-file-sync.md) + - [touch](kernel-small-debug-shell-file-touch.md) + - [writeproc](kernel-small-debug-shell-file-write.md) + - [umount](kernel-small-debug-shell-file-umount.md) + - [Network Commands](kernel-small-debug-shell-net.md) + - [arp](kernel-small-debug-shell-net-arp.md) + - [dhclient](kernel-small-debug-shell-net-dhclient.md) + - [ifconfig](kernel-small-debug-shell-net-ifconfig.md) + - [ipdebug](kernel-small-debug-shell-net-ipdebug.md) + - [netstat](kernel-small-debug-shell-net-netstat.md) + - [ntpdate](kernel-small-debug-shell-net-ntpdate.md) + - [ping](kernel-small-debug-shell-net-ping.md) + - [ping6](kernel-small-debug-shell-net-ping6.md) + - [telnet](kernel-small-debug-shell-net-telnet.md) + - [tftp](kernel-small-debug-shell-net-tftp.md) + - [Magic Key](kernel-small-debug-shell-magickey.md) + - [User-Space Exception Information](kernel-small-debug-shell-error.md) + - [Trace](kernel-small-debug-trace.md) + - [perf](kernel-mini-memory-perf) + - [LMS](kernel-small-memory-lms) + - [Process Commissioning](kernel-small-debug-process.md) + - [CPUP](kernel-small-debug-process-cpu.md) + - [Memory Debugging](kernel-small-debug-memory.md) + - [Memory Information Statistics](kernel-small-debug-memory-info.md) + - [Memory Leak Check](kernel-small-debug-memory-leak.md) + - [Memory Corruption Check](kernel-small-debug-memory-corrupt.md) + - [User-Mode Memory Debugging](kernel-small-debug-user.md) + - [Basic Concepts](kernel-small-debug-user-concept.md) + - [Working Principles](kernel-small-debug-user-function.md) + - [Usage](kernel-small-debug-user-guide.md) + - [API Description](kernel-small-debug-user-guide-api.md) + - [How to Use](kernel-small-debug-user-guide-use.md) + - [Calling APIs](kernel-small-debug-user-guide-use-api.md) + - [Using the CLI](kernel-small-debug-user-guide-use-cli.md) + - [Typical Memory Problems](kernel-small-debug-user-faqs.md) + - [Other Kernel Debugging Methods](kernel-small-debug-other.md) + - [Dying Gasp](kernel-small-debug-trace-other-lastwords.md) + - [Common Fault Locating Methods](kernel-small-debug-trace-other-faqs.md) + - [Appendix](kernel-small-apx.md) + - [Basic Data Structure](kernel-small-apx-structure.md) + - [Doubly Linked List](kernel-small-apx-dll.md) + - [Bitwise Operation](kernel-small-apx-bitwise.md) + - [Standard Library](kernel-small-apx-library.md) + - [Kernel for Standard Systems](kernel-standard.md) - [Linux Kernel Overview](kernel-standard-overview.md) - [Applying Patches on OpenHarmony Development Boards](kernel-standard-patch.md) diff --git a/en/device-dev/kernel/figure/changing-the-directory.png b/en/device-dev/kernel/figure/changing-the-directory.png deleted file mode 100644 index 3bca6f53527d2cb2fa388048c80b21419dee1539..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9998 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 diff --git a/en/device-dev/kernel/figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png b/en/device-dev/kernel/figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png deleted file mode 100644 index 3875d6a92e675a216d461f77885af51fc33ff7cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8850 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 SNMv)$PZBf diff --git a/en/device-dev/kernel/figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png b/en/device-dev/kernel/figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png deleted file mode 100644 index 09325296f8439d97c33767045f3d6adbc316d506..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8164 zcma)>cT`hb*Y1HJpay9oy(mamiZm$+O*qn#CQ=pYRSr@^BGP*=(u)Rw`5RgwAd>eKR=K81S9#8gh;{U!;H)a zEcp3?%w}3ZWazv-8ReNb3CGWvHr59xY%@(X5daT0^h~at_hk{N&!8Q1)!FG#RW1~c zBw0k+LWGv+8g-0lIK}icjtiOXD0jy`wKHIqZw3f3N~z(GnKjMt3!nKdM{5^r*~CDF z$sk?8Z<|9{FZ09=svydIjh9OK^LZ1sj{YDn>?(hngRo=#V2wR%z$M_~MmYa1Z!xY1 zBSUY+ZpXIfeOgH~7K?J}g`sQ%wO?FU2?y!vl?(TaYC1eCQD`}I@Eg0FHb0U-nC8*S zdYsgby%O5#E5V6o15o!R1~_9<7$0zkRvgu69v^d+lb*c}4UZUm^}YNYItOcxl)X~p zS<>1ZsL-;)kd~p`clOLrN|Ehi!E^14*p;6SJ29H(w08GI7)KmgCvqd-$(iyh3$t+T z!CBOOFfl3b{bQtMY$c7j=9c7J4wd>gk<{JNo0=D=(aeDD z0qZFB`mE{i68mPX0iq7rG`l-SyL~Kfid>pr9nwJegwQa>(=^t7s=2t_^?JqK1Ah$z z-)G?p7^_r-Cju#gxt=kXRsU+p+`Y|D)38P z&=zkBs!KiUOyjR0CKHw+9l0d#x2UR}=Mb?#Rw`HE$CxXxy~p^DRRt1T!(}SRaLd2$ zaqi`4IpLabH7nTrWd*E{K?b#ML=@R(r5$s?vfY2hDBX?V)RKFNTue6G-@az9=DzAmhHpWA?`g-1l;i{N)9OzEK5srqpC(oEu`!~#fyO@6C$ z`>qq{^9#(#E8m+-ZvJt8R^ zvG`b2TuVuU)!CJY=a$DFZ$#Qb$ZNGT$y3%^TRN~c{wXeO;X2Emjs>Z|#@pQpg+23f zpQGu?wryObb(w0SKc9Az(~43_weFejJM~{it$bNNfnJG82okUIRQk&HdFfmqv(|0+M%F0E4i>?^?PySDex|i8fT<_)uU(eoH+qY1 z#tQw)_GtuZtAma4ZmV#mo%-AS-DJ-euf_DsnK*7;({lfK6UzxmD7@;+sZ4u4#R)t- zY@@^^AM8^m<@s?`K$S<#4X2-$`z^hqa6yB>3wsC?;wfI&SFO@rt15uZ}x?!;5tLgDxdqD zi?ViBHs1}XMqIN$$vP+ zfGeM=RLOq*dSR*5rrCQbPbdqnMf|}|`IC>D-8X(Q@K%@>KiwZeyGxcFRRx(lCIpsSPh79PxZS)BaKS^Bbvp3-=#;%CgQKn|st0 zeFDI0)V+=b`9;{{9~&BRG`1192sL&u3a&o(b>bYiEi+$zw^>GLhIBdX+|w5)ByCZ( zX)%EiJJ0z|785#*XTh1re&^$uzfZ)s-feA+8c*}%>^Va9RPs=6c{3z6#rGFd9mJ;C z9)C-2^X0K-yz(&i_2Z;H8;7P;uZobyiTZaude?7!^&Hi2Jb@oHHCsLH1g6q5mN&*$ z4e*6}phNc^F?T)=Mbl1xD&2%S|Dc59qCzS43yG>o(?QDD2$(V6lgcJfNss~gKo<;lDu1A2mc1oPoC-Xk-!eQI5!Go>D75%0_M}OxYKmj_sWTntANV}QTlf%=mI1I3MTDl|G#PS_U4QoyNs-)G_#Wt-?*wu3drC|~r zVmnpV;_wO7BEZv^>74+1t1^EF&gUBaHxQQKWdM~od)F+UG$+S`!yM4jc}(ox+y0sq z6o+}i<#hjpU~s9j5(!dgr0_YqM~(;W+;%K|kljI!S2q?m8&nFZPHXY%=g5B3pW2bN z1@R-M+AR6*Z#@=}E%IZ(w?bFj;S|im!I+WTFw~_|bzp0$zh-kfZO;>CA7W;=jN?5w zKId4vM^%}}$t#?Jtz9B5J#Mgz`lX~lm}GLIANUzOgIqEQ92w%n(9OxMJJ>C|Mf2Q5 zLnw((*NT!}LG=3AW_bQKc_Q~qNZP{YuH>>2)HLshA2+q_2Sf=ux&6rxG+Fj( zn8$60d%J&QvX1&=Vx=W|D{fWq$cG4>i=lnUDRZkDSc=?5pAn9k$J@W3|x_Xy>M5^YT>S}kr+^)~P+4&Z|KR>x{ z;9&~!bY}>r)1j#S`M3Z_u$+mKUR?zwkY+Fqjgwo*NYV|wtuZOpU*=llNdOQv&*N6vNYT zVO3B_kS;&|9vc-K-08>0*fiaPrR(nU73^9T>e_zQO99u2bp;+ta5h&#%PnZ~cHpC# z;z((PC6nDN{fn%{s7`C}G##USH5#6f8t}qLm88$0<#fXWi^WsJ+_*K--Jyd!-ZW>& zgyo)7Z5&evF604JJL!ZM@<{13dOrr82nzkM4j1Z^9yoJi0+WE%64=0q~(FKk9{Bbn4&S(RDp z2D&936uRGFGevwU?VNdMeMrf{-k;NSg3n@gbDKd^r=yh8NH!7j#c+xaZCny5F`GJ$bWorK}NQ*I;#~faKy6{*=*+g1sfavyp z_GEM;nl>jSwW18i>BxTt7fRwgzSy29s8I4m8}Vz1!_NXrE%#xT?-eALJ^Z`XBDeSR zg#KIktRzIpU$2Ex=&uHwMw(qw%hvZin8A2~j3N(Y} z{KZ$8py~BYgeS=}F?{dIJ9NWrN6WV=szjmQ_z6GDXKtkx_BPp=tHuQ{r}c?)@ZBDU zOoZ4X`$cOWNzM(p7#sa=(|@b&2gw?@rM@qAgnIbQJWE4@FZ*=+P! zqG=1{C7Go#X$wzlaJ%3K_mDH4jtMTBufF$g*m4y``xh-yTlU4q&D=X+B2 z-o*cxr84_tsaF1POQj{3CrHEJizvc{(4NK+6JHbZGtCm^7Yns8gtYGt0*XKPLlTf? ziID8|sX?CS3w|Jsmx?nFL{s`L?+- zc7A+$d-j}Mz_sMj2DoDmyofzqgFYz!$B)%e{o}_ZA2`@68}l+iZJD5kO=qhSAI_7~ z6uZAI1e|0wnd8Fts%)*pg?7S##I4EEB}W`%E^A}Z2@RlPdaS9^kA|-10S_x zPGC7#58&e|p*}W;UCB_e7KqF)FpRNyJ|`3h%Xy* zqT|d@)}YiLHoAVU+yAHp@%@`3=zgzHw%Hl>JOh4RE8)S$*w5!VC7c`?IBrs2l67c( zSGn)W#Hyn_lp76DP#NByi!#o?WJa|+=RAt7Ej~VFA+L90xoh--Ji7y)f!(tIUb*`I zBE)HhIxcmJmM-uCqB!p_K5_kPPyFGW2a5ogHQ2a+LG>-4Q*8pG zKzaIo3TbhQfld$fs3e+CB7=JZ(b3U;WUDKYT;t7d=&=FH{y7E(?}4qYO>x`!{%y`-ZZ^wtf{AB|Kh!n_ zrU81QrLc~z76G0Nt+lL2dvFu6L{1FU$qZ;gfHxgV#uZ3*(((iHu!3A zcP2zq3YD=r>GCa&wxzC&fDbOTw>jpfQv89xHjyI(*L9OpUz^bK149@P&suzWvieD} zHr7VsqYap{W65gxMRnl~WFOKV*jgZ6!HeLU-1wE!C6(c7RwHBXIj0W`T}ixP-Iq%i zuq0L^(-YCvxaLmu{4K)6W@eRpoT%^H`uqXg|MiYJ~xODu;EJYpx zkt1@M{-lOC>|1!6O|=rCTCWe$F*~nyS@{&v+PKp8UY|;yc~&D_%rhD=-6?8MR76fZ z!t%{Sj@ZVXIrHZ+R}M~chC(Axa$-4Z2C5@NMI{aOg)Mjf;wlo|b@ny4Uw5T&o1@b1 z?zDVHHaRNh__(A+k!sJT_)<#~&?mCq>6#}rL6kVL|K?a?y0DQ8RJEA7FShhYv_r9- zuWpNMJN!$*Jx49CC}O<(tQvxMl!N%>YD;BSC%r^}*&iP0OYUnXE;U}ZEUDvn`~w+I z63KN<@=>Z)M6PlDz0x|327ieh$PI}LmPLLIkc^N8y?K3KYV#)6$f9JK%noH?_Zv-| zB!=z|;q48~Z7G00BE830qsvion)i=5++VD^4CN0#MYk8ff#}S98e#RMpxW~e3d&P} ztcI9?nq&DyPH(Q{q2ZXmJ9>N16MEQVo_1aUk0}7v!V;)b{>qksNONtbRg>r996(-= zs=N5&F&S%fcXTW(esVpFKwzrgX`T!*d5p|PbbVY5EI8LgW?l71ywk%?rx*U2D}bKr zchXzP_;4N7>NkL*_TLwjT%>JgksEUIpIJdi7i{#u>w@w%GJHl#(R^)48E+O3gM?M!EG^TX309Mo=KG)D0hX(dk{rf^;yAfq-EX3KE4TgaTw^cem`k&P%!U_QtMctUzUzg z?hx*43H{NwPaSlHE^R<5rLQb`WuyEqDJ*Smg<^I@@37YaXOt8wm>aI&bGJUX+%;h< zpmG)Yh{PR28>HDm46$krX*~)fG94^!I{BXvBLHFWfPnosXx(vqZ+GBRM zQ1t{EQo>gr2`9HKfXDkUAJ1*6Ps|C01}0F2WQ!dyMpkkf>F4r+5Ctv{K3rXTo?2KQ z{H#E{5H7tIprp47MbKDXtoPTXMAs`sdTGbzM!v%+|6q(v(95loL7e#2WyiFpo>zaU z4=`G83-bcC%Ll%W$2=e?G`e}(0w-;g+8)6bf?qo=kIpy_pJ8!8vpT+-0UF-yl z9r|z<&V%nQK;KB#v*kYghyDzYrEo}5LZSV4kCLgF!dMY(L5%b@ECSzI0F!@X zx4oFqvl?#Aa*_LNt!I%sC{i1Z}g4-3|RgME(;wcTasY`-a%ThBd#82CPNm2ug zAngo#s+D!}a+DYPxjjm*TwO8kPE2sND2d%xZ`LHsmC;|iCPc|WNuHhC=W(#Z&dlOn zVpYJ6yXQu4n8fKkymWK1(>b!Rs|S1Plmr&EwTXKb^o`vp9h}vN*EsLncz}yUuQ2Z1 z(-!ZqUbL4O#vUE!3TZ&zf8^2kSou;s0}I2f;GeAc>)83M54#`UZTzf}0sl3FGKvt+ z_&9raFRv25)T6TW`RCqN_uK2Krk05;Y|o^weiJ}*ipg;RFWiLeW5b0|@KmuJekIK$ zyJKtQe_%lHkRGVMoWl!e}Gg!r-V#M0K!dn4g=B8qI6nFC7EKk>bF3m=eApo7E* zA*Ni`K_a>QFn7M1%h89y3C09l=co+ZANu0<@GPTM0p+-b=vr#L4gL1W{JR}9%$lputEUw>fHx-Ht_-GReAmr5k;z(P7yo&xAo9`$m_&zV^m;(}?|8>#43etc!??<*0*R|z!6lv%v zH-cFMD(vG2_Yb&PoBu&M2aUf`&L@HV+m(bP=MD6yMM`gVr0GYpWxx%PXsUoh{T+}eS}3vVjm@s9F6t=W<+C?25A8PG7L!e>>{QcM{a{Ft4Bq3 z{{2^pBSczQf80fT3tQ~CFAiX`RX?L~s*V)iOO9XqhY=NsKNKS>@cu%4^t5{2I9dD+ z;}gS>gke%-Us?RlY%0xbXCj3J*e%mFW~2{%9QtNEDk>;4+Ibxw`^gy)m@#BUw!}CX z-N9+SEIwr`%2VM#uDBZ=iIjWq%A%G(oLHkA#OZ=}SyNM%>qb-~W0@m(sCUzj=y&)t zF9dFEkAd%}>vXb|`jp z_KRH~!3X2AE6Ny@D|Ye<360%BM;&HJv%PJ>eECnbuf$B> zHfroz!1e^$k($h!;ihm(+|j0F%Er)h*5`QzlBEVt;Oh}zC?d-fD55%Tk>dLCuypWJ?gd7JA34)?3HH*QT`N4@+hF?b419FQ zexT@w;XKq&Wp#B{zI#{F-PpBzo^j*vS!~*iXoiA(Fq{cW-D>SVX?sni2koLwc2MV- zpy~Ylca6}oh{r1u|`&%h{qH$0PwyErgyXvQ-*fxxDP!Hu&S_sF^%8*iTV>FuJ#A&K6e|St& zdK+c&gG1JE!AdUC{We~W{@drJVAt#tin-p%>7Q5gA}UcCMA#oX8r&+{2h|#%s$59v zS?C*g5gOhf-K2bxgK##yh!q2!bv|k-vAzxIv^FW~hFrVH7;$EZEP}avH4q(!$1bWt z?kDWO0n!AeRvFO(nPOMWjfD3{Y?DgC$?nNMN#a}{gwOCI| zhVlqq&{ch}SLE6K3QI1xi`V-TX~c@2;_p4#!w32rAJpt#{})o$gNOhC diff --git a/en/device-dev/kernel/figure/changing-the-permission-for-the-hello-harmony-txt-file-to-666.png b/en/device-dev/kernel/figure/changing-the-permission-for-the-hello-harmony-txt-file-to-666.png deleted file mode 100644 index 97d249223841af716073bdc5c66d4d19dc078471..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8193 zcmaLccTiK`x;OA33W^jv9rP!?BfSO%L_vxmy#}NxBE6>|EeZlsgY;gcML;CvN4jq3#4o?w)6{yQ^~luBSo! zo12n<9_~CZk3+kNA#{$E(yuE4lmLI94u!vw%K&lGO4+O-=U*T@8e2iY;=4h7TI0g5 zj4Mq0n5lY6An*^m-TF{#D`5wk!z%qYek%Kq?e=JTtk%0e#{bIg!I` z6Au-2d?isri=WTfBr4!19bv`tLpi-cBQDYAc*P#N{*L7~&D%FIk^s7gt32PhQHxEw%(Q$uZvz!qdJ$BK zXyymvj+0rhXGW9+S8s!W<(5x1;l2{^WxK&;mXr%x-dqhl(-l(|O_E#j`GzUFq!v1w zHjvC=PUn5i)kLN8TM$OJUJTY}1<>Qu;bC#>$FJdtpF@qiM<-=~%!8g2ZVEqN78CUX zk}<{zN~9O^H`6`V-~YXDYITmJlCNc6>o1<|o!UP06@A-O_~*8<^?<^*aYXgzW}g@> z4b;cXf_<0WIpfdNlAvF?U<%cm@G(m@(l7F z)fmqZqtN9U`XBvE0yjL-{!4FI0(fY=;9ZpT*u)SBkDa+JUW>k2oMtU&E$1zjeaKl4 zWu2qezr&;TY)2{2ey(Qg9hJSBgc`gn{$G>0v(3nEK`{KrP9MLP#aUa_{`@*cL4?_I z9sG~SVAL;v0YkKoFc7lE)Pj!iPYaVh*D49>tN94L;*1-AM-FS?*{aL3O z@z`*`bohaZbKY^;wV?T&Wz+DK`pupJeBuswUr^carZ1SVb$?-%c&1D`$qx=Wo5*s> ztQdpL&zEYD9bA(*u;lWL%|A-tCyQJ^yy}S^v3f92idVLdSc!pUF`g)GkIud;-fiIV z;`nZWg-JLPrK$a;(Ir;P~$U5jJLgtof zCp@3~`^=ZBmehcYh#SnWd3raP#Z>AP5vk5nB;U2F_uRpOUS;HR^?Hr)&yg2)PS;_0E_Xs?P~d%fwfvWn!%!o=&)?~peQx{=nf403kA{2>M&F ztW_ga7k4%+QuN=?uGD6FYCC!4i0jG{i<0IlQ5}}cM&&U6mgJ|)8?(h%nM4K*^>VXH zq2;IS1jD*@B-<9;F^u#w_(4!7gZ%p=-F|*Ifoi8C(|&a}u-55RPn`16saOr|WKE2( zgjbz6HuAg@hlJ${(h6>zLg>702al}I^Ne>-%aGO0H(jY>=irzSrg`?fMD@#zPBFN+ z{XH^iJw-(mXy{aWD%%3LNrznAaZ*M`LemJztV=RSA%2yuDt(8k6bv}4y*!)C~ z((8ZdAGr*3jO$1-l9kW9>>jYW>C`IsPhj5=8%($LMejt)<={v6PX$$y%*$cikf*KN z0d^P2gi&U!`$GQM!qmDc25nIaG~Y{+cMUx8?Grz7ukkCsyDSpT0zhwYOx8Y^qj09! zzI<1_-|-j)X8r6Ukx{)`4Cqn_ESAw{UggvKu9S%@00jx;?kCy#U7-#PJ~d(bGIM*4 z;ePnTOQ>%D@kLUS9amic>m}F7%le}rayo&5=yhzUEU_AJlS~*x%rR{^>8C#g=WI$y zY41h`<_(UFWdH0P7!_={g6dKp2b!}Q2PIYTpq7~>62vb!J7QC@lnB+wEiDQ8&Ualo zTV%t=_xkJ8Bome6!1LOzg~v0E+Y`sR=$xy;ym!AfHZx`6kiQ;|iwE**|okUI=&dK)lbJz({@}pkyKGK?jQCTN@}4`L*M&CD;O|bFydxM)d6qG;W@Y zvf2Cw_C02xIueN3YOwO}+va!>$>ATQ4DLRT&UxK?5jdckmU22({Z4Wx?z+H9Upq}Ycz+CAnzLJhPwr>`Hv%AyxbgJKc-O6%b zJh|-W_$a*03`k>Eu%g%~j!I_$uii60COrxXvqsf)}DPLav@$Gr*1Z zPUBS{7><%xn3hV6)rJ`Rql_^iwi>a+ToUh1^plRxYxg9giqCrOQpF^2J zE0mn$?mfAV;xVA&rHzcy0FONss`C2=$PZII87mOXtFp*V04~Qh@3v^2#s>K7(THZ{ zEbr|29q6D=*X7e~pO^Px?$|1Zlxdi>1+DHJuwMIt{iM+2^l>VT>1Gm(o3P7nkrCHr zA@aGO;kSfTMr_0_-|<5+X~2}^=I+>YoE0MtmsHl)cu`tpwI*@jH8$%N+hNKqVPZ=v zdlBc^uLdl1vEw_aD9}m6KG>p?DclwE}m8Q=3qMl)jNKwj<$>5+7)!ZLya#;5s z%w6u3t73G_>GN*h<*)iw@~^if?=PVR+Bb!Zrf}Z8$Acnc3iu!K=3909X6EcPQ0e^4 z<1Tl@LAp~$0nuZVppCl2TM%LE^-^W$#*6uvGX6m*qLsj?LTHY<)@I#Nm9FjF!-~DC z#j~NU5`;aTHz8X$R<9)e=8j?NGt!=F9U_?FC@KU_{5l_P(#(|=Ca*41s@OpU7=k|s zAvgat<;dBsP;vWc4Ce((_R#Qm)aYdkYQ7a3D#u?XH%#uwl-_Q(#Iq)+4HSU<*oTeHBN@V_LYrl>$yIUfF_J zG+HQKP>2LQyZcmr0D-Hboh!&usL)B|Rcrd{>}=83YVs^LFPx3SX6-&ZNpkg?t`=A3 zHIo-yQS#~RulVh;bWMwxw#nSM2=U#Iv)?y{ewKck-InMd zaIWhZOEyYX`FcOmced3{W4`p&y8)X##DmI!ywHTu6^)z#E&d}OtE_qgEC%-OSK5x{ zepP>HalnyM`Nzt=>rY-PBemh4`Ax581aM}e~OI$h3UFFuw z#=R1v;QhCVNLhN10yc`hVjYkRfGg35lO_UQ+&|5OJUCr&8718$#@qN@03*dMvasfc z7hsiT|nZTm*8oY*swmK_7t5VvFpr)ouy|_7TW^XQ)d2_ZDUqZmNBR z0h7=1{=dm=#4b4ezU2aPx1M9xZPaxv-=TMI+2r^I{zc)c*TE_3CT4!`cfydp9#r_N zM$s37P9G1$^z;uW)C9$BhG{?Bo3H&bgme#zU z^cYwP{R&NXn8|bg0?FZ!Y1z|($^ge7_f_<|S1p5@|5--+Ke7yW^~yLs-?aPWwHN?W zKO2UtT2R}zrUjU(hE<1jxF0dT7y+%|K6ERTet3;wr$8WjIx#J67mgdAvm(S!oL+4E z(=7XB>fBSm#OY<>RP&8_3E$v@2_#d63NMdzHf>t?cim6Vc^%r$*|spNmR9Pikluwe zOF5h$)we;ZFT$&Gx%eySPbw0`wief$*DB?jU-P@#3ImsKR>YY4xKn@I(%yabD~V7Qpd* z6DP@*LX2S(d`Fjf^SFQvJ|3SphbFPF6_FT-!7J!{b|D{@loN%gJ||Z+!X2?z993@_ zd8XtjC|*9mkF^Yq-XjK#Tcf;$`GbM6JNm8ksT{3Wf&^<0efnePA1lyaIstvxOZPoA zhl+C2>)+dh?~L5GRu}g@uPPPD6Q?}2=RTsNQ0N>zUx+pw;cZ^k$ztOcsY$AYWaGrG z23Y&_DrMGlotyu0wj$9zkd=>@tyZj3R7MIuK(C6%94hUf^Y}kPvc>-%k~dX+a^HJA zElRnM_K`>$0m(SCXcOCtaYzoz=5L)#Em#yECo&``-oG3Lc1;#1?v~`$E4uk&00+tT2TjPUc^I7LMc6EY9DoG*`F4YHRO_X2#LL$Tn-n^v* zJFTFJ7xrY$)f`%#^zk@+6bEA?ek9ixqdMt%GUIwLEJ^lKFkI8>s~25O@c}-{rPe_y z>BRF(c6@7Ou2pF==BW&43f4Fm2u=msVrIA|SK88I-s<)Bjw;o3DE=y*{sq64fCjjH z7|Ch#mwrU+Dw1I2v}C10V^!UFn3RK!-=`&V4o?+DXY^g)5YMC|EX=uA+Ol%+Y(>** z)!z2(A~c_^tD9dnCmD%&xmVlaCD-DF-P{G3h+#JWs?yJCR7-&UHO(T-5-H+cboz40 zX%U;J-=`%QW&v}FJHv77itB@qkP|l_lMR6W=#V*wCC|MkTsotp9MoPe^a@z|s8fxZ zhLn&K&RQ&4$Pj#&9{Cwl@)>ufk)s285^hWP!?*b#`^{d-I`7~H%-~n=uFnqD4%hxj zn1?O>Fla>b@4Xtm@&%f#2R-TU?MZQWu<(i*{J}}=wbzE+e#qbLVsmM3y7cn&&3CTU zE~9ijlHNy{CBwD5Brk;k<3|_hGw)vb1T*`9cR|R;QvQ5=j4qQOC&$ zFYD)_y>01XHYSQ&{6#2!2fw*);cIp$>sbQ_g5R4DY`{Ez;mk*rS*V8rMEXw)$UODy zf4E6BXm^t79h?`-d={(3l;iSQf4WWQE4VV(&~d9Ooa6nQC9+rm@Gp3-$pI;yK>z4J zf9-7sP;JUKZoSG*ppmXoytkEQ=Vac=F1b6)qK2OPJMZ^cC$D#+_ZSO30@pkxR#|LL z?beW2*ukrI;b#$rEB1|5h$syH1s-6Q+v>q~C2RqU|3I_t=-GKZd)K5+eD3#0i4RI5 zr$bL~{H4jxHnFpunVZ$SY-AE^a0WpkEDcOFYe@NofBv*Fge8EEUOD0eN6Qaq!UGkf zp|kNoI-iZT=X1?}8|V!dGrodoQD4=qnd?CKtHXMmWxH682^Fp2&zaMDoo#m|kpm!4 zX|KC2BOsM)B$4!Q2$ldb`jAE6|B;3O`wUojh72x4l&H_cEFY21kS?`tWYI8Qb^M!) z-|yuaCAMY_U`bi!?~WL@M<@S38oKds8v6Wy(NLhos%Kh7X5t6V{I3oDj&7|+bub6@ zAUnm)odzWUe^$qGLXW4k`h)C!U}`lu?Tu0zs5$j9blCLrlTT8LZ)_e)(Vwkvd{QsW zk?czN+8hNw2(WV_Kf@`_iMzpEfLg$`8duw3N&FQtLDh}0PtDLp#>Zveu&o2x(BrfkCbIo~G*y&%Cueq>f3e}B4R$VC(xuzZ^2%uvio=WW%ysn*zmiH)E zCt9!1|4B1jZ(*FeRg`iTjg*En^Ye)ndMrPw0?*>s@Im^bgKn#Ni;&}lvu$Jk*or#Z zhix!NZUZdN=i5W;UD7kIx#LsV>&%(pCfDAn%w=W`bUS`qsuL+yL1tuC4MkT=LHV^7 zK)z}9_&dXV)C``fp}-5=D#vAu#o8EARF&LPUaZUuan;gdL^t4>fmHZmx>uB&Q^P&D zjNI+I47*_uTam@80&2{~hq`(Q{apQ{lg4!#v9&wzJ9u64T{uGOI)j=>*wdL8_~pk2Lhi>FT8yjR@~e zF)+ri-=r40_bhvMv(Tt@%VkKk_K zP>3eju@qD~5<|tpA7+*0XZ`Nln>n5%-!tnNe_pa@tIlMGJV6wCY48Q!@-Zwl^&D=~ zs%jVS-CC z%FF%;m4e%pB(6T;NmN{`fUUnWG87twi{6vl9eJ_qdf*KgjXE;>3q&ey&16L^f?RLj zG#0O^bmuTs|0hig(k7>45TvW)w~ql43sV9V#WM)~h^x^wXx|2+pqi(iP4B*s=j-W< z0SO{1NyCBK5=w91G;cL|i>!+P2!*Uyq_r)A%wqQyGqSG@EPKxAg1>ttuVV__dk|v? z=%~S{K9KBlP1+q;p047?hJRCy9uR0}|J8fIJ^Hfvyf;yX%#U?+e1>~kmq3cOU2`TH zdYG8RnxA6U(#J8v@?hEO$q`qnN1`Zj8LL$9e$Q&fish&5iVd4H+o5NxGL^6?N1rUF zGP=IjASal5@ifx11k1gZOLWhL2KhAb>6bw(2r`a|DT84w4YX(FZx}RlwQ;UV8~XkU z=eyV}3!snLZwUdBuvk|e`eBx6$zO?Pe?7=tXhh@;qypR zmYSYrO%>#$8+UqWVEj(*9B@lfo9lM|GIhNI7GzE%9g6E1_gr>e6(#bZDY@PKELw#F`69onD)k|da4Se&sz$~kR4pO9vV2qoW!W7^kc{&$yzeT;rVAWGY@h{;7` z^qlAQaP6tlGs&>5rJCoHLS5>rpUGc`MIRdnJUYoP3UEZ2kMEQCGH_}2Z=Dy7?oChl zWPpV6quR<_{)?807@Mi&&W*4D|2OroDd8~TEDO!kqW^#p|9^o{jeo=5qD#jCjFW)F z)*E^(;~wT}HwzcLIKC?*Kuka`5~5iq@APpe`A3Mpn2?9$Pmy0nOXCkG<_pz9Ezigz z($k`+u47NPBX(}}<14?D#5#KR?;pfr-NT3MkVQF_lM03Sg%udgI(-Vg*{WZ``Segb zr~|kL`^Fu(7#v69#BXQNM?nq_(d_;x!iM;@dZOmHPbAL0?=-`86zgD3>oBJTQ|}MS zE{rx)Q(^8x68T?3Y1|dDpL0gVhecTr-yJFt5$iGvB5N)&-$eI1V)ul0((ZgdZog{o zZY|T;gUX?N!L?N1-2d(z5cH$E+}4FuSAsGb6h$eJo$LN7)hdSCE8QYId$O})`^nn~ zs+m;)Rc&#h7`)C&-#a^Hh-d2mpkxe+9CwT>e`Uns-OaI_aEXROS3;pbl9L9_u!|gpzG}-V=nX@7uvT z?7Kasxc1p5)EmPPl_CmQYPSC(pwG5{3263E#toB-GKLEO#9gHEz6Jr*N!Z&yfc)C= zg)bi>N%WHJ85gq^$p;T5g&xtp9a>m~*QDpoTGnrUpT4)T{^^wrsoQ&3e9Bw(T$*ls zzF3tz!t1MkM_HM=@1&!Xi-`4~nXlw1T!(K4PvCFha!I=DOr+rF4YK+*oHXxb&=+1hPkKr^~+R3%5)js=Ua8$v;A(kAIJY zJhK?X($=~!u<9=3h}B(^16xMIDvKx=CSmWAcOy)Ug*U`SrymHbZ&JH(KLxfi@0((^ zf)+1>i~RPFz5PFZs#6-cxBszX*9UvUN&oe*OJq{*;)6*oi-@(F^r)!dNk2 zFPyg+ziBFPjVMadnuNKLg$UL(GCE{%wwO)%vsk4R@zjiUpCjOnbyKe zxILs_oJNrziQhZN-C2w^&*C-SW!}i?Zt?~vLWCh6ZzS>6Hyi0f3Jk%woX(GPhGy)r zFXY-8lx#5g=qfR9{fMm>n%>#7)b39|d`O3NdzUP)V6y%rZ z%vP2ueO_sy-{(jMB4oQ~2xZYx`CRoXoC%RxD828v?Oj)PYXwA7$(KoUQa%wb9%Bl`EF zX+aC$ZnvB2f87Qb!$5cF#T?p$)VnzJ{v6fo^|F71dhD5@?oTz0me%-GcZt?xP_IzC z)USWPcVNC*q`p7Z_}T~R$M90)^By;R2X)*=Wd<+>^@sZJ>szUxAM^M9rT%=__FrH6 zyMLb_Mo{~|`uar#5A?s?)bC%P>hHIu{qv*#QTk<+BeGdNc7yt^p5sdm4{A5za|iX( z{&oC}4*5|3X~0<^fBaH^HMqaj9}px8>PY{OPxTMzeSfOoRwyw*>u244vtB^fPIj zK;^fSdo+-3JES)MzCP!)CQZmmmMJyD6v>PJQ6q|=ey9O}IHeVL^%$Pa1ErjPK(757 z9_GRE{?KVke^AU0*p!HGn6ihZ1q z!<;{La0EdO4}cGKzlR(lf!YoV+PCM_DF7^SPo+prK<7L#l5{5uY@Om5AnQRy^7Ck4 zJDkUHTJ1ee01rIj|rG%3X1)jjUeKR0M?aL4Aw$|5SfJe@*Ge??r!< zL%JIJIzP7qLO;N+HVlA|S(1Y&4XKBvw;t3t)pKgech$eA3yo^`t$Ye z<njcU7rAQ6>n>MpT(pNvCKAmhzF_`6Z z79uHmPQRy|6T59)+jdYlj3^z9E*Nv!ql3DG`f?b!oI<%qd#6(-iq^1e2X&9sm%~5< zh0b1&9FbqwZVwM9B4w@TK5qndY*H|o)Ccw1>yeY?=fKD9JaYH-@AeFU+Mo`t^Lnxz za+`UD{2VYlsP}+1wXX*x&JkI^TLFp=>QpE8`&^9H0yW)j!*>N=-aC9pu18LgU)PIR z-MpN7${&M~8p>VgcPU3KV+Ds{Ke8M88VB{DyPi<)>hve?PwM`o8gx4pYr$)6AS>ND z4e)nCbM!$}3)IL*j@0LlLi_vr9&&Z2>4|qke)w)WcI7^kAB>!x`ZJ>_m zPe3_=D3+elcHQ5;a7@0RK^@`WK|MQoa=>I10Tk5ecrP*jl1_+6$u>cLl=)^O;o9^= z>rc`$e60+RSV*zYe<1|Q7wbQ$>|RJj-M<)>KX*K1`kuuee>$E zA>uzwjkl(o1Zwh*rEfplp9OV7^BhPbOLjde;7=8QoR9HBbu!ZvcZi9;r+V0Sc zIkXS_?$AD{FNlHe)C)TG-J^8}^=43$RfNqn&as*h9VBM!9XF4fuXlG)Zw6!s^%CrK z>9E~^JrJnxZj~N?>{mT`!<#5Kbt??&DF1e#S%Mj5*#T-N+GBYD(p`702a<3^gsL*S z*?`-=t>jDKUlh~{{MR{J24YS+J3u|*W4~QnfhNw^-R+9sKN%&5lUT#LGs*J&X@5s< zKE~|EoV6E>#4LZGKB<@1IzwRCUXL9FZsIa<~pMt zgoRXuJM&IfB%^HnR(Py7#cB8Jp>1u)ye-c2Fawis)AYxAHiO!b`8;i}cEi?wO#C$1 zLiN~SZ&Ev=x6Ix1xgGs{`skMcsGa_deWsvvHBiram2{MDg+a&~)jFNNY2w@$Yxi>S zfb;oWouQ9F(pRRP%BT5_?)iYU-4Z|amWDhm9iNPxyG zcIBg_Q@V+~sqwWlaY>6@od=%Tv2yCMf!pF3go1L$w57q|Tu z_2?vM%r-=Sh*z;8OXOQ2NOOLnC|N^~*8FSeScyjmwKjA#N*1GWaKqdM|BU)jnNBI+3i`XNxep;W<_IOkux=tRf z4LTsGVR>sD)S$PNTY=hak_?Z4eKI@U1!e;OCT1JXxm7W_(+;*=} zhjS9@B=R>Ees@~ajeRt|2!DGo59-$XMSL{biv$a>6JHn>A%;dPeub&ebxIphb5Sz2 zUO84TJOhUZ7WhKo5BAqTb+@zLSsx@hE~_6W&=5S(!KK@C=;saYR9wa6bLkKz+=jGe zpIm(;qd^Y1tx{{7{Nm`J0XfY!)akn9(kty`Y-0xMmU?Q}Pm9t}Z9g|CEM^KT4?mzP z=?5}6c60TbY`d`CQa)Y}O)r&b{rg%(>JU$8gZgfov(f?QwCAp;j@3J3Q1IlVIXwbK z0)r!e^qIjsKN~@)gMwTyu4M><+RRkct|+&W@06<_^WXs`IH#bJ*{|FbhtAShYjC}S zFsk_5}6v6uhe{@wsf0FG?S_Ov>vPwqeit`2HC$U3Mm0qXYA zk%FrA=ML%)>dRr^atf7+5-X;6X~`_t;Mq%mZ~t6+6r|HZon+h04_nZ2uAa>+_$5iaJWg+e<0=TgqsR4i=ttz6_`nOo^DlhWKJRfmgqONQy zQ8JU!S-Z97UsAWqwCe(=vT`hVSQ)rTN1_+oCue(W{yBANPpgBvIAGg5IelXb;Wm+AZ!hovz!z>=5rg#Mg7t@(2@9r(Kr>Q&C!`arj} zpAY=4bhh^M`JdzeV}Y8UZ7~=Bw2?7u#N7a@*8Eou_G5v)4PZEfX(y6$Oeku4PN#g< zmQ$!_-T+Rm>*{{3`Pa60R(@HD?RaProY*P?IJ$Ox`|M|@}N(363>sOx;Ejz z{KZ~<#2S?=@Hu#Xw(duN34oT#68i?|bAeF!E<3?(z_ws{k|O$Xn2+@pgx|(1YPdk9 zTnN;buADZc)sDnYJ{@suT+m}Hf7sE4ZTp8kDtO&Y2|;NjGpl!gwmqNQKZ}s7oyp+q zBZ1nUzpR}Fqna;r&!BX8Fi24ne*dw#Y) z6*f`-Bz{5M1{=f9-_Lxe&w(Z6+?>1}T7f7H_i=JM{clQ+lo{%&OYu*j>w=iUO{Vj+ zqkKGjGxsyX#XHSl%yut~^c1HTmKO$+F9+2z!TB<%6CzbJ{(B>}>zBp(*>4%Cr{6@e z=RZTKWrOr1UMXj$*~ObN1o$$j<2iLp{%JY2En%f4v!J_I55EMp`OTa6%BeLd{HNo} z4~hvPU`RkW~=UQt1L0tf~etBX3WiWVC{<+A{eg9$r zbE7N6E6bYRx|bn2zGhvW_~9p;DtXNi(wQ)|!7Qz1q<2pw0@; zHcmWBgglBI9n>Avm&3s26go<@=yJ51wK}MiBK3-#mtE2;?cf#iar$bR1NGvuc8+Gl z?>eZHjK32!Nj&xdKbL$lIM!!=Q#_g;I1#sjGaddhy>rPI zqZ4b7$yulUAfRTHZM$yk?HpEjrpKSLj}!fK$rqy&YmdoUr~ROy*2eQ{CF&T&L~y^D z$~x2E5p?Q}b=^j|p87#{BiEi!9jsSIum$P+_0r6a9@3F)9c!2R)&2gMpk6igW;Ym9 zsi&P8uib#?$;xi~&#$P-=STDP)VAPgdK1X2S5Ba>YdgsK*w2yqnd}&7W9`{}u?e4> zIz{tQXKGxn=*p>gHT{Urev}6K+L_+W!QB@Gby|P^d}?D8v0gbUpB)sm9)puV2HIGA zZeMJp7jf`5qWeJ48M~SsOq2%RoHGSEoG4S>qkQ)_3YMcQ4UmiT)BS(J8iU~>i?L~3tP zc{KIx%F&_s#oFn;?LHq2)Esy!8b@4l(Q@t0sXb6Rpfi35@gLw-DQk=Mp!VvSAx(Nb z70`53#aQYWYd-{@4k5&3SbUgq4P8mbP!zIl{_4jprHNn zL9GqRMY>90J_P@ox|ZkFL7gc&9BS5ibDcV<-y8r}9E=^*9n_b@z~vMw5_$C6Gj3Q! z)_arJsaNEdt@)p9;CE23a@f`f%B}r;;BTd~wV%)b9RD8()c1!P#(683KX;;@yjdge z22i!;ziO}_3+(kk5;l_E9`~xq+Wk1CuyeKnoLcYI{aW)s3NALuv8hvmymjeBHd57! z2#eh~Yo`!6p%3QWgSY)``}sSPxb3|d@J;wHcN|6e7(WE-z4iTXctVrjQS%~on{C)| zrCh1=p=V&X;jc>+`uWtkqkOfI9G+>UC<)Of6sc|WVrLlLFRjXtucuC!DR%LPnbMQb z(whfc$lqqB73;m<^VCxtou&esyLvoFRX?W=M9JNtj#ugNZ@myO?HW`8{t0xW;O^&B z6Gus4$zkYK(Z*D$vGvqQCqbrNky_{F9{7;AWGC9b`OTZXk=pg=qBQnBBei`{^dq(Z zW`^g$X!KZlf4ox8$~nC&=sFYRkwG1=$8O0#EvGg!8T>Yk^AOq3r(OaY4?HtJg1{_2M#S8M+Ld};xhCBRmRW;{xk)wwl)XMk0* zc_E%<9aTu^@an}DhonZyEwoemwC0~8<9Y7spgzsOI}fPx2c31gcTjgwUkd~O1Fqg# UsNM{PG5`Po07*qoM6N<$g5~_%H~;_u diff --git a/en/device-dev/kernel/figure/command-output.png b/en/device-dev/kernel/figure/command-output.png deleted file mode 100644 index 86c14dc614b20edd875632212e3f26b689924c88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21005 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 VD)Ah(JQ)B0002ovPDHLkV1gLb0zCi# diff --git a/en/device-dev/kernel/figure/creating-file-c.png b/en/device-dev/kernel/figure/creating-file-c.png deleted file mode 100644 index a030a27f42db85d9dcd01eed586310261e682a9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4757 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 L*~#nDJ^sG{OHdNS diff --git a/en/device-dev/kernel/figure/creating-the-share-directory.png b/en/device-dev/kernel/figure/creating-the-share-directory.png deleted file mode 100644 index cc4564a075f63d3f95fba9d747a70ea203a1348c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8323 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 diff --git a/en/device-dev/kernel/figure/deleting-the-log1-txt-file.png b/en/device-dev/kernel/figure/deleting-the-log1-txt-file.png deleted file mode 100644 index dfe025c125714a7b7f3374b8323b785b59706c8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3797 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 diff --git a/en/device-dev/kernel/figure/displaying-content-of-the-current-directory.png b/en/device-dev/kernel/figure/displaying-content-of-the-current-directory.png deleted file mode 100644 index b8a236bdc184363d0463a7eaf5a4f054421e531c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6572 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 Sc;fsQ24JXbs#C3PAM-z#**41n diff --git a/en/device-dev/kernel/figure/displaying-the-content-of-hello-harmony-txt.png b/en/device-dev/kernel/figure/displaying-the-content-of-hello-harmony-txt.png deleted file mode 100644 index cb16d799c56e507b46472b26ac2baf44d53fb8f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2160 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 JPDHLkV1i)o9;N^Q diff --git a/en/device-dev/kernel/figure/displaying-the-memory-usage-in-three-units.png b/en/device-dev/kernel/figure/displaying-the-memory-usage-in-three-units.png deleted file mode 100644 index 04b9bfb50791497b0a0726310e797dd664469cba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17505 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 Bpd0`I diff --git a/en/device-dev/kernel/figure/en-us_image_0000001127519136.png b/en/device-dev/kernel/figure/en-us_image_0000001127519136.png deleted file mode 100644 index 35c9ac9964d62ec8633b843873a39491f33f0e8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43891 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

XIRMdB&lXmc8Pv=?!W+M*53|yM0CU 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 AE&u=k diff --git a/en/device-dev/kernel/figure/en-us_image_0000001127520662.png b/en/device-dev/kernel/figure/en-us_image_0000001127520662.png deleted file mode 100644 index 4b583a70058c965ebe857ef500343003375220af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25309 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 YU%Ir{+@Y^kivb8cUHx3vIVCg!0G)yTZ2$lO diff --git a/en/device-dev/kernel/figure/en-us_image_0000001133848370.png b/en/device-dev/kernel/figure/en-us_image_0000001133848370.png deleted file mode 100644 index 2fffea860deb6fd69baa93fa19ccf765fc659555..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38993 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 XadXM0*3VPr0PwN4w6~~*d1L<%Bifd6 diff --git a/en/device-dev/kernel/figure/en-us_image_0000001133848906.png b/en/device-dev/kernel/figure/en-us_image_0000001133848906.png deleted file mode 100644 index a62829d1b0d8e2da0d4d25f40c91b221a6aafd52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8094 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%0Ag!sTfL7oKR!+hrCaN2vvekpoUWVyA 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

s7U|1yb;6=P zMuVAwI-!vq#8dJ|yw6bwkO_Rda9HF7#}er7JgtBI1wI_-GtQoOGegZkfzRPUnG)!|HT^vx>9OD`#o^T;>E9I2Mb@kW&Nb>FUd--jZYa6;J zI6C$*?T7x|g!+Wi5~_OuF1@c&^qkLY1Km0FWdv_$jxjSx0h7)~R>y;S_r;~oO&vXV zEOpkCjuY*7k~t6%$Fro>bcs5IwPA2lP}w?K`XM-0<;Hz+JTSnmGyCNj)@Mw~&IW(a zK3=)lzI9(Ax9^|LWjk}d{)PR8_ZefCdFf6qQr zE_Vm4{F}f(FExux@bSM_a-r^ougILhd_Ea*BjuqB|Ak5_KVFSO~&?d#00)-U-A`55hEW~+cP z)2H__et6I%Jx&?OtTjiG!IBH?wDI&mr+h`QkozpzSH;fPH~)whzkZm5coN#P;$Y z=;Xo2sz>$tJ>B{fFTYr2#8x|tzVLRRYUbe4x5|;nP&xQjmY2}K{E1uRKFMSw_dY_D zY5xBnKz9yL2OO=D*9iXHnYH6FIH6ssPryRcP?=U=DRU&=W;RoREdvF}88Z_jV^VrX zeRiQarEc-}?BkVN{z2Ke{pFb>uYa-*ik88@JwQmTIZw1d>Mwd>xxqjCk?R}&6*{@x z_pi|Ot{n5qh0c6BF;MyFZgqumBeT(KGMzO?y$;C%fWZwxU4!Ei_OhmJpVLt&{vXgh;pjU3%n)yoKo6iTe(epc|nYG<0K<~}}K?Cnvqy40Nqqu&7 zxO#GM#LVj+L33~Z_t1IroB;hCG4SNz_#94}oo)JY#=wnZ;D6m{YM6@t+mZkP002ov JPDHLkV1oBa&Q<^b diff --git a/en/device-dev/kernel/figure/en-us_image_0000001134008688.png b/en/device-dev/kernel/figure/en-us_image_0000001134008688.png deleted file mode 100644 index 4dd18910133bf0d47064fa2a3b481ae3ecfa3239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3407 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

^Fv6BoStE0nRKM6 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 diff --git a/en/device-dev/kernel/figure/en-us_image_0000001179848349.png b/en/device-dev/kernel/figure/en-us_image_0000001179848349.png deleted file mode 100644 index 50ef4e85b9ec6820485ed96f9aa3559778e679e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4571 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 TLx9h6`^DPA?ilIFxoiIhs}%i- diff --git a/en/device-dev/kernel/figure/event-working-mechanism.png b/en/device-dev/kernel/figure/event-working-mechanism.png deleted file mode 100644 index ff238b1b976f7e51f3f13d495be2a01f18b327f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33007 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 ZU0t=*D-Vr!0)J+@d_nJg{yFR5{{h2zx(omS diff --git a/en/device-dev/kernel/figure/file-copying-result.png b/en/device-dev/kernel/figure/file-copying-result.png deleted file mode 100644 index 91d1d9264778c46ca6b1986470dc6fdc3d881ea7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11218 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 diff --git a/en/device-dev/kernel/figure/heap-memory-core-algorithm.png b/en/device-dev/kernel/figure/heap-memory-core-algorithm.png deleted file mode 100644 index 8fa49b71f46505f335a5e782cbef362f7336fdaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51453 zcmdRWXH=70*DXzhfC&gv1QHM%(k+lc2p}RV3J59@kd}k=8tH^0LXawofYQ4tEz%Ve zdXP|+4oVF{krFxy;?X~yXd#<_W;)%Yl_F;}=98641 zhp%0|Y{10CN@8MS{=|Ne@tb#fZ=;!*#F(yK*0}A>{PW}9TN~{f*`&RbT&4@&Z2Ju^u76*ejw8LExz{78rgsssGbcQR?b-RxqYXqyPJLznQb{ri=Kj>?g#;7lYu~&^-H15n1;XC0rs{*NqJB%*=h3x6 zRII3DidrDThImdoN##b(_F+6<0!_`K>`=WcDSLM{N+q?v#PoPui;Y4&9oK%WZ;=+;zoMt!gRbu0zO*Q!~{BHfqb?l1A)6U+d77p6^A+&|t^>U{}taPdTvPG#rvXsCpoS!*^l+PX=_2t3DXvtAE-ot}YcX@{6u`1{{A znSSuvbYyerUqK;%Ao%$Y+dt+InQZl%x7g5UpDls+hxWEJ>D4mF?A-Fs6m^a;&#{Hb z9i8SjwSE3ZU}T<}I@nx;D&(<=fvm)?+_`}S*~vnzF)6PPBhZEZ1MySZ5eT;)fu~sf zbn}U-$7PVZeVuSeVj9EkK?MsDZHL1Z*;?*oSytv`*(i^;!zyPC?Fmv8ez!%M(Xm zI1p)?D-iFCZSs522QjQGpWUQD-giX?!z3w1NN%;}q_vA$!cm86smHOyr{^<)q)(@p z^#wc!4;HwGDl5lky2mvC4xjf|o{JA25^cRN1`o;R`{-rWw z_aKYy+3J9FY3&HFk6~>U#p(Y(hfq9>QJb5`B$_B@z{bGH_|$ECH&t{ zU$L-eTs#6y+x2J{kG+n)CGD|%CRW$)q<=YBolTLKWWqrzdJKBJ{FdNH+>oqeGNt|d z!sQO`Xj)EaaF?1WBd18W4eVq#-9^g0%@fjN=tQd`+b9t&K(Nv8n& zUk@~RBGMz|S_rbc(@pSRisjqbKhT}d&R-BL{3K53<&5(1`$kR9p>oxubnCzoY{^S3 z4W1N26A@EP#=eIO?!Dh!@wWp1SYZPC3k6p&u0^w;Le@Wam_Bvb+YMjJs36QYj>1KcxSE+fI znM?#|ye^Rk$;p@;*E^T7ZFJuB$Dc6fWo)APEMh4WO>~}a9>;WH($#vOYQ(j|%?Lb+S_KpSb z3u^gU=0yT^I{JJ_ik>T_T!bULHozZfCUA%5eQ;FZ{cR!AzW3{b$W}z zGi_o-&FzG<;S~086mM0(R=^v?k7>5^Z8PE4gPI@0`?|NwYae(0A)2dSe>?EY);#$o z{#_!qT}b;aT;9{7Xgo&22FPDAT;9gK^ckYwl5~%=t7fONopol^7j7@QR})ZGvJB9Gpni0z&nRrls@W#ZeI??Teoo-$9ONF31uhs15ES(e zKZO?N0kvBVGqE;~lk5+00fmuUlS`qrrjvLH2)WfJH8cK_0IK`F8?X?oESTIM>v0Qf zUfXxdN#6GD;i5#}E9s8;f_XpI$uE{(R`5&C>#kMdxBAbps*PXARJ1@7)`yOROuhJ8 zsTj#qCRHwRtQKrz14-bqsunl9z@p_KpY$;A-gCP;7#F>Hlc``ES&r#V{AovG%z;0* zU8xEVe%E46CgVutj7`Z`=n)cM2LpKn#mvF-bJ-=IH8^;R1it=xK6;Ab)GB+F6i-cQr=AQ&tMC=(5 zMoj4a-s+>oWBMXEHH-A_+JvK*f?J@ zI=dv*UrTV?y1ucb_YFE~PU~^_8WM~5tzN`TlX$Mn}Shb_-(Ua^Y?6qBlpjS(UhEzJH{+^c}53l$Wc$|KP3SpFtV?^$EH6c#DXWv( z9@`R4nxSpztmleQ{@#$oF`|-=1*!>_X0IdTeH3zcpzBDvHQ-2%TmBCsBWRrt1xBuX zqp8w1`gam%OD=+|i>ue4Xz14B{JZQNM3_jUAO^C|v6@MvQU;BugHhVU`*9LT&LUI# zz3Y6QP@t2YWiu%&0#3a*{<~7Jp6AA+HKF&cddA;gAe@kBCYS_F=8lO@S=t3nTV6a^ zG+OJvbynX;K887Vi#?o50uQsAf2#@5$FJ%WVZ;y>+O*)*AbP6DKdQs3X4gFDwyr@} z5kyxZKX(ohN_yo}bCI}xk#0uvWY`F3`q~TPlu4LtF6y7U6**^7l%)T~SqHAqM?{}q zp`;M(t-A1k*~U*2`a?2-x)@Jw-kSMvdQYn0B=a*s-$|BOjZ0b&WXEy3*KrdV&Q}{U95XK1$&V`g}CEY;-k}#iH0fkH&t|PA43@r+c=0=;Q2}P z$Xi9kZ2p1z&lLpXx(v1M{N%kOq^ePOoy7MpALc7j9OJw6MYUekOr#us@T(h9)ZfE5 zjAt+v*)sFu$Wv}jH#f?oQ!E3Y=c-)r=*>09U4@ePk2TCkR!q(=JY3)k;Cm@qI0KHd z6Rx#Q*GZ##CrI?Vr^yb9?ZGx}5qJ?$fMYH>T zTv&B_ME34G)7V6YlN@lb`|)L-gd*xwWr^iNB6@l_=|v?7=q~X1++)|;r(>tXTt2S# ze_OWgTFe*N->C6VU%d~f^WVI7mcn+GgN$oXI~X5-CMRRs5*j*@!YbsJPJcU4BPUq^ zvq*#Yb{*=6CG!wQ>30!jO?xw&CeHYZWfQd&ma2a5apjn~v!}n=Z?(h+m`pLDQ7JJi zH=5^=HYJNP%NfW@aI7)WyvBB`<|24}BYZCc)@2UYwr8Bv<6>UqCim@UA|oc!+Lt>Q z=nGBmKbR6#{+Q->9m|ruw${t^$$~HBwllcEpIx6_^WX*WvsxWaJCbaOs)7z)CA*WbKJdBspL)<%dgLq-t$d0Q5i@ z33<^ru4dO=e^QTc9<8#yereb^=x5{4!bB(Xd7bUW3!5f$Si{2ScYQL{ zXF$bgQcO(gMea<6YuLQADIJZK=Cok1IqK_NkEadC9GI(U0cZ6{8=Ip?KuxhMFX_yo z=Se0y^%@IV88>tJ3T<_IuB+UdzQP>o%Uycb{iU`>DsP1#=UnO78UI_@<06=)ms6U@ zMr>cElf+APaJ3KP)@5F~cfZ&QOi1kPnjezksJ_<*cIdBKho&EfBHe}f?-vJVR&%OXVzetTu5vpj(&?4Fi};zcm&kADURTxHu9Lywjx_E;M!JO5#D5Xo z{t%n95Ykr5QW}VfRph$oM3tg)YAOVS5cb6|v1(qBr2^~gMV|PCS zYk}+ISUr@jorO%s9>X9n545* zs`T^tx&UEilSd9EukF_^X|%yeh{jCP91=jT5V* z)mPBi?h}-c&Xx}&jgsvH(NjrXNN~6~MfC-16tC08mhQVZVELK12P`;}Tbbp1@k@wa zYy!wFh?>)qsW`cU+(xMo5|0j{e9p{khJX3-+#fup?RN8B5l!_cv4UfyF!JFWxlGL1 zaBv5H*);HPNnR`>u!z2@Wd0+~f6F&7tSq{&l0E9{Q*`pRPyQm`JTzx4&FJcB&b7uZ zA!mQs;t?wrnLd8rW^IjvKWV_uTpVj>8?T#@WkW6B?lc1Y2AK$WZwi~cc`e^Hs4+1j zuvVKu67619A5ub$3pmaE$d+CD1NQC7VGQeHc}+aTJ%8>6M&f=0W3maZK?+%_&TH3F zS<{{vwd;N4wMnouNst6Ig|BTD2WX|-(>6>XLo?FJZG8!d*k<#Q&6+~}gJ~%5j4tj# zeB!eBU@oNK=DO0UJ}A3+)3LgaHImoxQJUpBU)# zkv=GpraJ0{nGao{cio@cu7I&7lqqRgw1*WY6BD`$ZXQbpE9#2y!T9?dCvJmYOAkC; z$SY9n_m=HoRhVD~EY=+aaL!nQ3#-^Zcn^M>;KgaD+eS77I!8`=q}<0UnA7HTzFEQcs_yEA}nACqR zCUrKe4O8jom{k+8&k$_D3AH71>uIY4w1_QQu>;c<5`dZG@USYpBuv89eud9OX0o@=tlM(Wa*>Qo*9oYod9B07KVL zjX>DtJ!)O3Th`5mr!6(pZ9`+d4EOM`wjV+_3c_rnuxM6LorF>gzA<$&$ssnN`pPWl z>&QxPy$Zt*sLlG6A?&b8TbC&~&pikRoT#tPT9JrpbC4!}XvxBfWE`fOHZTwP#ANq+ zzf=+ktn_++;{-3E1|GjG9+mA9T}SK|APO7OYKwWxEpN0}Sf`g0y)UIdK>X-Y>{n>J z*AkB*x80LVe8g&g#X^Qnw+I=QftjL>VCj7hE*{*3>U1CS6|6aKW+$3t^d1|y+%mEI zIo50r?7!OAh*^}7OXp^!$yI^mnuUDA?v8QFU@_0tIX*Q}ka!!`P56*9}W^j4Ol+>Up= zAkt7{6!$t!aY_iQNK05iT;eO%<)a``i8iQq2j%=Q^=WHuQkJf>Xw!S|^hVH3v(KBG zF&J4jw0BY?vpkz_0rcHtR;z0we93ql8XNKagJ>?dr&5c;M3HU!&l<-x@3cnEYY-Nf zCCI2G5Zlk*uW=TU<7fvSwpA&VD1Ktvei_k{?OBS4t>3Qc?@$f-kB{)H?R^WKoN8*L zUgq0c04gc@k>K~{)8=YNNMo4wA93LU)8EHVG@siQJ%721LF-&(K`Ty=wiujKbEdhW zI-QyZk+=AX4IysrVuUecY4`5Vq3!8FxH(Q95??oZ87sdCy+$ z)Z4I;&TABRrcv)Rngnl(AQk8j^@@oUq24!am!ipklj!sw&^+lRCikLiIq4ZFCT_7X zaSFfysqy1BKoA-_4$mf7eM=fR0<;K8;UVJV=bi*K;&2^&z-~EW+GMyQ`n$+Bx-vyg z?+j~I0X%+Hd^sWFKGLB8d3nrwL=fUd>y(%S^GM=RO;`xg4pM3^bOKaS+ldT}a7eEoivd-^~ zE3p&Pu_sE)VaJC@i=2ftM2usmX^TDX%c{0UhmQXX`29Z z<)eED6WNg~(q9IyZ*s$?Xybl2dJ<``643Cg7YU0n4l@2dj%)4~1!&?63@76-3!)D7 z|KSGtNSj`5o0I-4_xFqpgkGn7xI8$`25&BEN(2@wt_PTL!-=Z~k` zFV=3c+`|czH0>ahf~9Hn$wU4!6eEmvd5I(nJ9E<~j4*esp?d0AoeJ%xmB4RyHAQ3n zuOxa;p@d7l^P5O8PIx)~@B`=jV1ua%j|f%AZv}^WwlLU!Nlf7_FG!0aY!W!kDuxmaEs2mHkY5Kvvj_fVj9)5EI)vt zwidlK5V7!wDby=8X(CpLd72_zFY;+Zk%4cDR@&ID$Ds+>3V(L|^I@G&3jNnQ2|d91 zdsT8B%?)@(oFjWk=CW<YAcfsund^+jS zAI zz`LV??-=mv`-J3+e6oMb!ATN(iXxl8{BT!ZJ94TVc-oB9!!>r-8T@0}Vta0~Yt7=n z)c;^8@> zeP*CcMT>pYqCEX(O)qHO(FUAv#`zbGF8e3O*ZT*d{?{7)`F@d@-^GPm{vZD>F6eKz zTBEOwvoo?Ti8I?4Z0pfMpeyvD_${q^J5gQ6SI5CSU*Wyv`ptpn^tt+fln40VRXVV7 zNQ@t@*$sOCj*y6N3#jP>mz8@q+j_her|hf<*N*XmimdGicyKVShKfF2a$>Ayfz>CSQP3M zA5lzL9WyqGB=-xhcy~#&e0w_Q(h3#%T?X-%*>~Pw#R)MlXbyV-wOJtcPR&}s$%hf= z5A#SfPPvnhoev4iSlqFXVw7*5ZjaYg0Rc9SNc>0(lj*|F^8ae&=mE=cITF>E!Ak(m zpT$)^e8K(xq+|Kxq0czyQwd{xJ@ZX`wBbqjphAdP%{`f$be8#7_=i(1(FuN>rv1oie8nn=emd*k8qU z3KN-k;+jck!Hb~2AJD4hm$QL-aO!2R#g7}FSFxATk-G=QgMzp&s+Gl`U|fQ?gY&nJ?wm<#!^Ijv1mQgA^n#YHP^>c3I}z9WGR-vUyCjQ#pe4 zaMaCNa|(Qx;%{Odj6jnJTh_O;z#c^o zqY8m$i34YwPtRqUjS)hw?BNa%FH0>j?DF;fK4>_Z=rI%FN;*vx&9|Jgk$NIQYI9!!8#qkY;r$f7KYT(LT=&eAw7qbNJf#)+lyC%Bc9E zTFtq-*!K-g?vK&R73doW{|4N=U! zJmdq~C%u4o^uCe+kLk?yD$Hi`U!l)zRs1`J?-Kpf{vTSFS0_GsRcN}2hMt@=xZM(O z?%KznjxyP~ZhA@j3xckbdp1F`90rI=eU!|&I&2fy9*&~g45w^Qc3Jr_8v>uMv7S(R zd-A)|9%fbF5Zg$52jZFX${0^^nU?a{=}ASCwFAHz)3e7U5B34u49$ZLJu1Eq+6-$%Fc4W-cWwt>VYYUPpmgO!Jo2vJ z&ycD9b8rv?F#82oFy|>r`0DxQcEQn=Wg!c4(x_r zIyiOvy2-HFUfbDu2j#UA(I0_j%qlcPivbj5asY|?Zvz_xF%x+*u)Q< zYCFTd_LAjdWwRgOm)FTh(j1e|=9lJL|BnBykICqB0K zhc!jvXs$Y}z??;`CfV_eyYFYeyRSM%Em)W@-Wgw$d4>DpN1sUtywy$RZ7$-_g`;B5 zdh-Ou0eW702qnEVFm0)n9*AGR;4&-3!bebS_AQ`hb4@iBc?^X~wkd=`)8jh|P#r@L z#!#P+AkNRqKjGNCGnbzppnS{yoWmPJ^vkNb8)MTQjSt(e(_b>KHD>7VD!Gm6e&w8r zaZFr3u64?gL%Y%t$3<=RRmd&X`e18BvNbZ~(5Vm_d3`gAmHfKI>ZMOPuTxG-o|VA- zq>7Vxb7;Ka;b_0trV6%Hp8+eONzR6XFl4~$mc!S4!j{3tG-;r$R`>8z?g&YZC-9?j z-eF8lwT5d`iG$*}8w#K55T|m(qX&twQm~^{Ar7%pkGd|c?e{ts-Ya@uclBkNYM$yG z*MZ?eUPq*S-xyRW-&)CiMW4S5wrjUv@BY^QyWaibpY?7&3qB1=<`%IR*L9>{kqEWl zFh4oFzzZMn>z6imD8(LB2Xq0`p?ZJ@sb)Nt@VT(-%xT5fu?%^YkE5_*fBr`#VojCf zUhNd;g`czM=d+?31SEfyMmfn7lZcA1An8~~A`P>6(*Hq`*7Xm$+eIKi;$ausjHO_9 z#ZK!!%`Ng92AuEwMRWg|=6Omch{uaP-aJqdhTI);P>N|fr?papO9uavgw^bU_W%fH&2^04N;ARB6+PncMx#uk~rew#JeAdc+vz(%f}h zh7)HT(b8A#%twH#8$)3G$Yn-NwBWGN_L*;}r5@!aJ#rkPP%(e$s+twOKutu`@BVq^ zyKod9L&oiP)A_)qX)w7R@h|!iX>H+V33u%gW2}>*og-u}Lqs8H%XH3HM@VQFBn;@x$lg<7bP?uvhYD}H!Eb5d{ZN8 zb@F)$h%QGvXy%?b^;ekP>mnNfJDQFf}$9EsWV&!t+Qmd`eajcl) zN%lG9Qq;PFAR6eaudx&ZcwsAr&vzs$V-^{!pSv5j72-#Rbn!S$lfADDarciyhubYd zyA`rK8kov1FvgUUgQ3dDNe#S5r4yH#xcbJZV7KPcikKK?>pJ6su!O0a*tfUuH#2uN znK8Jf2zK{+FW1W>?K;tMibH@A+lZ~T7Y_F^U=s82WiG?rNO&rvMzyWqS$jJIHtij? z7F@ENfoVMG|9Es9(|&B?{S(YYs&&r>G79~dOWN|5B6cVN| z9Drf)N|;lOTr;zRl?uM>@bZ)MbGB{oL;$O0rZvN#DY#7sVYNiwPfd)>XjQ0k!cP+N z=sqoO_>aJXc(*Gf4Mx;XXwDpKSGAqah=W;YY}{B?CvKhAHl%&_0019VXUv{rjH~67 z_kXc}VQqSm^lDc>pdJv}T6?pufR(zuEn55Z$X~83Fa_7ea~ezfVSLyv(7+0NUd2g& zOT!SkALqx<+rEt+MYnktJD(+ls()x2Ge9#Qb)<0{xUvv>4kxB$aCuF~t>4odc_-~$ z-X3c=Dou^4?14Ou6-GrPE+>n)6sN4^<)D4WeXY&CiPiFe8F6dXc1~+a>05H{`HJ$3 z;fV>v^=Zh?T16xhwOt)ovJUgi5sXZr3eC5IR$B7Vu%I2N+2%Q7){aE%?orrhU)%I# z6eO@bGwBf)VK#JX`SGs8w`$qAF4*N5+encN)%}Nj)XkOCL;$Un&A88cQ=2o4a^Mr5 zfgvQYTbJ5GHw9Mf@;!$Vd+DazhLtHw=9jz3nK__fwM{*HQHi|ll2*5$kooUle({}^ z`+Vo%W6|Q%Mc8e@571MU9WTnvWdCw8QrhNeF0zGS*djnlUQF9A$(cELl}(I|?O^Wc zB&3a!c}(NfovO=_(!(kR>d8OK9`cTx;G)bUE*HHloXLTu7wc;TTD#@*8E22zl8)Zu$2n};nOifm=jrPRM_wY~U z%JgfzK|g@eKkd&YmBjp$*=0>2Ce^=Guag<+nkM~)&l*;%pD-1xSgs1w7Fs@P*l!~= ze?+G@8i@ub$<5>|E=9SIV(@$;v-IC|ssfgETx+BWEe)_GArf7ggqtLq<0eJZDU*=- zO$=WDpeNer3|Uia%vze= z=&^Y-hKyYl%wK*BIKGsyd}!J&tvrNp$LeQ|dr`7)8j0CWLNVfFr#Ag^fU``7^hLEw zquL}QA0l#DQY1r0{tLAZNMSW8Si>q81VBCGbNji8uXHF&@>o`ySsR104f3peHg#AH3?kIhcXw47iR65ea!-IWP6a7t_V=55KY2Cu|ZXCP?XYvtLU2 z;?lN0=$6UQ8+yJW9PUs9zo!-pn>()@P>a)EJpjxmEQxUhOp5L#%!Oe4ZRKKOS9C;I z6+CIT-=sKEa?sv&-h9GQ*Ay-b5lIR>DwFm8Ig--d2&*Ws`9#HTu(dzrIYTQev?wA> zJO-x6g0 z9(%Q5N|AzC=&ctC5voV?_x`CSA&<67r)Wv^jB@SVHU@H*z;SLf$=Rbry&^IVzC z>!T|rV{FeScGj!ekhWGHpL0!aW02R!T?z(6EAkY=yH@WPibivu$yfXAENh*Df_>}b z--aDE>;}+nOroAM$l6X{j3ji)nyvp5qdds`&XDy4%b}1vH!ilW9$=HvtP2)BC?pdZ ze1p^i|Kcffddv_59MT%OEjD8rQc1ChD^tC|NY1%!^J&7AgzJf$0L4na*qV;GosAb? z04-po9k1lJmXh_LJ|u!X?Af_;8!WGAp;#dYer=Fsp(_a-1kfS@M-n%s;otb&yPo=!1s^UX~-5WIy zf1CxOVdJBQf*lh~-maL{qOx#_xpz*|i+-^pbqTZp>BX|sT{g#%KKFbLuKu!`yDqyMOJo4anMX3G$A-yk+wg2ajJDcMn?|t@503 z=qZ8nM@uT0eZl8NiM~=I3n7Xf*r#F~m=K_kk=n^6}tu|2)s zL2l`y%cAp5c-psY{YVdr)rACX%{ojs!pfo^o`Z(z3!|t95@+>BbbY{+7O&xb1ITSd zr&OZ_>2tp+`Qb{-lKvys;cy3=Lx5??s!n7K-_B)71D$Ud3l%&&Kwa|T+AW-W_;IC0 z5Zu2iUN}~x*4l%-Fx_QrG{D+VLGE4pfX4wD6Jq|`gl;e<dGWI(1SME zh}jI4MdB`w|Id8shO~>Mbkz~Wx7X{qTQAuAW!Q}ABZ%z|28CR|pYOR1{HB#{K>O79 zU;F-nl@H0{U0>FayDnFo?!cioldbk=q1#4*D|c52^{yj<+s+#^CK-gIHp;RL84Z|7!qVFx$VWm;@<9J z*Yv2W9pn4!Awj5~fa;~IznZ=LuIyg}D*Pk{3q49{SNyo~&F{m2ncsYS=NPXN%M}X< zJCuJu1Q6S>Z&RtwzO1Meg>%H!)?qpwzhEH&)pSbWF6F#Rpx!8Bc#POMvK$14bL?AI zm&U``U3D?d?-(X+z{+m!t(ost&_^i9n zWOat<`r3G?&PPn$T@mf3OJk_7qk?hi@4gzTB?Rl3kBBXGsw_U-7)9%C^qcIKfGagd zKQdzm-Y&-FS_rtebDfY^BzKf2r_;(4O+TqsB_Z*_(^WppmA4 zm+3nBgPlWXCe9O68s$E+ZxWoohY~{>E9dx_u`E~AKm56*+3Y_Jq%~&?UPmm#>KnI@ zG*Fi1O1vQShB7R@xa4CuX0OKK{`N4#6qN2hO_M5@Ce9@8X}Gp^Qi-7yQyqUcmz>lb z-;neuncM@M%M{sZp|w+x9%DB1crH=cP6Vw)Ep7(O? zT>@V4gZOMcM&{Y#cci*J)OOYuL4<|WAA#4wlq)>fm~RM6GPj-Uzhl`B@0}1BP&ocV z5o@r-szLHCjYd#AYi7NXpzqyK=(?$2#nE4c67{Q<4_!TMuadk^RfmDkV^($^khXUnx}zzG5j6P=i%JfUiZV`D<^PDsT$hrZcuocv%@%m=F0%eIL#=;nR_j~%TU1^%sufE>?%XK*0n-85v_WjhYxF7nvXa1=?w|aR= z=`@(g4j;bygglsLb$hObL7Z@B)8+;+9%yUKqr1)i#TfH|^m)9ebQ!W!`ti}St+C45 zt(j!0b*nGG4#WV)2}7g0{pv^?mzH2GhUt%i(!^)9|0ZN@-%N2gEUPb{(VWg@@MQ{G zVumw%M@g^EFP%Y&U>@ zUS%wNFKbNXuY<%!kf92)v3_nUs zrCBFc=U@JrLR~*JjDM$qk#Qot=t`MDK2K3*j8GD=_V&{`n`8T})Rl~*%2q1pYwWLJ zkl7Cg!>pJr*C^XdsYQ>wZsXcZKIjn6@B$`}G@m;Fo5PJ2u!v6jzNveVUU1>Gtz=t% zj2^vps9zb=WwLd{WWsW%hemL^2SIJ@AJ_7X>!(q$CT#!Zdjq%nY%E`?9kFE%*~@&IMsRiXqME$ja*wDvkGvt|MszBkFYd!C3YC+ zFO?39)OcXqx$9yQ#_e9ic(KX;1#zHlq4C$MGdi7kN!)ULt$Yt8gSFzGUuRs{jFZH^ zu+z_mT9Tbu=PH$MCk1yrKinHQvdrkf6AjR0tKCGzFqaNZo&ylw7(%I|AQRVl#O@>Y zC@nKqI+ArpyenktX*NT-0SUezLC&4Dk(vkzNQmj1mq{2fpP?^^uZ>lDJCO%Mr%b@f zGE?90!hia$r4{!yBd4Lgg#Jq7{Z};J6-g<6u`nbUY{!n2)@z(YIsumanZ}m8jkDxj zphQ!@FNqABCM#Z;o0x39fwiK8lFE*Pl4V=Yf4ld0OS*+X#%a5!7%!0v8e)b+>U7u# zWt_Yl@0D_MT!`LtiY)YcOZ%+_7`PkY z4$&Xv)4EdH7f||z{KHZx_~w59A5$5tHzFvJyVPWODXh#woX_^y-Uxq5(f06gn^A{G z8fzq(B{CrY)CGQ@!#`1nldy1*$vi;iela+KXOL}QCoNA{l-MHZhcnH55ap`NEqTvA zPH^)1QIP+B5wqy`b#F5rF|b3499x2P)4zVw{CpQHv06q36&lYuNP&M8x0Ma4pn9D4 zs2{%Wt?BJmp>7=qI&HB^5VM}snWl25x`(1}rL9%6J2G-kz66s)ko^^~5py}Y7FOmo zZt244z_`01x3?_!b%3zDwy?Onu=rkOv36w^zxokkQg{+rz*w0nlR*EG2te`C{JG)C#@ znb?>n9EUZ0kI=RE*=oqjrwTEigu~P#%e0AE-|64)I@H+|!IezhN@s@4oFq!U_FC}n9;2v?_N0SrT?^=S z*iO-}`&GfyKTNkfr?knhh3Cgr`+ykC_5vN`bc@0$)kERgdhr+r@FD*E0qwRCnd_$C z#lJs+w~Q&M(ULasIBwJwS6!$0b17BQ&1URpBzasHM?uFJR+4f}sHGM@HQ(9T+;OwT zA7+}5Z{AtGziF_#7%xXuc1x}EjM7^*q+N9E2KFCp6Us+w8&;-2bFMfz({g+~43;;; zhZDO}@IFeW?m4+!v_=EQc>gS?Qk$*LuL0IyUay+8XfSZUBjNgEe}}1mA7x78@a}vo zRr_&58p+O?JUIZ_qcZ*_S?rp3?vO1MtncfKG_wLgvc9kD>$S9wfaHB$o0+dTP23xC zb%Z}Gz$A#1t1sxS(1CWi!{2mhKcq@(pIN&&`?FrDlbzHMfttq?eQT6`uWAXC4<$V% z@ToO%Tes!Utca0n73{8o-<_zoFk~~p&EmUu)3sUbqRcaZs7ExJ=%CZBs9#hE#WgL?|dH(33omU)zA38#;ASM7d|Xr zmET+2qotPt@V&|tmInbD-d8p5wNKSQ1{jFwPg=$S&a4B3aX@;mXn)^@;hu9*RWlRp zgoWK^xd5Dw=-vDlC94S7L`)LX2k1cS;o)Y@6Rz5-ll%%OLY#2FO~mpn;LOwnzbDe` z#*d_1788rzm!q`IX@Pj z0wq`m8b^1#pQxbY;ILdfbo^^+?yN z5muZ&rKEMLSYtr;nHxiQRm!n^TLqfW`=4~3#2iJg#ANx{`!|}pa_fm6pAy-Oq1Ev$ z!foG4CuTuZdnZ-hv6XRz6ql%ZrI`E^pwNV;9ekJ6Q9b(w`WP$q)!^6 zjf{3Xd6YLR_KJCn$}kR+=ZK|>fiT3~xUP#NUq`ig#-yV(uA)R(at*C`D38`4C??AD z20@==M&+{eOnNhAket>jl_{Y)@jIhve6X+Np1w)}#XyA5SXmLprh9UK`nIV@>I^kH zeLN1loBVV7gM8-D#TrW50)gI20E=Fa&(EZIhqw1p#Ge5~!4|8fj~kyel(YJgHt}U2 z*ELPxNNPr|$5PaGZ~evo$ivp8A}gm|EWxc(CE&S?o9C8woK-uO>s_f+G$Hs ziqc;$Os1_Io+cuCbr)(*fDR-+y?OK!6K*zeZ^ZBY>9k#+&jj~?;B7%xWTHdJZj0}# z4W3xh=y?V!vt|uPiI#$H*0c=jY9;q;B8VAVnq9g5OsLqrD9sGCvvh<)(2C{ujLIC( z>6vVBskq$qVe&MaWcsair;B$+4J-8%x7@hwPp_Fqgj^!EJcz0*xV)c37NJ?7tj86V zz7>oMhWMPl`uXk~RVRm6oYRsc?V3-GgbNrN;85oijwN+`ZS%%yI=DU$l~k7<@0Nevt39vTVlx3A9=L#_kZ{mm8?^_{3L}jK1+Q% ziL#;?o_^K`pD25~fxGL|ILpx}z*WN)3)oBv^|6AU0(01FZE4Hcd3{h+Pb=qDa0$#t4Yjgd-$4KY*nAQ1Gucfa{cB;-?XNc-J-lsyxL(ap^@c;<_G`1q3! zojH40nvey`WSw^fMbGqN^ZI((Rw?GtzHT7fDIQgeb80*F(-rl^(_j%cQt-Z}w#a{` zSL^AEQx`m(;*2(d+rf(k@w-`bApo%IYX%p3VWcNEE^j*?(GkKs;4Q+*kfTmT&tIq6 z|8S*&_Le|jzv!u{(u3N3Boo|#{(yj{r<-TxUSs{q!ESm!V*TZjzxLU>%7a>a!U>R+ zj70MN@VZebABt%w3{ik6b~{n!nbhUEWL?ZUe7P+k>0B``wOFZNC_jON^!Q#u@ zr_}e-BW(hZA*nlu@jOH9FmnpRD|`x6fC|v=&C_X@0N(o_~??dhJ#kE`y&{`ye+*W8F@tl#jYH+v>i*BFHP_ak;_tR&7TzPs}|2wc<1yH`4w%R&cQ& z!Z37m6%LtU5Y8_f{Mb|!t{wU3N5LfgvT1GZ2%1-u^i=Ji?e8idrAvHOn9!o{SBO+h zT>SMBOzxV0`q*rfHiAD;Dt=eM7~hV1m<)(?LuZf`aF33>kyzVsjCQs2^XI2S#B1%< z1GLLga@!Fwa63)lj^cAsju`1z`AZbL!O#*l)oMo3XK+`zq}7A5XmBMs0kDqg15^&c zE_!U{VR2WMi-?Y>Ry*_QVgd={zmZxJAuwEUteAtQr?vW!b+u)tycq}Y1c?o`Ro$`4 zqnMO92drH@UKa<3_W{$a~Y41U6O4<>f&!2qEN zCpXQ~D>nF@U5oJupA5&$o0w5Va`hje_KB4y^5kzs%fr#Q+xgn*XxGM9U0F;WLhpC2 z7P5H8nXM%DV?6HI8^l>@p-6LwWK8LU6}uK$I&iuK5)i&-5!M#h!1LYWg`$Xth#X)K z#NS6gI>Flw+tj3Aw_WrSR4_9oSy$y|D`=My5DJVZVf+ttm$_jy4A&@xX{jTGRs@)= zQV(ap<(1r^`x1A;Khobcl(P4H+^(2TVu=Eg}^(X*9p%wy|kN$Ri$Irtt1UpI5){DY&j)5&SrNG0Eg15&U}} zC=3@r@pE*D9Td7@m)C)O%040bFgI7U;M=c>Z?{H7uznXTP;&917OUskdJUZ-Rsdi^ z4&^cJy{dE=EDrxa^s|eSfctFUHz?WGRH}aB1Tdc@kBeB()wh38_k^-1Z7MCTc_={-~-l4%a4@}dLvJNKEZY{)nEUG`2&R9DZ zG-R4r;Bp2zHMGk&KZUVR2-l0xOk@kxCD0eJNa@$&L zqn8&+831O>aLfA&cmM|mRp($l*I}7x+*RF)+Ldr;X@yBWjxyXMyCQ}$7imSYjqT`` zM+c>avCivzFKo?tLHtC^4XjkREK5`7ZexN>i-5C`-fuQcg-7dbCv{#ML6K2A$K0%B zWI>=RjrV_?J~M$6Ylcwa_E?U><;SSfO^|50B_mp-@_2##6&a~R^=A?lS$m7gnkl5K z7XEe;@e1Q|7)zK)svqGucH0LoK4Vk0yE?ADms^CjbLOTG_UvLhY|WT#TfhrmPW0l2 z{6DKoLs~Z59}#@M&c*m9KO&!^75|?cl}#FDSA5ZcvCm&PmL%>?KIY!b&r}Y5g#JWP z{bTJmGL>z0N7ejOWm-`Z^1*N9HVW9ppe|?Wd1qI?HmG1bztmH&`u&9GExdn$5WU&# zn;i;fl-QYcq?2$|e4o;eQzJo~Ac=(WzxX7RpDq&yQgKwXz>CE;uVa7YydNlsiFA}u8&Y2C zNmFBHWOIk$Z{UC!k)@N^6hj+iiQO9WpD@VJj^I1Jo7wp<1ZWkB`Rw{UEQ>f*?sRVvh}2d zw+z%I%eySDv$ZpZj zR{9FPx^#KN3DAn5Cv}qcR#y-VllrWd;ZBRt>>Hndc79_%*az%`t#qE80Rh@MH|bSykRNO8extZoVB{6X8jS-)VD3=}XhtpikxWuZJ5}hV zLvSYAe?!y110F3TsTNqg;=S$fu+GGPmktYJU<1UM0_mfy0LW)^J`W44V!_D2KVPT8 zVnGW>ajFZK%LM-Kdw*?6e}tH^)crRVFwsyfl5<5(xD8MfPG-a|;ZunO&eMATx#c6z zx#bGtkK~?P+GUpWl<_PHzMLu(xE%ftumO0^e);`dBY;0D=&|jfG2li~=lk3~0DLp5 z;FK%a^zW7e;jsuTbf)<`JQnxg{tFagd1Z;e0$l&MmeAuicxVJP9BeCnnc3E^?X5>BTn={OnlLar+Y%j{T>}^REH@yqWTEcfLG@VSS)h z>om)dU{Jcx+Dyo{+%)E)=d|J~#(wHDxKXTNE9CMb$5EV2Cl+o(j2XtYs05Pb@p}}S zqGg@|y%u<7a+CivFT3aK_i6dB zw7bxm`}Gce>BF+;ZaB^SfQT2)#eWrc@gFZ0)h;q6bmYp6FAZ*%9W?tLWn5+MKO|;9 z40&Pi#V}w>OohaVwTJ@=DoU(Qui=mWC&8Wb{qBL9HP@Y z&(vEr>$h;Kx!h>Gydp>iiQTWEuC_z0WnPF^=#`;xhX8dabqef=fBCmFBVHu$L>4m8 zng^eGeK{U}dBr}$cU6DQ_i8j2J0w>U5+y(ybLJn|*ot7lDOw`j6oqEmQ_|V%(3ZZR zC_Yk6W3&-)x-E?jfV-NJDQyt)jPHmSG+!ye1-b#+ZShym{gQNY`WX;U8((nGXn$s*Hv#oa`qrD_ClI$?N!Qq3(g-09CK4F<%3t8%Hc3P6B*I zh{rD;QW?!a^`@u}ht7PvJPo514<`LCn`PkVnTq@^K$bvumn6^UENutCpuCe4S8`rM9maR=-Du85&u1~dNjhvp^3 z>o;8a3r5S}dqzL2vg{KS&8RJ4``Kf!v#Ke{l`Vb8)&aE`_9Um`i*Oa1;K1;Kx@Wa$ zLqM2_!Ul$~^}wjQ1J_A~LBa4MOFoLecWX!Px`iWlCl}nTsis;!bnYqiV;ve@lh{7Q zE-I|7UUwqioJq)-Nyp%o-2k;edZis5{Q$xg+lTB^deFn_ni`o8Q~~PkLVek0wlN{g z{gk9U7AP2y;jq-_Jw^d4oEF5pD7{QX2In-U&<5QG_O*<_KYbOHaUqy)>y4cdtQu8Ui)StM&?LBf9fnVxG8DR4_$kI1R%dG1OqY}lR~nLs&Zq$3v7k*v+jEiUroDu9>Vti3fxjLVyDru!TL)L8a-}DpQkmzC~j#_bRJ9X@g&wR{jl)z z>C&>D7hI^R7ReBT_#zlQ-e5(gcCUDM4EP#bSXHS`xpBRvf?iNQE%un$hfA4eYrSD&r9Mu>=>SNfT<$S|}M!Gtp2_<9>X^>Q;LXKOe8_?yml;>8>>YobPkxUr^ zp@;UL8LTHyS_8TP#iBD=Gehnra`DMy;M6&?=VVR~BYo8^2DCOnJ^Nuqu(?Y5aK)qn z{nPW=#8gj1{Bj{XXb0}Yr{{Fe*P%iW4aQ$a(ciz<-UMgTc491bZSks3hqmLNOIf6k zaag1^HsN1RBmjZ3)}xO%HB#%j6SWFb)4)J4jDP@40QhWaNiX?|IS6&HsRnq~I#G)o z0W!FZnx+&k#CepCK3%rXJYUIjN-rf^B~Lm=_?=0Co$sBprPu2$6Xl)zhatZPKzjx) zjFto!Fx#ix(g!1!iYmvpBb1$I82hu=!f>Hgfeeg(hi}cb`B$h%Uw4#6b~XJNNlVsL z;}z))hEd2{z-irlnKS;5bH4^Ys3~K|{$r5V+SF<~9yHZ<5O1T5#URnX z6W+4byVKlS4ZFh?I^+Us@((v!?yYZIFf_4+_BL)n$73tiGlK7aUXQZOlF_|IM(2E{ zNOWF76Ld&pWLGrZlGvK#n6)40Vz83v`kF_tMtG{!_a#8K9d?+!1eO4U66gCJ430>s ztL<9iyuBNbdgce>>()KRxz##k5&SS9oFUDdTcNr^TnOH+S*nKD-~@Gve*Nx+5?$&b zI&-ClKOij3_fh0V+=~rKSdXcWsEzE4Q>I$D9nPu(RD$oOy^e zf*mB~*XkA&RWdekQ46~KEx?J+T=4HL;=xwZVgZvP*1M83(qNj?Y37xS)&wU}AOVis zIORqmA5sibl1;Z^9$uTch~7H$0#-e$ZKJpI_g=5wPi;h9_oGPVe|Mt1|8~;;sB?%C zdB#c~x=jhWNmm&4T}(Iq^?bt)P+S~h^@)n(b4-XuVTg*UlcemK>ZA4l%>i{)+}lT; zUMopf=R&XI^WXBVEmNCx_gfzTdW+e7CZ0pi%uJ?VkJ-Oq1iOK_w|{zEi_dyjEq~Es zqHKd>Ry6JU4<&$Qx=7j(3IVosHe*|Dp;Oayl~H0g*WSmz;}+4eikRVGEV20T?Fs#U z+LDWf*u@tiGV@&cBl{xqAyXu}6?8tAx12|grnZ6hmH()CC)_k7YbNk#?aevA8@Yc( z=c3`S2i3=axD~gxhsSw3(EsiNbXE!oNZ+-pZS&D^pl$!a8P+p77fs0$ov9uIe}jJC`&%VYT3G$dyx z@Meh!6u}jd!x;nxtP#2k2mmpbhyX$S$kcuxJ5JJ|kHQNzGH~DR=Xg#}qxYvKiTxC!8Dm*XFWVK1ZGj>o~kBAMDXQbmq<@FcQy zzJ9m(&-^P%q}#i|h-3M_XShE}KjYonYIzdiDI<%lf1W=_B*DoN3%=7!zV3;j(F#tr zRJ^PcW6bMg+%@O8a0~D=G#qiXOPp{0ORri z*Gua4%Spv9S$k7Jqt>q%n=!c73uFw=o-@_x^<1Z>?s^QkfuHBz2P?y8X>PqWtJ$yr zkCLZ38T|8~4Z^d@MKgKYIYSGja&8`T_xr!kXVpdKf#oKO-s{{dLsk4VjZ1jfUVh|;KP@S0I4~v~Jz##ETGZPvKp==#X??~r$&skDKxUrEWo=41sWI@~zbr0Z z?_LJI#OVTv_(&=~&kj^`mkStn<;2>5CmN?eY)srDon6?S569VaqK`AUz$Tw!FOQ{| z=34(os?{>WnJw%^6Kl_)xVhJ{|1DWJzft1|&XGc%9zDBe5X*Le@Ev1N(gLzoZYHqRJ&reN^u~+;YB&j-q0}a#&ZbSi z$J-D3$zcrvXY))RNxa75&Zc!vS*NSI&ED%5bJWcvegHjLqJ9gQ<~e*wO5}6te?|SM&cD&j$KN=IzrVKA2@l0A&k#?$Jr=?eB8# zoUbttcGXk#(t#6&qEQ#(8$A(Yx{dh)$QMX$x8P4=Bl`^UHq%jO$9@wp9T_`jtD(|= zxiu9B;*Rj9;m4CTIA?ypoeb+WR#sft@@jS-$?IgJvPjBJ5AIL5x%b zJ?hhbi(vA0@hm*G`&5_(2pxV;|Nr4CB z2B)Y{wtIm`H~~vW+p#HIPXQWZB!>LMj$-kF<$!`1MsRjTq8>2G38tc@05Ae!A_T3p!Gw6OJLhJpsW$!8amwE)HDX=PqVc_u_}L5jDhkoryk^X{4{-cCU(x*!jX&mz#|!Sp-cdCL>v` zYcwY?h9fa!`UQVKhQD1(xv?BBTey>UM6yLujyc(odO(;@=FYzh_ z>>@BkWgo9PJSPiENM_@IEA2|gX{QnATftbT8H6}XUNw;Q8);3mje4{g-jFE;YB$^l zdYKG@7AiXDuM@i!Oz?{&G&MImq>jSfiGTq+2tbe;h5LvHy{H zz|zhvJx|Z|HMP~YahY_7pM8jR4YJ-2S--41OueU^_t#DaP+lhBRfCT?8OWDO*Cd68cs(|uj>j+!I=5d2s=&I%kUWlz*%midhv)1MZFuUSb3Qv2NDr4V6-^LsebBDgYHI?t z_G#?`uIH1I_Xw}K85NcwF#TgsTf@1|M|rQ6?N@`O7%O|J&fe?R1U+H^*_VAtL=&U& zA=2}X22ea?fTyE4OGZJk{BtAmMEo(Grj|IDk87587qs-z8{?QMiIn(-Ab*u+#K{Y$ z;L8F~R`f-TFF1#1qavEqR~;60P{V!rd>Z{_RsvCCd*`4}WUZ3BhRXGvbP@kw;1Ty- z@^GqV1}=`F#^Lp8C4s9dp#gLA1(dd*1U>k}{^=5fWT8CTd5QAT>@W?qN#KAj)q zmexu1-n*@Tjuc^gUGKS+gB;g8EnsWeY7$x6W;$+1zr%Ozn(jZP0?+g^f~d9lWllYh zmRLC4$WyrR9x^)RLVKCkpEInbp5%Hm--CrLBtsT`nLMA6nepj1mzPWKYDMCA`4p=6 zm`5f*>fq4efG4;-3db*zi;i)Bn4W8!0)3yjAhU7eHTL-{0f@4mRx5uOhe`FAde?=Y z%vQ~>x*R38Ljj#n-gbaA$VAtztYT5_z`7?g>o=b8ra)zRT5lLZ-)xK?)&<2*I{h>R zi}Ff7?BD#dG6sI~yrV}R!~~P0_KFPWr?2QBi4>)(&S}Zqm5z4f5TXBbl*~PBb(q&Qh1lX&e^v+~NYZZDV_Wy8r36&52;+k4oTh1V zbp2*XG- z2D4J-T@k8yjHja496Bgv(5>KJ>K^aa8ub7kENSeY06CB&t85NS*xvaK9%n+Sj5d5u zwV^*>ImQ%u&>G}5LJW$1 z_WLCeCvXu;)^-V|x%7Bk|F>+kw`CC%rSiM&tFAFMSu=LY719jUGXNrGwpbe1Uy#LL zVF&8WmEWLziycqh*x|vf573|ZNZHcy9fN{qs=uE$`47N$*Zq79^a(}mEae>RkY!J`o{ph$h#D;eE?zUjHU2qcTJi!8v;^i=?&Cl~4g7vsGz)onye5 z->}yd9(=JW7U{f8K_~#XQ>wG1uV|CnF4^irtsSkp_FUM$5 z&&QrKtF6IZnk*X%q9l64-IQ_x8JZHugo4_zt%UEDsMr%`QTArbvn-TDX(g4Hs6Bn) z)f*oJ$zdZuYt)fRNeAP!#L4Algp-c4Mh%EWy61cpI&|rmbHl9UYGOP^5>|u_v>7ig_$aVq`>F|J+7- zZC)&v6ypiunf_p5QXQ&|2;FURj^i9|GVt^Vl_n@k2zx%^4*`(j#+4pdr-zc?o- zS=-)bV~D@aHk0wKCqp{m54;?b7<*<4P9@8`8@)vEf}!vkZGHy(Cm)pPDq?IS^@f;m z)PGb;k7XGzSQ^>gM%+SlJ3Bi-q>wfN1*!9|IVaQfRIf>LqwkZP;ys|c{y&L0ib!P2 zQd(Y|tuVdK^PdcTug(9HiC6tO;=pf&G$Dv-!w?~#PUEXV?NR-CPIRcxBWm#zOKxtr z9t>=cLYp&XBmQ!-`>CdvdJwi*n+7-+e$;TI=_IXc6d+417pXW9DwBKk=X8mpY`1UT zt4|dDufn5PMWDmZ&b)SV;|3g&rbFg*W6Nu|UFY?}J0!JxE)11C0LomnrYVC?JSpKr z?s#RC(Z*)O_FkLcA>8y0d2<72#0L}KT?`xKY|^@%@!hgw`h|)n_xv=!+?)9^F6KOf zB8w;d&z*1jCKFFMX#tQ5noUPG%KLQ+W-u?(y?R)@Lf%JXpo(#b33(vb7oB84Sk8xw{&O7o4odF${?f3` zzT9l5`%^^Z;{9KJF9=;6?ADdxkM@$egej3&(Y^eQ#9vrqRbjlIoRs{SI&*rZy33!l z|MrSXag)3Z0afz1>$6$MauM02YdcYVgj`yQaueB7j%WnsBIS1oH-_<4o*|YemSr#< zOOBh^+^!7Wx)qRr95W4GfQ@16(5)V{4AV3OJ8zXhMZv(OI+Y=Iz{$oFID+=1u*JRYn( z>(He=9+|nGT)#OL>^@vPM9-BUkN$a1$QOg1!gcB@>(>=Ef@i3F{n3px29O>wJ zH!tfmK|@SX3*W5_g+jMt77t5?1wd{f`Tf7cw{?st?8)uHgL5fH{Wi-#H-`07wq~=RkngBeef7OBfS zvxsUC@+${%Br!-6B!|y?4(whLtbxPib?IdzX6<(iCk8p_S!i8N6FH4EINY+*pjK&3 z7XabpPT9H^Tr89W(R!jWk!?z1Y6OEoOvhTjNmbEvuIHi=;xKnhq`qVM3ifrAVm3lU z%0L*-Xsx;u1>}XyS9L}SQ+SY`{D*Enq=CosXK3EpYR%X}l5=;CjOsg!(tH#ZlB3a` zXIg9G9NaLQ5^fGW{>b)M{2Qvb#W zXM=y1BCYRyqns$Le3i0AnQbR0+qoB4Ni04(_9hpM8esw01;(BFM)XLG8DvM zgk4(JrlnuEvTAlC5JWroE9OpIBD%-QKmxS=0j*d$PjHV{xbKx z3&0S6NevcB{$4_-kMP*BtWyOiBd!Xl!F{p_Hvq+ndGpsT@vqxuM^>V}*Wb5Gy|#Z{ zWq~)xc7Nfwy|@9#g*eC8ZX*-p&J#z%N{9q%)FcGPKo#2;Y|(6U(Vt#$Jh9J3PeI!zPY zl~xOgZ$5lUMmY)&+)1m$lculs+*LkjvQ;G?oV zcE0wTmeH6zr%czc_VB7dh-s+3o-`L?vgbda7zKwE`qf|j6zJ4stau@$FlT&Dl$<~J zs)U&C2VL7OzlLCFgP%ePfA}MTv$iX+e)Y!%6pZ8@`h{Kn>Z9qlmlYK`HG|mqKV7`}KGzTLnEnj4zVZ|(a`>E)_FuS(av zup$0`!PWNOzOiks3EPtIgU8SkD?2nykhtN;r9AYF$Ak%Y-G5l&l|y=(Zebf!1EB(0 zqDi|j#CMXJKpf)3KT;A`1jcqVL*pA*P1knr(%W8^#6hb=>I*~e+Q%yaAR8b}JwL0l z6a#ydvDf;|BJk`7=h|yp`z+F3r+NLg-Mdzux6)flk7XJmYcax0Uu~T;{bBJT5eYq? zM02F!^_0ZR%7k$T#;aaDWJ)nxB_o{Oaz@SjI_>V5K^hO5oIVqXqU7dimo?MGHwc+i z6@3#DgAnJoEOOVUwxZ=jY${fZaS;BUA4Z+2FV5U^?Ye`28olBK038eYg6LR8UQUug zoLBQAy>}SABE>{re*IF8Drr+OKJAmk+lAa^193XUYHgJ6G!TI-m%6=0Ma><2<6N0s zMOnh0BIe@7pF7icdMqd)I}U`j9Z4CN)h+{ktWRxq-KLK(Zk*GdH(-i#ja!Nt| zi|$7JvtK`-N4-=k7S+0wMUDg)5a|E$BQo;6)m`~O^0N7MSzY_5ST6Sl=#lmunuX9d}&B7}r)8*IC|Jz_;07GRtZ=m$;W78GBW z`@&q8+@ul?eHTT;xymP9Bj@u&4{U371YbxJP3qR@3?$juQ{_fU(-D06BT%nQwrb@X zYCI z$Z&{q6J+51PNq|CI6P-Nj43i|=pFXz8bQE9f0i_~zp(1kTDQD_1l-R!nQKt$-`uT=~T)gk9&{^k61r|-`=4p?$WhwqeICb&tex-P>;R~!_r(uBK*4(#Jt zGQO30mK0sS9`{N^LqtnUxmM;-L_zniF(=ygo((LOsZ2=~2K|(>BdT0{54|THo$q(l zwVU<1Sb1?Cs@mF&VHWFPfldy|oU#`IF`<#aRuVz0c{v6y8 z<#YFy;?W*Aq2Vl#9Yj~VRDBh(AwJcbSkgbqZrHKtwOaf%=4V3rxDYiIU+)w3t zTK)?Eudk#72>tV4!;25C@sAxkpGWPBmT?8t;vtsD`wB1R?b)TMHA&RzSIe3;DZyL9R^hB+ zRr?xINNvi(2H!^v#4zuEd0UNi{U={m_4a9OI*B%I)8MWjNVTmyyQO%fcGA(x8=3ny zUcVmE&O?sW$0L>Zx_zd;lA<^87r)#>rgO}rYV=26H~lg z?fEp6fQ~}xn2vFz4d2~zJ{KPnH4BmXL|||mX|FnGPZ}>=&Y5;o)bWLO?V^AR>6Eaq z<5Z~8S*z}T&=zR)4a<9fGhNJ{UPRrdzEn#w^b^{)lWfnZw!A;;b9U$l(XUarjTPAjpjN!4+`RUt8y!)Vm6baEUn)b|f0g*NT|mea01*zqIKKfK8+`$&N*W)Tj#}A; zsM@Be!*r9tS`B*D%}7f)d5~|=zZ3F<=u3YdMC(NGGIf~9=5#kDPd<1eM!^n$j1O4N_W5%pQ$E7-=?2_p#rezddC6*jPkDu1kMek_3-5&; z`KymO7BHgj`r8%>vTEsbps)8vZ`!-S565<*Y^1^%D%u2@^b_B7JU+CH_A_-yiE>x9#s-xz@0|_BS!ZYGL>#wx$q#}*>DFl~nw`0lS>lhJxhMu%=9@PwDAh$0p@?K7QQ{@!O6LJCix zK?(`cz4vr|%bA+O87kzoTzh-h%(>r4Q&q?w3d?YN0A0ZsCJ}sw12GCgXGODukkYpNLsJ}m5+!^JY z!A(*jcX)&CnALrGifjajZX4FJ^q9$4#`PAq&%Mf!)C(aw)yxFaANPnlF?7wTonE)1 zLQ=Qm)#GQP%k`uG0JFc0dh$BebkX`wY9URnv8In+7y50*>2lLoH}R(X`_s3(#tySj zBIi=JKNphqn}tc&+554Q4{T*^)}D>J&WcgC z`g^hU@bzL%35Tje^=$RvN2O{vEi_7eExy(nUDP$~7WvYPY>a%@o0IG*7Piz__wCF% z5^WA`-mN1;z>iZC!|Hi4h7uOAUQ*(e3XiQRr~T!=)`N^#IUKxs<`yGCG6|PESq| z$~4bz=HYQrS=ktP^Uku#o?eV$eqKy1VwiV|&yQdaWaIRFOvPOI!RKSApU!uZdcqY= zeH|;ee9`MvKwEuJKXJ4*pRG059B6*lHj9++`e7k{{-||MsK@q2QJW9It{8yq9nW8cl@eGA!^qE~d_xzv+33p~!DQ}qdiZPa6uhtxa-4-&Agr2z*` zy|a2(l&YuIAaB6kitV< zu~UK!0zUG}+r~@xKUvv6+e1<3eZs*dk;x>*>yo!u&m+Z-S{vI#1BlTuW&MK3vH>|Xhe5t;+`J6v&0TT(A$2_6Y_~)giVoPLs>o^mJ=8D7r39YQF^+BE zorbWXRssd(K-jD5yv6U#K(_{1dnF)tEO&13-+&gyv5Gh+ZMPLOsWGAs zkPR;J)a;2o@x>;NU7ZN3Y`4{i9;5A;9*V?C{dD>>%1sL>JYBrD`8O4N~x zvVZq7X^$GWYX1hr2u>HC65ecow`^lsjG*HQ(Aeid4ji_zf^xtr9mPX>F!sAfl~p?Z zu+abB8}~=PIkz~n%+zL11WA3<#*b>;hRIhdYQ*hsxQ$_d&n;y4&4Z?)>}Gq|7Vxh1 znB)l|E(!NFTy!=&zhKfeU}VjRu3D=~^@B>6s;B=+LVq}Sq95s7CdY{whY)!~DS@^T zqoR_N@kEblKaaw)&rzW`1Sg7tuz~>LEJf`0QIFkQjdba2*nJ07Cz~{zj5Unfzwub^cfg#b{gDMM>{MNlC9~OH%w^#z1(Fjx$=t6!q^?1x3}Fqs{~0)W z!`#S`5sS2&a(!Nev zh6Raa$ChkgA+3|$JFhKVKo>!^rF;7dt+%-?`iH_8A~P~=`pN7^eMZO4dASZe{7mwE z3@rn_UOhM+p|T$}A6+6Y3xJUTuE2=lZS4#~X1`(wrqPe3K6tQZ`w#Xnk5TJZo#T1a z7U6Rqg4H(Rn~Ezg`@n#YOuM?;VGAml;01~idx={{ftLXc;_xRz4H@^HsSQY+e@@VGCBGte?RXzM=4mawGNIx%F_4%T+~1YK8uWcM_j{*z%$!U4NT-e`;%9(>}r1(cMoS27)h0_ftkedOW@oIN*6Xq`xtp4Z? z@O{D6_geqU_pGI!8bjDl_>W}G&MLUE6C_7P`bpjKweObil3NtEL6Whzh5bPi9g7|Q zXF{ATiHO!fP%M+T%O1Yo!S+3#buwf^HrixO;;@_qzSUx%N_B_W7 zw|O+5PF7eVVx0g|huwN{xQRjmOQO#jeisv|3Z7(P7_7kPJxikX(kDx3geW>Y{WAO-sYtWeUS;a%tA4=n2xCeTA;gzE07u$Q>5-XoaKByV*;sgI z4o}A2!S%jv`1*LQqZ~cru|DGRa6qE*j#8A~wsvWiO0$lk&S{O^@mRH7TU+evBfv^8 zsYC2zaM4*Vt9tLr18Vm@ba#a{DxD|z*zp40v%Q)7^6gl_xARREQ#>1oW8^o+ zFA*&vsHRGGm6fRkhg(N6lG9TWy56Y=^KAJdxv+-s8=%d}f;P9oYvW(m7I0n{zc!81 zlkzrm(_-MK8@;C+kjk-WEwRwaS>8F;B>uvGQAc{tdw#w;4p!e^Ck!O;n;GpYP>E3| z9H*bD?}eW$H`z{e(=zp}@l&JZt?aw!mmD5YLxqT5ehzopYxL@HeI{=0lO9nnVD%ZT zVd$I&IHQH)ni5{=F6pAtek^6>>vcR5+{cuyi+p#nhw`;by@F>I`qBCgDmPM+xyz=H z7PWP+jDvU+WvbQ*(Q`MT&$sJMz9d~ywc z6qzspPB7ssZ{Ea8wK2Z&`!zv(qc2x126mvidulhvtJ}h4MfL6j&+y7a)E3c1$4+3z zUwd^8u?Zq+)9WaeW3RE7zEeXq$ySV!r%RS7QYqd04m%C0>4r1jQa?u@q@@@&um0NH z6XdS6Ez7VOo$xYr*IS;+aUt1{mf32rBp7ZqovwQJmg<^lRE?mWMWyG?z~Xl8rPI9z zZ}-yPKVNg$`;aVsse|hW>mdps_85n>SMKK7R3@zMrsshc8?I$=zM-Ue$yx!0QZf2& zx01G=aa^8m-Jqt0!5?d+QiJ7JU`KCS=j1iH^8VP5*L4$(qkiGsD1ReI6vd5DIoSY! zA*GG4(4qsCVH-x+BdB~sgh%SAcNSBU2V)ZQomEXSj0-XC26Gsm_Y9Sfni5s>p7_e3 z6eD9%Oh6?>oqO@gUt>Y6-LmyK>TGOYX2tn)-ucA&k5HA^pi0=QMBx41{G~Wg2l8)6 z%GVP3MUsY7DFPt*o^bf0%U;-e)+A=(do|+{1k~>5W}rXvmBE0)PLL>w@%D0>-jMO) z#C+2ir#IoS$fMU5m7=>n21j$Xs?QH3nq9@umKPS^Puaha&^hTJ23JK`y_?;SZAPvk zZ??O{DIVi|LpR&?Z6#c82S}OLkK8vDZMQL?%)OB=Dk<5+^TOpuG1p=$NA0r97})%_ zYucn-36sw{M7>%ayO0Y)Ek{{VQA2tq;yqF4tS?TuohGTSZ6=}8Ha$bR^4~B#FkW&# z?I~`O$e7OyRT*nNU|uHEG(G4B=yIWamUx+_WW&1wl`Pm;g>tpG@n-lqS< zxKd&Ydtkc)UGBI#I_Nt+H+;D8tMPsx{k*X=tRd3%Le$vVz{sn0-g}NPhFYx9%+=Rn zmbR83>HO&i8;^S9(vv;zC~fB*3x34Y;evh7*&<8$@ri4cUQ$(Zjf{FjoYrQU+PRZh z)Q178$hgy)%Kq;F)&q40hppLo^G2RO^Jk31&;6<9>c4!0Uh_`B;nPmCw^zTfj}8w^KKtI?feimyD~hLu^!j_Mhbi~ z=kv*LNx-@`!YT?qo&mmlv1oc}zxzFfE4#Yfi#s^~ot4T7Mca9ZVARa7k3jd0O8sy|ln6qaCw&m8!_)>jwkeD-uMCj2zlaOA8HUvyuJIu+gm zOqSyrv^uXRsB8Sy8+gtIlP%fkzDJoa+U(gLg-VW_YkVr?GhFViiMw8@N^vb(l5k@@5J%vFZmidJCwhx_{l$W%t0ne zt&+zTeX%0(oBwsw`fPNY&}tOIWHNQFU%CO#5?<^^|h()^HM|h)uYEG}s$A zX!9E2oFP0OSUTtZ{G+kzZaxC>h5JRE>2(kKqm@6K*Jcc5=Z3!#LcWKTn~abnQE7G6 zEZG@i2eL1?*F3r?CdUR;CpLRyizBR@)tH(O9Dm$70Z_I{5E^n|HU-zHkNA=1!~gj@ zcT|Po)QzlaUbv6>yu40BuZurVfnc7miAZYK|I^u*$3xk@|Cgs-Su>Qal#&LC>`Nud zuCk1s@gUhkjFBPAIz>IQWRE0En8Db|GNz0rDf<#)?EB8}JGbx*f7raTFu1Kq7QNjYuY+Ec*2rQSa6Qw3c9mtrSx6VNX5qL za_*q?l&Z&s(~2q8%3`|0Q3c{_PzfK7SQvTHKOT{dIKdLv1!8l?HJ=!A6STozfLo_N*3)4wy!t zGAfm<#Teg8@4IChOqJEZl2kZ^DhQWboF*tsRCht!&Zfcg*I*t&L6(dCg;O9UY$aOM z)SWJrLPt?XXK)S8$MSTI$PfbR-VD9av@~|)fMI%T(4Pm-Oy+!CmGpVf1O*li?&i?c3M+#m1x6V4JyRfYi_@US z19!abn2>{UDyxB$Tx!ZB5p5;u;B0FuRGuN;#!uM zb=VG|^X+EQCl+G|ZSnS^n(GqzVS}=fl=79Fhi+wu!cE;=ityzu4L(koQKvAsk-h`3 zl^90+p{3R@+H@{FKJuVg>Lp=)Pxr;akAodvFZCK_?vm{3gyBr&;+WWyWFxnyfkUwY z3~hUS&@iP@nyVCp#MiW3LT3gyMv-SCVWd$BlNt}ka6*b_mLdAH)Uc!@GAs9K-sOg% zzf<+{6+&$4z!<+JrqpE3QO1;4_1RJ<{-*Dc9?qQ4o08~p<kR7R>~zwAuM3uUq`tBXE77QN7XQorm_eMi(+fkbJ2!c}mj-HSkJ0i)&R+ev z$}z1)8|6NmJXhqQ6H1n-7kC>hrrG}8h(daY^}Gv{4pd^fjt|O~&JP{X(TqJSEB>I3 zF`$keYZBMhswhU#{0cli`xOj9KP&N00c{$lwbp;*%7c zm|1j~MWUTxG>{gwhpuN@grb{{j26wc>%t0yZ^zAY=!q6|?aPwS4;wCMZ=6aXvtZ~X zO^=H~Srv!u!^`pq7H+{QHSKUGdv(}d>j8b1%IPubVGkB`CA*nU8`tn_A`~9** zWoA!XKFfXg8qCN+UP)O&3;lw9;X}EjgP0YdFKOX~3 z@kMuK-^)j!WPC={<`l@=E))J9Kf4>IM8qbGQDM>x)pS&j6ms+Vf1fGkm}k)Ikb{`) z;pjX@@}SuXL;Pacu3ytkuaM6}BP%tF@1lvDEn1rAMGwc#T^Y*!@cS2d*Gl7mZ z<%h(ZvjcCTc2RQ_b(=yR{vV~yge`99Li(` z9<(&-(me5*BJC36BkV?^$D?@n(Wo=rQHK|tgLg5>Mduae%FscagZ#mbO8aroV>&Z_ zvD=Ri2<_?0Q!re56ZdWp+h0AQyX~~>{(5H-g(ZX-B2Q>VUbaORshf91%-GCFGYnx_ zhU{0>dUmU#x48b~GUw~_gf|6~g9j;}YF8T2kMBk7gKX~#8aUI@vk2@G527i8Z7me&0D3|8gp>vM@ z`dBUkng(T&2ylH>F9s9GnK9vk3DF}iYIjD&LYR19-`GGWYzvEWFn)~8} z!7Jea{s^K@l3PScB@>z7dQ+;^qFqjJgoGa~e8nN&FX9(+mFCAl?Y!@T1Wnmd@_b+s z;>D$to*|{Vu=166%wg2V=~y~>DYWEkR1A1!!(AATLq2*^NaS-#QCvz$m_ zvu40ah<^HyaaWs5V%pe*o~fcUG@*oPAuxYA{1j_-OLm!j2eM|y zqc3idD>e-gFx-SRbji47<7?52kJ?^eD%_(T_;%~f%9N@AwvqgPvHfp1MViWcd& z-?S{}WJH3rla0bPd6$VtnTXcuDBj|Hfk%i4tq{`*-pYE5c9Bq#L;q>d#acVfV|_fc~ns3unjV z^4J25O_@i%Q~}AcSYzHmf?n|iiFys*B)p4{=GReV1RrX-M_^C-l%{yXgcYQVeECc9Z_6BLi{$9W3W+a{NXV=-3t_Vzpx1&)1OOVfSa zf+nSfH^h@1{&g1c#l(Q^Iqi$!N<|P>h?ojnsX9~E+RTlNEMgBD>F+Pm>P=L>wk|m zhoLaLS|E=SxM4)VWxNw3^ii)$x3%ocwRBV<*de7|$G&`Du3t0G_3C?a$HAB1^;cI+ z!~ji$We|?AX{ZM@4f$wwdz@jbTlCVgvJF*lao*-kahvg{oxi)s`+M75?;%`wFSx4* zHmi=cED7I?(NEIf`kJ|A*Xk{v3-Rp#23zVjcYX>Aw(09erS8HLeHHR{edV&5nVBb| zGki~R|LPu6JRmgh<^r62{8!BBXx<3aM7uC!law_?ng8oWYf4bxp9!?AnJb-2CgH%z z74Azk3bNrpwE*RqbziPFt3RGnfS!VZr<{*0zdZUCTd_cMp~t4xF$OwxzF6lL*RO^% z+<6Es*4KV46L$Q?<>hj#8RyDm9{`8A;@I-X%Znj`wi2=&R1-Rq)=aIa^7Ftct51c> zFokeRM>Hs%{vVJ z8~77Ldd*PdvrEmLlz#fhr@&z%?v2&2&wv%O#M_b8W#_G{`bD_?*v03ojsYt* zx~*QNW>;*k0S8&`^WOS?(_R+e@VkG({Xq{r9RIC?YreRW0vM<3pl(6iZT+g*W3??_ z_JOa-KDUuiuM)-Y{xSRwU;$^H@!SdQ+r>>#TzpKQ?d7aQ56l3UZtEs3_SLVIoTE;@ z*z`Ko+{e!gz8D><_5 zQSJMS6A4B3Wh`%su78V7#z#pYg#6Fv?;r+$6|+2~eyDn%)3?+xYStsiy+Nkau$n`z zsqM(sBIZc3YYQSIxevjXU!9g7*)l&k6~Rcx9A9A-GCABwokE>OMYD`~KJU7?T9K8X zainqbd4TJKOq+v0{OrOWsA;bK<5_vrr_Xn9mKFGVkvJU5c{#;y_A*rxC;{W(SM90M z60LETJ?5=(R-klwum39ZSBEretkBy}B~N<?6`%obTGJO{Neol>*_-fU2mUGgG%FIJTK5e{_e)nQgydWuYxg;*zSXi$WYDva9u9*%)ad*T!8fXkS7b+TD3Bs#eq7{>$<-Zw`RISg`j(4~}XWx0F z8%-GlS@P!6O!9iQwPO!K`R&kvGq#%mBY-}vbK<&fWGL4XaByg6YMFz|xOrQaaeq6` z!o}5grwfgyB=t@rn*5$#{Smc%nwduY5Do_S^Ye3z-}vdYh>aOy0D4WZVhS2Qr4*vJ zXZ{hroCM>iU{!HytNzwttONP`7IulgXHls0o6$9^%@v;BocM%uygS`!v0cOaYH5I2 zRPPq+Nl?VTI_}V_a122b-=Kdp+kH)G=v;TN(16XmZ#o zLRvgu5NgOZT7mlad-UgoLxm2hq*w78PMo=q!DlhYa8O<3$=*^rYuWr{*)m=E6brFY z%?mHKMrOmk{bT%??Ls& zZS=gj=3J`!VKr-BW^y_X~ z1&jh6^*B;X^(7oQ4?yt*)r+RU7z@0&HkF6I-acy2;Rr$z?JeUixisc+Q$!0SHV`<47 zn7kao<#C7B8cVVF#-JozhSe-9;dD#}Ou9OL+I4W!ITqKJ8s`x2V-_haP6QO85{!Mu zJVBlxKJdI`xLq*oR0C_*dvtIOzV^0(SLdo|tCa>+L$v@U*4=?*0c*W4?@yf z`W0Ki87GYgB(vH`nsTduuap@!*%$TZO)FAxeCO+u-MgxhYD3O6@bWJG({wD^Wtp-m zL+)FvkzBpsI`&RCQHg_Bgz{oqmyJ9aLq)SI?qBHRmoq*c!IHpEZxd7GGFOjWd5$g`|W$X71dqNuO|-cLu*4oj8?=L!tqN1Z~J zz1KE^o=Ptk8}^A!OJ!m`MamppTs&_|5@V8y&Ww(2msH={TK)t|iLnr(T;5u^YwJ6A zyMT~;;4+-v@C3>9-iZit&7f5#I+)LdNBf6p?TRb6~zp)+CP!MQemxk-FloOVH7s;OIH1O8sK zoUy1Q1N{%bW@CbQ0^6_ph;RYq4O`sT%AdM6?`{aJntu#jYxun%>(Ky>t@xpNg2kNKDbRK{}=f^$n!nPm6&K9=azYVd6t zNkhqoMV%uh3!{KI1Ufs&)z-F?4jxySt`4i{cUvWi+oHy%4V8^4h^aA zjUkgzG6I1DW3fuF#zP0wIl$`fD#03LNjsEe%j!K8)N zM*8*Qm7%PXV9gke2ApCSZhQ9Wc=Y0g2p#VZ?w*8_5;GHP^Kd~U2}h-)tWH+_66=@W z4sO91aI)~@r=>EgkK(bZ!$`rHxhT zc8m%J>s2rP1}FY{6|zOC!7Ii-HYz3!AO;nXRp`&6v`14({i4mcM3;)8Pv6GbIkAWY zg<3R+536^Ccc_B(C4z|hsDCPvZafwdLKPj(v`8Vs2TId44dJP-pje=9)R#AyrQaks zs73Q*QTg

>6mG+lUfUjzzH@FRoK1z5^U>!2b#2X$2#H_HF70BWV-*p-8V}o zAmrF(Z=Vyk(FnU+7CF>!SEbVKlTT@mU~4d3__u^6QFcwTUu#!ViF~ zllJvRWS@n1Y8JocL~lG#$01?48;TBOzp$(Z&Cn(=`mvjt`bRbMF2K&nrI$ZN8B(*~ zLFMD^&4vk;XGPd~Oc*FE3%IQO5#0EebFh2>MxKrbU999E+D8g?09Q3`w|KuCgfau{ zEIEY!SJ`))XJ!Ed1+nkBkVY1i}1!P(jORv*gl0kfdOwNFP zj*(4BI!vO`NL4nzu6TM4L3XdUsR^7p7s9i(_z5>F{LP<5eX8bQL34X;gtwq4Kd^&< zJ8xH_+=bFBiXEssMHf3jq+g{P+b=zmAXlE3?B=oksRAq^U;s`Yg2V65YTk+s(rRmtJ7? z&SL_GRjYOO?8YgehI@wc)wEH&XNI?mhJd>|I>IG%bdp9dKrZAwwdpsiC>6chYL6?= zC%-^lCjuS}*OpR-h}YHGzJq5QRYB!j>Q3W}!6abYFe=iHX9CdQJ`hwXex9$Ymw2B_ zREtJl^$g_08=#_uX?{6L@>5Po|ubP31t31vTwFoUL-VT{pfsBKFjrd{@Wxd8SAEa#`;W$Pi~26{z{RU&_|M&#oNp_zON#y6=Q=GcXI47&bb0C$Oh#H_r)1FS*v} zsjku#5#ZzWL`>2kF_5{<0h^7~NG!y`F~nXTiwZqKPN>ebAao-_6rLH2(E%gkLNGSb!=Dk8?5m=DbGt97o)y zWE5Q_IZ~_ji|o)-yQjVQJ4x_Sl{oa3dfVlh*IVPe;tn7ve)0kv7%9IhrTgAq`NV*I z0witba`RYDo_MV`-GUv3KxEY|>|w)RsjQ0Vx!vvgwiQU8BnUFe)!SZsb6i&$Dg~tw zJ$;m+d({eNk+&=Qwv$FW0V^Qb@l~DeYovhN{t)3dwXM8Hfwt9`9%nSX9b2?G`fji8 z1Cg>qnJ8*|6n6FKV+XDvq{FpM+J#l^XCIOu(GhZ&Qh(O}(|dn>paJ_E9$DtnTxr@{>OAeqHjd z33J;{%2az&y|AKDfYh!S1tY|%XDEXq>q?+{*#!n1)eMpI%-i$KQxK#2c_{C;r}+vO z@wVJb*R?&uO*2nrcjvPs$ng!>amk!K%%y0c(Cdhy4FDz#8t=6)pLX_v(K6j!7syi5 zTz)wfX+KKp34SRmATYS@O0igFr>Ow82{94dcVW;TG_`y!5yCasd!au;EYThp&<=yI zB52-C+AawTfk$$8Iz6dfiUT2syLVtiK<=jQqz}Q<**tFnZ=@;3#knu(J4kKn&<5j#5OC825ZIU#)4@IQp>LmLQe+nq%Rli>xv&5GQ2O{B`;>}C3Ro>`D zwup^m?;@iQ6GdQW_1!X~6<&;dYTtOQ-H%THO?xtWn>Pi2@}tw6i6Sy`G>N<+b%hs1 zdPQW2yH5mCf`x$%+OYF{%R(Hqmn!v+{Q{P|KTS_hhXF}a{mgMOkQx1~dP(|%Q0#0D z%!|t{2eR*kaK)P)PPP!0eCWY>gT}qcKo_;TH}gOJ-flg$8qB?$#exXC*-DqyyD(HB zc3L`=Qv#VKYU~F=G5^v66pnD<>e;k_(2e2|>+P}9U>D1r`|1(-0?|11X)ZK@+@N_@ z+;Gqhl6uJQg(^O&4dFg{&H1Rz=)Wu1m(keW&;GtQ5qdUxznG-qcFRR_A}_;zD)>}1 z?K#_$A!@!S)5pKV$OpTfLE!EKfq67=-#CNW@jG>D){F0_O_#u*S-vWiX#PU|jXodJ z_01b5wz};JlSw!uyK7O;3q>;2_D@{GspX9odIzD>dkr^px*Xr#7E~(r3@bdl*z+3G zxm}J-%du0Lh{O3G&sI6_djuTprrJR48jo{xW^cco0=Oc*(EE6Spy>VNasBQ8TJuy&~;&9`l1wI{xYkO*Y@W7v8h-Jpe6m&F;%Un-`|5X{VWf zcb-}Ajr`-cnmF_!$zpaBAS>GIVm*)XJ$tKUIbqFJL=SNy?_a@UN2LF%cifJ#uJX?L*w4P2yOv~gvGNp$eXkH zM;+Wsv2r~dA_py3ImQ8`;SeH?+A0z?g_ zl$W%Jdmu@7^W%?G@wr~w2L?P2b(l4NjpZ?R#YRI0Ak1~yX70WKN9uX`Tcyc?=Kb*~ zY5tp)8M}V531!62wW)I2>7v7DJ5G^C`z2NvT6Q#1Vo3F4WB6E5jP|elHy}1Ebkg60 zJo#`Rm(zQrE7UMl1iR_HH-MI6tk%tBsk8ZPWFeGLkJ?KI`1)gt^sj#w2Nu=4+tQ+5 zz75gj${nheg8v?9-@Xu^Z8Dwy$=W;DqH5oGUW~oVse2z=EQt8tC;j4DA>I1d*9EIA zuH?BdvG7CUZ&%!IOUg-X7yQO*FoUWMsXk>GQL-)$Wmw|EUj3?B-Vv$p`aHt`ASS`BDoV zThqIS-cFsi}r&_-qBrc6daYF_|zy@*&H$%~$Kv9{rDNVi6W!(sVHP45&y4 zi6P7h!4U@e2SZzm_j z$G3Y`?!4Vi{#9vBoizSr{B#GK)+q>0vu`uTSGsZH?3b)~Hx!4u?DmEVr?Yno7$^jo$@ z_92goVeU;#lNJIYl!)ty*7_OK5!J2p8V(8Q`mpf&A>eB3 zX7N#QprzK)J%JgZVT;X~@_OhaDush$WJXI5rQhf=qOu3G<31vOV%H&xWp}Q7DOnqx zUL$iMP)7;*pO$*xaO*iSTVyRvX+&oRPCkf|Vf`Gm`FukhdxHgG0rXvTOYfD_D?CaX zDJ98Q7b=)+h}O41WKW}sB|pQ}gf6buifgcUbTP;RrLy3T7cIFqRK!#SjJ z*3tUF)2r26!Lr{e|LR^|DXVvTH5%oGpsnE%{DbUxd*&%Gvsn>sL;5a3gB{8Jb!3ML zM{k=g;&o@$AcIf`Mc?_@4+$v=2{uawdG#XgPNRYmDMh`2hd8j`nH&MvE)d9%1Y{*v zZ2u|{_S<$+#IIqv^7c_s6n$h`|1B?J!zBZ0_atSMk98G#9zGzmBNo;H>1d&_%kn6p zntK-W>FPuN`uz+#lvCwEX*4@>-4o?oS~Cm99;*`N;VJX$R6$!hd}tv@%*d>Gdab8_ zJ+a-ihhYXi=qDIRChtE~jFzIY@#K^H&&JyM(`^b$_bp+tczm#Qy(3Eh^5W~(t3zto z2o@IC^WYYWuadD$rQF54)hWGf5p2lF*cKO?%DPRqzGb;eZHG#zK(sXb_OLXB2ua5z zmjWrshDlUm+eUmFChsh@#S6oV9CD`!gh_=Xr6G?$J`GuFGlaZ*gM*;m;ga|?4oS9; z!i1wm@y5c@C}Mdzf*w%N1*$NzLel+P;1CQhE-X@s!XYfWkZ&Whb#)5p=;#P{!)hWb zOPWAyL~00xo)l)<@adPG@^|Y&9O_@(6KX>8GDDVwXn)b564^u$d?{#b4Gx`BCO?;z zrZG*_023ia3q|72Kab^G9UA&C`AIN!;@$>`BdBP|3|^ zZGVwLh6MKynMqe->u{By7&2%O9PY%3C^HkpL}rEEDf2)Jt*lG@jscY!?C4c(PSU-P zDF_O{OA@$HBEeu{hj6`tK_V^i@Ji4n7)pXY9z88#sou# zj~m<@ap+1#pQ~r?;^E;}U_$Aa)zHVfOz^(Fg#;CM@6FLgnx?tD<>)DhiG(=Xj@yPp z1ahRt(^X{KnB;%b!{nG=!-+%CBt{OPN~P9qZQJxp5RyRM)w;2fgLo!+IlPupdc;=_ zG`5g>SnHE!y!R42^jScf+5Udh(sPpP&8Dn5=v*; z3VB8V;rR;T0*gvJvBuY}lIRb!e5F?Ia45H+@?pFe2c*(q=r zR~I%1Ko}6CSdl?E|BtEnj;A{O|F}QL>c~1qb*yX|(J?YYI3kWs*|M@X+3Of7vNB3` zWbeIaMj<16MT8`KW#5rCw+2L(}~P#%w&eFJ6c6S^x8`CRR9oVnnPG;QQ%CQQTC_`#xyl()o}GgV+Xdz^u!(7WuC|73{f z{2Vvl^hh3qhVv09;DD21Qsi(BS9S-&1P?7gYSq-)9<^z`Z}FpbB{lz^sKZ{uhBO8P z4`WWXQp1R@qA^_A8YzfJ?97Z2{3P`5&xG_^Yd&_BmSydB)kc!M`eEh~P^I$BG^O%* zsWQ$j>c2nRrV^@{QdfKeBk)#hiJ)@1r!~7rdFrjM3v#lW|_gOWrL9y$^whhow%~hVP6mq@LV7F zy=Eoek3KI-sITVyLG9{P)p|T=6li+d+idpPdv^f(vpI{Ut6=ap5)<~oVQkFo9yq3c z=SdbW@isY^iN5=ri|{d%gOIDC;VA1UE1wl{uTt^{ciJWr-q;-ZBzmryM{1PnosFwl zKez8rhqrcb!Qd2T`;)!aiU>c@5wyKi7-a4emhg zn!b1U*1~_;#x3h^bZsxz{-kmxS83YXPB0==`Wl@4bLWti?RSMO97cI8k`eEPhbMh; zVuDs<@BdL{$ijt^>6vuy{AGQx!+qn?u#>BZlR75C#sM>HcrFbt@#QzLPpyMTmK3zAo@ub(3d*~`{ zCwR@=wf*JNd}f7oyi`bKTy-;e2MtYY8=bPd!PR zQ`JL6MAF+iJb&K8(HbCe5=VzE4Kin6AcWf|5x1@9+7ttjo~Lvv4XnW8)`B zmQ_YF{GXbhq;_3aGdDk98c#z_s9!t|Kv17q_YKILeSd#^g)^jg1cD}*V|RT@95!7f zJ5WHE7%u;9Z*O~nIKWp>1q>1%fc3-}wFH8j79isJir#%P{%ai3%OKmCVm%%sUQG;e zRnjT4Q$H@e!K+iY0J>5`17pq-&7zKhHUm_>hK7bK<_$}fh$)ELX&buTfbaAz+m4)comyKnP+r?exb{n%nqQ-tJ^=tAak3wd}66bhPLS z*cK0|`B^=e#~jx-B?hP-Hqi?=-uvHWYtkAGP3WVngMLNeMn60PBYt0I=>G99*N2Vv zKP8p|RnPlsTh2DpsWuk!A742AD$h+j+jRB+_nB5zMK8dS>VO zq_`$3&esGiighYmo;luj`C@W?K>b>a^Lc}8+@0eLy6=Bti|%rSY~12zl-RrdY^Q}K zItjwci2TKBMkTj;>nObENCq+hi%b<*~nIW-?Bu%m8YGYmP=qm&*^EW)HtTs=)Q3U_Hs5{ z2GxdqPQ?cxawsgKL+QY4Q(gBD7?2Tx z_B~hQ`qI1}vyO>%e;K9}R(if0S6%jMm5jhT806U`lnP0bm0bPKK43-j{lKK{mi0)^Rp=%wg_M+J;Nh>bl1KP;dr}igX89`gF9N~F3#WShmT%1{fbrP zHEej{WV~9lpq=kfT!+nex$$f);6aa!~by#3c=y$dS``~8@M5h5GE zD20oSD22k7UikePu@rk2Y&JV(nM&Cc$x(2NXmg@<$2`he+vu2qkicexSPdiE|;Y1eR5r=waroLgx8hu81F&!FpEF&xXgr-QzWJ9j+nXeaL&t%as|wpDelzw`Ua z!my!vICgpbjl1-chV>;&fXha}*>>_gzWI}ak@<@ivZl+8o1gG*eVO72G@I>o5POfC zjVH_K$mawp1v%lz(|yENtU|XR1x^`aJ^G>p_P>=HY-l|3T~9k@@Ll5TfgQ#-lX`l8 zZ3rfPXfYpr_^fI_%=e?lTH5yM{G88JZt30k*Q1I>Qi5je6-E98{0wT26*-w^;Z`8J zL;jBUpQ7-2%joUP_5b_Q^Yz`s!fBtIYU8_5pf;!P8I&J};d9rFuKZ}-4r^T5*Mpn~ zTDM1z=Dj4ZUCy@pZuog`?WdcU zJhx&xx$q6~ykxl}g4LiD{$(*gVm3Jw{SC*Q|VMc=*JukEXKzGXKXz zt~|x<))?K#h1)GbUy@q(o-(`GdDVYuSbg^WZBZ8GA%dXeaJJ(&4(axb(REvqh5sGh zFZq~v4VUZ?gi^`_kzyj(lw7F#4gyyikz91&IRiz^TZ=NJ?AAPB@q8wfzj&BnMrt@} zhz@%$x?ZX_dvoXByQW0)y>0l6xOoPoc}^JCI_015tV$ZM{l9da!k6oh)0cKBI!fkTaysrdJ|)sP2Z|7*L$H }&45ot84G1mguIr|P_ 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%0AywPCM6d{d1WAG>l9+SA&!O! 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

i>=qhL^QL#*_~iXFixM!jxvcn5 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 z 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Ν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%0Dj{yho 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 diff --git a/en/device-dev/kernel/figure/output-of-the-statfs-command.png b/en/device-dev/kernel/figure/output-of-the-statfs-command.png deleted file mode 100644 index ee40e273e6ef5872a6567144132392fd5a689d0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9019 zcmZ{qXE5Ah*Z+TO$%@|VY7x;(5G|{B!s@*yM2iq1th!2wAc!u?>O=&wqIW?oqW6T2 z-plIs$$ig%o|)&x|HZkkci%H}ojGMb*NN8CRVO84A_4$_R8vF6;NQLY&uR(p{5#cN z;)(!(9ne%!H1Y%OSYxV}>dAb_vK7^bjsNKQ;IXuCH|Iz}J28sVPwsqpI{87l5}>*d zgt7hn#x-X)KU#YR20@YX?@Got#4mGk?LKyrEYlVCkXB~-DNtSD90Lk>EU~b6dLG<1 zIE9n&`I<7A=xjb0CCt~GywY2Fz91j+3%Bskau;y7!4c@T;Oh?G+nZQK$W70}?eztv zfLRe#iA_VU{8hI_IJlB6i@F@<}InG^EOD7h53&B2ZgO`X4K8d}3P z=4xO>NS~B6KY>rZGnZez1?k;fW!}nUuZ9GJDMEhT0`D?`FKLgj&mP@E>~5~9x9%(4 z>^b4Tgi8^6qd3rszykl2h6gy>PhalS3UD8ex9Hd?EXDvYbR-WyCvaDDjIqRD{h1Xzi`WA+miE0<&Mk1HXVeNU&dbw%E;)Wv=%xZfB#>y zx;68N)<0&_kMJu-MF$`&gZYxpx|5!#Gw5WsXusWGQGV3KV(lEtGa@y2+tnHjpM1K# z5xc#_sUL<}hZcFgk|MF8xs_p$os=K!7)m>r`H8h0OH#E{$hq{URE~NsjoBg@9$iu% zc`%8{EzxFBvh>c$QPGY!f!mUH>QxblY7w)ui(JWu*A=2?ul6f#+qy)=@d%Mp_XUo= zfIOw3ci_`FXlY>GITP)8zb#L#F}I)WE&;rx!TjszBXo zFD74G2Lx_Hrkc3@+q?VNaJKSd6x3#hjU0AIVVJd$HH=Tr%Q`6%W1@NBBZE+<-l0CA zWXWP7Ivslhu1}^{^L*8)20G&r6qH8H7N|WS3i)XzL`M0lb(+VNhe6nscK+A-g81^l zAG&6b%v=+Umg*fnQV_3ys<`(fnt*DEk+=n#=1SAiPR^7mULEM0vrvm!=B@0#U5Jo0 z(hPc3BRlY)SYJK5y^N_qZcdCBda8hB!GvRYdR7@bL|1{?C0ksAGnTIl_jQMe$ErwA z_lCrT`aI#(vTN3Z+|;uE&V<)YD6W*LKoJsP_3axeYm?Rrml5>&p1N#~5L_#ybE3!n z6cjRWdv(LPhD7^LQ!Qtn+kSzQaCwXc@=E*=#wD8wo%8Wnnv28MHXPEl+eN-}T%bk% zhy^1-=|XC=7C=5IvAm1RHui);$M_i*A&yGDdDFwD)gazy)se<`)U@IYuo5B3>V3h( z1xGRf3-T-Y@g`C%M157>Rkr2oGM)j7BvY6QW%02KSzVe$%BVMRD$kcUx0xci89#ul z8W?|5STtqHc+Quu&7fY4Ne`7cjcpu@HKZP^u^M}d2w?; z%Q$oIUuP2{Y~DU|YqZYZIHQ(SnZDp@;XWh2`0(pbC7LX%;bXk7sBe1Uwc;BCR|rE; z+nDDzvr8Niovc3IZ_CI-e7z`7mY~8fPsS1tbjTS(-E;I_?VZK7&wTy`MeZb|6o-AJ zVp^mA=bnS7)otvlKc_W)$qy~Vkvl;${OaAMdpGl1ylrJUuEk&FVj|oNQrUoIAI3Lv9?lUR+Ok&WrP49N#^#e9nh2TM{@Si%KgO&wokGo|3f3 zKNAw@EVWWF26>@SPB#2CfgMp_t*EJRE z>z=(h7C5;aDe_M)`99Ht1CN!xwY@du&3LHeK-A!-XY1J6i$4eRmy+fNds_jU3sk^Y zVwOYd2ikrlw%C_J9osP5#mExBzUv-S#EkuGSnQBTD3yzdd@+1)P5QN*)Lzf=Th>>h zUh8A`!|8fK^|8HUg{|&dC5ZLQ!mHC2Cexq}sZKe^W`9z$v6A@9LuEn*;_KpD7EfXP zEY`AEo?b2f84}#XT{%?O*ungR-*`q}pXWGf@e5p|^rsWC7C`nw;CRQasaFh)`jpV7 z*ss>yT!>jUp#tow9;6rcf_J}%Rc|3EO->_bC*hIsDNd5O?H`OIE1oqY2-)Y(I*&t%vyw$)?vP&^*;Io7TPo6*@FUl=urWaoR*dobf!XQ zhvE|zp*b|Xd>kt=T6z^B>Rh1A!>sqbewhKhHtA?Q`1FCKeL5--FpzqofHY=hQ>>ZBw}fB?E#Wkmf9!dlm`8iNAi4nUi&m1BHkW#9fAGcXjTkLbvW~HpMbp>Z)mf(Kvg!{ z_FlE1l*xfA`qkHKU0N?nBq4?8B=cR8gQi=eNzX)^!B2sO3V-1%$G@+|?~Y@RGldF3 zIfVgRiMdzA;0|!UZ^UDgnK%P(wy-zLHGuH5i#k+i3h?5O0L|LNd#<3_2J0~`rvO^< zZI>eKrdf&Y;PSyq`=yb*1Hrey9EP9w0xS2_qDBh>h1k3E9BGqG3a6znPp3q(fj?hIJSGb)c_nPKL!y8wmjO-kz89|eKe6W zo#l)y;n&R~%lhI{01IJcYv4Lwg2Bz+Mm>K6=7LaW5xCOB_~Wm5F_E zcwEKdI|$GP8QrpufhC`opVu{_@W};oJxJQoiQDgm5G}m&VfKl*vp}g&%x2d?*>9%D z)%QAC)gaIF1gdb)(&&~o<&gWI91)atm3jQ^d zcqp4eBLtd2hrUapb@e$q|1BivZ_kZ;j*4EnOsgZ$)09+0qpuqARx^)GLVxg}RM&VG zajU3au<>wCBOjafKKvGN!*-rR!YaR+y1@rS-AU&P$?grYEGQgU{_GY{ zs%M4PK(|z&0^Yr^b z-TCL{EE_~~)+0gK(SxaII}P`;gsgg^OcNsrfk6q^fCt)FaX4>8U-?P(Sr?*sV?5~h zmM=H-Zq(Gb_-Wszpob)E%hzdOU*V2`Cfl!mC*Et93R?=E?Db^ZrQn73zyJo#uKro* zOZB{Z-!oSD87Xii*Z5HS3mG(3

;-rks(3MJUA+ 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 diff --git a/en/device-dev/kernel/figure/program-execution-process.png b/en/device-dev/kernel/figure/program-execution-process.png deleted file mode 100644 index 41e88e6c7eaa02179eb2f1f2637fc5c07cc3eb03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82026 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 MuY2yTre*N|13*h0DgXcg diff --git a/en/device-dev/kernel/figure/querying-information-about-all-semaphores-in-use.png b/en/device-dev/kernel/figure/querying-information-about-all-semaphores-in-use.png deleted file mode 100644 index c8a81f76e32077daf829033b4d7386b5e263c8a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12931 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 HedPZE-fcWJ diff --git a/en/device-dev/kernel/figure/querying-information-about-all-software-timers.png b/en/device-dev/kernel/figure/querying-information-about-all-software-timers.png deleted file mode 100644 index 9dfc32ec75527292d8666da08e198e8dc9cb0d72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14879 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 MD<+qVF4{f*Uo9ymdjJ3c diff --git a/en/device-dev/kernel/figure/querying-information-about-software-timer-1.png b/en/device-dev/kernel/figure/querying-information-about-software-timer-1.png deleted file mode 100644 index b947a3eda54ebe0c6c70cd6e630a368d8432b712..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5787 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 BeAfT~ diff --git a/en/device-dev/kernel/figure/querying-partial-task-information.png b/en/device-dev/kernel/figure/querying-partial-task-information.png deleted file mode 100644 index 3c9bcd7afb18abec424ad478f5c3bb1ebc2f2a11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51379 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 diff --git a/en/device-dev/kernel/figure/querying-pids.png b/en/device-dev/kernel/figure/querying-pids.png deleted file mode 100644 index 8fb629e38738641a958cba848c37a522ee8b893b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15377 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 diff --git a/en/device-dev/kernel/figure/reading-and-writing-data-in-a-queue.png b/en/device-dev/kernel/figure/reading-and-writing-data-in-a-queue.png deleted file mode 100644 index 677d351338e6251a0e5a85b8ecc2cc883e9ba148..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14495 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 diff --git a/en/device-dev/kernel/figure/semaphore-working-mechanism.png b/en/device-dev/kernel/figure/semaphore-working-mechanism.png deleted file mode 100644 index 4981aad660fbc82d9ae016b27e2b50fff9f66eec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41616 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�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 I)vyiwAJMOe2LJ#7 diff --git a/en/device-dev/kernel/figure/signal-sending-failure.png b/en/device-dev/kernel/figure/signal-sending-failure.png deleted file mode 100644 index bbac94b4cedd784cf2affc0b7bed38f0ab2962a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3171 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 Xxok`omrMlyrGd0H5OCa`Cqe%JwXU$} diff --git a/en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58.png b/en/device-dev/kernel/figure/snipaste_2021-01-26_10-38-58.png deleted file mode 100644 index c2c10e4703081a15ea0bbf8c08baa49fafe0c7a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2702 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 diff --git a/en/device-dev/kernel/figure/stack-analysis-mechanism.png b/en/device-dev/kernel/figure/stack-analysis-mechanism.png deleted file mode 100644 index 0c10e4285f0b2c1a992228770a49c497f5382725..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42471 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 MXZs6PmNy^%FF_X31poj5 diff --git a/en/device-dev/kernel/figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png b/en/device-dev/kernel/figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png deleted file mode 100644 index 5f4052419e2b1b8453b3a89fb14709834610a9ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8877 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 z 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 n^t+NL#(yTs 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 a6B+Bs!3L=9az6V12e7qrw5&4sPW&$#jUTlD diff --git a/en/device-dev/kernel/figure/viewing-the-usage-of-physical-pages.png b/en/device-dev/kernel/figure/viewing-the-usage-of-physical-pages.png deleted file mode 100644 index 1c213aa35d8bb8d04013d63d0313ab6f1cdea2cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5973 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

m9F=f{W)JLMd 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

jViJ;YdvKMS;Bi%wD5bh>;F1Bf<9h3GrXK05f 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 diff --git a/en/device-dev/kernel/figure/process-of-creating-a-vnode.png b/en/device-dev/kernel/figure/process-of-creating-a-vnode.png deleted file mode 100644 index 196379c4e96421909b045bdfee66aad69ed09855..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38518 zcmcfpc{r5q8#oS+JgF?Hn24CP+agJ28!1%w?7J)>TZ^4Bo+O3PGS)Cz#=ea)LX47# zvhQO_vJbM2Wz6_pH$Bhi`Mt;YdmQia{_+0NOlI!uy3Xx7_j8`>XsL0q^0C5TFpiry zuHS~inC-wnm%S|D6X{Cl4DiPE=(d_Ntf2Ym6!_yWhpU=bVX)#Tw#_@c!QcDt-!ORu zgYB<{{xQ|NXMyE0Y&Wl8)%UTS9i$Z=9ZQ<`-`cm368-y{^p)dsXCq%J=xV73AL4ex zhdkbu@bdDl&yEKg<8`l7za8NII$9LG%E$agDColT^BTvrzKzSWm?_y@36ei>$Ui99 zUal#&_Xmw0Sv>PQyUS`~#zCRWpvut5$WviHcKM}|k%5s>k7=&2VrNIyH~<6&3sTi- zfZnk}+)~iHZf2!tXyaiP zeMSsde`wkrsdG1|uW>`K(K#_iR-rz5oYOpd3_JZR3`{xll zQ`0?XP7}>#epE1qx8hLl->WIf!$%th$@j%*E5EW`Mu#5t6^!!W)8-wXL`OQbd}Zq+ z(}r8nt1Em(zcAPOHhHKMg&d3(WvdyHgo5M;W9&6&A#gs0Cu;xdc?@#l!>1~^!Yl$ zRxl})2E)ys;?1q6^(>Z84zx@7&H60Pj`kVF&c0u+csP4a4sTSJGF>$dtGTb+0E@_A zKGWiG30X~R51L|I)g14L-k(&(D`0m}xdGd@HBi3s5ozJuqyJ^llnHk2x)8IZ*HHhX z)3i;_GfPbEAN+}TS4n=C$=(UaRrekV1TY0I_P?Z%B;x(Pw>d`@d}FRD0_a7+Q4doU z4~lP*x{$+lp$`uzs~*y{@AUt++@HqDFfLzkoHy79yBn&^Vl6hw#XWE7e+nzre;&XyG+K*Ihw<*k~q41rDF()z8wfjgsf$eb-0|d;(_yz-LoeV=O9e zZ}pzLbtK5-9rRqKl#KgAHzg!LGnM(I^4=r%mVLhC?X*UZ40hPvFu>QY<>d2~QmRKz zJRt~+*n4GYpl|TO?mhV4C!P{rY?tJFF2}+`JM+`L^dGL|WP3LQkS)#)~=h z=FiY_Q|5l8{btfv1rUgAAe;DF14gR9x(qwvL=Gu`Ig??e;fd4q}|O zgPC62Qd?J7&t$ou)zK?r+ z4=8_;=~0lsIJ+^@!?|iX2*dJ*uq!zSJgO@QIFLq~;o|>wK)Kneaoul80=Uipe;Pv*Z*F{Pe{&X zYXE`|8p~3KE_l{$t*ZGKK7<`m0|>Hi{qFQ%|1tJ*Sm4Eex4lAkZ&R~-{4_iCU0{4{<fkudeQ%nw>hc~{7q0QlbaxnBrEW*J(4(a1mFt(r96Zo*>Ottv!+v zQIDzWDXq;!PX2>s{_p%VL*KWw@k5Ue@(&#NnRY1sG2G0dtt+or#`G{l0e>~^vD(2C z^u=%BX7os-!o*(mat6hYeWnb7~KjfD2JY=wlM zY1xX!O#6kNL|g*~Ee=H;LjDSIDLV{PLI67F-$5VS_*xdFw&x1iX1__5FVG1EC`YyV zE)G~2q=KKKHtE1-KHL8gXr7~sJyBZpmJCGU#ONH;8|eOVp!$Et#<(@@krHLh7<*u^ z?G z0?+sR>;;y_*QK^|OQ#*f;5=tesY+#1LPOv#O;h#OvE#t5{^H`hthT3n`!pe|0-#GUj?co4l!(bucU+&_9Ol!*gwkKQGqA8~Y!V zg&hZ0#qO(U=weS!E>O>!g7Q87aOR+U5KJ?`p;$y7&i{LVN(C@qwuY{<@$|l}p;sis z{6Rnb>hx|{7eu4}uwle^w!Skwu3v#!JuQ0-YG%eWv&!LHL4@uX*tf&bm%iZU#41i+Lp*O8 z7C!ML;`ok*_T%`eU<-R10$dBqWCst@dmgd)_sgN$h2E#OeeX(m(t^(_?~Qj|=CegF zo9MyUrBz_Hked^;?A=H~**9K94karrH9w!U4m+TH_f=P-_FXFr;%NI!1Y`07+JU{M z2v8!Tl;=`P17kYVt!DXmbHIT*_yy$#jntm~RZllp($E_SMJv+^akG`?g`wR2Fm@gQ zZ*Rw*K>79YV#*To?Z)1FV|w1M->d1%$u47N^}Z=bgwoxY`QC|A{JyWbxXTh!d$_CI z4GPc0ba((On=kt_Y^Xr!mz-2&u(t~~d&K)*Acrx7z;01r_eB0WHQVz#6R){vI5Y3y zE1lC(Z(ATEfOesuAju_=P7e?sdV7tfW^=OQ&1tQXl=>OYg?(W#RmkgkO+AWC*-Dvp zFX;80(mS$G2&iY(NrmhUgsdN01Qu}!7{dtxxko}~B~v~O^oRKXC$!g0$NX5ZM3uy6 z#(UA5XSUWPxcWBNm(pf#lq~^cF>cgKTKQbrw|UWjDXO5yzjl8L1G{>U36=(g7IxBp z;b)yM_z#u?NI_6K6jZoE5ynZtGngY6>k-&7VZ(;zq*2bzU9g1hC3UQQFHflXse_ng zKZr@9xxqtN&HwvyaD|i-p^a~v;O+K-6|H>GN4H}nthB&M1eX8nCg3FMEZP76hm(N& z3F`+&4R!;_F0A$R_JM)ak`y2>uzcV{!cLB5XC|kD$4o(h0lN_f$CnNH<(B;g3mV^s zwOE;Wr}pX4As8$H+@b#$J^qK#|M3`z5;D*?vd+WRDBp!e6QYZWWrJa!@ymRRN-F;7 zm51rx+OX}&1~!>@Ep)#<+hMT=He-_*F_Tvo@9)3+-?!3RrAJe=r z?0E?KLtzE4raItEFh__y(SKQ-qJ88Hyl-;E?EU>aUgO{5hYrJF5rWWn>=qnLArZN@ zAaa9f_qDZ4(gLn`q{F|_131h^le`V6yg2jFP_B?t)F#Tc4^a{h?lVDRI58Pyr+3>g5kd%=(a9 zO`j;F!F8+H7$<&LIrR4-m$5Ht>xwWK?{0vQwF?v-Qh$zf^;OO6w;MJu7NvdrnIDUh z5H$n(;RJ0c0o7;AA8AiQ&$|!M8$fa`@qF*(EAtRaDdS!$Pq|-{->B3t*`Z2(e(i z!kSARo!2yJ&9nomAlxr0F3X~ zmhV8(3o3Z0Y>fcC5rxP%RTW8KO{)q-!cz%`nNyw#cQdEFig&%s4o$#iYM<@|*bIlm z4@oH)WXdwSv@>zC1#1d=0!&yo2ooo13oSj)izuxWUfx8%EGO>-@Ztl#_!g&Ly(@^5 z-KDe&MEBT(1eQ!~21J{vT&WeEj@dZB%Nve4qcfE)<9Y(_C@*a)CgpRX{!=}Hs3eF| z1UR@AhiW@(-BgAXd5Fo4;CSE?QIn>9$TJKp%IA2cBF z+JHeIb-|l7on@ae?K7dSrzhY&6A24?2}Dmx%@L44(zW^7B9lWOwN0 z{zy==hbTZca1J0ZugCTn2xrha`=DDndk ziZ5sFYT^>#zWrtyxIRYt@iDmSRBVT=Yw*Iy&TH*4z54Z`f&S98Oap(Kmgk4{g~4_G z`eBV^J3uA&AZ3<_EAZm-M-z9sxVWlLq46G5?Ex0LCfAlA5pc5CP&laxGBnxQk?NN5 z3Dav6ySHk8h;9)TX!Q<&nboBe>=4|r5cWwJrntywMf9Fyq~cetjt|m<>K)Z#igc}x zItZ2e<>$U5*tlq!jA{LPkcf%jq7?dt0_m|nYp1j)E5PDG9lTGxY@ppt%AlPf_CXdW z9ATRIMDIvxenE~?62m@cl;YSQ14zdg3tmi(F5fVa=Fmt9$ONJ$_@(oj)EvZ7ePH`! zZR*0{eQ&QkT0E37IUN_{E8=1rNSiI2uyUqNB>SJUaxm&FC?8Mw5bab|t$I-gKv%N- z+`|BD+s~uNc~hiKzaE5*jdSRg`wY3?A+#J#PkH}j0BgkyWfqTT7N_*azbE#X$=0!w zzr5i0S7%6f>3WQ5%+!kBduBU5GFd`tgZK4R2VSElk=jL<-2}<#>bZY;{I;h zti`NH{ANZD9?2d7#h#-F=yURmm4KgC7Kcggn;;zsq-wP)K+>!d12Fu;4>-w-Dfm4d z=eY4s^Cr8k(RUBHCfQMGA~y3nxT~7CIx?hPZ*^qaFe{_*Z*dk=ug4+&7TW|j5mkoC zQ2}cTL@8X>uinMe;aViHS8s)`T3uJ;9ha)bMt;4mVA}<{dfLoPgrN6ZHj}syrnEOcU(yV1KT}f&i2w!?0q7;c zz~#r~{la{Cg(kGc44dvRQ$enxM=BOGZ2RB);^#L`7swK4&ASc)O)`0i^+@Y^mAWRy z)-;hs2Co+Cs6#?`y7ogzt$2$7{iFSCrax1V%Ac1jKPl3uhV-fJzJag z@H{)974>e6sM)7~GrvPd)=eOGP`hcic)1WIVEM8gHLIwiQbLKdZL9XssL*z)YEHw6 z^}E6?$=yiHHu%@y@>2{0V#y;oP0;8H&*(j}l+D_elJ+5G%@d8_=8mZyBcM(|KB zGfW!z5FQ%3LM5xuvg7*vKZ7FBM>O=LjmsvPFA!cx!1#VU z#}{Cyszp>Q1Y-7yGWToI+Pp+gCsaF-9g||FSYM^O67q+mq9U(FWz(kvH~J&3W+<2Q zZuI*T_4PMxvyVENnYm{_{HD@Iy!C#7I;9?UD_S6z(eiFj82=E;Z_XkN$Oz zFJi>}?mk*QH%cJTB{0z-38+3z3!uk4CjDpj%-o?gMp-!F+qq&`_&d!Wv>6}qHc(vHZrV*J?PN?9h5HGYANxv^_g97Xb$t zY_!Gf$k%&XRxIsdSV3;7V^>GIBnyWth^;_8F0~U*Xd>IC)9>qKIQGASMDR6E@C%D$ z_Nk+Jp~bJ#cD*Bu@bG;LC5PC5VOgtoIcs=b|D66_iej~k{_{B=L2sWtMcKPn1hM|1 zMth7cwW;(wHsVwcw5}m#g$1 zWC8-r3#G^mJC=ns6*@hRgO}yh`$g%FvJg0auM}VA&**VFB-}3&JpI-!^J738H89EI ze1|InzE`~L(>oh1xuUR9$@pp5AvrfuJEA)vUuFB)=&IgI9IcKu7oLxQH4(c$Mm6@* z81WjZ2sC<67)ZA5dUTb+4IO?FI=l_gf~y_8@I&`yN=;Zx;jL36%ZOoIp3X9Ph=ocm zB^q3PR%dmj-IZ*)FO&bvA-Vmt^@10O<}E5#p~bn{!ABqI=GF8+YJKzh_hn2@$hS!0 z0j&kv-ua2NF)w!0LbCnDn}Tg0!zi(JmY#59MSV>mNq-TKhP)f^TW9k>J1PqRbQ zq7Z=aQ(l2p1$kL^YqMg3W}*)bZbhirE75x3xL&`M-Uqolj^&J%rf?j`)A+CF>r+R2 zxMy_iiQPgWpPrzy*;4#pMslX(w z+CX~u^yki6zn^<%6#3qh&n&Fxo;E!2NmSVIskEn7+3c;Cg9QnxsfSK`4XA`@=(g!? zVDjSyAMs)YX4NKgvdj&|?NsX1C+^f~m*sDUsHl^jwwb&;9z{*6j??xuuLuNIz-j=2 zenD&6L$n8pUEpM0@=Cf3tQsJ_-{kAB(ynS9-qJ75P|;BrfyzZMKX*vjpRTPG&f(GU zJN08lSS)K$sjClu!j|39a{@Nejr5^bUq>H%0D3s8{XF6r7yB6>uR<9UXhq@ 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 E0E13K^#A|> diff --git a/en/device-dev/kernel/figure/process-of-locating-a-file.png b/en/device-dev/kernel/figure/process-of-locating-a-file.png deleted file mode 100644 index 1f2a1adb1e33ba8847dfc45b1eb496bac7639d67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51389 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

a 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 XKazf)dYpeh^phh8j~z%hvcCNv7Nf_v diff --git a/en/device-dev/kernel/figure/writing-dmesg-content-to-a-file.png b/en/device-dev/kernel/figure/writing-dmesg-content-to-a-file.png deleted file mode 100644 index c1fc9bfa12430aac4e8b25ac65040cd069d7211e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3198 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 D)F2RuRzqFI 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 F{|DBGG|>P6 literal 0 HcmV?d00001 diff --git "a/zh-cn/device-dev/kernel/figure/\351\235\236\350\277\236\347\273\255\346\200\247\345\206\205\345\255\230\345\220\210\344\270\200\347\244\272\346\204\217\345\233\276.png" b/en/device-dev/kernel/figures/integrating-discontiguous-memory-regions.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\351\235\236\350\277\236\347\273\255\346\200\247\345\206\205\345\255\230\345\220\210\344\270\200\347\244\272\346\204\217\345\233\276.png" rename to en/device-dev/kernel/figures/integrating-discontiguous-memory-regions.png diff --git a/en/device-dev/kernel/figures/interrupt-vector-table.png b/en/device-dev/kernel/figures/interrupt-vector-table.png new file mode 100644 index 0000000000000000000000000000000000000000..f8c06a083a422984e3118c44f068eb7b8e5d774f GIT binary patch literal 23554 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 literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figures/kernel-architecture.png b/en/device-dev/kernel/figures/kernel-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..dfe167e24812c8146866ee20cd22c4deb9f71d29 GIT binary patch literal 18365 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 Zx3V`FUig|l`yXHq*d4MZ?>lz+{{RQWjxzuN literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figures/kernel-small-mode-process-4.png b/en/device-dev/kernel/figures/kernel-small-mode-process-4.png new file mode 100644 index 0000000000000000000000000000000000000000..e0d74d9b4f39f9bd218943b0a6d7464c9d2eb581 GIT binary patch literal 12813 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 literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figure/en-us_image_0000001127390512.png b/en/device-dev/kernel/figures/kernel-small-mode-process.png similarity index 100% rename from en/device-dev/kernel/figure/en-us_image_0000001127390512.png rename to en/device-dev/kernel/figures/kernel-small-mode-process.png diff --git a/en/device-dev/kernel/figure/en-us_image_0000001178856385.png b/en/device-dev/kernel/figures/kernel-startup-process-2.png similarity index 100% rename from en/device-dev/kernel/figure/en-us_image_0000001178856385.png rename to en/device-dev/kernel/figures/kernel-startup-process-2.png diff --git a/en/device-dev/kernel/figure/kernel-startup-process.png b/en/device-dev/kernel/figures/kernel-startup-process.png similarity index 100% rename from en/device-dev/kernel/figure/kernel-startup-process.png rename to en/device-dev/kernel/figures/kernel-startup-process.png diff --git a/en/device-dev/kernel/figure/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png b/en/device-dev/kernel/figures/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png similarity index 100% rename from en/device-dev/kernel/figure/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png rename to en/device-dev/kernel/figures/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png diff --git a/en/device-dev/kernel/figure/liteos-m-kernel-dynamic-loading-architecture.png b/en/device-dev/kernel/figures/liteos-m-kernel-dynamic-loading-architecture.png similarity index 100% rename from en/device-dev/kernel/figure/liteos-m-kernel-dynamic-loading-architecture.png rename to en/device-dev/kernel/figures/liteos-m-kernel-dynamic-loading-architecture.png diff --git a/en/device-dev/kernel/figure/mapping-between-the-virtual-and-physical-memory-addresses.png b/en/device-dev/kernel/figures/mapping-between-the-virtual-and-physical-memory-addresses.png similarity index 100% rename from en/device-dev/kernel/figure/mapping-between-the-virtual-and-physical-memory-addresses.png rename to en/device-dev/kernel/figures/mapping-between-the-virtual-and-physical-memory-addresses.png diff --git a/en/device-dev/kernel/figures/mutex-working-mechanism-for-mini-systems.png b/en/device-dev/kernel/figures/mutex-working-mechanism-for-mini-systems.png new file mode 100644 index 0000000000000000000000000000000000000000..a1a1359b6efbc2c84e614e8b06add7f318abb871 GIT binary patch literal 39258 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 literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figure/mutex-working-mechanism-23.png b/en/device-dev/kernel/figures/mutex-working-mechanism-for-small-systems.png similarity index 100% rename from en/device-dev/kernel/figure/mutex-working-mechanism-23.png rename to en/device-dev/kernel/figures/mutex-working-mechanism-for-small-systems.png diff --git a/en/device-dev/kernel/figure/overall-file-system-architecture.png b/en/device-dev/kernel/figures/overall-file-system-architecture.png similarity index 100% rename from en/device-dev/kernel/figure/overall-file-system-architecture.png rename to en/device-dev/kernel/figures/overall-file-system-architecture.png diff --git a/en/device-dev/kernel/figure/physical-memory-usage-distribution.png b/en/device-dev/kernel/figures/physical-memory-usage-distribution.png similarity index 100% rename from en/device-dev/kernel/figure/physical-memory-usage-distribution.png rename to en/device-dev/kernel/figures/physical-memory-usage-distribution.png diff --git a/en/device-dev/kernel/figure/posix-framework.png b/en/device-dev/kernel/figures/posix-framework.png similarity index 100% rename from en/device-dev/kernel/figure/posix-framework.png rename to en/device-dev/kernel/figures/posix-framework.png diff --git a/en/device-dev/kernel/figures/process-management.png b/en/device-dev/kernel/figures/process-management.png new file mode 100644 index 0000000000000000000000000000000000000000..53c9fd21c953bda67ea7b2825c41d59cbd471ada GIT binary patch literal 25001 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 literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figures/process-of-creating-a-vnode.png b/en/device-dev/kernel/figures/process-of-creating-a-vnode.png new file mode 100644 index 0000000000000000000000000000000000000000..86bbe0b5884aec64efe1b8cf6f1acefe0f30b17d GIT binary patch literal 38532 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 Y48`BWwuBDFLU%uAY<4Km$l=QW0vG`%u>b%7 literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figure/process-of-loading-an-elf-file.png b/en/device-dev/kernel/figures/process-of-loading-an-elf-file.png similarity index 100% rename from en/device-dev/kernel/figure/process-of-loading-an-elf-file.png rename to en/device-dev/kernel/figures/process-of-loading-an-elf-file.png diff --git a/en/device-dev/kernel/figures/process-of-locating-a-file.png b/en/device-dev/kernel/figures/process-of-locating-a-file.png new file mode 100644 index 0000000000000000000000000000000000000000..3ca6aed01a3b3354324584abaad5d40180c5f5e7 GIT binary patch literal 51175 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 qf9F= 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 literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figure/semaphore-working-mechanism-22.png b/en/device-dev/kernel/figures/semaphore-working-mechanism-for-small-systems.png similarity index 100% rename from en/device-dev/kernel/figure/semaphore-working-mechanism-22.png rename to en/device-dev/kernel/figures/semaphore-working-mechanism-for-small-systems.png diff --git a/en/device-dev/kernel/figures/stack-analysis-mechanism.png b/en/device-dev/kernel/figures/stack-analysis-mechanism.png new file mode 100644 index 0000000000000000000000000000000000000000..45a8059f0a31a849d73333d109db526186fe7205 GIT binary patch literal 27103 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 Ks&hK~)4u_k6McI~RY z&-c~6iw-uMHtgO20)aN!o;&Rf0@Jq_B?vKb3p5-3;yeKZnpXF-2Kz7_iD52QyxC_di%uwsP2`Nj?>}& zV>>DPwuJJqft|Z~F9V72MS&J$%B;L}aq0%Woat6tP917))n0PKOZ?*bcsjaFbfUD0 zdRw6u=+F}#MRDm@Kv@vz&BnAo3=Di4-rTp#HaJX3DCBlUGb0WN=I9` zx+C$}gC7XJl@1^K_$Xt-4>eR6+E2+gG$bT+v3RXS(cw@C^da6sC_7rl)K#!daeBv7{PJ9ysb+1n~k4PY)kd>ZF$kZO{;Kv_F40T@%uB>U3O*q+VGv8 znK!zv9gz-{x}&_Z$$z<%1_dPnljiAX(nidg9uvI2=_NC;z^-Z`ZlYB*aE^~*^_}k# zzhvmOU)-HHV|XM8lgI>tB2z2#A`xquxqYFe{Ok3)+2uE;#;Kxdi^lHlqSrrz) zcgs)9kn$#_BJrTQa61+kki&DmG1!{cRUsF}d1Z?hxwNJMMu1ZwD#%vN!aeWx1$(ut zd1K)xvfBQFwN?P*NrI~zU>V}9CVQdr$Uvr;G46zW_BhV@nR*YLf7B5z%FS@pwh>|N z)LL*M$%8xyG%vk6oTNo?l1+T@ql9Kx=JhaOcr6MV6O??B#i@>o)6QHlPrsG!%UBol z!(=;hb;P=ExpjEmEN8vjh5iC_r-hPBWJ)JS_qON~vydD;zK@*|a$EM?r2HYP++&)S z?E`thEFhaW2BY$eEVhT2N)7w(nCoWp)c6eZ^!{+|ifv#t^;LaNSA+fUxLSH+XEjY` zq1q3oS(a$FxkehV19hJ%hxTfnJ?i2(8-9!_vLrkNUWy1+q|2 zczABgeZ4$`TD#=u@@+&p(qj7yF}E*TZ>y4Hed*0wx=FgShI1U0S*M+>B=nQ!YEA$a>{5?RQ(^;&CK+;k~hg6bZS8`{Kd!II?c8?nu>>)X-F>`oi^3zgz+8a^r|g?|8mT2 z#9VGsBfS9qvLeW4PIKxSAZT|H_nSFm#H6k;!V42Hg>J5t9dk{)-OxId5!@&`#I{mDLKZs|O9OvcG>9$FNYLG!Du{V5Tskji+^8$& zrwjd)&7mi~RA2NW|GX>iObz3$DVvb$2%J#&rEe~3`U#aUqjd23_*UsGmQn^jaz;*% zy83OWhv>Z{*-aCEDCQII7U9gq!mUoOvTD-YS5&18e|G-ZXD5uKJ1^8y8#%u`#tA@a zJ;NAbXN_ndEzsdHa&)VR3$?^R`=y8IP4uNWl6!$$+U>^A{dzIp8lpz5xcBJ&ajAEa zc;-}vfPQHLJ{}{CS~!l>sEIJ}CU4Fu_xxOPy;iJ?Yen$h+i^{3Fig%oCBtgYG~v0m&w z>_Wd}9Ym{_%1PKQM7$~x8WxUK??7v5uCq+{4j7)Yj9H_BDYjLk+v}U!pL=OMCzwm| z>(%8~c21EQCt(As@F`k zjgB~p0SqpQ+7%-5CigVu=kSi}=efSB;yE??dE2w_=scyjfi;@gg`a^i$p2(u-J?`} z*5MCPYj{K%9FYt@?J#vleb~nxRk$zSnYBS!n=bXrxaL@+Y4&8tVFtYB^XY_h$-}V? zU_+dp+J%XucV>WjOKSDp|09xi-}zUVeV4^$M2Bu%W`6crsyIu04cQL_-nOOxA~uiQ zwOCsEJaGaT;PXdHBXo zXNPPE*><3$#;+u^F?PY4zHL8VM=sFGl>MMKAE3wMKW|OhtH=Y$HG@?f(*7~diYE%NTeg!0^gXMJFD&!T1viU6KR)#vAX(~GyYiNq_&tJZ$QbS$TeILG8K3t~Khl`*6&zjmz;>~G!rkmjOHoO;?NI9!;rw?K6;RUj7t)#I zC2v*UDQmATbTV8lz9>aG1c^_a+hH}V-LRH(X0_-04#OcY z1E5~xD>Tu`*h`JCO|dl*YiYlJ#mjI75B-`vF^$guD+(R)^pGq_kbb^1IjgFjMmFxsIkI3Y< z)n}XY4F?mORDmux-&0zXvtE%aM(P2{q59k$pKaJ0M-?ed*LGR)Dtd~P54ir3TP* zkTwSjk)g8Fkh9u zGMXt6Ru3ryW5^dQRTddP`O=gRQZ3k6uEmEI{)Kp9DOR%P8{-znolxSOaamUePeb_& z*yX&M7;e9`yMxd2Q|56YdN>=xm|EwbcF>Km;8hxD2%g17F-Cd)Un)F!wfVxqUwhMr zz*P)Mjx>whIcvsz1x^onL|?87pTO=D>p|wUE~+(=8g`%s)@rKS=X2+`O1bde_4yJ zt0VMeiHL|Qhl_9-WO^ga7nAyR_j_0wmB>3J`q<~{$Zzg~`uZ*4wbGvnZ`uQa+?zEj zJD6@-62a>Az&Xw}%>>}sa7ZRaj5ricg8Kv!!`&jpWK?H#_>Hu9OViPXTrN6@R_+LM z+W0c6axCfnH&M;B#d1@3@SJF-Z!)1=lZf)cVeDJQ-Xpvo28yWtfgIhR;C{7E@WiVg zj2SQ?(2zXuf!6b=(1L^bxBrYft3q@vksNoov& zF&Bgxbp|{)Pxip_(2mjw6ByKYd~%PiD`_ZbycIEmYo4uf=xi+q6WnU}FQWA!WSf@m zIt=TH(2^eBOg5n0&GP*yo7(v*Fuj=9v*IO;T_R?CU*E`wB5`o=E7>Jk!fWVBVJ+sc zR^ALw!a(8{jGoHeBre`W2cdU>Ut^^oH1QWL%s6a=wzsRJ<|!AmOu`I-+!y!@c1%~3 zEOX;YvGSTn*l4insRqq*y|T?XiRcyll+3uK)%=yStco$9S9Tb_(aoK_6(*7WYEdtW zGe4_U>VX5oy~XxSI%kEchkIYkrIm_!f|qstzROnEiBr<4Im-+VgW+4qa<|k!wwNE9 z=(`TTnTs6K~X z;mfqbXq*L$zog#eH9Rco*nRUhr0~H7T&r!u7KGhdOgG8d0n z&#y4y8RKA>y_%E&Gld5;xTW+7qaV2wyy`@@WqACcDfI^Nn)Bc*b1zOqy|?W3pzLb} zuAUq)F$>n`z(XruJ9^T2)esT0;tw%4rb0fS`&H)UKq1DLIiogcQY96yfq8^i!M*%! z7!RZ`$2i1diJwp`^`eZO7o!GIuch3bcxd;<0L}j1A z!dgF+nK&=(MC{UdlW*&0XXU;fn5l6@9(}q5;i>m!N019M0|qW!t#{=m?v`7f>h z2~i%NXG2Ly)5c!&+RBIoCo{Y)EL#KPE+1m>%Vo%oHG?nAeIx4aWpVkwH^4eIRY(VJ zTWfWrE+CPmK$jmu7H*Ih5q4OXgN0MP(8Fs)Y9=DA#V@qF*ol5Kpx9$=&gM!Cj3H z7G~x~t&#I?dT%LDW%~+rASno=DPsLJ{>GZpmLzY}yn5Qt*8I6MPoJ1J(#*Y0@6e}r zE|&*PxpBc+0U7e1_)JE$<_Ug={7dX%sCKsK(eT)VEXzWKPn4#6w##4^d^%2Ws#R+~ zw*%#z22aEG#^jPi=jOKc3p5_kb3E`^CR=pvwE^UqaYD<`&hvas*ELOd@=JyH!aWcd z=6!O+G4Wm;+!^v0wAP+4HB9$(;~!fv*|h~jZ4~n!xoGVTDL6?Uyu&i+XM~*+=Db2# zh>0FFe>y)xFZ0Y$jum71pDlZhW`)3u01U9;j`$ucw~<}dUi4!;@k4!dA(tKVJ}ZGJPv$S7We+cDmR z`XoE=w-GH=57w`Mx%vIF?1v;*$-PSHo`#2L#o{Iy5_gG^9w-AoDRCa@8Nrya<_K5X zSW`>4Xk_ZQM(;Zk0(Rrcoq z!pD}b6u^jE?A0!>`Lgvz{t29mOHob_Ao581lJclz+BeTbhONL-v zo@hV$EF2M5;U1r`+4qLfhj5j31`hRvH(BCUJ6Q?DYgW$u46#$Z1D=1O2nUGQ739JZrBQ1 zcUX2>CW=*4A&H<=J+xk8K?s4BAUkJGDhl>W2nx5#*d zfW+&>#VXJAc*^4#XX>1JXe!PZZzJQ<7%ALoU%SIhs@$3A)g3T}bg}%(d(hRiIg@Ys zz>EK7&UFah%s+MY#2HvmwAhwTtAGhGEayg8mSh;b$c2g=`4^Xn)Z4OfB!m)vte))O zr@6!8`F-S*up*1 ze7G0(1i4)lTtLCb4+l3>Z!Y(xg%QT z@P+npy-bl=v^I+0Xb3Ls+BD7Rk#ckH3wic(_X0TNFb6+8HqivH;ZFu|;+h_L(ovlO zWvxi9y7aD>Fy`^o6<~Zj$9lkTK@?`TU4SD)Skb#=#k~DgmzN8!IHxb@R#Q}KIZ}(^ zgldh2w;;PkLy}-(mX}ZJ>lS8tq$W}bt!H$bo9MgXVw|2G;z$!JH7b6MK6IMzj1nEk zqbBE~693qa9b?GdUcsww&?*ec)oCbScbUa@E#-8m@5fR)dl%^9lyyaF$R?}1?W#dG z!c+FV+5r=7{ZN}Ms$AZ7Bd-peo-u-|FQaPb8+&O>@nPu4=b;4+pHG47LRt1Qj?&wK z?KXucoKX0OFG4e;W?r~CLc`{p=J1nI^9=}#8bbq?x#RJ?p?%*Hw8#4hRZ#^jFY2qN zj4o-eWVxH;s6~Z&*}xX7D(~3HR9V2~ za#NYV7Y0_YeoeHOAnBqZk6K)2pRH)6_l?8H=0wL40~T6HxF^g7CA$zhne;EXU~STu zY5Bfxqw&(9m=R2Z=*7z7W>8Y?Z`J??P|T3tcm8OEI+LRPVz{T?P7N(iebBxty}D!c zx{vIZSo*s%%Dk|LxCvk{?m1rj$-C$D=#2<k*Zl2;jQ$SVyh-zp9%F*!pJk|7F|%PVWC}b>sp^HS~N0xWIo)=@^p~j>ANMs&=%J zdhkUy8jvN&^uh~DcbD6><(;M4zkIM5`-(v~e2)Y_H2luT(mH%^ST!an`&TwNuE{susx*8z zLDcMMI20!t10WV7U>Qdaol{HNJC9c`^c-jbI(V2Va2zZRc;``=G{=&l&L@L3wro}M zANZJ~GrMP#|93G8^Hc|9GtOg^s^eBf5&+`+I7zz!-tC(_8zixM@1cHkOS7Cx(z6D= zX(p}6Acp9bcUYja>c*A%<_8hqXKzn@JwBUf<3F%@F3(1x(!hTpW&UAWC@Ho*aV0g; z%is}!0v-tmsKD-VWl|h!u8r#FZLnr%p3zWog7KD}gi{H|Pn6ai|IG>^C}<~WAwn9J z{KEt*Un0&*yuq!x>mRayZOuIg4B$!j(D&JKZH=`%OO00Q3URt?$71i|bQR+`n|R2c zl%{mVAcC~o+@39vPmGSSNRX;s%6|(GH~|`VO#K=?QMAKx<@E-m!MK@zg5wJG#FvUJ z?}@w99~5BR=#VxkI@*Dp@}ERo74+UJF}D8om3pGc%J0&^>NgL^?y@YA{F~RE9CwSw z4||Gb{F}41(+X42P6KdOj*fh!+%S<-mciBvo_}Sl5qUr{($Z5X#YjQATq;R2&}ro` zR@!|0kJjAd>2c%IJd7;#MWHr;1YRG#2(jO14NAKARpPKZFGR!V*R0WaiZ(Cn41^}1 zyrB2j_#Ev6;(=T~FecL*E1SC6doS8L6^TLgfu{x23qNzDTE)74_FHh-Y| zQvjUSc6u5Yq;EZp8(6#ZK2GYh6#Cm8ogd1ro_?WlZZqFm~58Mxw^gFPUlF}}yaZ9{1{I{ljQ`k`o+@8Nz54A_~ zKJ@c!)xhb1EnX>Z<`zYCr~^_Y`t2}bt5W6-fP<>k9T_t41TP=Fuz{aZ=K!Ckkvh-m zW61Rv;ugz0qK&OPqLCP%?Dw{*U5Lv0xVGw9)VK5XC=z!lXM?C1eCv}WPMEs+R9PDR z*w36)MIYZs^p<~pt&#-(w3wR#LES}q2FCn0Y_T|+^V0Y=<=!wXd>#3uBuS9k64WmF+$#V8`?1r2HxFnwUtmbE$b@CAdU>_FRP7z#iHasw{ZNmWPt}X8pSc=XsqvJr8!&3{;Y8}a)Twm?>ZyKv zykMVJUZ>IH=k^t~;%fNj+qLJ9n=~o^QutS%K$#?MosDUi)Cw+v&x0j?+<5NZaK#kbikG`A4XzWyc(;XZCF)~^s=Dyq;TD(0c}k(JjhbC z&Vmxi`T#epJEZR+dq!y+nAVz=zkos{Iew^!3HfNy`AzKXWwdYdMZ!Ik8o0MW zuYaf#!b9Fu5@;wkzT>FplgdU(3mGcO!Or=VCJ)Q99gZcMW}egudzIuR&*vSs_1vDO z^MQ5f!P@ugvP#wjbgPa*aYy~Vk8fE=J$s`0L22s*7Jw{J(%ur=hQ#}-`~G>rOf6&} z>;Boa5+9|qwVo@MGeB$nPmjoCTC2RfmCp8Q1&Be=5o6XTj`IHXHwNY7^P0emq_X~N zV5n%QO6)m^@2$dcr*XqXMi1zl*DpjViq zMS4S*3}7Y)tmC+ulI{PHeSli}t)dRQ2N+T$^oQILVmiQ!eJ?1@vQspEHA)pEUYp~d z&_0}Pvga?I4$`V2)u0f?mn&E#P*SzamDx;Lz07(QAhOuL%t>uiMYH3O-1iZ(h%=r|5a>s5 z4r=vsyF5@5LJ{QlN%8LstxAT7r_F*Lam)+_f-nM&O}* z9ac7E{H7<&9Y0~_w2Sb?)g--uzJGncRpwkZw0WMOw?ScExgrVLvM}yl)QJ!Ntx}~y z?}LL{=)1=mQQ2@!1Mh5m86r<_yf6-m%EGGLtY_E~L%i+PTupeCqv3?KCzSr}+RfqX zKr;$P|LiB=%)#{N)wk+bi02)+?Xuwb0t-%klMm%Qy+A#V()7n=Dk?+l*1y}+kK(X? zUwUb4(9x$b7=91vjU_N6JB{?#kKQBr8Q&DA^r^>W(xNxPa2Y{Fq_=Ms>vYBxnv#vv4Eh}b{PB;fA8OIlZZX1{eT_GpQ-T6_#%vS;afZ? z2dr?;XG;gIzKcPiN#HC3;Ew;}?e?FejCK#&Nuc|3W!2dO2f`G7ZhOYzbk#}!bdWAB6qP0*Xs7~$vOq9|j#L4W4nYM4LQ#50L5h?J2q-o5 z-V~`yl`hhIJ2S3*_qzK&_c{O0`9YcEW4z-VU+0|()zeX)kOS)w7KM2 z0RT6N#?2ddz0j*^M^S9w;@b8yLSx}VN8=ZG84NX_#>R>8LXB@VNbn*q3BzD+My~)J z230yy-uSnI=cnTe+0ui4-S@KOMh7VvR*)KL1C~-4OXO7=T*Hr93D1+FCClFomA;4f zzAYH~D}MRw>jRI1s+{V+&y!Uix;silo$N#r5CFh3KBFZ*Nc?X;Ad*^IXet!T5ye#x zxeKe_vi8>G(JQ+4O5A<3&9PED;_8AyXwZh;xT8njex|XW1V0J0P1??8m46qrs4KJb>j5 zi*{8_ipfvr+syz?mOaD0+-%}sJ=W0MV?kWR0k~lMVGWAYcYTY6;cB`RfW)$CB6;kK z$APczfOa!lL|y$Zz(t+*d=)c_adrpfT!2VftG`NZs zYW7uZgeyBmBR0WR{$Q^@H3TG&l1>#|C1lgA5#j%w3c7>gzdh9E;#xxC*`59G-Yc)~ zdo;vNn+%^yAI~?a#fUa`UA=obC(!i>+Y6GM1=J z*;QzP__&@zI!BMkwb%hQzYnC$)CMa*$r+Br?$za8CA8mVqHNb75 z^m(SooD{t1tJ|uu4t&h^z{nthY*0rZ8W!^$btS-ic*uG@B>+omh} z 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 Z6%IH!_5r_MfgeEtG;ZnKELOoh{VyxdjgSBU literal 0 HcmV?d00001 diff --git a/en/device-dev/kernel/figure/vdso-system-design.jpg b/en/device-dev/kernel/figures/vdso-system-design.jpg similarity index 100% rename from en/device-dev/kernel/figure/vdso-system-design.jpg rename to en/device-dev/kernel/figures/vdso-system-design.jpg diff --git a/en/device-dev/kernel/kernel-basic-mini-time.md b/en/device-dev/kernel/kernel-basic-mini-time.md index f529600d20..eb5fd111c4 100644 --- a/en/device-dev/kernel/kernel-basic-mini-time.md +++ b/en/device-dev/kernel/kernel-basic-mini-time.md @@ -1,7 +1,178 @@ # Time Management -- **[Basic Concepts](kernel-mini-basic-time-basic.md)** +- [Basic Concepts](#section36251149131120) +- [Time Unit](#section97172532397) +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Example Description](#section127752801718) + - [Sample Code](#section321653551711) + - [Verification](#section4366193318167) -- **[Development Guidelines](kernel-mini-basic-time-guide.md)** +## 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. + +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 time management module of the OpenHarmony LiteOS-M kernel provides time conversion and statistics functions. + +## Time Unit + +- 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. + +- 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. + + +## Available APIs + +The following table describes APIs available for the OpenHarmony LiteOS-M time management. For more details about the APIs, see the API reference. + +**Table 1** APIs of the time management module + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Time conversion

+

LOS_MS2Tick

+

Converts milliseconds into ticks.

+

LOS_Tick2MS

+

Converts ticks into milliseconds.

+

OsCpuTick2MS

+

Converts cycles into milliseconds. Two UINT32 values indicate the high-order and low-order 32 bits of the result value, respectively.

+

OsCpuTick2US

+

Converts cycles into microseconds. Two UINT32 values indicate the high-order and low-order 32 bits of the result value, respectively.

+

Time statistics

+

LOS_SysClockGet

+

Obtains the system clock.

+

LOS_TickCountGet

+

Obtains the number of ticks since the system starts.

+

LOS_CyclePerTickGet

+

Obtains the number of cycles for each tick.

+
+ +## How to Develop + +The typical development process of time management is as follows: + +1. Complete board configuration and adaptation as required, and configure the system clock frequency \(**OS\_SYS\_CLOCK** in Hz and **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**\). The default value of **OS\_SYS\_CLOCK** varies with the hardware platform. +2. Call the clock conversion and statistics APIs. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- The time management module depends on **OS\_SYS\_CLOCK** and **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**. +>- 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 configuration options are maintained in the **target\_config.h** file of the development board project. + +## Development Example + +### Example Description + +The following example describes basic time management methods, including: + +1. Time conversion: convert milliseconds to ticks or convert ticks to milliseconds. +2. Time statistics: obtain the number of cycles per tick, number of ticks since system startup, and number of delayed ticks. + +### Sample Code + +Prerequisites + +- The default value of **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND** is **100**. +- The system clock frequency **OS\_SYS\_CLOCK** is configured. + +Time conversion: + +``` +VOID Example_TransformTime(VOID) +{ + UINT32 ms; + UINT32 tick; + + tick = LOS_MS2Tick(10000); // Convert 10000 ms into ticks. + dprintf("tick = %d \n", tick); + ms = LOS_Tick2MS(100); // Convert 100 ticks into ms. + dprintf("ms = %d \n", ms); +} +``` + +Time statistics and delay: + +``` +VOID Example_GetTime(VOID) +{ + UINT32 cyclePerTick; + UINT64 tickCount; + + cyclePerTick = LOS_CyclePerTickGet(); + if(0 != cyclePerTick) { + dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); + } + + tickCount = LOS_TickCountGet(); + if(0 != tickCount) { + dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); + } + + LOS_TaskDelay(200); + tickCount = LOS_TickCountGet(); + if(0 != tickCount) { + dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); + } +} +``` + +### Verification + +The development is successful if the return result is as follows: + +Time conversion: + +``` +tick = 1000 +ms = 1000 +``` + +Time statistics and delay: + +``` +LOS_CyclePerTickGet = 495000 +LOS_TickCountGet = 1 +LOS_TickCountGet after delay = 201 +``` diff --git a/en/device-dev/kernel/kernel-mini-appx-code.md b/en/device-dev/kernel/kernel-mini-appx-code.md index bea0dbabe8..7892f4823b 100644 --- a/en/device-dev/kernel/kernel-mini-appx-code.md +++ b/en/device-dev/kernel/kernel-mini-appx-code.md @@ -1,5 +1,17 @@ # Kernel Coding Specification +- [Principle](#section9512812145915) +- [Directory Structure](#section1355317267017) +- [Naming](#section1375364815017) +- [Comments](#section1692516179119) +- [Format](#section10888536113) +- [Macros](#section12276501124) +- [Header Files](#section158507231319) +- [Data Types](#section91351731446) +- [Variables](#section575493915417) +- [Assertions](#section13864440410) +- [Functions](#section671919481745) + This kernel coding specification is developed based on the general programming specifications in the industry. It defines the programming styles for kernel developers to follow. ## Principle @@ -144,14 +156,13 @@ Example: struct MyType { // Add a comment here, and leave a space between the comment sign (//) and the comment. ... }; // The right brace is followed by a semicolon (;). -int Foo(int a) -{ // The left brace of the function is placed at the beginning of a line and occupies one line. +int Foo(int a) {// The left brace of the function is placed at the beginning of a line and occupies one line. if (a > 0) { Foo(); // There is only one statement in a line. Bar(); } else { // The right brace, else, and the subsequent left brace are in the same line. ... - } // The right brace occupies one line exclusively. + } // The right brace occupies one line exclusively. ... } ``` diff --git a/en/device-dev/kernel/kernel-mini-appx-data-list.md b/en/device-dev/kernel/kernel-mini-appx-data-list.md index 814913de30..88fe04134a 100644 --- a/en/device-dev/kernel/kernel-mini-appx-data-list.md +++ b/en/device-dev/kernel/kernel-mini-appx-data-list.md @@ -1,5 +1,14 @@ # Doubly Linked List +- [Basic Concepts](#section1990715203418) +- [Available APIs](#section848334511411) +- [How to Develop](#section01781261552) +- [Development Example](#section67569495514) + - [Example Description](#section48761994551) + - [Sample Code](#section1280202685519) + - [Verification](#section5811249105512) + + ## Basic Concepts A doubly linked list is a linked data structure that consists of a set of sequentially linked records called nodes. Each node contains a pointer to the previous node and a pointer to the next node in the sequence of nodes. The pointer head is unique. @@ -11,7 +20,7 @@ A doubly linked list allows access from a list node to its next node and also th The doubly linked list module provides the following APIs. For more details about the APIs, see the API reference. -

Category

+ diff --git a/en/device-dev/kernel/kernel-mini-appx-lib-cmsis.md b/en/device-dev/kernel/kernel-mini-appx-lib-cmsis.md index 46081c4d32..faae4988fa 100644 --- a/en/device-dev/kernel/kernel-mini-appx-lib-cmsis.md +++ b/en/device-dev/kernel/kernel-mini-appx-lib-cmsis.md @@ -1,5 +1,12 @@ # CMSIS Support +- [Basic Concepts](#section131091144111615) +- [Development Guidelines](#section57653573161) + - [Available APIs](#section1795910417173) + - [How to Develop](#section48301225131720) + - [Development Example](#section524434761713) + + ## Basic Concepts The Cortex Microcontroller Software Interface Standard \([CMSIS](https://developer.arm.com/tools-and-software/embedded/cmsis)\) is a vendor-independent hardware abstraction layer for microcontrollers based on Arm Cortex processors. Of the CMSIS components, the Real Time Operating System \(RTOS\) defines a set of universal and standardized APIs to reduce the dependency of application developers on specific RTOS and facilitate software porting and reuse. The CMSIS provides CMSIS-RTOS v1 and CMSIS-RTOS v2. The OpenHarmony LiteOS-M supports only the implementation of CMSIS-RTOS v2. @@ -13,7 +20,7 @@ The following table describes CMSIS-RTOS v2 APIs. For more details about the API **Table 1** CMSIS-RTOS v2 APIs -

Function

API

Category

+ @@ -260,7 +267,7 @@ The following table describes CMSIS-RTOS v2 APIs. For more details about the API - - - @@ -262,7 +268,7 @@ name="p157951148105019">#include <fcntl.h& - -

Function

API

osTimerIsRunning

Check whether a timer is running.

+

Checks whether a timer is running.

osTimerNew

@@ -450,7 +457,7 @@ The CMSIS-RTOS v2 component can be provided as a library \(shown in the figure\) The RTOS object control block definition needs to be called for static object allocation. The implementation-specific header file \(**os\_xx.h** in the following figure\) provides access to such control block definitions. In the OpenHarmony LiteOS-M kernel, the header files whose names start with **los\_** provide the definitions of the kernel. -![](figure/en-us_image_0000001132778524.png) +![](figures/how-to-develop.png) ### Development Example diff --git a/en/device-dev/kernel/kernel-mini-appx-lib-posix.md b/en/device-dev/kernel/kernel-mini-appx-lib-posix.md index 6290211b98..ad017c0f5c 100644 --- a/en/device-dev/kernel/kernel-mini-appx-lib-posix.md +++ b/en/device-dev/kernel/kernel-mini-appx-lib-posix.md @@ -1,5 +1,12 @@ # POSIX Support +- [Basic Concepts](#section1757915134139) +- [Development Guidelines](#section1573664211318) + - [Available APIs](#section10429150121317) + - [Important Notes](#section109174418147) + - [Development Example](#section206149278155) + + ## Basic Concepts The OpenHarmony kernel uses the **musl libc** library and self-developed APIs and supports the Portable Operating System Interface \(POSIX\). You can develop components and applications working on the kernel based on the POSIX. @@ -188,7 +195,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs

int pthread_setname_np(pthread_t pthread, const char *name);

Set the thread name.

+

Sets the thread name.

#include <pthread.h>

@@ -243,8 +250,7 @@ The OpenHarmony kernel uses the **musl libc** library and self-developed APIs

Deletes a file.

#include <fcntl.h>

+

#include <fcntl.h

int open(const char *path, int oflags, ...);

int rename(const char *oldpath, const char *newpath);

Rename the specified file.

+

Renames the specified file.

#include <dirent.h>

@@ -795,7 +801,7 @@ name="p157951148105019">#include <fcntl.h&

FILE *fopen(const char *path, const char *mode);

Open a stream.

+

Opens a stream.

#include <stdio.h>

diff --git a/en/device-dev/kernel/kernel-mini-basic-interrupt-concept.md b/en/device-dev/kernel/kernel-mini-basic-interrupt-concept.md deleted file mode 100644 index 658ff6c4be..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-interrupt-concept.md +++ /dev/null @@ -1,37 +0,0 @@ -# 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 to a high-priority condition requiring the interruption of the current code being executed by the processor. When a hardware interrupt is triggered, the interrupt handler is located based on the interrupt ID and then executed to handle the interrupt. - -By using 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. 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. - -The following describes the concepts related to interrupts: - -- Interrupt ID - - Identifies an interrupt request signal. The computer locates the device that sends the interrupt request based on the interrupt ID. - -- Interrupt request - - A process in which an electrical pulse signal is sent to the CPU, alerting the CPU to a high-priority event requiring the interruption of the current code being executed by the CPU. - -- Interrupt priority - - Prioritizes the sources that trigger interrupts based on the importance and urgency of interrupt events, so that the CPU can respond to and handle all interrupts in a timely manner. - -- Interrupt handler - - A program executed by the CPU to respond to the interrupt request from a peripheral. Each device that triggers an interrupt has its own interrupt handler. - -- Interrupt triggering - - The interrupt source sends an interrupt signal to the interrupt controller. The interrupt controller arbitrates all pending interrupts, determines the priority, and sends the interrupt signal to the CPU. When an interrupt source generates an interrupt signal, the interrupt trigger is set to **1**, alerting the CPU to respond to the interrupt. - -- Interrupt vector - - Entry address of an interrupt handler. - -- Interrupt vector table - - An area for storing interrupt vectors. It stores the mapping between interrupt vectors and interrupt IDs. - - diff --git a/en/device-dev/kernel/kernel-mini-basic-interrupt-guide.md b/en/device-dev/kernel/kernel-mini-basic-interrupt-guide.md deleted file mode 100644 index e92a43816c..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-interrupt-guide.md +++ /dev/null @@ -1,124 +0,0 @@ -# Development Guidelines - -When an interrupt request is generated by a peripheral, the CPU suspends the current task and responds to the interrupt request. You need to register the interrupt handler and specify the operation to be performed by the CPU. - -## Available APIs - -The following table describes APIs available for the OpenHarmony LiteOS-M interrupt module. For more details about the APIs, see the API reference. - -**Table 1** APIs of the interrupt module - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Creating or deleting interrupts

-

HalHwiCreate

-

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.

-

HalHwiDelete

-

Deletes an interrupt based on the specified interrupt ID.

-

Enabling or disabling interrupts

-

LOS_IntUnLock

-

Enables the CPU to respond to all interrupt requests.

-

LOS_IntLock

-

Disables the CPU from responding to interrupt requests.

-

LOS_IntRestore

-

Restores the interrupt status before the LOS_IntLock and LOS_IntUnLock operations are performed.

-
- -## How to Develop - -1. Create an interrupt by calling **HalHwiCreate**. -2. Call **TestHwiTrigger** to trigger the specified interrupt. \(This API is defined in the test suite. It simulates an external interrupt by writing the related register of the interrupt controller. Skip this step for common peripheral devices.\) -3. Call **HalHwiDelete** to delete the specified interrupt. Use this API based on actual requirements. - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- Configure the maximum number of interrupts supported and the number of configurable interrupt priorities based on the specific hardware. ->- If the interrupt handler takes long time, the CPU cannot respond to interrupt requests in a timely manner. ->- Functions that trigger **LOS\_Schedule** cannot be directly or indirectly executed during interrupt response process. ->- The input parameter of **LOS\_IntRestore\(\)** must be the return value of **LOS\_IntLock\(\)**, that is, the current program status register \(CPSR\) value before the interrupt is disabled. Interrupts 0 to 15 in the Cortex-M series processors are for internal use. You are advised not to apply for or create interrupts 0 to 15. - -## Development Example - -This example implements the following: - -1. Create an interrupt. -2. Trigger an interrupt. -3. 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. - -``` -#include "los_interrupt.h" - -/* Create an interrupt.*/ -#define HWI_NUM_TEST 7 - -STATIC VOID HwiUsrIrq(VOID) -{ - printf("in the func HwiUsrIrq \n"); -} - -static UINT32 Example_Interrupt(VOID) -{ - UINT32 ret; - HWI_PRIOR_T hwiPrio = 3; - HWI_MODE_T mode = 0; - HWI_ARG_T arg = 0; - - /* Create an interrupt. */ - ret = HalHwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, arg); - if(ret == LOS_OK){ - printf("Hwi create success!\n"); - } else { - printf("Hwi create failed!\n"); - return LOS_NOK; - } - - /* Delay 50 ticks. When a hardware interrupt occurs, the HwiUsrIrq function will be called.*/ - LOS_TaskDelay(50); - - /* Delete an interrupt./ - ret = HalHwiDelete(HWI_NUM_TEST); - if(ret == LOS_OK){ - printf("Hwi delete success!\n"); - } else { - printf("Hwi delete failed!\n"); - return LOS_NOK; - } - return LOS_OK; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -Hwi create success! -Hwi delete success! -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-interrupt.md b/en/device-dev/kernel/kernel-mini-basic-interrupt.md index 3f7c1ac22f..f1ac97b017 100644 --- a/en/device-dev/kernel/kernel-mini-basic-interrupt.md +++ b/en/device-dev/kernel/kernel-mini-basic-interrupt.md @@ -1,7 +1,165 @@ # Interrupt Management -- **[Basic Concepts](kernel-mini-basic-interrupt-concept.md)** +- [Basic Concepts](#section1699312388210) +- [Available APIs](#section158501652121514) +- [How to Develop](#section11841123033618) +- [Development Example](#section460018317164) +- [Verification](#section668510614519) -- **[Development Guidelines](kernel-mini-basic-interrupt-guide.md)** +## 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 to a high-priority condition requiring the interruption of the current code being executed by the processor. When a hardware interrupt is triggered, the interrupt handler is located based on the interrupt ID and then executed to handle the interrupt. + +By using 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. 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. + +The following describes the concepts related to interrupts: + +- Interrupt ID + + Identifies an interrupt request signal. The computer locates the device that sends the interrupt request based on the interrupt ID. + +- Interrupt request + + A process in which an electrical pulse signal is sent to the CPU, alerting the CPU to a high-priority event requiring the interruption of the current code being executed by the CPU. + +- Interrupt priority + + Prioritizes the sources that trigger interrupts based on the importance and urgency of interrupt events, so that the CPU can respond to and handle all interrupts in a timely manner. + +- Interrupt handler + + A program executed by the CPU to respond to the interrupt request from a peripheral. Each device that triggers an interrupt has its own interrupt handler. + +- Interrupt triggering + + The interrupt source sends an interrupt signal to the interrupt controller. The interrupt controller arbitrates all pending interrupts, determines the priority, and sends the interrupt signal to the CPU. When an interrupt source generates an interrupt signal, the interrupt trigger is set to **1**, alerting the CPU to respond to the interrupt. + +- Interrupt vector + + Entry address of an interrupt handler. + +- Interrupt vector table + + An area for storing interrupt vectors. It stores the mapping between interrupt vectors and interrupt IDs. + + +## Available APIs + +The following table describes APIs available for the OpenHarmony LiteOS-M interrupt module. For more details about the APIs, see the API reference. + +**Table 1** APIs of the interrupt module + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Creating or deleting interrupts

+

HalHwiCreate

+

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.

+

HalHwiDelete

+

Deletes an interrupt based on the specified interrupt ID.

+

Enabling or disabling interrupts

+

LOS_IntUnLock

+

Enables the CPU to respond to all interrupt requests.

+

LOS_IntLock

+

Disables the CPU from responding to interrupt requests.

+

LOS_IntRestore

+

Restores the interrupt status before the LOS_IntLock and LOS_IntUnLock operations are performed.

+
+ +## How to Develop + +1. Create an interrupt by calling **HalHwiCreate**. +2. Call **TestHwiTrigger** to trigger the specified interrupt. \(This API is defined in the test suite. It simulates an external interrupt by writing the related register of the interrupt controller. Skip this step for common peripheral devices.\) +3. Call **HalHwiDelete** to delete the specified interrupt. Use this API based on actual requirements. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- Configure the maximum number of interrupts supported and the number of configurable interrupt priorities based on the specific hardware. +>- If the interrupt handler takes long time, the CPU cannot respond to interrupt requests in a timely manner. +>- Functions that trigger **LOS\_Schedule** cannot be directly or indirectly executed during interrupt response process. +>- The input parameter of **LOS\_IntRestore\(\)** must be the return value of **LOS\_IntLock\(\)**, that is, the current program status register \(CPSR\) value before the interrupt is disabled. Interrupts 0 to 15 in the Cortex-M series processors are for internal use. You are advised not to apply for or create interrupts 0 to 15. + +## Development Example + +This example implements the following: + +1. Create an interrupt. +2. Trigger an interrupt. +3. 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. + +``` +#include "los_interrupt.h" + +/* Create an interrupt. */ +#define HWI_NUM_TEST 7 + +STATIC VOID HwiUsrIrq(VOID) +{ + printf("in the func HwiUsrIrq \n"); +} + +static UINT32 Example_Interrupt(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + /* Create an interrupt. */ + ret = HalHwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, arg); + if(ret == LOS_OK){ + printf("Hwi create success!\n"); + } else { + printf("Hwi create failed!\n"); + return LOS_NOK; + } + + /* Delay 50 ticks. When a hardware interrupt occurs, the HwiUsrIrq function will be called. */ + LOS_TaskDelay(50); + + /* Delete an interrupt. */ + ret = HalHwiDelete(HWI_NUM_TEST); + if(ret == LOS_OK){ + printf("Hwi delete success!\n"); + } else { + printf("Hwi delete failed!\n"); + return LOS_NOK; + } + return LOS_OK; +} +``` + +## Verification + +The development is successful if the return result is as follows: + +``` +Hwi create success! +Hwi delete success! +``` diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md b/en/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md deleted file mode 100644 index 435d4ce5c3..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md +++ /dev/null @@ -1,45 +0,0 @@ -# Basic Concepts - -An event is a mechanism for communication between tasks. It can be used to synchronize tasks. The 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. -- Event read timeout mechanism is used. -- Events are used only for task synchronization, but not for data transmission. - -APIs are provided to initialize, read/write, clear, and destroy events. - -## Working Principles - -### Event Control Block - -``` -/** -* Event control block data structure - */ -typedef struct tagEvent { - 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*/ -} EVENT_CB_S, *PEVENT_CB_S; -``` - -### 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. - -**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. - -**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. - -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: - -- **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. -- **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. -- **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 event**: 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. - -**Destroying an event**: Destroy the specified event control block. - -**Figure 1** Event working mechanism -![](figure/event-working-mechanism.png "event-working-mechanism") - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md b/en/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md deleted file mode 100644 index 8b0b3913c1..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md +++ /dev/null @@ -1,186 +0,0 @@ -# Development Guidelines - -## Available APIs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Checking events

-

LOS_EventPoll

-

Checks whether the expected event occurs based on eventID, eventMask, and mode.

-
NOTICE:

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.

-
-

Initializing events

-

LOS_EventInit

-

Initializes an event control block.

-

Reading events

-

LOS_EventRead

-

Reads an event (wait event). The task is blocked to wait based on the timeout period (in ticks).

-

If no event is read, 0 is returned.

-

If an event is successfully read, a positive value (event set) is returned.

-

In other cases, a specific error code is returned.

-

Writing events

-

LOS_EventWrite

-

Writes a specific event to the event control block.

-

Clearing events

-

LOS_EventClear

-

Clears an event in the event control block based on the event mask.

-

Destroying events

-

LOS_EventDestroy

-

Destroys an event control block.

-
- -## How to Develop - -The typical event development process is as follows: - -1. Initialize an event control block. -2. Block a read event control block. -3. Write related events. -4. Wake up a blocked task, read the event, and check whether the event meets conditions. -5. Handle the event control block. -6. Destroy an event control block. - ->![](../public_sys-resources/icon-note.gif) **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. - -## 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. - -1. Create the **Example\_Event** task in the **Example\_TaskEntry** task with a higher priority than the **Example\_TaskEntry** task. -2. Run the **Example\_Event** task to read event **0x00000001**. Task switching occurs to execute the **Example\_TaskEntry** task. -3. Run the **Example\_TaskEntry** task to write event **0x00000001**. Task switching occurs to execute the **Example\_Event** task. -4. The **Example\_Event** task is executed. -5. The **Example\_TaskEntry** task is executed. - -### Sample Code - -The sample code is as follows: - -``` -#include "los_event.h" -#include "los_task.h" -#include "securec.h" - -/* Task ID*/ -UINT32 g_testTaskId; - -/* Event control structure*/ -EVENT_CB_S g_exampleEvent; - -/* Type of the wait event*/ -#define EVENT_WAIT 0x00000001 - -/* Example task entry function*/ -VOID Example_Event(VOID) -{ - UINT32 ret; - 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.*/ - printf("Example_Event wait event 0x%x \n", EVENT_WAIT); - - event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); - if (event == EVENT_WAIT) { - printf("Example_Event,read event :0x%x\n", event); - } else { - printf("Example_Event,read event timeout\n"); - } -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - - /* Initialize the event.*/ - ret = LOS_EventInit(&g_exampleEvent); - if (ret != LOS_OK) { - printf("init event failed .\n"); - return -1; - } - - /* Create a task.*/ - (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; - task1.pcName = "EventTsk1"; - task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId, &task1); - if (ret != LOS_OK) { - printf("task create failed.\n"); - return LOS_NOK; - } - - /* Write the task wait event (g_testTaskId). */ - printf("Example_TaskEntry write event.\n"); - - ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); - if (ret != LOS_OK) { - printf("event write failed.\n"); - return LOS_NOK; - } - - /* Clear the flag.*/ - printf("EventMask:%d\n", g_exampleEvent.uwEventID); - LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); - printf("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; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -Example_Event wait event 0x1 -Example_TaskEntry write event. -Example_Event,read event :0x1 -EventMask:1 -EventMask:0 -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-event.md b/en/device-dev/kernel/kernel-mini-basic-ipc-event.md index 1693a5bc36..25bc83caa1 100644 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-event.md +++ b/en/device-dev/kernel/kernel-mini-basic-ipc-event.md @@ -1,7 +1,244 @@ # Event -- **[Basic Concepts](kernel-mini-basic-ipc-event-basic.md)** +- [Basic Concepts](#section11650123134315) +- [Working Principles](#section1735611583011) + - [Event Control Block](#section1161415384467) + - [Working Principles](#section187761153144617) -- **[Development Guidelines](kernel-mini-basic-ipc-event-guide.md)** +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Example Description](#section896412438910) + - [Sample Code](#section149077554912) + - [Verification](#section4461439172017) +## Basic Concepts + +An event is a mechanism for communication between tasks. It can be used to synchronize tasks. The 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. +- Event read timeout mechanism is used. +- Events are used only for task synchronization, but not for data transmission. + +APIs are provided to initialize, read/write, clear, and destroy events. + +## Working Principles + +### Event Control Block + +``` +/** +* Event control block data structure + */ +typedef struct tagEvent { + 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*/ +} EVENT_CB_S, *PEVENT_CB_S; +``` + +### 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. + +**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. + +**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. + +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: + +- **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. +- **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. +- **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 event**: 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. + +**Destroying an event**: Destroy the specified event control block. + +**Figure 1** Event working mechanism for mini systems +![](figures/event-working-mechanism-for-mini-systems.png "event-working-mechanism-for-mini-systems") + +## Available APIs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Checking events

+

LOS_EventPoll

+

Checks whether the expected event occurs based on eventID, eventMask, and mode.

+
NOTICE:

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.

+
+

Initializing events

+

LOS_EventInit

+

Initializes an event control block.

+

Reading events

+

LOS_EventRead

+

Reads an event (wait event). The task is blocked to wait based on the timeout period (in ticks).

+

If no event is read, 0 is returned.

+

If an event is successfully read, a positive value (event set) is returned.

+

In other cases, a specific error code is returned.

+

Writing events

+

LOS_EventWrite

+

Writes a specific event to the event control block.

+

Clearing events

+

LOS_EventClear

+

Clears an event in the event control block based on the event mask.

+

Destroying events

+

LOS_EventDestroy

+

Destroys an event control block.

+
+ +## How to Develop + +The typical event development process is as follows: + +1. Initialize an event control block. +2. Block a read event control block. +3. Write related events. +4. Wake up a blocked task, read the event, and check whether the event meets conditions. +5. Handle the event control block. +6. Destroy an event control block. + +>![](../public_sys-resources/icon-note.gif) **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. + +## 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. + +1. Create the **Example\_Event** task in the **Example\_TaskEntry** task with a higher priority than the **Example\_TaskEntry** task. +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 + +The sample code is as follows: + +``` +#include "los_event.h" +#include "los_task.h" +#include "securec.h" + +/* Task ID*/ +UINT32 g_testTaskId; + +/* Event control structure*/ +EVENT_CB_S g_exampleEvent; + +/* Type of the wait event*/ +#define EVENT_WAIT 0x00000001 + +/* Example task entry function*/ +VOID Example_Event(VOID) +{ + UINT32 ret; + 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. */ + printf("Example_Event wait event 0x%x \n", EVENT_WAIT); + + event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); + if (event == EVENT_WAIT) { + printf("Example_Event,read event :0x%x\n", event); + } else { + printf("Example_Event,read event timeout\n"); + } +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + + /* Initialize the event. */ + ret = LOS_EventInit(&g_exampleEvent); + if (ret != LOS_OK) { + printf("init event failed .\n"); + return -1; + } + + /* Create a task. */ + (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; + task1.pcName = "EventTsk1"; + task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId, &task1); + if (ret != LOS_OK) { + printf("task create failed.\n"); + return LOS_NOK; + } + + /* Write the task wait event (g_testTaskId). */ + printf("Example_TaskEntry write event.\n"); + + ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); + if (ret != LOS_OK) { + printf("event write failed.\n"); + return LOS_NOK; + } + + /* Clear the flag. */ + printf("EventMask:%d\n", g_exampleEvent.uwEventID); + LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); + printf("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; +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +Example_Event wait event 0x1 +Example_TaskEntry write event. +Example_Event,read event :0x1 +EventMask:1 +EventMask:0 +``` + diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md b/en/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md deleted file mode 100644 index e638e55d44..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md +++ /dev/null @@ -1,17 +0,0 @@ -# Basic Concepts - -A mutual exclusion \(mutex\) is a special binary semaphore used for exclusive access to shared resources. - -A mutex can be unlocked or locked. When a mutex is held by a task, the mutex is locked and the task obtains the ownership of the mutex. When the task releases the mutex, the mutex is unlocked and the task will lose the ownership of the mutex. When a task holds a mutex, other tasks cannot unlock or hold the mutex. - -In an environment where multiple tasks compete for shared resources, the mutex can protect the shared resources via exclusive access. In addition, the mutex can prevent semaphore priority inversion, which occurs when a low-priority task holds a semaphore but a high-priority task has to wait until the low-priority task releases it. - -## Working Principles - -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. - -**Figure 1** Mutex working mechanism -![](figure/mutex-working-mechanism.png "mutex-working-mechanism") - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md b/en/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md deleted file mode 100644 index 4d3ed8e8ec..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md +++ /dev/null @@ -1,197 +0,0 @@ -# Development Guidelines - -## Available APIs - -**Table 1** APIs of the mutex module - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Creating or deleting a mutex

-

LOS_MuxCreate

-

Creates a mutex.

-

LOS_MuxDelete

-

Deletes the specified mutex.

-

Requesting or releasing a mutex

-

LOS_MuxPend

-

Requests the specified mutex.

-

LOS_MuxPost

-

Releases the specified mutex.

-
- -## How to Develop - -The typical mutex development process is as follows: - -1. Call **LOS\_MuxCreate** to create a mutex. -2. Call **LOS\_MuxPend** to request a mutex. - - 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. - - 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. - - 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\_MuxPost** 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 no task is blocked by the specified mutex, the mutex is released successfully. - -4. Call **LOS\_MuxDelete** to delete a mutex. - ->![](../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 unclocked. ->- Mutexes cannot be used in the interrupt service program. ->- When using the LiteOS-M kernel, 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. ->- When a mutex is held by a task, the task priority cannot be changed by using APIs such as **LOS\_TaskPriSet**. - -## Development Example - -### Example Description - -This example implements the following: - -1. Create the **Example\_TaskEntry** task. In this task, create a mutex, lock task scheduling, create two tasks **Example\_MutexTask1** \(with a lower priority\) and **Example\_MutexTask2** \(with a higher priority\), and 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**. -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 - -The sample code is as follows: - -``` -#include -#include "los_mux.h" - -/* Mutex handler ID*/ -UINT32 g_testMux; -/* Task ID*/ -UINT32 g_testTaskId01; -UINT32 g_testTaskId02; - -VOID Example_MutexTask1(VOID) -{ - UINT32 ret; - - printf("task1 try to get mutex, wait 10 ticks.\n"); - /* Request a mutex.*/ - ret = LOS_MuxPend(g_testMux, 10); - - if (ret == LOS_OK) { - printf("task1 get mutex g_testMux.\n"); - /*Release the mutex.*/ - LOS_MuxPost(g_testMux); - return; - } - if (ret == LOS_ERRNO_MUX_TIMEOUT ) { - printf("task1 timeout and try to get mutex, wait forever.\n"); - /* Request a mutex.*/ - ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); - if (ret == LOS_OK) { - printf("task1 wait forever, get mutex g_testMux.\n"); - /*Release the mutex.*/ - LOS_MuxPost(g_testMux); - /* Delete the mutex. */ - LOS_MuxDelete(g_testMux); - printf("task1 post and delete mutex g_testMux.\n"); - return; - } - } - return; -} - -VOID Example_MutexTask2(VOID) -{ - printf("task2 try to get mutex, wait forever.\n"); - /* Request a mutex.*/ - (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); - - printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); - - /* Enable the task to enter sleep mode for 100 ticks.*/ - LOS_TaskDelay(100); - - printf("task2 resumed and post the g_testMux\n"); - /* Release the mutex.*/ - LOS_MuxPost(g_testMux); - return; -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - TSK_INIT_PARAM_S task2; - - /* Create a mutex.*/ - LOS_MuxCreate(&g_testMux); - - /* Lock task scheduling.*/ - LOS_TaskLock(); - - /* Create task 1.*/ - memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; - task1.pcName = "MutexTsk1"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("task1 create failed.\n"); - return LOS_NOK; - } - - /* Create task 2.*/ - memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); - task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; - task2.pcName = "MutexTsk2"; - task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task2.usTaskPrio = 4; - ret = LOS_TaskCreate(&g_testTaskId02, &task2); - if (ret != LOS_OK) { - printf("task2 create failed.\n"); - return LOS_NOK; - } - - /* Unlock task scheduling.*/ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -task2 try to get mutex, wait forever. -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. -task2 resumed and post the g_testMux -task1 wait forever, get mutex g_testMux. -task1 post and delete mutex g_testMux. -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-mutex.md b/en/device-dev/kernel/kernel-mini-basic-ipc-mutex.md index 15585c6ed4..a995b78930 100644 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-mutex.md +++ b/en/device-dev/kernel/kernel-mini-basic-ipc-mutex.md @@ -1,7 +1,224 @@ # Mutex -- **[Basic Concepts](kernel-mini-basic-ipc-mutex-basic.md)** +- [Basic Concepts](#section1663192064511) +- [Working Principles](#section115161649726) +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section1426719434114) + - [Example Description](#section896412438910) + - [Sample Code](#section149077554912) + - [Verification](#section2059413981311) -- **[Development Guidelines](kernel-mini-basic-ipc-mutex-guide.md)** +## Basic Concepts + +A mutual exclusion \(mutex\) is a special binary semaphore used for exclusive access to shared resources. + +A mutex can be unlocked or locked. When a mutex is held by a task, the mutex is locked and the task obtains the ownership of the mutex. When the task releases the mutex, the mutex is unlocked and the task will lose the ownership of the mutex. When a task holds a mutex, other tasks cannot unlock or hold the mutex. + +In an environment where multiple tasks compete for shared resources, the mutex can protect the shared resources via exclusive access. In addition, the mutex can prevent semaphore priority inversion, which occurs when a low-priority task holds a semaphore but a high-priority task has to wait until the low-priority task releases it. + +## Working Principles + +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. + +**Figure 1** Mutex working mechanism for mini systems +![](figures/mutex-working-mechanism-for-mini-systems.png "mutex-working-mechanism-for-mini-systems") + +## Available APIs + +**Table 1** APIs of the mutex module + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Creating or deleting a mutex

+

LOS_MuxCreate

+

Creates a mutex.

+

LOS_MuxDelete

+

Deletes the specified mutex.

+

Requesting or releasing a mutex

+

LOS_MuxPend

+

Requests the specified mutex.

+

LOS_MuxPost

+

Releases the specified mutex.

+
+ +## How to Develop + +The typical mutex development process is as follows: + +1. Call **LOS\_MuxCreate** to create a mutex. +2. Call **LOS\_MuxPend** to request a mutex. + + 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. + - 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. + - 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\_MuxPost** 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 no task is blocked by the specified mutex, the mutex is released successfully. + +4. Call **LOS\_MuxDelete** to delete a mutex. + +>![](../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 unclocked. +>- Mutexes cannot be used in the interrupt service program. +>- When using the LiteOS-M kernel, 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. +>- When a mutex is held by a task, the task priority cannot be changed by using APIs such as **LOS\_TaskPriSet**. + +## Development Example + +### Example Description + +This example implements the following: + +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**. +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 + +The sample code is as follows: + +``` +#include +#include "los_mux.h" + +/* Mutex handler ID*/ +UINT32 g_testMux; +/* Task ID*/ +UINT32 g_testTaskId01; +UINT32 g_testTaskId02; + +VOID Example_MutexTask1(VOID) +{ + UINT32 ret; + + printf("task1 try to get mutex, wait 10 ticks.\n"); + /* Request a mutex. */ + ret = LOS_MuxPend(g_testMux, 10); + + if (ret == LOS_OK) { + printf("task1 get mutex g_testMux.\n"); + /*Release the mutex. */ + LOS_MuxPost(g_testMux); + return; + } + if (ret == LOS_ERRNO_MUX_TIMEOUT ) { + printf("task1 timeout and try to get mutex, wait forever.\n"); + /* Request a mutex. */ + ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); + if (ret == LOS_OK) { + printf("task1 wait forever, get mutex g_testMux.\n"); + /*Release the mutex. */ + LOS_MuxPost(g_testMux); + /* Delete the mutex. */ + LOS_MuxDelete(g_testMux); + printf("task1 post and delete mutex g_testMux.\n"); + return; + } + } + return; +} + +VOID Example_MutexTask2(VOID) +{ + printf("task2 try to get mutex, wait forever.\n"); + /* Request a mutex. */ + (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); + + printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); + + /* Enable the task to enter sleep mode for 100 ticks. */ + LOS_TaskDelay(100); + + printf("task2 resumed and post the g_testMux\n"); + /* Release the mutex. */ + LOS_MuxPost(g_testMux); + return; +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + TSK_INIT_PARAM_S task2; + + /* Create a mutex. */ + LOS_MuxCreate(&g_testMux); + + /* Lock task scheduling. */ + LOS_TaskLock(); + + /* Create task 1. */ + memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; + task1.pcName = "MutexTsk1"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("task1 create failed.\n"); + return LOS_NOK; + } + + /* Create task 2. */ + memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; + task2.pcName = "MutexTsk2"; + task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task2.usTaskPrio = 4; + ret = LOS_TaskCreate(&g_testTaskId02, &task2); + if (ret != LOS_OK) { + printf("task2 create failed.\n"); + return LOS_NOK; + } + + /* Unlock task scheduling. */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +task2 try to get mutex, wait forever. +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. +task2 resumed and post the g_testMux +task1 wait forever, get mutex g_testMux. +task1 post and delete mutex g_testMux. +``` diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md b/en/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md deleted file mode 100644 index 7bd2e29fa0..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md +++ /dev/null @@ -1,62 +0,0 @@ -# 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. - -Tasks can read messages from a queue. When the queue has no messages, the tasks are suspended. When the queue has a new message, the suspended tasks are woken up and process the new message. Tasks can also write messages to the queue. When the queue is full, the write task is suspended. When there is an available message node in the queue, the suspended write task is woken up and writes a message. - -You can adjust the timeout period of the read queue and write queue to adjust the block mode of the read and write APIs. If the timeout period is set to **0** for the read queue and write queue, tasks will not be suspended and the API directly returns. This is the non-block mode. If the timeout period is greater than **0**, block mode is used. - -An asynchronous processing mechanism is provided to allows 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 first-in-first-out \(FIFO\) mode and can be read and written asynchronously. -- Both the read queue and write queue support the timeout mechanism. -- 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. -- 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. -- When a queue is created, the required dynamic memory space is automatically allocated in the queue API. - -## Working Principles - -### Queue Control Block - -``` -/** - * Data structure of the queue control block - */ -typedef struct -{ - UINT8 *queue; /* Pointer to the memory space of queue messages */ - UINT16 queueState; /* Queue status*/ - UINT16 queueLen; /* Number of message nodes in a queue, that is, the queue length */ - UINT16 queueSize; /* Size of a message node */ - UINT16 queueID; /*Queue ID */ - UINT16 queueHead; /* Position of the message head node (array subscript)*/ - UINT16 queueTail; /* Position of the message tail node (array subscript) */ - UINT16 readWriteableCnt[OS_READWRITE_LEN];/* The array element with subscript 0 indicates the number of readable messages in a queue. - The element with subscript 1 indicates the number of writable messages in a queue. */ - LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /* A linked list of tasks waiting to read or write messages. - Subscript 0: list of tasks waiting to read messages. Subscript 1: list of tasks waiting to write messages.*/ - LOS_DL_LIST memList; /* A linked list of memory blocks*/ -} LosQueueCB; -``` - -Each queue control block contains information about the queue status. - -- **OS\_QUEUE\_UNUSED**: The queue is not in use. -- **OS\_QUEUE\_INUSED**: The queue is in use. - -### Working Principles - -- 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. -- 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 - -![](figure/en-us_image_0000001132935054.png) - -The preceding figure illustrates how to write data to the tail node only. Writing data to the head node is similar. - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md b/en/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md deleted file mode 100644 index 32984c25fc..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md +++ /dev/null @@ -1,190 +0,0 @@ -# Development Guidelines - -## Available APIs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Creating or deleting a message queue

-

LOS_QueueCreate

-

Creates a message queue. The system dynamically allocates the queue space.

-

LOS_QueueDelete

-

Deletes the specified queue based on the queue ID.

-

Reading or writing data in a queue (without the content contained in the address)

-

LOS_QueueRead

-

Reads data in the head node of the specified queue. The data in the queue node is an address.

-

LOS_QueueWrite

-

Writes the value of the input parameter bufferAddr (buffer address) to the tail node of the specified queue.

-

LOS_QueueWriteHead

-

Writes the value of the input parameter bufferAddr (buffer address) to the head node of the specified queue.

-

Reading or writing in a queue (with the content contained in the address)

-

LOS_QueueReadCopy

-

Reads data from the head node of the specified queue.

-

LOS_QueueWriteCopy

-

Writes the data saved in the input parameter bufferAddr to the tail node of the specified queue.

-

LOS_QueueWriteHeadCopy

-

Writes the data saved in the input parameter bufferAddr to the head node of the specified queue.

-

Obtaining queue information

-

LOS_QueueInfoGet

-

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.

-
- -## How to Develop - -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 the 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. ->- **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 - -### Example Description - -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. Delete the queue by calling **LOS\_QueueDelete**. - -### Sample Code - -The sample code is as follows: - -``` -#include "los_task.h" -#include "los_queue.h" -static UINT32 g_queue; -#define BUFFER_LEN 50 - -VOID SendEntry(VOID) -{ - UINT32 ret = 0; - CHAR abuf[] = "test message"; - UINT32 len = sizeof(abuf); - - ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); - if(ret != LOS_OK) { - printf("Failed to send the message. Error: %x\n", ret); - } -} - -VOID RecvEntry(VOID) -{ - UINT32 ret = 0; - CHAR readBuf[BUFFER_LEN] = {0}; - UINT32 readLen = BUFFER_LEN; - - ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); - if(ret != LOS_OK) { - printf("Failed to receive the message. Error: %x\n", ret); - } - - printf("Message received: %s\n", readBuf); - - ret = LOS_QueueDelete(g_queue); - if(ret != LOS_OK) { - printf("Failed to delete the queue. Error: %x\n", ret); - } - - printf("Queue deleted.\n"); -} - -UINT32 ExampleQueue(VOID) -{ - printf("Start queue example.\n"); - UINT32 ret = 0; - UINT32 task1, task2; - TSK_INIT_PARAM_S initParam = {0}; - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; - initParam.usTaskPrio = 9; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - initParam.pcName = "SendQueue"; - - LOS_TaskLock(); - ret = LOS_TaskCreate(&task1, &initParam); - if(ret != LOS_OK) { - printf("Failed to create task1. Error: %x\n", ret); - return ret; - } - - initParam.pcName = "RecvQueue"; - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; - initParam.usTaskPrio = 10; - ret = LOS_TaskCreate(&task2, &initParam); - if(ret != LOS_OK) { - printf("Failed to create task2. Error: %x\n", ret); - return ret; - } - - ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); - if(ret != LOS_OK) { - printf("Failed to create the queue. Error: %x\n", ret); - } - - printf("Queue created.\n"); - LOS_TaskUnlock(); - return ret; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -Start queue example. -Queue created. -Message received: test message. -Queue deleted. -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-queue.md b/en/device-dev/kernel/kernel-mini-basic-ipc-queue.md index 221b182a2b..042d150cbb 100644 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-queue.md +++ b/en/device-dev/kernel/kernel-mini-basic-ipc-queue.md @@ -1,7 +1,266 @@ # Queue -- **[Basic Concepts](kernel-mini-basic-ipc-queue-basic.md)** +- [Basic Concepts](#section5747112216469) +- [Working Principles](#section1582619446311) + - [Queue Control Block](#section1648304614720) + - [Working Principles](#section15384012164811) -- **[Development Guidelines](kernel-mini-basic-ipc-queue-guide.md)** +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Example Description](#section2148236125814) + - [Sample Code](#section121451047155716) + - [Verification](#section2742182082117) +## 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. + +Tasks can read messages from a queue. When the queue has no messages, the tasks are suspended. When the queue has a new message, the suspended tasks are woken up and process the new message. Tasks can also write messages to the queue. When the queue is full, the write task is suspended. When there is an available message node in the queue, the suspended write task is woken up and writes a message. + +You can adjust the timeout period of the read queue and write queue to adjust the block mode of the read and write APIs. If the timeout period is set to **0** for the read queue and write queue, tasks will not be suspended and the API directly returns. This is the non-block mode. If the timeout period is greater than **0**, block mode is used. + +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 first-in-first-out \(FIFO\) mode and can be read and written asynchronously. +- Both the read queue and write queue support the timeout mechanism. +- 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. +- 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. +- When a queue is created, the required dynamic memory space is automatically allocated in the queue API. + +## Working Principles + +### Queue Control Block + +``` +/** + * Data structure of the queue control block + */ +typedef struct +{ + UINT8 *queue; /* Pointer to the memory space of queue messages */ + UINT16 queueState; /* Queue status*/ + UINT16 queueLen; /* Number of message nodes in a queue, that is, the queue length */ + UINT16 queueSize; /* Size of a message node */ + UINT16 queueID; /*Queue ID */ + UINT16 queueHead; /* Position of the message head node (array subscript)*/ + UINT16 queueTail; /* Position of the message tail node (array subscript) */ + UINT16 readWriteableCnt[OS_READWRITE_LEN];/* The array element with subscript 0 indicates the number of readable messages in a queue. + The element with subscript 1 indicates the number of writable messages in a queue. */ + LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /* A linked list of tasks waiting to read or write messages. + Subscript 0: list of tasks waiting to read messages. Subscript 1: list of tasks waiting to write messages. */ + LOS_DL_LIST memList; /* A linked list of memory blocks*/ +} LosQueueCB; +``` + +Each queue control block contains information about the queue status. + +- **OS\_QUEUE\_UNUSED**: The queue is not in use. +- **OS\_QUEUE\_INUSED**: The queue is in use. + +### Working Principles + +- 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. +- 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 +![](figures/reading-and-writing-data-in-a-queue.png "reading-and-writing-data-in-a-queue") + +The preceding figure illustrates how to write data to the tail node only. Writing data to the head node is similar. + +## Available APIs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Creating or deleting a message queue

+

LOS_QueueCreate

+

Creates a message queue. The system dynamically allocates the queue space.

+

LOS_QueueDelete

+

Deletes the specified queue based on the queue ID.

+

Reading or writing data in a queue (without the content contained in the address)

+

LOS_QueueRead

+

Reads data in the head node of the specified queue. The data in the queue node is an address.

+

LOS_QueueWrite

+

Writes the value of the input parameter bufferAddr (buffer address) to the tail node of the specified queue.

+

LOS_QueueWriteHead

+

Writes the value of the input parameter bufferAddr (buffer address) to the head node of the specified queue.

+

Reading or writing in a queue (with the content contained in the address)

+

LOS_QueueReadCopy

+

Reads data from the head node of the specified queue.

+

LOS_QueueWriteCopy

+

Writes the data saved in the input parameter bufferAddr to the tail node of the specified queue.

+

LOS_QueueWriteHeadCopy

+

Writes the data saved in the input parameter bufferAddr to the head node of the specified queue.

+

Obtaining queue information

+

LOS_QueueInfoGet

+

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.

+
+ +## How to Develop + +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 the 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. +>- **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 + +### Example Description + +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 the queue. + +### Sample Code + +The sample code is as follows: + +``` +#include "los_task.h" +#include "los_queue.h" +static UINT32 g_queue; +#define BUFFER_LEN 50 + +VOID SendEntry(VOID) +{ + UINT32 ret = 0; + CHAR abuf[] = "test message"; + UINT32 len = sizeof(abuf); + + ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); + if(ret != LOS_OK) { + printf("send message failure, error: %x\n", ret); + } +} + +VOID RecvEntry(VOID) +{ + UINT32 ret = 0; + CHAR readBuf[BUFFER_LEN] = {0}; + UINT32 readLen = BUFFER_LEN; + + // Sleep for 1s. + usleep(1000000); + ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); + if(ret != LOS_OK) { + printf("recv message failure, error: %x\n", ret); + } + + printf("recv message: %s\n", readBuf); + + ret = LOS_QueueDelete(g_queue); + if(ret != LOS_OK) { + printf("delete the queue failure, error: %x\n", ret); + } + + printf("delete the queue success.\n"); +} + +UINT32 ExampleQueue(VOID) +{ + printf("start queue example.\n"); + UINT32 ret = 0; + UINT32 task1, task2; + TSK_INIT_PARAM_S initParam = {0}; + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; + initParam.usTaskPrio = 9; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + initParam.pcName = "SendQueue"; + + LOS_TaskLock(); + ret = LOS_TaskCreate(&task1, &initParam); + if(ret != LOS_OK) { + printf("create task1 failed, error: %x\n", ret); + return ret; + } + + initParam.pcName = "RecvQueue"; + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; + initParam.usTaskPrio = 10; + ret = LOS_TaskCreate(&task2, &initParam); + if(ret != LOS_OK) { + printf("create task2 failed, error: %x\n", 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 succes.\n"); + LOS_TaskUnlock(); + return ret; +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +start queue example. +create the queue success. +recv message: test message. +delete the queue success. +``` + diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md b/en/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md deleted file mode 100644 index 9a99c27ef2..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md +++ /dev/null @@ -1,48 +0,0 @@ -# Basic Concepts - -Semaphore is a mechanism for implementing inter-task communication. It implements 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: - -- **0**: The semaphore is unavailable. Tasks waiting for the semaphore may exist. -- Positive number: The semaphore is available. - -The semaphore for synchronization is different from the semaphore for mutex: - -- Semaphore used for exclusive access: The initial semaphore counter value is not 0, indicating the number of shared resources available. The semaphore counter value must be acquired before a shared resource is used, and released after the resource is used. 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. In this way, task synchronization is implemented. - -## Working Principles - -### Semaphore control block - -``` -/** - * Data structure of the semaphore control block - */ -typedef struct { - UINT16 semStat; /* Semaphore status */ - UINT16 semType; /* Semaphore type*/ - UINT16 semCount; /* Semaphore count*/ - UINT16 semId; /* Semaphore index*/ - LOS_DL_LIST semList; /* Mount the task blocked by the semaphore.*/ -} LosSemCB; -``` - -### Working Principles - -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. - -Semaphore creation: The system obtains a semaphore from the linked list of unused semaphores and assigns an initial value to the semaphore. - -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 adds the task to the end of a task queue waiting for semaphores. The wait timeout period can be set. - -Semaphore release: When a semaphore is released, if there is no task waiting for it, the counter is increased by 1. Otherwise, the first task in the wait queue is woken up. - -Semaphore deletion: The system sets a semaphore in use to unused state and inserts it to the linked list of unused semaphores. - -Semaphore allows only a specified number of tasks to access a shared resource at a time. When the number of tasks accessing the resource reaches the limit, other tasks will be blocked until the semaphore is released. - -**Figure 1** Semaphore working mechanism -![](figure/semaphore-working-mechanism.png "semaphore-working-mechanism") - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md b/en/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md deleted file mode 100644 index 54556674c8..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md +++ /dev/null @@ -1,198 +0,0 @@ -# Development Guidelines - -## Available APIs - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Creating or deleting a semaphore

-

LOS_SemCreate

-

Creates a semaphore and returns the semaphore ID.

-

LOS_BinarySemCreate

-

Creates a binary semaphore. The maximum counter value is 1.

-

LOS_SemDelete

-

Deletes a semaphore.

-

Requesting or releasing a semaphore

-

LOS_SemPend

-

Requests a specified semaphore and sets the timeout period.

-

LOS_SemPost

-

Posts (releases) a semaphore.

-
- -## How to Develop - -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 - -### Example Description - -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**. -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. -5. Task **ExampleSem** is woken up after 400 ticks and deletes the semaphore. - -### Sample Code - -The sample code is as follows: - -``` -#include "los_sem.h" -#include "securec.h" - -/* Task ID*/ -static UINT32 g_testTaskId01; -static UINT32 g_testTaskId02; - -/* Task priority */ -#define TASK_PRIO_TEST 5 - -/* Semaphore structure ID*/ -static UINT32 g_semId; - -VOID ExampleSemTask1(VOID) -{ - UINT32 ret; - - printf("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.*/ - ret = LOS_SemPend(g_semId, 10); - - /* The semaphore is acquired.*/ - if (ret == LOS_OK) { - LOS_SemPost(g_semId); - return; - } - /* The semaphore is not acquired when the timeout period has expired.*/ - if (ret == LOS_ERRNO_SEM_TIMEOUT) { - printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); - - /* Request the semaphore in permanent block mode.*/ - ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); - printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); - if (ret == LOS_OK) { - LOS_SemPost(g_semId); - return; - } - } -} - -VOID ExampleSemTask2(VOID) -{ - UINT32 ret; - printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); - - /* Request the semaphore in permanent block mode.*/ - ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); - - if (ret == LOS_OK) { - printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); - } - - /* Enable the task to enter sleep mode for 20 ticks.*/ - LOS_TaskDelay(20); - - printf("ExampleSemTask2 post sem g_semId.\n"); - /* Release the semaphore.*/ - LOS_SemPost(g_semId); - return; -} - -UINT32 ExampleSem(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - TSK_INIT_PARAM_S task2; - - /* Create a semaphore.*/ - LOS_SemCreate(0, &g_semId); - - /* Lock task scheduling.*/ - LOS_TaskLock(); - - /* Create task 1.*/ - (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; - task1.pcName = "TestTask1"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = TASK_PRIO_TEST; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("task1 create failed.\n"); - return LOS_NOK; - } - - /* Create task 2.*/ - (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; - task2.pcName = "TestTask2"; - task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task2.usTaskPrio = (TASK_PRIO_TEST - 1); - ret = LOS_TaskCreate(&g_testTaskId02, &task2); - if (ret != LOS_OK) { - printf("task2 create failed.\n"); - return LOS_NOK; - } - - /* Unlock task scheduling.*/ - LOS_TaskUnlock(); - - ret = LOS_SemPost(g_semId); - - /* Enable the task to enter sleep mode for 400 ticks.*/ - LOS_TaskDelay(400); - - /* Delete the semaphore. */ - LOS_SemDelete(g_semId); - return LOS_OK; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -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 timeout and try get sem g_semId wait forever. -ExampleSemTask2 post sem g_semId. -ExampleSemTask1 wait_forever and get sem g_semId. -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-ipc-sem.md b/en/device-dev/kernel/kernel-mini-basic-ipc-sem.md index 602aedfb3c..02da5be605 100644 --- a/en/device-dev/kernel/kernel-mini-basic-ipc-sem.md +++ b/en/device-dev/kernel/kernel-mini-basic-ipc-sem.md @@ -1,7 +1,259 @@ # Semaphore -- **[Basic Concepts](kernel-mini-basic-ipc-sem-basic.md)** +- [Basic Concepts](#section716754913479) +- [Working Principles](#section1794010261861) + - [Semaphore control block](#section11372149164815) + - [Working Principles](#section139726510491) -- **[Development Guidelines](kernel-mini-basic-ipc-sem-guide.md)** +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Example Description](#section22061718111412) + - [Sample Code](#section1775922321416) + - [Verification](#section160404016213) +## Basic Concepts + +Semaphore is a mechanism for implementing communication between tasks. It implements synchronization between tasks or exclusive access to shared resources. + +In the data structure of a semaphore, there is usually a counter value indicating the available resources. The counter value can be: + +- **0**: The semaphore is unavailable. In this case, tasks waiting for the semaphore may exist. +- Positive number: The semaphore is available. + +The usage of the counter value varies with the function of the semaphore. + +- If the semaphore is used as a mutex, the counter value indicates the number of units of the shared resources available and its initial value cannot be **0**. The semaphore must be acquired before the shared resource is used, and released after the resource is used. 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. +- If the semaphore is used for synchronization, the initial semaphore counter value is **0**. When a task fails to acquire the semaphore, it will be blocked and enters Ready or Running state only when the semaphore is released. In this way, task synchronization is implemented. + +## Working Principles + +### Semaphore control block + +``` +/** + * Data structure of the semaphore control block + */ +typedef struct { + UINT16 semStat; /* Semaphore status */ + UINT16 semType; /* Semaphore type */ + UINT16 semCount; /* Semaphore count */ + UINT16 semId; /* Semaphore index */ + LOS_DL_LIST semList; /* Insert the task blocked by the semaphore to the DL list.*/ +} LosSemCB; +``` + +### Working Principles + +Initializing semaphores: Request memory for the semaphores configured \(the number of semaphores can be configured in the **LOSCFG\_BASE\_IPC\_SEM\_LIMIT** macro by users\), set all semaphores to the unused state, and add them to the linked list for unused semaphores. + +Creating a semaphore: Obtain a semaphore from the linked list for unused semaphores and set its initial value. + +Requesting a semaphore: If the counter value is greater than **0**, the system allocates a semaphore, decreases the counter value by 1, and returns a success message. If the counter value is **0**, the task is blocked and waits for other tasks to release a semaphore. The waiting timeout period can be set. When a task is blocked by a semaphore, the task will be added to the end of the semaphore waiting task queue. + +Releasing a semaphore: If there is no task waiting for the semaphore released, the counter is incremented by 1. Otherwise, wake up the first task in the semaphore waiting queue. + +Deleting a semaphore: Set the semaphore in use to the unused state, and adds it to the linked list for unused semaphores. + +A semaphore can also be used to limit the number of tasks that can access the shared resource at the same time. When the number of tasks accessing the resource reaches the limit, other tasks will be blocked until a task releases the semaphore. + +**Figure 1** Semaphore working mechanism for mini systems +![](figures/semaphore-working-mechanism-for-mini-systems.png "semaphore-working-mechanism-for-mini-systems") + +## Available APIs + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Creating or deleting a semaphore

+

LOS_SemCreate

+

Creates a semaphore and returns the semaphore ID.

+

LOS_BinarySemCreate

+

Creates a binary semaphore. The maximum counter value is 1.

+

LOS_SemDelete

+

Deletes a semaphore.

+

Requesting or releasing a semaphore

+

LOS_SemPend

+

Requests a specified semaphore and sets the timeout period.

+

LOS_SemPost

+

Posts (releases) a semaphore.

+
+ +## How to Develop + +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 + +### Example Description + +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**. +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. +5. Task **ExampleSem** is woken up after 400 ticks and deletes the semaphore. + +### Sample Code + +The sample code is as follows: + +``` +#include "los_sem.h" +#include "securec.h" + +/* Task ID*/ +static UINT32 g_testTaskId01; +static UINT32 g_testTaskId02; + +/* Task priority */ +#define TASK_PRIO_TEST 5 + +/* Semaphore structure ID */ +static UINT32 g_semId; + +VOID ExampleSemTask1(VOID) +{ + UINT32 ret; + + printf("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. */ + ret = LOS_SemPend(g_semId, 10); + + /* The semaphore is acquired. */ + if (ret == LOS_OK) { + LOS_SemPost(g_semId); + return; + } + /* The semaphore is not acquired when the timeout period has expired. */ + if (ret == LOS_ERRNO_SEM_TIMEOUT) { + printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); + + /* Request the semaphore in permanent block mode. */ + ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); + printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); + if (ret == LOS_OK) { + LOS_SemPost(g_semId); + return; + } + } +} + +VOID ExampleSemTask2(VOID) +{ + UINT32 ret; + printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); + + /* Request the semaphore in permanent block mode. */ + ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); + + if (ret == LOS_OK) { + printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); + } + + /* Enable the task to enter sleep mode for 20 ticks. */ + LOS_TaskDelay(20); + + printf("ExampleSemTask2 post sem g_semId.\n"); + /* Release the semaphore. */ + LOS_SemPost(g_semId); + return; +} + +UINT32 ExampleSem(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + TSK_INIT_PARAM_S task2; + + /* Create a semaphore. */ + LOS_SemCreate(0, &g_semId); + + /* Lock task scheduling. */ + LOS_TaskLock(); + + /* Create task 1. */ + (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; + task1.pcName = "TestTask1"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = TASK_PRIO_TEST; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("task1 create failed.\n"); + return LOS_NOK; + } + + /* Create task 2. */ + (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; + task2.pcName = "TestTask2"; + task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task2.usTaskPrio = (TASK_PRIO_TEST - 1); + ret = LOS_TaskCreate(&g_testTaskId02, &task2); + if (ret != LOS_OK) { + printf("task2 create failed.\n"); + return LOS_NOK; + } + + /* Unlock task scheduling. */ + LOS_TaskUnlock(); + + ret = LOS_SemPost(g_semId); + + /* Enable the task to enter sleep mode for 400 ticks. */ + LOS_TaskDelay(400); + + /* Delete the semaphore. */ + LOS_SemDelete(g_semId); + return LOS_OK; +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +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 timeout and try get sem g_semId wait forever. +ExampleSemTask2 post sem g_semId. +ExampleSemTask1 wait_forever and get sem g_semId. +``` + diff --git a/en/device-dev/kernel/kernel-mini-basic-memory-dynamic.md b/en/device-dev/kernel/kernel-mini-basic-memory-dynamic.md index be8191b3c7..25f5fece5f 100644 --- a/en/device-dev/kernel/kernel-mini-basic-memory-dynamic.md +++ b/en/device-dev/kernel/kernel-mini-basic-memory-dynamic.md @@ -1,25 +1,34 @@ # Dynamic Memory +- [Working Principles](#section328282013571) +- [Development Guidelines](#section7921151015814) + - [When to Use](#section326917198583) + - [Available APIs](#section1032331584) + - [How to Develop](#section07271773592) + - [Development Example](#section84931234145913) + - [Verification](#section165233233917) + + ## Working Principles Dynamic memory management allows memory blocks of any size to be allocated from a large contiguous memory \(memory pool or heap memory\) configured in the system based on user demands when memory resources are sufficient. The memory block can be released for further use when not required. Compared with static memory management, dynamic memory management allows memory allocation on demand but causes fragmentation of memory. -The dynamic memory of the OpenHarmony LiteOS-M has optimized the memory space partitioning based on the Two-Level Segregate Fit \(TLSF\) algorithm to achieve higher performance and minimize fragmentation. [Figure 1](#fig14558185217397) shows the core algorithm of the dynamic memory. +The dynamic memory of the OpenHarmony LiteOS-M has optimized the memory space partitioning based on the Two-Level Segregate Fit \(TLSF\) algorithm to achieve higher performance and minimize fragmentation. [Figure 1](#fig1179964042818) shows the core algorithm of the dynamic memory. -**Figure 1** Dynamic memory core algorithm -![](figure/dynamic-memory-core-algorithm.png "dynamic-memory-core-algorithm") +**Figure 1** Dynamic memory algorithm for mini systems +![](figures/dynamic-memory-algorithm-for-mini-systems.png "dynamic-memory-algorithm-for-mini-systems") -Multiple free lists are used for management based on the size of the free memory block. The free memory blocks are divided into two parts: \[4, 127\] and \[27, 231\], as indicated by the size class in [Figure 1](#fig14558185217397). +Multiple free lists are used for management based on the size of the free memory block. The free memory blocks are divided into two parts: \[4, 127\] and \[27, 231\], as indicated by the size class in [Figure 1](#fig1179964042818). -1. The memory in the range of \[4, 127\] \(lower part in [Figure 1](#fig14558185217397)\) is divided into 31 parts. The size of the memory block corresponding to each part is a multiple of 4 bytes. Each part corresponds to a free list and a bit that indicates whether the free list is empty. The value **1** indicates that the free list is not empty. There are 31 bits corresponding to the 31 memory parts in the range of \[4, 127\]. -2. The memory greater than 127 bytes is managed in power of two increments. The size of each range is \[2^n, 2^\(n+1\)-1\], where n is an integer in \[7, 30\]. This range is divided into 24 parts, each of which is further divided into 8 second-level \(L2\) ranges, as shown in Size Class and Size SubClass in the upper part of [Figure 1](#fig14558185217397). Each L2 range corresponds to a free list and a bit that indicates whether the free list is empty. There are a total of 192 \(24 x 8\) L2 ranges, corresponding to 192 free lists and 192 bits. +1. The memory in the range of \[4, 127\] \(lower part in [Figure 1](#fig1179964042818)\) is divided into 31 parts. The size of the memory block corresponding to each part is a multiple of 4 bytes. Each part corresponds to a free list and a bit that indicates whether the free list is empty. The value **1** indicates that the free list is not empty. There are 31 bits corresponding to the 31 memory parts in the range of \[4, 127\]. +2. The memory greater than 127 bytes is managed in power of two increments. The size of each range is \[2^n, 2^\(n+1\)-1\], where n is an integer in \[7, 30\]. This range is divided into 24 parts, each of which is further divided into 8 second-level \(L2\) ranges, as shown in Size Class and Size SubClass in the upper part of [Figure 1](#fig1179964042818). Each L2 range corresponds to a free list and a bit that indicates whether the free list is empty. There are a total of 192 \(24 x 8\) L2 ranges, corresponding to 192 free lists and 192 bits. For example, insert 40-byte free memory to a free list. The 40-byte free memory corresponds to the 10th free list in the range of \[40, 43\], and the 10th bit indicates the use of the free list. The system inserts the 40-byte free memory to the 10th free list and determines whether to update the bitmap flag. When 40-byte memory is requested, the system obtains the free list corresponding to the memory block of the requested size based on the bitmap flag, and then obtains a free memory node from the free list. If the size of the allocated node is greater than the memory requested, the system splits the node and inserts the remaining node to the free list. If 580-byte free memory needs to be inserted to a free list, the 580-byte free memory corresponds to the 47th \(31 + 2 x 8\) free list in L2 range \[2^9, 2^9+2^6\], and the 47th bit indicates the use of the free list. The system inserts the 580-byte free memory to the 47th free list and determines whether to update the bitmap flag. When 580-byte memory is requested, the system obtains the free list corresponding to the memory block of the requested size based on the bitmap flag, and then obtains a free memory node from the free list. If the size of the allocated node is greater than the memory requested, the system splits the node and inserts the remaining node to the free list. If the corresponding free list is empty, the system checks for a free list meeting the requirements in a larger memory range. In actual application, the system can locate the free list that meets the requirements at a time. -[Figure 2](#fig5395115964114) shows the memory management structure. +[Figure 2](#fig10997102213017) shows the memory management structure. -**Figure 2** Dynamic memory management structure -![](figure/dynamic-memory-management-structure.png "dynamic-memory-management-structure") +**Figure 2** Dynamic memory management structure for mini systems +![](figures/dynamic-memory-management-structure-for-mini-systems.png "dynamic-memory-management-structure-for-mini-systems") - Memory pool header @@ -30,6 +39,19 @@ For example, insert 40-byte free memory to a free list. The 40-byte free memory There are three types of nodes: free node, used node, and end node. Each memory node maintains the size and use flag of the memory node and a pointer to the previous memory node in the memory pool. The free nodes and used nodes have a data area, but the end node has no data area. +The off-chip physical memory needs to be used because the on-chip RAMs of some chips cannot meet requirements. The OpenHarmony LiteOS-M kernel can logically combine multiple discontiguous memory regions so that users are unaware of the discontiguous memory regions in the underlying layer. The OpenHarmony LiteOS-M kernel memory module inserts discontiguous memory regions into a free list as free memory nodes and marks the discontiguous parts as virtual memory nodes that have been used. In this way, the discontinuous memory regions are logically combined as a unified memory pool. [Figure 3](#fig18471556115917) shows how the discontiguous memory regions are logically integrated. + +**Figure 3** Integrating discontiguous memory regions +![](figures/integrating-discontiguous-memory-regions.png "integrating-discontiguous-memory-regions") + +The discontiguous memory regions are integrated into a unified memory pool as follows: + +1. Call **LOS\_MemInit** to initialize the first memory region of multiple discontiguous memory regions. +2. Obtain the start address and length of the next memory region, and calculate the **gapSize** between the current memory region and its previous memory region. The **gapSize** is considered as a used virtual node. +3. Set the size of the end node of the previous memory region to the sum of **gapSize** and **OS\_MEM\_NODE\_HEAD\_SIZE**. +4. Divide the current memory region into a free memory node and an end node, insert the free memory node to the free list, and set the link relationship between the nodes. +5. Repeat [2](#li26042441209) to [4](#li10604194419014) to integrate more discontiguous memory regions. + ## Development Guidelines ### When to Use @@ -43,7 +65,7 @@ The following table describes APIs available for OpenHarmony LiteOS-M dynamic me **Table 1** APIs of the dynamic memory module -

Category

+ @@ -126,12 +148,20 @@ The following table describes APIs available for OpenHarmony LiteOS-M dynamic me + + + +

Function

API

Checks the integrity of the specified memory pool. It is valid only when LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK is enabled.

Adding discontiguous memory regions

+

LOS_MemRegionsAdd

+

Logically integrates multiple discontiguous memory regions into a unified memory pool. It is valid only when LOSCFG_MEM_MUL_REGIONS is enabled. If the memory pool pointer parameter pool is empty, initialize the first of the multiple memory regions in the memory pool and insert other memory regions as free nodes. If pool is not empty, insert the multiple memory regions into the specified memory pool as free nodes.

+
>![](../public_sys-resources/icon-note.gif) **NOTE:** >- The dynamic memory module manages memory through control block structures, which consume extra memory. Therefore, the actual memory space available to users is less than the value of **OS\_SYS\_MEM\_SIZE**. >- The **LOS\_MemAllocAlign** and **LOS\_MemMallocAlign** APIs consume extra memory for memory alignment, which may cause memory loss. When the memory used for alignment is freed up, the lost memory will be reclaimed. +>- The discontiguous memory regions passed by the **LosMemRegion** array to the **LOS\_MemRegionsAdd** API must be sorted in ascending order by memory start address in memory regions, and the memory regions cannot overlap. ### How to Develop @@ -154,7 +184,7 @@ The typical development process of dynamic memory is as follows: ### Development Example -The example below implements the following: +This example implements the following: 1. Initialize a dynamic memory pool. 2. Allocate a memory block from the dynamic memory pool. @@ -166,10 +196,8 @@ The sample code is as follows: ``` #include "los_memory.h" - #define TEST_POOL_SIZE (2*1024) __attribute__((aligned(4))) UINT8 g_testPool[TEST_POOL_SIZE]; - VOID Example_DynMem(VOID) { UINT32 *mem = NULL; @@ -178,19 +206,19 @@ VOID Example_DynMem(VOID) /* Initialize the memory pool. */ ret = LOS_MemInit(g_testPool, TEST_POOL_SIZE); if (LOS_OK == ret) { - printf("Memory pool initialized.\n"); + printf("Mem init success!\n"); } else { - printf("Memory pool initialization failed.\n"); + printf("Mem init failed!\n"); return; } /* Allocate memory.*/ mem = (UINT32 *)LOS_MemAlloc(g_testPool, 4); if (NULL == mem) { - printf("Memory allocation failed.\n"); + printf("Mem alloc failed!\n"); return; } - printf("Memory allocated.\n"); + printf("Mem alloc success!\n"); /* Assign a value.*/ *mem = 828; @@ -199,9 +227,9 @@ VOID Example_DynMem(VOID) /* Release memory.*/ ret = LOS_MemFree(g_testPool, mem); if (LOS_OK == ret) { - printf("Memory released.\n"); + printf("Mem free success!\n"); } else { - printf("Memory release failed.\n"); + printf("Mem free failed!\n"); } return; @@ -213,9 +241,9 @@ VOID Example_DynMem(VOID) The output is as follows: ``` -Memory pool initialized. -Memory allocated. +Mem init success! +Mem alloc success! *mem = 828 -Memory released. +Mem free success! ``` diff --git a/en/device-dev/kernel/kernel-mini-basic-memory-static.md b/en/device-dev/kernel/kernel-mini-basic-memory-static.md index d3f1f131dd..d8091d9a25 100644 --- a/en/device-dev/kernel/kernel-mini-basic-memory-static.md +++ b/en/device-dev/kernel/kernel-mini-basic-memory-static.md @@ -1,13 +1,22 @@ # Static Memory +- [Working Principles](#section165473517522) +- [Development Guidelines](#section57511620165218) + - [When to Use](#section215474911529) + - [Available APIs](#section79231214539) + - [How to Develop](#section1388511316548) + - [Development Example](#section17801515105519) + - [Verification](#section11818154112319) + + ## Working Principles The static memory is a static array. The block size in the static memory pool is set during initialization and cannot be changed after initialization. The static memory pool consists of a control block **LOS\_MEMBOX\_INFO** and several memory blocks **LOS\_MEMBOX\_NODE** of the same size. The control block is located at the head of the memory pool and used for memory block management. It contains the memory block size \(**uwBlkSize**\), number of memory blocks \(**uwBlkNum**\), number of allocated memory blocks \(**uwBlkCnt**\), and free list \(**stFreeList**\). Memory is allocated and released by block size. Each memory block contains the pointer **pstNext** that points to the next memory block. -**Figure 1** Static memory -![](figure/static-memory.png "static-memory") +**Figure 1** Static memory +![](figures/static-memory.png "static-memory") ## Development Guidelines @@ -22,7 +31,7 @@ The following table describes APIs available for OpenHarmony LiteOS-M static mem **Table 1** APIs of the static memory module -

Category

+ @@ -98,7 +107,7 @@ The typical development process of static memory is as follows: ### Development Example -The example below implements the following: +This example implements the following: 1. Initialize a static memory pool. 2. Allocate a memory block from the static memory pool. diff --git a/en/device-dev/kernel/kernel-mini-basic-soft-basic.md b/en/device-dev/kernel/kernel-mini-basic-soft-basic.md deleted file mode 100644 index f624e67f4c..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-soft-basic.md +++ /dev/null @@ -1,49 +0,0 @@ -# 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-M 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: - -- Disabling the software timer using a macro -- Creating a software timer -- Starting a software timer -- Stopping a software timer -- Deleting a software timer -- Obtaining the number of remaining ticks of a software timer - -## Working Principles - -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. A timer with a shorter value is always closer to the queue head than a 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 LiteOS-M kernel 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. - -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. - -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. - -### Timer States - -- OS\_SWTMR\_STATUS\_UNUSED - -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 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 - -The timer is running \(counting\). When **LOS\_SwtmrStart** is called for a newly created timer, the timer enters this state. - -### Timer Modes - -The OpenHarmony LiteOS-M kernel provides three types of software timers: - -- 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. -- One-shot timer deleted by calling an API - diff --git a/en/device-dev/kernel/kernel-mini-basic-soft-guide.md b/en/device-dev/kernel/kernel-mini-basic-soft-guide.md deleted file mode 100644 index 914242f715..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-soft-guide.md +++ /dev/null @@ -1,211 +0,0 @@ -# Development Guidelines - -## Available APIs - -The following table describes APIs available for the OpenHarmony LiteOS-M software timer module. For more details about the APIs, see the API reference. - -**Table 1** Software timer APIs - - -

Function

API

- - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Creating or deleting timers

-

LOS_SwtmrCreate

-

Creates a software timer.

-

LOS_SwtmrDelete

-

Deletes a software timer.

-

Starting or stopping timers

-

LOS_SwtmrStart

-

Starts a software timer.

-

LOS_SwtmrStop

-

Stop a software timer.

-

Obtaining remaining ticks of a software timer

-

LOS_SwtmrTimeGet

-

Obtains the number of remaining ticks of a software timer.

-
- -## How to Develop - -The typical development process of software timers is as follows: - -1. Configure the software timer. - - Check that **LOSCFG\_BASE\_CORE\_SWTMR** and **LOSCFG\_BASE\_IPC\_QUEUE** are set to **1**. - - 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\). - -2. Call **LOS\_SwtmrCreate** to create a software timer. - - Create a software timer with the specified timing duration, timeout handling function, and triggering mode. - - Return the function execution result \(success or failure\). - -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:** ->- 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 - -### Example Description - -The following programming example demonstrates how to: - -1. Create, start, delete, pause, and restart a software timer. -2. Use a one-shot software timer and a periodic software timer - -### Sample Code - -Prerequisites - -- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR** is enabled. -- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR\_ALIGN** is disabled. The sample code does not involve timer alignment. -- 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. - -The sample code is as follows: - -``` -#include "los_swtmr.h" - -/* Timer count */ -UINT32 g_timerCount1 = 0; -UINT32 g_timerCount2 = 0; - -/* Task ID*/ -UINT32 g_testTaskId01; - -void Timer1_Callback(UINT32 arg) // Callback function 1 -{ - UINT32 tick_last1; - g_timerCount1++; - tick_last1 = (UINT32)LOS_TickCountGet(); // Obtain the current number of ticks. - printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); -} - -void Timer2_Callback(UINT32 arg) // Callback function 2 -{ - UINT32 tick_last2; - tick_last2 = (UINT32)LOS_TickCountGet(); - g_timerCount2++; - printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); -} - -void Timer_example(void) -{ - UINT32 ret; - UINT32 id1; // timer id1 - UINT32 id2; // timer id2 - UINT32 tickCount; - - /* 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. */ - LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); - - /* Create a periodic software timer and execute callback function 2 every 100 ticks. */ - LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); - printf("Timer 1 created.\n"); - - LOS_SwtmrStart(id1); // Start the one-shot software timer. - printf("Timer 1 started.\n"); - - LOS_TaskDelay(200); // Delay 200 ticks. - LOS_SwtmrTimeGet(id1, &tickCount); // Obtain the number of remaining ticks of the one-short software timer. - printf("tickCount=%d\n", tickCount); - - LOS_SwtmrStop(id1); // Stop the software timer. - printf("Timer 1 stopped.\n"); - - LOS_SwtmrStart(id1); - LOS_TaskDelay(1000); - - LOS_SwtmrStart(id2); // Start the periodic software timer. - printf("Timer 2 started.\n"); - - LOS_TaskDelay(1000); - LOS_SwtmrStop(id2); - ret = LOS_SwtmrDelete(id2); // Delete the software timer. - if (ret == LOS_OK) { - printf("Timer 2 deleted.\n"); - } -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - - /* Lock task scheduling. */ - LOS_TaskLock(); - - /* Create task 1. */ - (VOID)memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; - task1.pcName = "TimerTsk"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("Failed to create the timer task.\n"); - return LOS_NOK; - } - - /* Unlock task scheduling. */ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### Verification - -The output is as follows: - -``` -Timer 1 created. -Timer 1 started. -tickCount=798 -Timer 1 stopped. -g_timerCount1=1, tick_last1=1208 -Timer 2 started. -g_timerCount2=1 tick_last2=1313 -g_timerCount2=2 tick_last2=1413 -g_timerCount2=3 tick_last2=1513 -g_timerCount2=4 tick_last2=1613 -g_timerCount2=5 tick_last2=1713 -g_timerCount2=6 tick_last2=1813 -g_timerCount2=7 tick_last2=1913 -g_timerCount2=8 tick_last2=2013 -g_timerCount2=9 tick_last2=2113 -g_timerCount2=10 tick_last2=2213 -Timer 2 deleted. -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-soft.md b/en/device-dev/kernel/kernel-mini-basic-soft.md index 73dc746166..2beb8407c6 100644 --- a/en/device-dev/kernel/kernel-mini-basic-soft.md +++ b/en/device-dev/kernel/kernel-mini-basic-soft.md @@ -1,7 +1,277 @@ # Software Timer -- **[Basic Concepts](kernel-mini-basic-soft-basic.md)** +- [Basic Concepts](#section13256164145219) +- [Working Principles](#section070665816719) + - [Timer States](#section115453813506) + - [Timer Modes](#section137521353175010) -- **[Development Guidelines](kernel-mini-basic-soft-guide.md)** +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Example Description](#section3741753191918) + - [Sample Code](#section20760101182016) + - [Verification](#section11244112818172) +## 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-M 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: + +- Disabling the software timer using a macro +- Creating a software timer +- Starting a software timer +- Stopping a software timer +- Deleting a software timer +- Obtaining the number of remaining ticks of a software timer + +## Working Principles + +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. A timer with a shorter value is always closer to the queue head than a 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 LiteOS-M kernel 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. + +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. + +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. + +### Timer States + +- OS\_SWTMR\_STATUS\_UNUSED + + 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 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 + + The timer is running \(counting\). When **LOS\_SwtmrStart** is called for a newly created timer, the timer enters this state. + + +### Timer Modes + +The OpenHarmony LiteOS-M kernel provides three types of software timers: + +- 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. +- One-shot timer deleted by calling an API + +## Available APIs + +The following table describes APIs available for the OpenHarmony LiteOS-M software timer module. For more details about the APIs, see the API reference. + +**Table 1** Software timer APIs + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Creating or deleting timers

+

LOS_SwtmrCreate

+

Creates a software timer.

+

LOS_SwtmrDelete

+

Deletes a software timer.

+

Starting or stopping timers

+

LOS_SwtmrStart

+

Starts a software timer.

+

LOS_SwtmrStop

+

Stop a software timer.

+

Obtaining remaining ticks of a software timer

+

LOS_SwtmrTimeGet

+

Obtaining remaining ticks of a software timer

+
+ +## How to Develop + +The typical development process of software timers is as follows: + +1. Configure the software timer. + - Check that **LOSCFG\_BASE\_CORE\_SWTMR** and **LOSCFG\_BASE\_IPC\_QUEUE** are set to **1**. + - 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\). + +2. Call **LOS\_SwtmrCreate** to create a software timer. + - Create a software timer with the specified timing duration, timeout handling function, and triggering mode. + - Return the function execution result \(success or failure\). + +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:** +>- 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 + +### Example Description + +The following programming example demonstrates how to: + +1. Create, start, delete, pause, and restart a software timer. +2. Use a one-shot software timer and a periodic software timer + +### Sample Code + +Prerequisites + +- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR** is enabled. +- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR\_ALIGN** is disabled. The sample code does not involve timer alignment. +- 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. + +The sample code is as follows: + +``` +#include "los_swtmr.h" + +/* Timer count */ +UINT32 g_timerCount1 = 0; +UINT32 g_timerCount2 = 0; + +/* Task ID*/ +UINT32 g_testTaskId01; + +void Timer1_Callback(UINT32 arg) //Callback function 1 +{ + UINT32 tick_last1; + g_timerCount1++; + tick_last1 = (UINT32)LOS_TickCountGet(); // Obtain the current number of ticks. + printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); +} + +void Timer2_Callback(UINT32 arg) //Callback function 2 +{ + UINT32 tick_last2; + tick_last2 = (UINT32)LOS_TickCountGet(); + g_timerCount2++; + printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); +} + +void Timer_example(void) +{ + UINT32 ret; + UINT32 id1; // timer id1 + UINT32 id2; // timer id2 + UINT32 tickCount; + + /* 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. */ + LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); + + /* Create a periodic software timer and execute callback function 2 every 100 ticks. */ + LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); + printf("create Timer1 success\n"); + + LOS_SwtmrStart(id1); // Start the one-shot software timer. + printf("start Timer1 success\n"); + + LOS_TaskDelay(200); // Delay 200 ticks. + LOS_SwtmrTimeGet(id1, &tickCount); // Obtain the number of remaining ticks of the one-short software timer. + printf("tickCount=%d\n", tickCount); + + LOS_SwtmrStop(id1); // Stop the software timer. + printf("stop Timer1 success\n"); + + LOS_SwtmrStart(id1); + LOS_TaskDelay(1000); + + LOS_SwtmrStart(id2); // Start the periodic software timer. + printf("start Timer2\n"); + + LOS_TaskDelay(1000); + LOS_SwtmrStop(id2); + ret = LOS_SwtmrDelete(id2); // Delete the software timer. + if (ret == LOS_OK) { + printf("delete Timer2 success\n"); + } +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + + /* Lock task scheduling. */ + LOS_TaskLock(); + + /* Create task 1. */ + (VOID)memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; + task1.pcName = "TimerTsk"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("TimerTsk create failed.\n"); + return LOS_NOK; + } + + /* Unlock task scheduling. */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + +### Verification + +The output is as follows: + +``` +create Timer1 success +start Timer1 success +tickCount=798 +stop Timer1 success +g_timerCount1=1, tick_last1=1208 +delete Timer1 sucess +start Timer2 +g_timerCount2=1 tick_last2=1313 +g_timerCount2=2 tick_last2=1413 +g_timerCount2=3 tick_last2=1513 +g_timerCount2=4 tick_last2=1613 +g_timerCount2=5 tick_last2=1713 +g_timerCount2=6 tick_last2=1813 +g_timerCount2=7 tick_last2=1913 +g_timerCount2=8 tick_last2=2013 +g_timerCount2=9 tick_last2=2113 +g_timerCount2=10 tick_last2=2213 +delete Timer2 success +``` + diff --git a/en/device-dev/kernel/kernel-mini-basic-task-basic.md b/en/device-dev/kernel/kernel-mini-basic-task-basic.md deleted file mode 100644 index fcf257f7b0..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-task-basic.md +++ /dev/null @@ -1,93 +0,0 @@ -# Basic Concepts - -From the perspective of the operating system, tasks are the minimum running units that compete for system resources. They can use or wait for CPUs, use system resources such as memory, and run independently. - -The task module of the OpenHarmony LiteOS-M provides multiple tasks and supports switching between tasks, helping users manage business process procedures. The task module has the following features: - -- Multiple tasks are supported. -- A task represents a thread. -- The preemptive scheduling mechanism is used for tasks. High-priority tasks can interrupt low-priority tasks. Low-priority tasks can be scheduled only after high-priority tasks are blocked or complete. -- Time slice round-robin is used to schedule tasks with the same priority. -- A total of 32 \(**0** to **31**\) priorities are defined. **0** is the highest priority, and **31** is the lowest. - -## Task-related Concepts - -**Task States** - -A task has multiple states. After the system initialization is complete, the created tasks can compete for certain resources in the system according to the scheduling procedure regulated by the kernel. - -A task can be in any of the following states: - -- Ready: The task is in the ready queue, waiting for execution by a CPU. -- Running: The task is being executed. -- Blocked: The task is not in the ready queue. The task may be suspended, delayed, waiting for a semaphore, waiting to read from or write into a queue, or reading from or writing into an event. -- Dead: The task execution is complete and waiting for the system to reclaim resources. - -**Task State Transition** - -**Figure 1** Task state transition -![](figure/task-state-transition.png "task-state-transition") - -The task transition process is as follows: - -- Ready → Running - - A task enters Ready state once created. When task switching occurs, the task with the highest priority in the Ready queue will be executed. The task being executed enters the Running state and is removed from the Ready queue. - -- Running → Blocked - - When a running task is blocked \(suspended, delayed, or reading semaphores\), it will be inserted into the corresponding blocking queue and changes from the Running state to the Blocked state. Then, task switching is triggered to run the task with the highest priority in the Ready queue. - -- Blocked → Ready \(Blocked → Running\) - - When a blocked task is recovered \(for example, the task is resumed, the delay period or semaphore read period times out, or the task successfully reads a semaphore\), the task will be added to the Ready queue and change from the Blocked state to the Ready state. If the priority of the recovered task is higher than that of the running task, task switching will be triggered to run the recovered task. Then, the task changes from the Ready state to the Running state. - -- 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. - -- 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 remains in the Ready queue. - -- Running → Dead - - When a running task is complete, it changes to the Dead state. The Dead state includes normal exit state as the task is complete and the Invalid state. For example, if a task is complete but is not automatically deleted, the task is in the Invalid state. - -- Blocked → Dead - - If an API is called to delete a blocked task, the task state change from Blocked to Dead. - - -**Task ID** - -You will receive a task ID after successfully creating a task. The task IDs are unique in the operating system. You can suspend, restore, or query tasks by task ID. - -**Task Priority** - -Tasks are executed based on their priority. When task switching occurs, the task with the highest priority in the Ready queue will be executed. - -**Task Entry Function** - -Function to be executed when a task is scheduled. This function is implemented by users and set in the task creation structure when a task is created. - -**Task Stack** - -An independent memory space for each task. The stack stores information such as local variables, registers, function parameters, and function return addresses. - -**Task Context** - -Resources, such as registers, used during the running of a task. When a task is suspended, other running tasks might modify the register values of the suspended task. If the original task context is not saved when task switching occurs, an unknown error may occur when the task is recovered. The context information of switched-out tasks is saved into their own task stacks so that the context information can be resumed along with tasks and the system can start from the interrupted code after the tasks are resumed. - -**Task Control Block** - -Each task has a task control block \(TCB\). A TCB contains task information, such as context stack pointer, state, priority, ID, name, and stack size. The TCB reflects the running status of a task. - -**Task Switching** - -Task switching involves actions, such as obtaining the task with the highest priority in the Ready queue, saving the context of the switched-out task, and restoring the context of the switched-in task. - -## Task Running Mechanism - -When a task is created, 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 will be executed when the task enters the Running state for the first time. - diff --git a/en/device-dev/kernel/kernel-mini-basic-task-guide.md b/en/device-dev/kernel/kernel-mini-basic-task-guide.md deleted file mode 100644 index 8b7cee6487..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-task-guide.md +++ /dev/null @@ -1,300 +0,0 @@ -# Development Guidelines - -When a task is created, the OpenHarmony LiteOS-M kernel can perform operations, such as locking or unlocking task scheduling, suspending, restoring, and delaying the task, and setting or obtaining the task priority. - -## Available APIs - -The following table describes APIs available for the OpenHarmony LiteOS-M task module. For more details about the APIs, see the API reference. - -**Table 1** APIs of the task management module - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Creating or deleting a task

-

LOS_TaskCreateOnly

-

Creates a task and suspends the task to disable scheduling of the task. To enable scheduling of the task, call LOS_TaskResume to make the task enter the Ready state.

-

LOS_TaskCreate

-

Creates a task and places the task in the Ready state. If there is no task with a higher priority in the Ready queue, the task will be executed.

-

LOS_TaskDelete

-

Deletes the specified task.

-

Controlling task status

-

LOS_TaskResume

-

Resumes a suspended task to place the task in the Ready state.

-

LOS_TaskSuspend

-

Suspends the specified task and performs task switching.

-

LOS_TaskDelay

-

Makes a task wait for a period of time (in ticks) and releases CPU resources. When the delay time expires, the task enters the Ready state again. The input parameter is the number of ticks.

-

LOS_Msleep

-

Converts the input parameter number of milliseconds into number of ticks, and use the result to calls LOS_TaskDelay.

-

LOS_TaskYield

-

Sets the time slice of the current task to 0 to release CPU resources and schedule the task with the highest priority in the Ready queue to run.

-

Control task scheduling

-

LOS_TaskLock

-

Locks task scheduling. However, tasks can still be interrupted.

-

LOS_TaskUnlock

-

Unlocks task scheduling.

-

LOS_Schedule

-

Triggers task scheduling

-

Controlling task priority

-

LOS_CurTaskPriSet

-

Sets the priority for the current task.

-

LOS_TaskPriSet

-

Sets the priority for a specified task.

-

LOS_TaskPriGet

-

Obtains the priority of a specified task.

-

Obtaining task information

-

LOS_CurTaskIDGet

-

Obtains the ID of the current task.

-

LOS_NextTaskIDGet

-

Obtains the ID of the task with the highest priority in the Ready queue.

-

LOS_NewTaskIDGet

-

Same as LOS_NextTaskIDGet.

-

LOS_CurTaskNameGet

-

Obtains the name of the current task.

-

LOS_TaskNameGet

-

Obtains the name of a specified task.

-

LOS_TaskStatusGet

-

Obtains the state of a specified task.

-

LOS_TaskInfoGet

-

Obtains information about a specified task, including the task state, priority, stack size, stack pointer (SP), task entry function, and used stack space.

-

LOS_TaskIsRunning

-

Checks whether the task module has started scheduling.

-

Maintaining and testing task information

-

LOS_TaskSwitchInfoGet

-

Obtains task switching information. The macro LOSCFG_BASE_CORE_EXC_TSK_SWITCH must be enabled.

-
- -## How to Develop - -The typical development process of the task module is as follows: - -1. Use **LOS\_TaskLock** to lock task scheduling and prevent high-priority tasks from being scheduled. -2. Use **LOS\_TaskCreate** to create a task. -3. Use **LOS\_TaskUnlock** to unlock task scheduling so that tasks can be scheduled by priority. -4. Use **LOS\_TaskDelay** to delay a task. -5. Use **LOS\_TaskSuspend** to suspend a task. -6. Use **LOS\_TaskResume** to resume the suspended task. - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- Running idle tasks reclaims the TCBs and stacks in the to-be-recycled linked list. ->- The task name is a pointer without memory space allocated. When setting the task name, do not assign the local variable address to the task name pointer. ->- The task stack size is 8-byte aligned. Follow the "nothing more and nothing less" principle while determining the task stack size. ->- A running task cannot be suspended if task scheduling is locked. ->- Idle tasks and software timer tasks cannot be suspended or deleted. ->- In an interrupt handler or when a task is locked, the operation of calling **LOS\_TaskDelay** fails. ->- Locking task scheduling does not disable interrupts. Tasks can still be interrupted while task scheduling is locked. ->- Locking task scheduling must be used together with unlocking task scheduling. ->- Task scheduling may occur while a task priority is being set. ->- The maximum number of tasks that can be set for the operating system is the total number of tasks of the operating system, not the number of tasks available to users. For example, if the system software timer occupies one more task resource, the number of task resources available to users decreases by one. ->- **LOS\_CurTaskPriSet** and **LOS\_TaskPriSet** cannot be used in interrupts or used to modify the priorities of software timer tasks. ->- If the task corresponding to the task ID sent to **LOS\_TaskPriGet** has not been created or the task ID exceeds the maximum number of tasks, **-1** will be returned. ->- Resources such as a mutex or a semaphore allocated to a task must have been released before the task is deleted. - -## Development Example - -This example describes the priority-based task scheduling and use of task-related APIs, including creating, delaying, suspending, and resuming two tasks with different priorities, and locking/unlocking task scheduling. The sample code is as follows: - -``` -UINT32 g_taskHiId; -UINT32 g_taskLoId; -#define TSK_PRIOR_HI 4 -#define TSK_PRIOR_LO 5 - -UINT32 Example_TaskHi(VOID) -{ - UINT32 ret; - - printf("Enter TaskHi Handler.\n"); - - /* Delay the task for 100 ticks. The task is then suspended, and the remaining task with the highest priority (TaskLo) will be executed.*/ - ret = LOS_TaskDelay(100); - if (ret != LOS_OK) { - printf("Delay TaskHi Failed.\n"); - return LOS_NOK; - } - - /*After 100 ticks elapse, the task is resumed.*/ - printf("TaskHi LOS_TaskDelay Done.\n"); - - /* Suspend the task.*/ - ret = LOS_TaskSuspend(g_taskHiId); - if (ret != LOS_OK) { - printf("Suspend TaskHi Failed.\n"); - return LOS_NOK; - } - printf("TaskHi LOS_TaskResume Success.\n"); - return ret; -} - -/* Entry function of low-priority tasks */ -UINT32 Example_TaskLo(VOID) -{ - UINT32 ret; - - printf("Enter TaskLo Handler.\n"); - - /* Delay the task for 100 ticks. The task is then suspended, and the remaining task with the highest priority will be executed.*/ - ret = LOS_TaskDelay(100); - if (ret != LOS_OK) { - printf("Delay TaskLo Failed.\n"); - return LOS_NOK; - } - - printf("TaskHi LOS_TaskSuspend Success.\n"); - - /* Resume the suspended task g_taskHiId.*/ - ret = LOS_TaskResume(g_taskHiId); - if (ret != LOS_OK) { - printf("Resume TaskHi Failed.\n"); - return LOS_NOK; - } - return ret; -} - -/* Task entry function used to create two tasks with different priorities */ -UINT32 Example_TskCaseEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S initParam; - - /* Lock task scheduling to prevent newly created tasks from being scheduled prior to this task due to higher priority.*/ - LOS_TaskLock(); - - printf("LOS_TaskLock() Success!\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; - initParam.usTaskPrio = TSK_PRIOR_HI; - initParam.pcName = "TaskHi"; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - - /* Create a high-priority task. The task will not be executed immediately after being created, because task scheduling is locked.*/ - ret = LOS_TaskCreate(&g_taskHiId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - - printf("Example_TaskHi create Failed!\n"); - return LOS_NOK; - } - - printf("Example_TaskHi create Success!\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; - initParam.usTaskPrio = TSK_PRIOR_LO; - initParam.pcName = "TaskLo"; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - - /*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); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - printf("Example_TaskLo create Failed!\n"); - return LOS_NOK; - } - - printf("Example_TaskLo create Success!\n"); - - /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed.*/ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -LOS_TaskLock() Success! -Example_TaskHi create Success! -Example_TaskLo create Success! -Enter TaskHi Handler. -Enter TaskLo Handler. -TaskHi LOS_TaskDelay Done. -TaskHi LOS_TaskSuspend Success. -TaskHi LOS_TaskResume Success. -``` - diff --git a/en/device-dev/kernel/kernel-mini-basic-task.md b/en/device-dev/kernel/kernel-mini-basic-task.md index 9c9c0db330..3087fd0aaa 100644 --- a/en/device-dev/kernel/kernel-mini-basic-task.md +++ b/en/device-dev/kernel/kernel-mini-basic-task.md @@ -1,7 +1,413 @@ # Task Management -- **[Basic Concepts](kernel-mini-basic-task-basic.md)** +- [Basic Concepts](#section1524821422111) + - [Task-related Concepts](#section1124425582117) + - [Task Running Mechanism](#section123321315152219) -- **[Development Guidelines](kernel-mini-basic-task-guide.md)** +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Verification](#section62921315208) +## Basic Concepts + +From the perspective of the operating system, tasks are the minimum running units that compete for system resources. They can use or wait for CPUs, use system resources such as memory, and run independently. + +The task module of the OpenHarmony LiteOS-M provides multiple tasks and supports switching between tasks, helping users manage business process procedures. The task module has the following features: + +- Multiple tasks are supported. +- A task represents a thread. +- The preemptive scheduling mechanism is used for tasks. High-priority tasks can interrupt low-priority tasks. Low-priority tasks can be scheduled only after high-priority tasks are blocked or complete. +- Time slice round-robin is used to schedule tasks with the same priority. +- A total of 32 \(**0** to **31**\) priorities are defined. **0** is the highest priority, and **31** is the lowest. + +### Task-related Concepts + +**Task States** + +A task has multiple states. After the system initialization is complete, the created tasks can compete for certain resources in the system according to the scheduling procedure regulated by the kernel. + +A task can be in any of the following states: + +- Ready: The task is in the ready queue, waiting for execution by a CPU. +- Running: The task is being executed. +- Blocked: The task is not in the ready queue. The task may be suspended, delayed, waiting for a semaphore, waiting to read from or write into a queue, or reading from or writing into an event. +- Dead: The task execution is complete and waiting for the system to reclaim resources. + +**Task State Transitions** + +**Figure 1** Task state transitions +![](figures/task-state-transitions.png "task-state-transitions") + +The task transition process is as follows: + +- Ready → Running + + A task enters Ready state once created. When task switching occurs, the task with the highest priority in the Ready queue will be executed. The task being executed enters the Running state and is removed from the Ready queue. + +- Running → Blocked + + When a running task is blocked \(suspended, delayed, or reading semaphores\), it will be inserted to the blocked task queue and changes from the Running state to the Blocked state. Then, task switching is triggered to run the task with the highest priority in the Ready queue. + +- Blocked → Ready \(Blocked → Running\) + + When a blocked task is recovered \(for example, the task is resumed, the delay period or semaphore read period times out, or the task successfully reads a semaphore\), the task will be added to the Ready queue and change from the Blocked state to the Ready state. If the priority of the recovered task is higher than that of the running task, task switching will be triggered to run the recovered task. Then, the task changes from the Ready state to the Running state. + +- 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. + +- 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 remains in the Ready queue. + +- Running → Dead + + When a running task is complete, it changes to the Dead state. The Dead state includes normal exit state as the task is complete and the Invalid state. For example, if a task is complete but is not automatically deleted, the task is in the Invalid state. + +- Blocked → Dead + + If an API is called to delete a blocked task, the task state change from Blocked to Dead. + + +**Task ID** + +You will receive a task ID after successfully creating a task. The task IDs are unique in the operating system. You can suspend, restore, or query tasks by task ID. + +**Task Priority** + +Tasks are executed based on their priority. When task switching occurs, the task with the highest priority in the Ready queue will be executed. + +**Task Entry Function** + +Function to be executed when a task is scheduled. This function is implemented by users and set in the task creation structure when a task is created. + +**Task Stack** + +An independent memory space for each task. The stack stores information such as local variables, registers, function parameters, and function return addresses. + +**Task Context** + +Resources, such as registers, used during the running of a task. When a task is suspended, other running tasks might modify the register values of the suspended task. If the original task context is not saved when task switching occurs, an unknown error may occur when the task is recovered. The context information of switched-out tasks is saved into their own task stacks so that the context information can be resumed along with tasks and the system can start from the interrupted code after the tasks are resumed. + +**Task Control Block** + +Each task has a task control block \(TCB\). A TCB contains task information, such as context stack pointer, state, priority, ID, name, and stack size. The TCB reflects the running status of a task. + +**Task Switching** + +Task switching involves actions, such as obtaining the task with the highest priority in the Ready queue, saving the context of the switched-out task, and restoring the context of the switched-in task. + +### Task Running Mechanism + +When a task is created, 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 is executed when the task enters the running state for the first time. + +## Available APIs + +The following table describes APIs available for the OpenHarmony LiteOS-M task module. For more details about the APIs, see the API reference. + +**Table 1** APIs of the task management module + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Creating or deleting a task

+

LOS_TaskCreateOnly

+

Creates a task and suspends the task to disable scheduling of the task. To enable scheduling of the task, call LOS_TaskResume to make the task enter the Ready state.

+

LOS_TaskCreate

+

Creates a task and places the task in the Ready state. If there is no task with a higher priority in the Ready queue, the task will be executed.

+

LOS_TaskDelete

+

Deletes the specified task.

+

Controlling task status

+

LOS_TaskResume

+

Resumes a suspended task to place the task in the Ready state.

+

LOS_TaskSuspend

+

Suspends the specified task and performs task switching.

+

LOS_TaskJoin

+

Suspends this task till the specified task is complete and the task control block resources are reclaimed.

+

LOS_TaskDelay

+

Makes a task wait for a period of time (in ticks) and releases CPU resources. When the delay time expires, the task enters the Ready state again. The input parameter is the number of ticks.

+

LOS_Msleep

+

Converts the input parameter number of milliseconds into number of ticks, and use the result to call LOS_TaskDelay.

+

LOS_TaskYield

+

Sets the time slice of the current task to 0 to release CPU resources and schedule the task with the highest priority in the Ready queue to run.

+

Control task scheduling

+

LOS_TaskLock

+

Locks task scheduling. However, tasks can still be interrupted.

+

LOS_TaskUnlock

+

Unlocks task scheduling.

+

LOS_Schedule

+

Triggers task scheduling

+

Controlling task priority

+

LOS_CurTaskPriSet

+

Sets the priority for the current task.

+

LOS_TaskPriSet

+

Sets the priority for a specified task.

+

LOS_TaskPriGet

+

Obtains the priority of a specified task.

+

Obtaining task information

+

LOS_CurTaskIDGet

+

Obtains the ID of the current task.

+

LOS_NextTaskIDGet

+

Obtains the ID of the task with the highest priority in the Ready queue.

+

LOS_NewTaskIDGet

+

Same as LOS_NextTaskIDGet.

+

LOS_CurTaskNameGet

+

Obtains the name of the current task.

+

LOS_TaskNameGet

+

Obtains the name of a specified task.

+

LOS_TaskStatusGet

+

Obtains the state of a specified task.

+

LOS_TaskInfoGet

+

Obtains information about a specified task, including the task state, priority, stack size, stack pointer (SP), task entry function, and used stack space.

+

LOS_TaskIsRunning

+

Checks whether the task module has started scheduling.

+

Maintaining and testing task information

+

LOS_TaskSwitchInfoGet

+

Obtains task switching information. The macro LOSCFG_BASE_CORE_EXC_TSK_SWITCH must be enabled.

+
+ +## How to Develop + +The typical development process of the task module is as follows: + +1. Use **LOS\_TaskLock** to lock task scheduling and prevent high-priority tasks from being scheduled. +2. Use **LOS\_TaskCreate** to create a task. +3. Use **LOS\_TaskUnlock** to unlock task scheduling so that tasks can be scheduled by priority. +4. Use **LOS\_TaskDelay** to delay a task. +5. Use **LOS\_TaskSuspend** to suspend a task. +6. Use **LOS\_TaskResume** to resume the suspended task. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- Running idle tasks reclaims the TCBs and stacks in the to-be-recycled linked list. +>- The task name is a pointer without memory space allocated. When setting the task name, do not assign the local variable address to the task name pointer. +>- The task stack size is 8-byte aligned. Follow the "nothing more and nothing less" principle while determining the task stack size. +>- A running task cannot be suspended if task scheduling is locked. +>- Idle tasks and software timer tasks cannot be suspended or deleted. +>- In an interrupt handler or when a task is locked, the operation of calling **LOS\_TaskDelay** fails. +>- Locking task scheduling does not disable interrupts. Tasks can still be interrupted while task scheduling is locked. +>- Locking task scheduling must be used together with unlocking task scheduling. +>- Task scheduling may occur while a task priority is being set. +>- The maximum number of tasks that can be set for the operating system is the total number of tasks of the operating system, not the number of tasks available to users. For example, if the system software timer occupies one more task resource, the number of task resources available to users decreases by one. +>- **LOS\_CurTaskPriSet** and **LOS\_TaskPriSet** cannot be used in interrupts or used to modify the priorities of software timer tasks. +>- If the task corresponding to the task ID sent to **LOS\_TaskPriGet** has not been created or the task ID exceeds the maximum number of tasks, **-1** will be returned. +>- Resources such as a mutex or a semaphore allocated to a task must have been released before the task is deleted. + +## Development Example + +This example describes the priority-based task scheduling and use of task-related APIs, including creating, delaying, suspending, and resuming two tasks with different priorities, and locking/unlocking task scheduling. The sample code is as follows: + +``` +UINT32 g_taskHiId; +UINT32 g_taskLoId; +#define TSK_PRIOR_HI 4 +#define TSK_PRIOR_LO 5 + +UINT32 Example_TaskHi(VOID) +{ + UINT32 ret; + + printf("Enter TaskHi Handler.\n"); + + /* Delay the task for 100 ticks. The task is then suspended, and the remaining task with the highest priority (TaskLo) will be executed. */ + ret = LOS_TaskDelay(100); + if (ret != LOS_OK) { + printf("Delay TaskHi Failed.\n"); + return LOS_NOK; + } + + /*After 100 ticks elapse, the task is resumed. */ + printf("TaskHi LOS_TaskDelay Done.\n"); + + /* Suspend the task. */ + ret = LOS_TaskSuspend(g_taskHiId); + if (ret != LOS_OK) { + printf("Suspend TaskHi Failed.\n"); + return LOS_NOK; + } + printf("TaskHi LOS_TaskResume Success.\n"); + return ret; +} + +/* Entry function of low-priority tasks */ +UINT32 Example_TaskLo(VOID) +{ + UINT32 ret; + + printf("Enter TaskLo Handler.\n"); + + /* Delay the task for 100 ticks. The task is then suspended, and the remaining task with the highest priority will be executed. */ + ret = LOS_TaskDelay(100); + if (ret != LOS_OK) { + printf("Delay TaskLo Failed.\n"); + return LOS_NOK; + } + + printf("TaskHi LOS_TaskSuspend Success.\n"); + + /* Resume the suspended task g_taskHiId. */ + ret = LOS_TaskResume(g_taskHiId); + if (ret != LOS_OK) { + printf("Resume TaskHi Failed.\n"); + return LOS_NOK; + } + return ret; +} + +/* Task entry function used to create two tasks with different priorities */ +UINT32 Example_TskCaseEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S initParam; + + /* Lock task scheduling to prevent newly created tasks from being scheduled prior to this task due to higher priority. */ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success!\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; + initParam.usTaskPrio = TSK_PRIOR_HI; + initParam.pcName = "TaskHi"; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + initParam.uwResved = 0; /* Detach attributes. */ + + /* 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); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + + printf("Example_TaskHi create Failed!\n"); + return LOS_NOK; + } + + printf("Example_TaskHi create Success!\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; + initParam.usTaskPrio = TSK_PRIOR_LO; + initParam.pcName = "TaskLo"; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + + /*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); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + printf("Example_TaskLo create Failed!\n"); + return LOS_NOK; + } + + printf("Example_TaskLo create Success!\n"); + + /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed. */ + LOS_TaskUnlock(); + ret = LOS_TaskJoin(g_taskHiId, NULL); + if (ret != LOS_OK) { + printf("Join Example_TaskHi Failed!\n"); + } else { + printf("Join Example_TaskHi Success!\n"); + } + return LOS_OK; +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +LOS_TaskLock() Success! +Example_TaskHi create Success! +Example_TaskLo create Success! +Enter TaskHi Handler. +Enter TaskLo Handler. +TaskHi LOS_TaskDelay Done. +TaskHi LOS_TaskSuspend Success. +TaskHi LOS_TaskResume Success. +Join Example_TaskHi Success! +``` + diff --git a/en/device-dev/kernel/kernel-mini-basic-time-basic.md b/en/device-dev/kernel/kernel-mini-basic-time-basic.md deleted file mode 100644 index 5952854109..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-time-basic.md +++ /dev/null @@ -1,21 +0,0 @@ -# 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. - -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 time management module of the OpenHarmony LiteOS-M kernel provides time conversion and statistics functions. - -## Time Unit - -- 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. - -- 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. - - diff --git a/en/device-dev/kernel/kernel-mini-basic-time-guide.md b/en/device-dev/kernel/kernel-mini-basic-time-guide.md deleted file mode 100644 index 3041a87576..0000000000 --- a/en/device-dev/kernel/kernel-mini-basic-time-guide.md +++ /dev/null @@ -1,149 +0,0 @@ -# Development Guidelines - -The time management module provides APIs to implement conversion between the system running time, ticks, and seconds/milliseconds. - -## Available APIs - -The following table describes APIs available for the OpenHarmony LiteOS-M time management. For more details about the APIs, see the API reference. - -**Table 1** APIs of the time management module - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Time conversion

-

LOS_MS2Tick

-

Converts milliseconds into ticks.

-

LOS_Tick2MS

-

Converts ticks into milliseconds.

-

OsCpuTick2MS

-

Converts cycles into milliseconds. Two UINT32 values indicate the high-order and low-order 32 bits of the result value, respectively.

-

OsCpuTick2US

-

Converts cycles into microseconds. Two UINT32 values indicate the high-order and low-order 32 bits of the result value, respectively.

-

Time statistics

-

LOS_SysClockGet

-

Obtains the system clock.

-

LOS_TickCountGet

-

Obtains the number of ticks since the system starts.

-

LOS_CyclePerTickGet

-

Obtains the number of cycles for each tick.

-
- -## How to Develop - -The typical development process of time management is as follows: - -1. Complete board configuration and adaptation as required, and configure the system clock frequency \(**OS\_SYS\_CLOCK** in Hz and **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**\). The default value of **OS\_SYS\_CLOCK** varies with the hardware platform. -2. Call the clock conversion and statistics APIs. - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->- The time management module depends on **OS\_SYS\_CLOCK** and **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**. ->- 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 configuration options are maintained in the **target\_config.h** file of the development board project. - -## Development Example - -### Example Description - -The following example describes basic time management methods, including: - -1. Time conversion: converts milliseconds to ticks or converts ticks to milliseconds. -2. Time statistics: obtains the number of cycles per tick, number of ticks since system startup, and number of delayed ticks. - -### Sample Code - -Prerequisites - -- The default value of **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND** is **100**. -- The system clock frequency **OS\_SYS\_CLOCK** is configured. - -Time conversion: - -``` -VOID Example_TransformTime(VOID) -{ - UINT32 ms; - UINT32 tick; - - tick = LOS_MS2Tick(10000); // Convert 10000 ms into ticks. - dprintf("tick = %d \n", tick); - ms = LOS_Tick2MS(100); // Convert 100 ticks into ms. - dprintf("ms = %d \n", ms); -} -``` - -Time statistics and delay: - -``` -VOID Example_GetTime(VOID) -{ - UINT32 cyclePerTick; - UINT64 tickCount; - - cyclePerTick = LOS_CyclePerTickGet(); - if(0 != cyclePerTick) { - dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); - } - - tickCount = LOS_TickCountGet(); - if(0 != tickCount) { - dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); - } - - LOS_TaskDelay(200); - tickCount = LOS_TickCountGet(); - if(0 != tickCount) { - dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); - } -} -``` - -### Verification - -The development is successful if the return result is as follows: - -Time conversion: - -``` -tick = 1000 -ms = 1000 -``` - -Time statistics and delay: - -``` -LOS_CyclePerTickGet = 495000 -LOS_TickCountGet = 1 -LOS_TickCountGet after delay = 201 -``` - diff --git a/en/device-dev/kernel/kernel-memory-inner.md b/en/device-dev/kernel/kernel-mini-debug.md similarity index 67% rename from en/device-dev/kernel/kernel-memory-inner.md rename to en/device-dev/kernel/kernel-mini-debug.md index fe608e0da4..8142a264fa 100644 --- a/en/device-dev/kernel/kernel-memory-inner.md +++ b/en/device-dev/kernel/kernel-mini-debug.md @@ -4,6 +4,8 @@ - **[Exception Debugging](kernel-mini-memory-exception.md)** -- **[Trace Debugging](kernel-mini-memory-trace.md)** +- **[Trace](kernel-mini-memory-trace.md)** + +- **[LMS](kernel-mini-memory-lms.md)** diff --git a/en/device-dev/kernel/kernel-mini-extend-cpup-basic.md b/en/device-dev/kernel/kernel-mini-extend-cpup-basic.md deleted file mode 100644 index 46c5ddf8e4..0000000000 --- a/en/device-dev/kernel/kernel-mini-extend-cpup-basic.md +++ /dev/null @@ -1,29 +0,0 @@ -# Basic Concepts - -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. - -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. - -With the system CPUP, you can determine whether the current system load exceeds the designed specifications. - -With the CPUP of each task, you can determine whether the CPU usage of each task meets expectations of the design. - -## 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. - -You can configure this function in **target\_config.h**. - -The OpenHarmony LiteOS-M provides the following types of CPUP information: - -- System CPUP -- Task CPUP - -The CPUP is calculated as follows: - -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 - diff --git a/en/device-dev/kernel/kernel-mini-extend-cpup-guide.md b/en/device-dev/kernel/kernel-mini-extend-cpup-guide.md deleted file mode 100644 index 031156bb21..0000000000 --- a/en/device-dev/kernel/kernel-mini-extend-cpup-guide.md +++ /dev/null @@ -1,155 +0,0 @@ -# Development Guidelines - -## Available APIs - -**Table 1** Functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Obtaining the system CPU usage

-

LOS_SysCpuUsage

-

Obtains the current system CPUP.

-

LOS_HistorySysCpuUsage

-

Obtains the historical CPUP of the system.

-

Obtaining the task CPUP

-

LOS_TaskCpuUsage

-

Obtains the CPUP of a specified task.

-

LOS_HistoryTaskCpuUsage

-

Obtains the historical CPUP of a specified task.

-

LOS_AllCpuUsage

-

Obtains the CPUP of all tasks.

-

Outputting the task CPUP

-

LOS_CpupUsageMonitor

-

Outputs the historical CPUP of a task.

-
- -## How to Develop - -The typical CPUP development process is as follows. - -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. - - 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. - -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 is not created, return an error code. - -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 is not initialized or has invalid input parameters, return an error code. - - -## Development Example - -### Example Description - -This example implements the following: - -1. Create a task for the CPUP test. -2. Obtain the CPUP of the current system. -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. - -### Sample Code - -Prerequisites - -In **target\_config.h**, the **LOSCFG\_BASE\_CORE\_CPUP** parameter is enabled. - -The sample code is as follows: - -``` -#include "los_task.h" -#include "los_cpup.h" -#define MODE 4 -UINT32 g_cpuTestTaskID; -VOID ExampleCpup(VOID) -{ - printf("entry cpup test example\n"); - while(1) { - usleep(100); - } -} -UINT32 ItCpupTest(VOID) -{ - UINT32 ret; - UINT32 cpupUse; - TSK_INIT_PARAM_S cpupTestTask = { 0 }; - memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S)); - cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup; - cpupTestTask.pcName = "TestCpupTsk"; - cpupTestTask.uwStackSize = 0x800; - cpupTestTask.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask); - if(ret != LOS_OK) { - printf("cpupTestTask create failed .\n"); - return LOS_NOK; - } - - usleep(100); - - /* Obtain the current CPUP of the system. */ - cpupUse = LOS_SysCpuUsage(); - printf("the current system cpu usage is: %u.%u\n", - cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); - - cpupUse = LOS_HistorySysCpuUsage(CPU_LESS_THAN_1S); - /* Obtain the CPUP of the specified task (cpupTestTask in this example).*/ - printf("the history system CPUP in all time: %u.%u\n", - 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. */ - 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); - cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPU_LESS_THAN_1S); - 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); - return LOS_OK; -} -``` - -### Verification - -The development is successful if the return result is as follows: - -``` -entry cpup test example -the current system cpu usage is : 1.5 - the history system cpu usage in all time: 3.0 - cpu usage of the cpupTestTask: TaskID:10 usage: 0.0 - cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0 -``` - diff --git a/en/device-dev/kernel/kernel-mini-extend-cpup.md b/en/device-dev/kernel/kernel-mini-extend-cpup.md index 2c0e14e994..72d4acaac8 100644 --- a/en/device-dev/kernel/kernel-mini-extend-cpup.md +++ b/en/device-dev/kernel/kernel-mini-extend-cpup.md @@ -1,7 +1,194 @@ # CPUP -- **[Basic Concepts](kernel-mini-extend-cpup-basic.md)** +- [Basic Concepts](#section1275484221216) +- [Working Principles](#section96644177124) +- [Available APIs](#section158501652121514) +- [How to Develop](#section783435801510) +- [Development Example](#section460018317164) + - [Example Description](#section51413507517) + - [Sample Code](#section17617965523) + - [Verification](#section1968771515188) -- **[Development Guidelines](kernel-mini-extend-cpup-guide.md)** +## Basic Concepts + +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. + +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. + +With the system CPUP, you can determine whether the current system load exceeds the designed specifications. + +With the CPUP of each task, you can determine whether the CPU usage of each task meets expectations of the design. + +## 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. + +You can configure this function in **target\_config.h**. + +The OpenHarmony LiteOS-M provides the following types of CPUP information: + +- System CPUP +- Task CPUP + +The CPUP is calculated as follows: + +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 + +## Available APIs + +**Table 1** Functions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Obtaining the system CPU usage

+

LOS_SysCpuUsage

+

Obtains the current system CPUP.

+

LOS_HistorySysCpuUsage

+

Obtains the historical CPUP of the system.

+

Obtaining the task CPUP

+

LOS_TaskCpuUsage

+

Obtains the CPUP of a specified task.

+

LOS_HistoryTaskCpuUsage

+

Obtains the historical CPUP of a specified task.

+

LOS_AllCpuUsage

+

Obtains the CPUP of all tasks.

+

Outputting the task CPUP

+

LOS_CpupUsageMonitor

+

Outputs the historical CPUP of a task.

+
+ +## How to Develop + +The typical CPUP development process is as follows: + +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. + - 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. + +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 is not created, return an error code. + +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 is not initialized or has invalid input parameters, return an error code. + + +## Development Example + +### Example Description + +This example implements the following: + +1. Create a task for the CPUP test. +2. Obtain the CPUP of the current system. +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. + +### Sample Code + +Prerequisites + +In **target\_config.h**, the **LOSCFG\_BASE\_CORE\_CPUP** parameter is enabled. + +The sample code is as follows: + +``` +#include "los_task.h" +#include "los_cpup.h" +#define MODE 4 +UINT32 g_cpuTestTaskID; +VOID ExampleCpup(VOID) +{ + printf("entry cpup test example\n"); + while(1) { + usleep(100); + } +} +UINT32 ItCpupTest(VOID) +{ + UINT32 ret; + UINT32 cpupUse; + TSK_INIT_PARAM_S cpupTestTask = { 0 }; + memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup; + cpupTestTask.pcName = "TestCpupTsk"; + cpupTestTask.uwStackSize = 0x800; + cpupTestTask.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask); + if(ret != LOS_OK) { + printf("cpupTestTask create failed .\n"); + return LOS_NOK; + } + + usleep(100); + + /* Obtain the current CPUP of the system. */ + cpupUse = LOS_SysCpuUsage(); + printf("the current system cpu usage is: %u.%u\n", + cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); + + cpupUse = LOS_HistorySysCpuUsage(CPU_LESS_THAN_1S); + /* Obtain the CPUP of the specified task (cpupTestTask in this example).*/ + printf("the history system CPUP in all time: %u.%u\n", + 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. */ + 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); + cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPU_LESS_THAN_1S); + 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); + return LOS_OK; +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +entry cpup test example +the current system cpu usage is : 1.5 + the history system cpu usage in all time: 3.0 + cpu usage of the cpupTestTask: TaskID:10 usage: 0.0 + cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0 +``` diff --git a/en/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md b/en/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md deleted file mode 100644 index 92f841ff8b..0000000000 --- a/en/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md +++ /dev/null @@ -1,81 +0,0 @@ -# Basic Concepts - -In small devices with limited hardware resources, dynamic algorithm deployment capability is required to solve the problem that multiple algorithms cannot be deployed at the same time. The LiteOS-M kernel uses the Executable and Linkable Format \(ELF\) because it is easy to use and compatible with a wide variety of platforms. The LiteOS-M provides APIs similar to **dlopen** and **dlsym**. Apps can load and unload required algorithm libraries by using the APIs provided by the dynamic loading module. As shown in the following figure, the app obtains the corresponding information output through the API required by the third-party algorithm library. The third-party algorithm library depends on the basic APIs provided by the kernel, such as **malloc**. After the app loads the API and relocates undefined symbols, it can call the API to complete the function. The dynamic loading component supports only the Arm architecture. In addition, the signature and source of the shared library to be loaded must be verified to ensure the system security. - -**Figure 1** LiteOS-M kernel dynamic loading architecture -![](figure/liteos-m-kernel-dynamic-loading-architecture.png "liteos-m-kernel-dynamic-loading-architecture") - -## Working Principles - -### Exporting the Symbol Table - -The kernel needs to proactively expose the API required by the dynamic library when the shared library calls a kernel API, as shown in the following figure. This mechanism compiles the symbol information to the specified section and calls the **SYM\_EXPORT** macro to export information of the specified symbol. The symbol information is described in the structure **SymInfo**. Its members include the symbol name and symbol address information. The macro **SYM\_EXPORT** imports the symbol information to the **.sym.\*** section by using the **\_\_attribute\_\_** compilation attribute. - -``` -typedef struct { - CHAR *name; - UINTPTR addr; -} SymInfo; - -#define SYM_EXPORT(func) \ -const SymInfo sym_##func __attribute__((section(".sym."#func))) = { \ - .name = #func, \ - .addr = (UINTPTR)func \ -}; -``` - -**Figure 2** Exported symbol table information -![](figure/exported-symbol-table-information.png "exported-symbol-table-information") - -### Loading an ELF File - -During the loading process, the LOAD section to be loaded to the memory is obtained based on the ELF file handle and the section offset of the program header table. Generally, there are two sections: read-only section and read-write section. You can run the **readelf -l** command to view the LOAD section information of the ELF file. The physical memory is requested according to the related alignment attributes. Then, a code section or a data segment is written into the memory based on the loading base address and an offset of each section. - -``` -$ readelf -l lib.so - -Elf file type is DYN (Shared object file) -Entry point 0x5b4 -There are 4 program headers, starting at offset 52 - -Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - EXIDX 0x000760 0x00000760 0x00000760 0x00008 0x00008 R 0x4 - LOAD 0x000000 0x00000000 0x00000000 0x0076c 0x0076c R E 0x10000 - LOAD 0x00076c 0x0001076c 0x0001076c 0x0010c 0x00128 RW 0x10000 - DYNAMIC 0x000774 0x00010774 0x00010774 0x000c8 0x000c8 RW 0x4 - - Section to Segment mapping: - Segment Sections... - 00 .ARM.exidx - 01 .hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .ARM.exidx .eh_frame - 02 .init_array .fini_array .dynamic .got .data .bss - 03 .dynamic -``` - -**Figure 3** Process of loading an ELF file -![](figure/process-of-loading-an-elf-file.png "process-of-loading-an-elf-file") - -### ELF File Link - -A relocation table is obtained by using a **.dynamic** section of the ELF file. Each entry that needs to be relocated in the table is traversed. Then, the symbol is searched, based on the symbol name that needs to be relocated, in the shared library and the exported symbol table provided by the kernel. The relocation information is updated based on the symbol found. - -**Figure 4** ELF file linking process -![](figure/elf-file-linking-process.png "elf-file-linking-process") - -## ELF Specifications - -### ELF Type - -When compiling a shared library, you can add **-fPIC** \(a compilation option\) to compile location-independent code. The shared library file type is **ET\_DYN**, which can be loaded to any valid address range. - -Example: **arm-none-eabi-gcc -fPIC –shared –o lib.so lib.c** - -### Options for Linking - -1. **-nostdlib**: Do not use the lib library in the compiler when linking. -2. **-nostartfiles**: Do not use the startup files in the compiler when linking. -3. **-fPIC**: compiles location-independent shared libraries. -4. **-z max-page-size=4**: sets the number of alignment bytes of the loadable sections in the binary file to **4**. This setting saves memory and can be used for a dynamic library. -5. **-mcpu=** specifies the CPU architecture. - diff --git a/en/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md b/en/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md deleted file mode 100644 index 7e78607627..0000000000 --- a/en/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md +++ /dev/null @@ -1,183 +0,0 @@ -# Development Guidelines - -## Available APIs - -**Table 1** Functions - - - - - - - - - - - - - - - - - - - - - -

Category

-

API

-

Description

-

Dynamic loading

-

LOS_DynlinkInit

-

Initializes the dynamic linker linked list and mutex.

-

LOS_SoLoad

-

Loads the shared library in a specified path.

-

LOS_FindSym

-

Searches for the specified symbol based on the shared library handle.

-

LOS_SoUnload

-

Unloads the shared library handle.

-
- -## How to Develop - -1. Use the arm-none-eabi-gcc cross compiler to compile the shared library and build a FAT or LittleFS image, and burn the image to the flash memory. -2. In the **target\_config.h** file, set **LOSCFG\_DYNLINK** to **1** to enable the dynamic loading module. -3. Call **LOS\_SoLoad** to load the shared library in the specified path. -4. Call **LOS\_FindSym** to search for the specified symbol and obtain the symbol address. -5. Call **LOS\_SoUnload** to unload the handle of the specified shared library. - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->1. For details about the compilation options required for compiling the shared library using the cross compiler, see the ELF specifications. ->2. Before creating a file system image, you need to adapt the FAT or LittleFS to the specific board. ->3. The shared library does not depend on the libc library in the compiler and does not support C++. ->4. The shared library depends only on the APIs provided by the kernel and cannot depend on other shared libraries. - -## Development Example - -The following uses the Arm Cortex-M4 board as an example. - -1. Sample Code and Compilation of the Shared Library - - The sample code is used to test the calling of global symbols and calling of the kernel APIs **malloc**, **free**, and **memset**. - - ``` - #include - #include - - int g_param = 10; - - int callee(int a, int b) - { - char *addr = malloc(g_param); - if (addr == NULL) { - return 0; - } - - memset(addr, '1', g_param); - - free(addr); - return a + b + g_param; - } - - int caller(int a, int b) - { - return callee(a, b); - } - ``` - - ``` - $ arm-none-eabi-gcc -fPIC -shared -mcpu=cortex-m4 -nostdlib -nostartfiles -z max-page-size=4 -o test.so test.c - ``` - -2. Export the malloc, free, and memset symbols used in the shared library. Compile the following code into a .c file and use it for OS compilation. - - ``` - #include "stdlib.h" - #include "string.h" - - SYM_EXPORT(malloc); - SYM_EXPORT(free); - SYM_EXPORT(memset); - ``` - -3. Determine the kernel compilation environment and add the following statement to the linking script of the compiler to ensure that the symbol table information is output to the specified section during compilation and linking. - - Add the following statement to the **.icf** linking script of the IAR compiler: - - ``` - keep {section .TABLE.START}; - keep {section .sym.*}; - keep {section .table.end}; - define block SYMBOL_TABLE with fixed order - { - section .TABLE.START, - section .sym.*, - section .table.end - }; - place in ROM_region {readonly, block SYMBOL_TABLE}; - ``` - - Add the following statement to the **.ld** linking script of the GCC compiler: - - ``` - __sym_table_start = .; - KEEP(*( SORT (.sym.*))); - __sym_table_end = .; - ``` - -4. Load, link, execute, and unload the shared library. - - The sample code is used to test whether the functions of the **LOS\_SoLoad**, **LOS\_FindSym**, and **LOS\_SoUnload** can be implemented normally and whether the symbols located by using **LOS\_FindSym** can be properly called. - - ``` - #include "los_dynlink.h" - - VOID DynlinkTest(VOID) - { - VOID *handle = NULL; - INT32 (*func)(INT32, INT32) = NULL; - CHAR *symbolName = "caller"; - CHAR *dsoName = "/lib/test.so"; - INT32 ret; - - handle = (VOID *)LOS_SoLoad(dsoName, NULL); - if (handle == NULL) { - printf("Failed to load so\n"); - return; - } - - func = (INT32 (*)(INT32, INT32))LOS_FindSym(handle, symbolName); - if (func == NULL) { - printf("Failed to find symbol\n"); - LOS_SoUnload(handle); - return; - } - - ret = func(1, 1); - if (ret != 12) { - printf("Failed to execute function\n"); - LOS_SoUnload(handle); - return; - } - - ret = LOS_SoUnload(handle); - if (ret != 0) { - printf("Failed to unload so\n"); - } - - - printf("Success!\n"); - } - ``` - -5. Verification - - ``` - Success! - ``` - - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->In this example, the file system path is **/lib/test.so**. ->You can create a task and call **DynlinkTest** in the task to perform the test. - diff --git a/en/device-dev/kernel/kernel-mini-extend-dynamic-loading.md b/en/device-dev/kernel/kernel-mini-extend-dynamic-loading.md index 4e652b4cd8..df9c13c881 100644 --- a/en/device-dev/kernel/kernel-mini-extend-dynamic-loading.md +++ b/en/device-dev/kernel/kernel-mini-extend-dynamic-loading.md @@ -1,7 +1,94 @@ # Dynamic Loading -- **[Basic Concepts](kernel-mini-extend-dynamic-loading-basic.md)** +- [Basic Concepts](#section4330230191314) +- [Working Principles](#section139861939219) + - [Exporting the Symbol Table](#section15414650102716) + - [Loading an ELF File](#section5221181562810) + - [ELF File Link](#section68441639182817) -- **[Development Guidelines](kernel-mini-extend-dynamic-loading-guide.md)** +- [ELF Specifications](#section187315541916) + - [ELF Type](#section1701552268) + - [Options for Linking](#section17292133274) +## Basic Concepts + +In small devices with limited hardware resources, dynamic algorithm deployment capability is required to solve the problem that multiple algorithms cannot be deployed at the same time. The LiteOS-M kernel uses the Executable and Linkable Format \(ELF\) loading because it is easy to use and compatible with a wide variety of platforms. The LiteOS-M provides APIs similar to **dlopen** and **dlsym**. Apps can load and unload required algorithm libraries by using the APIs provided by the dynamic loading module. As shown in the following figure, the app obtains the corresponding information output through the API required by the third-party algorithm library. The third-party algorithm library depends on the basic APIs provided by the kernel, such as **malloc**. After the app loads the API and relocates undefined symbols, it can call the API to complete the function. The dynamic loading component supports only the Arm architecture. In addition, the signature and source of the shared library to be loaded must be verified to ensure system security. + +**Figure 1** LiteOS-M kernel dynamic loading architecture +![](figures/liteos-m-kernel-dynamic-loading-architecture.png "liteos-m-kernel-dynamic-loading-architecture") + +## Working Principles + +### Exporting the Symbol Table + +The kernel needs to proactively expose the API required by the dynamic library when the shared library calls a kernel API, as shown in the following figure. This mechanism compiles the symbol information to the specified section and calls the **SYM\_EXPORT** macro to export information of the specified symbol. The symbol information is described in the structure **SymInfo**. Its members include the symbol name and symbol address information. The macro **SYM\_EXPORT** imports the symbol information to the **.sym.\*** section by using the **\_\_attribute\_\_** compilation attribute. + +``` +typedef struct { + CHAR *name; + UINTPTR addr; +} SymInfo; + +#define SYM_EXPORT(func) \ +const SymInfo sym_##func __attribute__((section(".sym."#func))) = { \ + .name = #func, \ + .addr = (UINTPTR)func \ +}; +``` + +**Figure 2** Exported symbol table information +![](figures/exported-symbol-table-information.png "exported-symbol-table-information") + +### Loading an ELF File + +During the loading process, the LOAD section to be loaded to the memory is obtained based on the ELF file handle and the section offset of the program header table. Generally, there are two sections: read-only section and read-write section. You can run the **readelf -l** command to view the LOAD section information of the ELF file. The physical memory is requested according to the related alignment attributes. Then, a code section or a data segment is written into the memory based on the loading base address and an offset of each section. + +``` +$ readelf -l lib.so + +Elf file type is DYN (Shared object file) +Entry point 0x5b4 +There are 4 program headers, starting at offset 52 + +Program Headers: + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align + EXIDX 0x000760 0x00000760 0x00000760 0x00008 0x00008 R 0x4 + LOAD 0x000000 0x00000000 0x00000000 0x0076c 0x0076c R E 0x10000 + LOAD 0x00076c 0x0001076c 0x0001076c 0x0010c 0x00128 RW 0x10000 + DYNAMIC 0x000774 0x00010774 0x00010774 0x000c8 0x000c8 RW 0x4 + + Section to Segment mapping: + Segment Sections... + 00 .ARM.exidx + 01 .hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .ARM.exidx .eh_frame + 02 .init_array .fini_array .dynamic .got .data .bss + 03 .dynamic +``` + +**Figure 3** Process of loading an ELF file +![](figures/process-of-loading-an-elf-file.png "process-of-loading-an-elf-file") + +### ELF File Link + +A relocation table is obtained by using a **.dynamic** section of the ELF file. Each entry that needs to be relocated in the table is traversed. Then, the symbol is searched, based on the symbol name that needs to be relocated, in the shared library and the exported symbol table provided by the kernel. The relocation information is updated based on the symbol found. + +**Figure 4** ELF file linking process +![](figures/elf-file-linking-process.png "elf-file-linking-process") + +## ELF Specifications + +### ELF Type + +When compiling a shared library, you can add **-fPIC** \(a compilation option\) to compile location-independent code. The shared library file type is **ET\_DYN**, which can be loaded to any valid address range. + +Example: **arm-none-eabi-gcc -fPIC –shared –o lib.so lib.c** + +### Options for Linking + +1. **-nostdlib**: Do not use the lib library in the compiler when linking. +2. **-nostartfiles**: Do not use the startup files in the compiler when linking. +3. **-fPIC**: compiles location-independent shared libraries. +4. **-z max-page-size=4**: sets the number of alignment bytes of the loadable sections in the binary file to **4**. This setting saves memory and can be used for a dynamic library. +5. **-mcpu=** specifies the CPU architecture. + diff --git a/en/device-dev/kernel/kernel-mini-extend-file-fat.md b/en/device-dev/kernel/kernel-mini-extend-file-fat.md index 4c836ad974..1daa2c5ba1 100644 --- a/en/device-dev/kernel/kernel-mini-extend-file-fat.md +++ b/en/device-dev/kernel/kernel-mini-extend-file-fat.md @@ -1,8 +1,19 @@ # FAT +- [Basic Concepts](#section1772629121418) +- [Development Guidelines](#section1149072811148) + - [Adaptation of Drivers](#section19174939191414) + - [How to Develop](#section131211626151513) + +- [Development Example](#section1133718619459) + - [Example Description](#section45337345313) + - [Sample Code](#section119813171539) + - [Verification](#section7987101232311) + + ## 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 bytes per cluster within the FAT, respectively. The FAT file system supports multiple media, especially removable storage 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. +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. 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. diff --git a/en/device-dev/kernel/kernel-mini-extend-file-lit.md b/en/device-dev/kernel/kernel-mini-extend-file-lit.md index ed34604fff..5a75459596 100644 --- a/en/device-dev/kernel/kernel-mini-extend-file-lit.md +++ b/en/device-dev/kernel/kernel-mini-extend-file-lit.md @@ -1,7 +1,105 @@ # LittleFS -- **[Basic Concepts](kernel-mini-extend-file-littlefs-basic.md)** +- [Basic Concepts](#section1553253111412) +- [Development Guidelines](#section1496101821515) +- [Sample Code](#section1034515054620) + - [Verification](#section176167422148) -- **[Development Guidelines](kernel-mini-extend-file-littlefs-guide.md)** +## 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 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 + +When porting LittleFS to a new hardware device, you need to declare **lfs\_config**: + +``` +const struct lfs_config cfg = { + // block device operations + .read = user_provided_block_device_read, + .prog = user_provided_block_device_prog, + .erase = user_provided_block_device_erase, + .sync = user_provided_block_device_sync, + + // block device configuration + .read_size = 16, + .prog_size = 16, + .block_size = 4096, + .block_count = 128, + .cache_size = 16, + .lookahead_size = 16, + .block_cycles = 500, +}; +``` + +**.read**, **.prog**, **.erase**, and **.sync** correspond to the read, write, erase, and synchronization APIs at the bottom layer of the hardware platform, respectively. + +**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. + +**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. + +**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**. + +**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**\). + +## Sample Code + +The sample code is as follows: + +``` +#include "lfs.h" +#include "stdio.h" +lfs_t lfs; +lfs_file_t file; +const struct lfs_config cfg = { + // block device operations + .read = user_provided_block_device_read, + .prog = user_provided_block_device_prog, + .erase = user_provided_block_device_erase, + .sync = user_provided_block_device_sync, + // block device configuration + .read_size = 16, + .prog_size = 16, + .block_size = 4096, + .block_count = 128, + .cache_size = 16, + .lookahead_size = 16, + .block_cycles = 500, +}; +int main(void) { + // mount the filesystem + int err = lfs_mount(&lfs, &cfg); + // reformat if we can't mount the filesystem + // this should only happen on the first boot + if (err) { + lfs_format(&lfs, &cfg); + lfs_mount(&lfs, &cfg); + } + // read current count + uint32_t boot_count = 0; + lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); + // update boot count + boot_count += 1; + 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 + lfs_file_close(&lfs, &file); + // release any resources we were using + lfs_unmount(&lfs); + // print the boot count + printf("boot_count: %d\n", boot_count); +} +``` + +### Verification + +The development is successful if the return result is as follows: + +``` +Say hello 1 times. +``` diff --git a/en/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md b/en/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md deleted file mode 100644 index b794e8bbed..0000000000 --- a/en/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md +++ /dev/null @@ -1,6 +0,0 @@ -# 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 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. - diff --git a/en/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md b/en/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md deleted file mode 100644 index 29fcd7d933..0000000000 --- a/en/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md +++ /dev/null @@ -1,93 +0,0 @@ -# Development Guidelines - -Before porting LittleFS to a new hardware device, declare **lfs\_config**: - -``` -const struct lfs_config cfg = { - // block device operations - .read = user_provided_block_device_read, - .prog = user_provided_block_device_prog, - .erase = user_provided_block_device_erase, - .sync = user_provided_block_device_sync, - - // block device configuration - .read_size = 16, - .prog_size = 16, - .block_size = 4096, - .block_count = 128, - .cache_size = 16, - .lookahead_size = 16, - .block_cycles = 500, -}; -``` - -**.read**, **.prog**, **.erase**, and **.sync** correspond to the underlying read, write, erase, and synchronization APIs of the hardware platform, respectively. - -**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. - -**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. - -**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**. - -**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**\). - -## Sample Code - -The sample code is as follows: - -``` -#include "lfs.h" -#include "stdio.h" - -lfs_t lfs; -lfs_file_t file; - -const struct lfs_config cfg = { - // block device operations - .read = user_provided_block_device_read, - .prog = user_provided_block_device_prog, - .erase = user_provided_block_device_erase, - .sync = user_provided_block_device_sync, - - // block device configuration - .read_size = 16, - .prog_size = 16, - .block_size = 4096, - .block_count = 128, - .cache_size = 16, - .lookahead_size = 16, - .block_cycles = 500, -}; - -int main(void) { - // mount the filesystem - int err = lfs_mount(&lfs, &cfg); - - // reformat if we can't mount the filesystem - // this should only happen on the first boot - if (err) { - lfs_format(&lfs, &cfg); - lfs_mount(&lfs, &cfg); - } - - // read current count - uint32_t boot_count = 0; - lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); - lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); - - // update boot count - boot_count += 1; - 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 - lfs_file_close(&lfs, &file); - - // release any resources we were using - lfs_unmount(&lfs); - - // print the boot count - printf("boot_count: %d\n", boot_count); -} -``` - diff --git a/en/device-dev/kernel/kernel-mini-extend-file.md b/en/device-dev/kernel/kernel-mini-extend-file.md index 91bac1858a..dea5684718 100644 --- a/en/device-dev/kernel/kernel-mini-extend-file.md +++ b/en/device-dev/kernel/kernel-mini-extend-file.md @@ -1,11 +1,11 @@ # File System -The OpenHarmony LiteOS-M kernel supports the FAT file system \(FATFS\) and LittleFS. [Table 1](#table147491853163018) lists the comparison of the functions supported by these two 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. The following table lists the functions supported by the file systems. **Table 1** Function list -

Category

+ @@ -13,7 +13,7 @@ The OpenHarmony LiteOS-M kernel supports the FAT file system \(FATFS\) and Littl - diff --git a/en/device-dev/kernel/kernel-mini-extend-support.md b/en/device-dev/kernel/kernel-mini-extend-support.md index 653adb507f..e8cbd42d8c 100644 --- a/en/device-dev/kernel/kernel-mini-extend-support.md +++ b/en/device-dev/kernel/kernel-mini-extend-support.md @@ -1,5 +1,13 @@ # C++ Support +- [Basic Concepts](#section11374125415814) +- [Working Principles](#section189351319134418) +- [Development Guidelines](#section166302407911) + - [Available APIs](#section1881825119919) + - [How to Develop](#section76371145108) + - [Development Example](#section994427141111) + + ## Basic Concepts As one of the most widely used programming languages, C++ supports features, such as classes, encapsulation, and overloading. It is an object-oriented programming language developed based on the C language. @@ -15,7 +23,7 @@ The compiler supports C++ code identification. The system calls the constructors **Table 1** APIs supported by C++ -

Function

API

FATFS

LittleFS

+

LITTLEFS

Category

+ diff --git a/en/device-dev/kernel/kernel-mini-extend.md b/en/device-dev/kernel/kernel-mini-extend.md index 605a1b425b..96e3fe5ea4 100644 --- a/en/device-dev/kernel/kernel-mini-extend.md +++ b/en/device-dev/kernel/kernel-mini-extend.md @@ -1,4 +1,4 @@ -# Extension Components +# Extended Components - **[C++ Support](kernel-mini-extend-support.md)** diff --git a/en/device-dev/kernel/kernel-mini-imemory-debug-det.md b/en/device-dev/kernel/kernel-mini-imemory-debug-det.md index 0ea70a2387..c3fc32bd9e 100644 --- a/en/device-dev/kernel/kernel-mini-imemory-debug-det.md +++ b/en/device-dev/kernel/kernel-mini-imemory-debug-det.md @@ -1,5 +1,14 @@ # Memory Leak Check +- [Basic Concepts](#section1026719436293) +- [Function Configuration](#section13991354162914) +- [Development Guidelines](#section95828159308) + - [How to Develop](#section369844416304) + - [Development Example](#section460801313313) + - [Sample Code](#section96539275311) + - [Verification](#section20527343183119) + + ## 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 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. @@ -41,9 +50,9 @@ node size LR[0] LR[1] LR[2] This example implements the following: -1. Calls **LOS\_MemUsedNodeShow** to print information about all nodes. -2. Simulates a memory leak by requesting memory without releasing it. -3. Calls **LOS\_MemUsedNodeShow** to print information about all nodes. +1. Call **LOS\_MemUsedNodeShow** to print information about all nodes. +2. Simulate a memory leak by requesting memory without releasing it. +3. Call **LOS\_MemUsedNodeShow** to print information about all nodes. 4. Compare the logs to obtain information about the node where a memory leak occurred. 5. Locate the code based on the LR address. diff --git a/en/device-dev/kernel/kernel-mini-memory-debug-cet.md b/en/device-dev/kernel/kernel-mini-memory-debug-cet.md index e770a78d21..ead21236f3 100644 --- a/en/device-dev/kernel/kernel-mini-memory-debug-cet.md +++ b/en/device-dev/kernel/kernel-mini-memory-debug-cet.md @@ -1,5 +1,14 @@ # Memory Corruption Check +- [Basic Concepts](#section17368154517335) +- [Function Configuration](#section4696190123420) +- [Development Guidelines](#section672362973417) + - [How to Develop](#section026014863416) + - [Development Example](#section186311302356) + - [Sample Code](#section12709533354) + - [Verification](#section81214126369) + + ## 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. @@ -26,9 +35,9 @@ Check for memory corruption by calling **LOS\_MemIntegrityCheck**. If no memory This example implements the following: -1. Requests 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. +1. Request two physically adjacent memory blocks. +2. Call **memset** to construct an out-of-bounds access and overwrites the first four bytes of the next node. +3. Call **LOS\_MemIntegrityCheck** to check whether memory corruption occurs. ### Sample Code diff --git a/en/device-dev/kernel/kernel-mini-memory-debug-mes.md b/en/device-dev/kernel/kernel-mini-memory-debug-mes.md index 02d6310be3..b0bcda96d9 100644 --- a/en/device-dev/kernel/kernel-mini-memory-debug-mes.md +++ b/en/device-dev/kernel/kernel-mini-memory-debug-mes.md @@ -1,5 +1,14 @@ # Memory Information Statistics +- [Basic Concepts](#section52691565235) +- [Function Configuration](#section470611682411) +- [Development Guidelines](#section9368374243) + - [How to Develop](#section679912407257) + - [Development Example](#section1025453412611) + - [Sample Code](#section165277971315) + - [Verification](#section3460102414271) + + ## 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. @@ -47,11 +56,11 @@ typedef struct { 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. +2. Call **LOS\_MemInfoGet** to obtain the basic information about the memory pool. -3. Calculates the memory usage and fragmentation rate. +3. Calculate the memory usage and fragmentation rate. ### Sample Code @@ -64,6 +73,7 @@ The sample code is as follows: #include "los_memory.h" #include "los_config.h" + void MemInfoTaskFunc(void) { LOS_MEM_POOL_STATUS poolStatus = {0}; diff --git a/en/device-dev/kernel/kernel-mini-memory-exception.md b/en/device-dev/kernel/kernel-mini-memory-exception.md index bf9b4b029c..bdbb43b4b1 100644 --- a/en/device-dev/kernel/kernel-mini-memory-exception.md +++ b/en/device-dev/kernel/kernel-mini-memory-exception.md @@ -1,5 +1,13 @@ # Exception Debugging +- [Basic Concepts](#section2741911123412) +- [Working Principles](#section16618124317346) +- [Available APIs](#section16111931351) +- [Usage Guidelines](#section16317163520350) + - [How to Develop](#section13457839133618) + - [How to Locate Exceptions](#section197332323815) + + ## 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. @@ -13,7 +21,7 @@ When an exception occurs in the system, the system prints the register informati 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/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. @@ -24,7 +32,7 @@ The following table describes APIs available for the OpenHarmony LiteOS-M stack **Table 1** APIs of the stack trace module -

Function

API

Category

+ @@ -101,7 +109,7 @@ The typical process for enabling exception debugging is as follows: #define TSK_PRIOR 4 /* Simulate an abnormal function. */ - + UINT32 Get_Result_Exception_0(UINT16 dividend){ UINT32 divisor = 0; UINT32 result = dividend / divisor; @@ -271,21 +279,21 @@ The procedure for locating the exception is as follows: ``` UINT32 Get_Result_Exception_0(UINT16 dividend){ - 80037c8: b480 push {r7} - 80037ca: b085 sub sp, #20 - 80037cc: af00 add r7, sp, #0 - 80037ce: 4603 mov r3, r0 - 80037d0: 80fb strh r3, [r7, #6] + 80037c8: b480 push {r7} + 80037ca: b085 sub sp, #20 + 80037cc: af00 add r7, sp, #0 + 80037ce: 4603 mov r3, r0 + 80037d0: 80fb strh r3, [r7, #6] kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:10 UINT32 divisor = 0; - 80037d2: 2300 movs r3, #0 - 80037d4: 60fb str r3, [r7, #12] + 80037d2: 2300 movs r3, #0 + 80037d4: 60fb str r3, [r7, #12] kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:11 UINT32 result = dividend / divisor; - 80037d6: 88fa ldrh r2, [r7, #6] - 80037d8: 68fb ldr r3, [r7, #12] - 80037da: fbb2 f3f3 udiv r3, r2, r3 - 80037de: 60bb str r3, [r7, #8] + 80037d6: 88fa ldrh r2, [r7, #6] + 80037d8: 68fb ldr r3, [r7, #12] + 80037da: fbb2 f3f3 udiv r3, r2, r3 + 80037de: 60bb str r3, [r7, #8] ``` @@ -302,17 +310,17 @@ The procedure for locating the exception is as follows: Get_Result_Exception_1(): kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:15 UINT32 Get_Result_Exception_1(UINT16 dividend){ - 80037ec: b580 push {r7, lr} - 80037ee: b082 sub sp, #8 - 80037f0: af00 add r7, sp, #0 - 80037f2: 4603 mov r3, r0 - 80037f4: 80fb strh r3, [r7, #6] + 80037ec: b580 push {r7, lr} + 80037ee: b082 sub sp, #8 + 80037f0: af00 add r7, sp, #0 + 80037f2: 4603 mov r3, r0 + 80037f4: 80fb strh r3, [r7, #6] kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:16 return Get_Result_Exception_0(dividend); - 80037f6: 88fb ldrh r3, [r7, #6] - 80037f8: 4618 mov r0, r3 - 80037fa: f7ff ffe5 bl 80037c8 - 80037fe: 4603 mov r3, r0 + 80037f6: 88fb ldrh r3, [r7, #6] + 80037f8: 4618 mov r0, r3 + 80037fa: f7ff ffe5 bl 80037c8 + 80037fe: 4603 mov r3, r0 ``` diff --git a/en/device-dev/kernel/kernel-mini-memory-lms.md b/en/device-dev/kernel/kernel-mini-memory-lms.md new file mode 100644 index 0000000000..1508f02869 --- /dev/null +++ b/en/device-dev/kernel/kernel-mini-memory-lms.md @@ -0,0 +1,328 @@ +# LMS + +- [Basic Concepts](#section7605453104815) +- [Working Principles](#section8495832174910) +- [Available APIs](#section05501853194918) +- [Development Guidelines](#section177357243510) + - [How to Develop](#section125863345112) + - [Development Example](#section812115715313) + - [Sample Code](#section614842310538) + - [Verification](#section980212293548) + + +## 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. + +The LMS module of the OpenHarmony LiteOS-M kernel provides the following functions: + +- 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 when libc frequently accessed functions, including **memset**, **memcpy**, **memmove**, **strcat**, **strcpy**, **strncat** and **strncpy**, are called. + +## 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. + +- 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. +- 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. + +## 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. + +**Table 1** LMS module APIs + + +

Function

API

+ + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

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.

+

Deleting a memory pool from the LMS check linked list

+

LOS_LmsCheckPoolDel

+

Cancels the validity check on the specified memory pool.

+

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.

+

Disabling protection of a specified memory chunk

+

LOS_LmsAddrDisableProtect

+

Unlocks a memory chunk to make it readable and writable.

+
+ +## Development Guidelines + +### How to Develop + +The typical process for enabling LMS is as follows: + +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\_m** directory, choose **Kernel**, and set **Enable Lite Memory Sanitizer** to **Yes**. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Macro

+

menuconfig Option

+

Description

+

Value

+

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_LOAD_CHECK

+

Enable lms read check

+

Whether to enable LMS read 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

+
+ +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") { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + ] + } else { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + ] + } + ``` + +3. Recompile the code and check the serial port output. The memory problem detected will be displayed. + +### Development Example + +This example implements the following: + +1. Create a task for LMS. +2. Construct a buffer overflow error and a UAF error. +3. Add "-fsanitize=kernel-address", execute the compilation, and check the output. + +### Sample Code + +The code is as follows: + +``` +#define PAGE_SIZE (0x1000U) +#define INDEX_MAX 20 +UINT32 g_lmsTestTaskId; +char g_testLmsPool[2 * PAGE_SIZE]; +STATIC VOID testPoolInit(void) +{ + UINT32 ret = LOS_MemInit(g_testLmsPool, 2 * PAGE_SIZE); + if (ret != 0) { + PRINT_ERR("%s failed, ret = 0x%x\n", __FUNCTION__, ret); + return; + } +} +static VOID LmsTestOsmallocOverflow(VOID) +{ + PRINTK("\n######%s start ######\n", __FUNCTION__); + UINT32 i; + CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); + PRINTK("str[%2d]=0x%2x ", INDEX_MAX, str[INDEX_MAX]); /* trigger heap overflow at str[INDEX_MAX] */ + PRINTK("\n######%s stop ######\n", __FUNCTION__); +} +static VOID LmsTestUseAfterFree(VOID) +{ + PRINTK("\n######%s start ######\n", __FUNCTION__); + UINT32 i; + CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); + LOS_MemFree(g_testLmsPool, str); + PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */ + PRINTK("\n######%s stop ######\n", __FUNCTION__); +} +VOID LmsTestCaseTask(VOID) +{ + testPoolInit(); + LmsTestOsmallocOverflow(); + LmsTestUseAfterFree(); +} +UINT32 Example_Lms_test(VOID){ + UINT32 ret; + TSK_INIT_PARAM_S lmsTestTask; + /* Create a task for LMS. */ + memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask; + lmsTestTask.pcName = "TestLmsTsk"; /* Task name. */ + lmsTestTask.uwStackSize = 0x800; + lmsTestTask.usTaskPrio = 5; + lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_lmsTestTaskId, &lmsTestTask); + if(ret != LOS_OK){ + PRINT_ERR("LmsTestTask create failed .\n"); + return LOS_NOK; + } + return LOS_OK; +} +``` + +### Verification + +The output is as follows: + +``` +######LmsTestOsmallocOverflow start ###### +[ERR]***** Kernel Address Sanitizer Error Detected Start ***** +[ERR]Heap buffer overflow error detected +[ERR]Illegal READ address at: [0x4157a3c8] +[ERR]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2] +OsBackTrace fp = 0x402c0f88 +runTask->taskName = LmsTestCaseTask +runTask->taskID = 2 +*******backtrace begin******* +traceback fp fixed, trace using fp = 0x402c0fd0 +traceback 0 -- lr = 0x400655a4 fp = 0x402c0ff8 +traceback 1 -- lr = 0x40065754 fp = 0x402c1010 +traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 +traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca +[LMS] Dump info around address [0x4157a3c8]: + [0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1 + [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 + [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 + [0x4157a3c8]: [ba] dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: [2] 2 + [0x4157a3d0]: 2c 1a 00 00 00 00 00 00 | [0x4157be3d | 0]: 2 3 + [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 + [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 + [0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3 + [0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3 +[ERR]***** Kernel Address Sanitizer Error Detected End ***** +str[20]=0xffffffba +######LmsTestOsmallocOverflow stop ###### +###### LmsTestUseAfterFree start ###### +[ERR]***** Kernel Address Sanitizer Error Detected Start ***** +[ERR]Use after free error detected +[ERR]Illegal READ address at: [0x4157a3d4] +[ERR]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3] +OsBackTrace fp = 0x402c0f90 +runTask->taskName = LmsTestCaseTask +runTask->taskID = 2 +*******backtrace begin******* +traceback fp fixed, trace using fp = 0x402c0fd8 +traceback 0 -- lr = 0x40065680 fp = 0x402c0ff8 +traceback 1 -- lr = 0x40065758 fp = 0x402c1010 +traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 +traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca +[LMS] Dump info around address [0x4157a3d4]: + [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 + [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 + [0x4157a3c8]: ba dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: 2 2 + [0x4157a3d0]: 2c 1a 00 00 [00] 00 00 00 | [0x4157be3d | 0]: 2 [3] + [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 + [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 + [0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2 + [0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3 + [0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3 +[ERR]***** Kernel Address Sanitizer Error Detected End ***** +str[ 0]=0x 0 +######LmsTestUseAfterFree stop ###### +``` + +The key output information is as follows: + +- Error type: + - Heap buffer overflow + - UAF + +- Incorrect operations: + - Illegal read + - Illegal write + - Illegal double free + +- Context: + - Task information \(**taskName** and **taskId**\) + - Backtrace + +- Memory information of the error addresses: + - Memory value and the value of the corresponding shadow memory + - 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\) + + diff --git a/en/device-dev/kernel/kernel-mini-memory-perf.md b/en/device-dev/kernel/kernel-mini-memory-perf.md new file mode 100644 index 0000000000..5d20af7b12 --- /dev/null +++ b/en/device-dev/kernel/kernel-mini-memory-perf.md @@ -0,0 +1,535 @@ +# perf + +- [Basic Concepts](#section531482192018) +- [Working Principles](#section5125124532010) +- [Available APIs](#section17747184017458) + - [Kernel Mode](#section104473014465) + - [User Mode](#section1996920294531) + +- [Development Guidelines](#section10302175017543) + - [Kernel-mode Development Process](#section04021008552) + +- [Kernel-mode Development Example](#section112034213583) +- [Kernel-mode Sample Code](#section10348549155812) + - [Kernel-mode Verification](#section61719481795) + - [User-mode Development Process](#section1425821711114) + - [User-mode Development Example](#section3470546163) + - [User-Mode Sample Code](#section183253286161) + - [User-mode Verification](#section5665123516214) + + +## 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 + +### Kernel Mode + +The perf module of the OpenHarmony LiteOS-A kernel provides the following APIs. For more details about the APIs, see the [API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_perf.h) reference. + +**Table 1** perf module APIs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

Starting or stopping perf sampling

+

LOS_PerfStart

+

Starts sampling.

+

LOS_PerfStop

+

Stops sampling.

+

Configuring perf sampling events

+

LOS_PerfConfig

+

Sets the type and period of a sampling event.

+

Reading sampling data

+

LOS_PerfDataRead

+

Reads the sampling data to a specified address.

+

Registering a hook for the sampling data buffer

+

LOS_PerfNotifyHookReg

+

Registers the hook to be called when the buffer waterline is reached.

+

LOS_PerfFlushHookReg

+

Registers the hook for flushing the cache in the buffer.

+
+ +1. The structure of the perf sampling event is **PerfConfigAttr**. For details, see **kernel\\include\\los\_perf.h**. +2. The sampling data buffer is a circular buffer, and only the region that has been read in the buffer can be overwritten. +3. 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 sample code is as follows: + + ``` + 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); + ``` + +4. If the buffer sampled by perf involves caches across CPUs, you can register a hook for flushing the cache to ensure cache consistency. The sample code is as follows: + + ``` + 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. + + +### User Mode + +The perf character device is located in **/dev/perf**. You can read, write, and control the user-mode perf by running the following commands on the device node: + +- **read**: reads perf data in user mode. +- **write**: writes user-mode sampling events. +- **ioctl**: controls the user-mode perf, which includes the following: + + ``` + #define PERF_IOC_MAGIC 'T' + #define PERF_START _IO(PERF_IOC_MAGIC, 1) + #define PERF_STOP _IO(PERF_IOC_MAGIC, 2) + ``` + + The operations correspond to **LOS\_PerfStart** and **LOS\_PerfStop**. + + +For more details, see [User-mode Development Example](#section3470546163). + +## 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**. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Macro

+

menuconfig Option

+

Description

+

Value

+

LOSCFG_KERNEL_PERF

+

Enable Perf Feature

+

Whether to enable perf.

+

YES/NO

+

LOSCFG_PERF_CALC_TIME_BY_TICK

+

Time-consuming Calc Methods->By Tick

+

Whether to use tick as the perf timing unit.

+

YES/NO

+

LOSCFG_PERF_CALC_TIME_BY_CYCLE

+

Time-consuming Calc Methods->By Cpu Cycle

+

Whether to use cycle as the perf timing unit.

+

YES/NO

+

LOSCFG_PERF_BUFFER_SIZE

+

Perf Sampling Buffer Size

+

Size of the buffer used for perf sampling.

+

INT

+

LOSCFG_PERF_HW_PMU

+

Enable Hardware Pmu Events for Sampling

+

Whether to enable hardware PMU events. The target platform must support the hardware PMU.

+

YES/NO

+

LOSCFG_PERF_TIMED_PMU

+

Enable Hrtimer Period Events for 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 Software Events for 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. + + Two modes: counting mode \(counts only the number of event occurrences\) and sampling mode \(collects context information such as task IDs, PC, and backtrace\) + + Three types of events: 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. + +## Kernel-mode 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. + +## Kernel-mode Sample Code + +Prerequisites: The perf module configuration is complete in **menuconfig**. + +The code is as follows: + +``` +#include "los_perf.h" +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; + PerfConfigAttr attr = { + .eventsCfg = { + .type = PERF_EVENT_TYPE_HW, + .events = { + [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, + [1] = {PERF_COUNT_HW_BRANCH_INSTRUCTIONS, 0xFFFFFF00}, + }, + .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); + 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; + /* Create a perf task.*/ + memset(&perfTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + perfTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)perfTestHwEvent; + perfTestTask.pcName = "TestPerfTsk"; /* Task name.*/ + perfTestTask.uwStackSize = 0x800; + perfTestTask.usTaskPrio = 5; + perfTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_perfTestTaskId, &perfTestTask); + if(ret != LOS_OK){ + PRINT_ERR("PerfTestTask create failed.\n"); + return LOS_NOK; + } + return LOS_OK; +} +LOS_MODULE_INIT(perfTestHwEvent, LOS_INIT_LEVEL_KMOD_EXTENDED); +``` + +### Kernel-mode Verification + +The output is as follows: + +``` +--------count mode---------- +[EMG] [cycles] eventType: 0xff: 5466989440 +[EMG] [branches] eventType: 0xc: 602166445 +------- sample mode---------- +[EMG] dump section data, addr: 0x8000000 length: 0x800000 +num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ... +hex: 00 ef ef ef 00 00 00 00 14 00 00 00 60 00 00 00 00 00 00 00 70 88 36 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 01 00 00 00 cc 55 30 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 +``` + +- 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. + + +### User-mode Development Process + +Choose **Driver** \> **Enable PERF DRIVER** in **menuconfig** to enable the perf driver. This option is available in **Driver** only after **Enable Perf Feature** is selected in the kernel. + +1. Open the **/dev/perf** file and perform read, write, and ioctl operations. +2. Run the **perf** commands in user mode in the **/bin** directory. After running **cd bin**, you can use the following commands: + - **./perf start \[_id_\]**: starts perf sampling. _id_ is optional and is **0** by default. + - **./perf stop**: stops perf sampling. + - **./perf read <_nBytes_\>**: reads n-byte data from the sampling buffer and displays the data. + - **./perf list**: lists the events supported by **-e**. + - **./perf stat/record \[_option_\] <_command_\>**: sets counting or sampling parameters. + - The \[_option_\] can be any of the following: + - **-e**: sets sampling events. Events of the same type listed in **./perf list** can be used. + - **-p**: sets the event sampling interval. + - **-o**: specifies the path of the file for saving the perf sampling data. + - **-t**: specifies the task IDs for data collection. Only the contexts of the specified tasks are collected. If this parameter is not specified, all tasks are collected by default. + - **-s**: specifies the context type for sampling. For details, see **PerfSampleType** defined in **los\_perf.h**. + - **-P**: specifies the process IDs for data collection. Only the contexts of the specified processes are collected. If this parameter is not specified, all processes are collected by default. + - **-d**: specifies whether to divide the frequency \(the value is incremented by 1 each time an event occurs 64 times\). This option is valid only for hardware cycle events. + + - _command_ specifies the program to be checked by perf. + + + +Examples: + +Run the **./perf list** command to display available events. The output is as follows: + +``` +cycles [Hardware event] +instruction [Hardware event] +dcache [Hardware event] +dcache-miss [Hardware event] +icache [Hardware event] +icache-miss [Hardware event] +branch [Hardware event] +branch-miss [Hardware event] +clock [Timed event] +task-switch [Software event] +irq-in [Software event] +mem-alloc [Software event] +mux-pend [Software event] +``` + +Run **./perf stat -e cycles os\_dump**. The output is as follows: + +``` +type: 0 +events[0]: 255, 0xffff +predivided: 0 +sampleType: 0x0 +needSample: 0 +usage os_dump [--help | -l | SERVICE] + --help: shows this help + -l: only list services, do not dump them + SERVICE: dumps only service SERVICE +time used: 0.058000(s) +[cycles] eventType: 0xff [core 0]: 21720647 +[cycles] eventType: 0xff [core 1]: 13583830 +``` + +Run **./perf record -e cycles os\_dump**. The output is as follows: + +``` +type: 0 +events[0]: 255, 0xffff +predivided: 0 +sampleType: 0x60 +needSample: 1 +usage os_dump [--help | -l | SERVICE] + --help: shows this help + -l: only list services, do not dump them + SERVICE: dumps only service SERVICE +dump perf data, addr: 0x408643d8 length: 0x5000 +time used: 0.059000(s) +save perf data success at /storage/data/perf.data +``` + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>After running the **./perf stat/record** command, you can run the **./perf start** and **./perf stop** commands multiple times. The sampling event configuration is as per the parameters set in the latest **./perfstat/record** command. + +### User-mode Development Example + +This example implements the following: + +1. Open the perf character device. +2. Write the perf events. +3. Start perf. +4. Stop perf. +5. Read the perf sampling data. + +### User-Mode Sample Code + +The code is as follows: + +``` +#include "fcntl.h" +#include "user_copy.h" +#include "sys/ioctl.h" +#include "fs/driver.h" +#include "los_dev_perf.h" +#include "los_perf.h" +#include "los_init.h" +/* perf ioctl */ +#define PERF_IOC_MAGIC 'T' +#define PERF_START _IO(PERF_IOC_MAGIC, 1) +#define PERF_STOP _IO(PERF_IOC_MAGIC, 2) +int main(int argc, char **argv) +{ + char *buf = NULL; + ssize_t len; + int fd = open("/dev/perf", O_RDWR); + if (fd == -1) { + printf("Perf open failed.\n"); + exit(EXIT_FAILURE); + } + PerfConfigAttr attr = { + .eventsCfg = { +#ifdef LOSCFG_PERF_HW_PMU + .type = PERF_EVENT_TYPE_HW, + .events = { + [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, + }, +#elif defined LOSCFG_PERF_TIMED_PMU + .type = PERF_EVENT_TYPE_TIMED, + .events = { + [0] = {PERF_COUNT_CPU_CLOCK, 100}, + }, +#elif defined LOSCFG_PERF_SW_PMU + .type = PERF_EVENT_TYPE_SW, + .events = { + [0] = {PERF_COUNT_SW_TASK_SWITCH, 1}, + }, +#endif + .eventsNr = 1, /* 1 event */ + .predivided = 0, + }, + .taskIds = {0}, + .taskIdsNr = 0, + .processIds = {0}, + .processIdsNr = 0, + .needSample = 1, + .sampleType = PERF_RECORD_IP | PERF_RECORD_CALLCHAIN, + }; + (void)write(fd, &attr, sizeof(PerfConfigAttr)); /* perf config */ + ioctl(fd, PERF_START, NULL); /* perf start */ + test(); + ioctl(fd, PERF_STOP, NULL); /* perf stop */ + buf = (char *)malloc(LOSCFG_PERF_BUFFER_SIZE); + if (buf == NULL) { + printf("no memory for read perf 0x%x\n", LOSCFG_PERF_BUFFER_SIZE); + return -1; + } + len = read(fd, buf, LOSCFG_PERF_BUFFER_SIZE); + OsPrintBuff(buf, len); /* print data */ + free(buf); + close(fd); + return 0; +} +``` + +### User-mode Verification + +The output is as follows: + +``` +[EMG] dump section data, addr: 0x8000000 length: 0x800000 +num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ... +hex: 00 ef ef ef 00 00 00 00 14 00 00 00 60 00 00 00 00 00 00 00 70 88 36 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 01 00 00 00 cc 55 30 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 +``` + diff --git a/en/device-dev/kernel/kernel-mini-memory-trace.md b/en/device-dev/kernel/kernel-mini-memory-trace.md index e39a993963..bd9b0553e9 100644 --- a/en/device-dev/kernel/kernel-mini-memory-trace.md +++ b/en/device-dev/kernel/kernel-mini-memory-trace.md @@ -1,21 +1,41 @@ -# Trace Debugging +# Trace + +- [Basic Concepts](#section44851752123712) +- [Working Principles](#section5282148123813) +- [Available APIs](#section16304193215387) +- [Development Guidelines](#section498695853819) + - [How to Develop](#section1875652316393) + - [Development Example](#section0403134913395) + - [Sample Code](#section1492711418400) + - [Verification](#section869613984012) + ## Basic Concepts -Trace debugging 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 information, you can better understand the code running process of the kernel and locate time sequence problems. ## Working Principles -The kernel provides a framework to embed hooks in main processes of modules. You can register callback functions at the required hooks. When the kernel runs the corresponding process, the kernel proactively calls the **Hook** function to transfer key data of the current process to you. +The kernel provides a hook framework to embed hooks in the main process of each module. In the initial startup phase of the kernel, the trace function is initialized and the trace handlers are registered with the hooks. + +When a hook is triggered, the trace module encapsulates the input information and adds the trace frame header information, including the event type, ID of the running CPU, ID of the running task, and relative timestamp. + +The trace module provides two working modes: offline mode and online mode. + +In offline mode, trace frames are stored in a circular buffer. If too many frames are stored in the circular buffer, earlier frames will be overwritten to ensure that the information in the buffer is always the latest. Data in the circular buffer can be exported by running the shell command for further analysis. The exported information is sorted by timestamp. + +![](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. ## Available APIs -The following table describes APIs available for the OpenHarmony trace module. For more details about the APIs, see the API reference. +The trace module of the OpenHarmony LiteOS-M kernel provides the following functions. For more details about the APIs, see the API reference. **Table 1** Trace module APIs -

Category

+ @@ -23,164 +43,340 @@ The following table describes APIs available for the OpenHarmony trace module. F - + + + + + + + + + + + + + + + - + + + + + + - - - - + + +

Function

API

Registering a hook

+

Starting and stopping trace

+

LOS_TraceStart

+

Starts trace.

+

LOS_TraceStop

+

Stops trace.

+

Managing trace records

+

LOS_TraceRecordDump

+

Exports data in the trace buffer.

+

LOS_TraceRecordGet

+

Obtains the start address of the trace buffer.

+

LOS_TraceReset

+

Clears events in the trace buffer.

LOS_HookReg

+

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 callback function at a specified hook.

+

Registers a hook to filter out events of specified interrupt IDs.

Unregistering a hook

+

Performing function instrumentation

LOS_HookUnReg

+

LOS_TRACE_EASY

Unregisters the callback function at the current hook.

+

Performs simple instrumentation.

+

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 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. + - **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. + - Example: + + ``` + Perform simple instrumentation for reading and writing files fd1 and fd2. + Set TYPE to 1 for read operations and 2 for write operations. + Insert the following to the position where the fd1 file is read: + 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. + - 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. + - The **IDENTITY** and **Params** are the same as those of simple instrumentation. + - Example: + + ``` + 1. Set the event mask (module-level event type) in enum LOS_TRACE_MASK. + Format: TRACE_#MOD#_FLAG (MOD indicates the module name) + Example: + 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:** + >The trace event types and parameters can be modified 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**. +- 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. + + The sample code is as follows: + + ``` + BOOL Example_HwiNumFilter(UINT32 hwiNum) + { + if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { + return TRUE; + } + return FALSE; + } + LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); + ``` + + The interrupt events with interrupt ID of **TIMER\_INT** or **DMA\_INT** are not traced. + + ## Development Guidelines ### How to Develop -The typical process for enabling trace debugging is as follows: +The typical trace process is as follows: -1. Configure the macros related to the trace module. +1. Configure the macro related to the trace module. Modify the configuration in the **target\_config.h** file. - -

Parameter

+ + - - - + + + + + + + + + - - + + + + + + + + + + + + + + + + + + +

Configuration

Description

+

Description

Value

+

Value

LOSCFG_DEBUG_HOOK

+

LOSCFG_KERNEL_TRACE

+

Specifies whether to enable the trace feature.

+

YES/NO

+

LOSCFG_RECORDER_MODE_OFFLINE

+

Specifies whether to enable the online trace mode.

+

YES/NO

+

LOSCFG_RECORDER_MODE_ONLINE

+

Specifies whether to enable the offline trace mode.

Setting of the trace function

+

YES/NO

0: disable; 1: enable

+

LOSCFG_TRACE_CLIENT_INTERACT

+

Specifies whether to enable interaction with Trace IDE (dev tools), including data visualization and process control.

+

YES/NO

+

LOSCFG_TRACE_FRAME_CORE_MSG

+

Specifies whether to enable recording of the CPU ID, interruption state, and lock task state.

+

YES/NO

+

LOSCFG_TRACE_FRAME_EVENT_COUNT

+

Specifies whether to enables recording of the event sequence number.

+

YES/NO

+

LOSCFG_TRACE_FRAME_MAX_PARAMS

+

Specifies the maximum number of parameters for event recording.

+

INT

+

LOSCFG_TRACE_BUFFER_SIZE

+

Specifies the trace buffer size.

+

INT

-2. Select the hooks for registering callback functions. For details about the hook types, see **liteos\_m/utils/internal/los\_hook\_types.h**. -3. Call **LOS\_HookReg** to register functions. +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: + +- LOS\_TraceReset —— trace\_reset +- LOS\_TraceEventMaskSet —— trace\_mask +- LOS\_TraceStart —— trace\_start +- LOS\_TraceStop —— trace\_stop +- LOS\_TraceRecordDump —— trace\_dump ### Development Example -This example invokes the malloc and free APIs to allocate and release memory of different sizes and records the malloc and free behavior and time sequence. +This example implements the following: + +1. Create a trace task. +2. Set the event mask. +3. Start trace. +4. Stop trace. +5. Output trace data in the specified format. ### Sample Code The sample code is as follows: ``` -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "los_hook.h" - -#define SIZE_512 512 -#define SIZE_1K 1024 -#define SIZE_2K 2048 - -/* Print the size of malloc when the callback function is invoked. */ -void MallocRecord(void *pool, unsigned int size) -{ - printf("malloc size = %u\n", size); - return; +#include "los_trace.h" +UINT32 g_traceTestTaskId; +VOID Example_Trace(VOID) +{ + UINT32 ret; + LOS_TaskDelay(10); + /* Start trace. */ + ret = LOS_TraceStart(); + if (ret != LOS_OK) { + dprintf("trace start error\n"); + return; + } + /* Trigger a task switching event.*/ + LOS_TaskDelay(1); + LOS_TaskDelay(1); + LOS_TaskDelay(1); + /* Stop trace.*/ + LOS_TraceStop(); + LOS_TraceRecordDump(FALSE); } - -/* Print the free pointer address when the callback function is invoked. */ -void FreeRecord(void *pool, void *ptr) -{ - printf("free pool = 0x%x ptr = 0x%x\n", pool, ptr); - return; +UINT32 Example_Trace_test(VOID){ + UINT32 ret; + TSK_INIT_PARAM_S traceTestTask; + /* Create a trace task. */ + memset(&traceTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + traceTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Trace; + traceTestTask.pcName = "TestTraceTsk"; /* Trace task name*/ + traceTestTask.uwStackSize = 0x800; + traceTestTask.usTaskPrio = 5; + traceTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_traceTestTaskId, &traceTestTask); + if(ret != LOS_OK){ + dprintf("TraceTestTask create failed .\n"); + return LOS_NOK; + } + /* Trace is started by default. Therefore, you can stop trace, clear the buffer, and then restart trace. */ + LOS_TraceStop(); + LOS_TraceReset(); + /* Enable trace of the Task module events. */ + LOS_TraceEventMaskSet(TRACE_TASK_FLAG); + return LOS_OK; } +``` -void TestTrace(void) -{ - char *pool1 = NULL; - char *pool2 = NULL; - char *pool3 = NULL; - char *retptr = NULL; - /* Allocate memory of different sizes to pool1, pool2, and pool3. */ - pool1 = (char *)malloc(SIZE_512); - if (pool1 == NULL) { - printf("pool1 malloc failed!\n"); - return; - } - retptr = memset(pool1, 'a', SIZE_512); - if (retptr == NULL) { - printf("pool1 memset failed!\n"); - return; - } - printf("pool1 addr = 0x%x *pool1[0] = %c\n", pool1, *pool1); +### Verification - pool2 = (char *)malloc(SIZE_1K); - if (pool2 == NULL) { - printf("pool2 malloc failed!\n"); - return; - } - retptr = memset(pool2, 'b', SIZE_1K); - if (retptr == NULL) { - printf("pool2 memset failed!\n"); - return; - } - printf("pool2 addr = 0x%x *pool2[0] = %c\n", pool2, *pool2); +The output is as follows: - pool3 = (char *)malloc(SIZE_2K); - if (pool3 == NULL) { - printf("pool3 malloc failed!\n"); - return; - } - retptr = memset(pool3, 'c', SIZE_2K); - if (retptr == NULL) { - printf("pool3 memset failed!\n"); - return; - } - printf("pool3 addr = 0x%x *pool3[0] = %c\n", pool3, *pool3); +``` +*******TraceInfo begin******* +clockFreq = 50000000 +CurEvtIndex = 7 +Index Time(cycles) EventType CurTask Identity params +0 0x366d5e88 0x45 0x1 0x0 0x1f 0x4 0x0 +1 0x366d74ae 0x45 0x0 0x1 0x0 0x8 0x1f +2 0x36940da6 0x45 0x1 0xc 0x1f 0x4 0x9 +3 0x3694337c 0x45 0xc 0x1 0x9 0x8 0x1f +4 0x36eea56e 0x45 0x1 0xc 0x1f 0x4 0x9 +5 0x36eec810 0x45 0xc 0x1 0x9 0x8 0x1f +6 0x3706f804 0x45 0x1 0x0 0x1f 0x4 0x0 +7 0x37070e59 0x45 0x0 0x1 0x0 0x8 0x1f +*******TraceInfo end******* +``` - /* Release pool3, pool1, and pool2 in sequence to check the time sequence of the callback functions. */ - free(pool3); - free(pool1); - free(pool2); +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. - return; -} -/* Before the trace module is used, callback functions are registered. Note that the return value of the callback functions is void. */ -void InitTest(void) -{ - printf("init hook\n"); - /* Register the hook based on the trace information to be obtained. For details about the hook types, see liteos_m/utils/internal/los_hook_types.h. */. - LOS_HookReg(LOS_HOOK_TYPE_MEM_ALLOC, MallocRecord); - LOS_HookReg(LOS_HOOK_TYPE_MEM_FREE, FreeRecord); - return; -} -``` +- **EventType**: event type. For details, see **enum LOS\_TRACE\_TYPE** in the header file **los\_trace.h**. +- **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**. -### Verification +The following uses output No. 0 as an example. -The output is as follows: +``` +Index Time(cycles) EventType CurTask Identity params +0 0x366d5e88 0x45 0x1 0x0 0x1f 0x4 +``` + +- **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. +- For details about the meanings of **Identity** and **params**, see the **TASK\_SWITCH\_PARAMS** macro. ``` -init hook -malloc size = 512 -pool1 addr = 0x20002f44 *pool1[0] = a -malloc size = 1024 -pool2 addr = 0x2000314c *pool2[0] = b -malloc size = 2048 -pool3 addr = 0x20003554 *pool3[0] = c -free pool = 0x200002a4 ptr = 0x20003554 -free pool = 0x200002a4 ptr = 0x20002f44 -free pool = 0x200002a4 ptr = 0x2000314c +#define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ +taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus ``` -According to the address information, the sequence of free is pool3, pool1, and pool2. +Because of **\#TYPE\#\_PARAMS\(IDENTITY, parma1...\) IDENTITY, ...**, **Identity** is **taskId \(0x0\)** and the first parameter is **oldPriority \(0x1f\)**. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>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**. diff --git a/en/device-dev/kernel/kernel-mini-overview.md b/en/device-dev/kernel/kernel-mini-overview.md index e058b9a1aa..c960444afb 100644 --- a/en/device-dev/kernel/kernel-mini-overview.md +++ b/en/device-dev/kernel/kernel-mini-overview.md @@ -1,15 +1,18 @@ # Kernel Overview -## Overview +- [Overview](#section1429342661510) + - [CPU Architecture Support](#section48891456112819) + - [Working Principles](#section4599142312817) + -The OpenHarmony LiteOS-M kernel is a lightweight operating system \(OS\) kernel designed for the IoT field. It features small size, low power consumption, and high performance. The LiteOS-M kernel has simple code structure, including the minimum function set, kernel abstraction layer, optional components, and project directory. +## Overview -The OpenHarmony LiteOS-M kernel architecture consists of the hardware layer and the hardware-irrelevant layers, as shown in [Figure Kernel architecture](#fig17231457191415). +The OpenHarmony LiteOS-M kernel is a lightweight operating system \(OS\) kernel designed for the IoT field. It features small size, low power consumption, and high performance. The LiteOS-M kernel has simple code structure, including the minimum function set, kernel abstraction layer \(KAL\), optional components, and project directory. It supports the Hardware Driver Foundation \(HDF\), which provides unified driver standards and access mode for device vendors to simplify porting of drivers and allow one-time development for multi-device deployment. -The hardware layer is classified based on the compilation toolchain and chip architecture, and provides a unified Hardware Abstraction Layer \(HAL\) interface to improve hardware adaptation and facilitate the expansion of various types of &IoT hardware and compilation toolchains. The basic kernel provides basic kernel capabilities. The extended modules provide capabilities of components, such as network and file systems, as well as exception handling and debug tools. The Kernel Abstraction Layer \(**KAL**\) provides unified standard APIs. +The OpenHarmony LiteOS-M kernel architecture consists of the hardware layer and hardware-irrelevant layers, as shown in [Figure 1](#fig1287712172318). The hardware layer is classified based on the compiler toolchain and chip architecture, and provides a unified Hardware Abstraction Layer \(HAL\) interface to improve hardware adaptation and facilitate the expansion of various types of AIoT hardware and compilation toolchains. The other modules are irrelevant to the hardware. The basic kernel module provides basic kernel capabilities. The extended modules provide capabilities of components, such as the network and file systems, as well as exception handling and debug tools. The KAL provides unified standard APIs. -**Figure 1** Kernel architecture -![](figure/kernel-architecture.png "kernel-architecture") +**Figure 1** Kernel architecture +![](figures/kernel-architecture.png "kernel-architecture") ### CPU Architecture Support @@ -54,8 +57,8 @@ LiteOS-M supports mainstream architectures, such as ARM Cortex-M3, ARM Cortex-M4 ### Working Principles -Configure the system clock and number of ticks per second in the **target\_config.h** file of the development board. Configure the task, memory, inter-process communication \(IPC\), and exception handling modules based on service requirements. When the system boots, the modules are initialized based on the configuration. The kernel startup process includes peripheral initialization, system clock configuration, kernel initialization, and OS boot. For details, see [Figure 2](#fig19742101817344). +Configure the system clock and number of ticks per second in the **target\_config.h** file of the development board. Configure the task, memory, inter-process communication \(IPC\), and exception handling modules based on service requirements. When the system boots, the modules are initialized based on the configuration. The kernel startup process includes peripheral initialization, system clock configuration, kernel initialization, and OS boot. For details, see [Figure 2](#fig74259220441). -**Figure 2** Kernel startup process -![](figure/kernel-startup-process.png "kernel-startup-process") +**Figure 2** Kernel startup process +![](figures/kernel-startup-process.png "kernel-startup-process") diff --git a/en/device-dev/kernel/kernel-mini.md b/en/device-dev/kernel/kernel-mini.md index c1bba9a66c..a674d66e9f 100644 --- a/en/device-dev/kernel/kernel-mini.md +++ b/en/device-dev/kernel/kernel-mini.md @@ -4,9 +4,9 @@ - **[Basic Kernel](kernel-mini-basic.md)** -- **[Extension Components](kernel-mini-extend.md)** +- **[Extended Components](kernel-mini-extend.md)** -- **[Kernel Debugging](kernel-memory-inner.md)** +- **[Kernel Debugging](kernel-mini-debug.md)** - **[Appendix](kernel-mini-app.md)** diff --git a/en/device-dev/kernel/kernel-small-apx-bitwise.md b/en/device-dev/kernel/kernel-small-apx-bitwise.md index d7393cba5b..ffeae41515 100644 --- a/en/device-dev/kernel/kernel-small-apx-bitwise.md +++ b/en/device-dev/kernel/kernel-small-apx-bitwise.md @@ -1,8 +1,15 @@ # Bitwise Operation +- [Basic Concepts](#section1990715203418) +- [Available APIs](#section848334511411) +- [Development Example](#section67569495514) + - [Example Description](#section33551554391) + - [Verification](#section8931859194) + + ## 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 PSW \(PSW\), and each bit \(flag bit\) in the PSW can have a self-defined meaning. +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. ## Available APIs @@ -11,7 +18,7 @@ The system provides operations for setting the flag bit to **1** or **0**, ch **Table 1** Bitwise operation module APIs -

Category

+ @@ -72,7 +79,7 @@ This example implements the following: 1. Set a flag bit to **1**. 2. Obtain the most significant bit of flag bit 1. 3. Set a flag bit to **0**. -4. Obtains the least significant bit of the flag bit 1. +4. Obtain the least significant bit of the flag bit 1. ``` #include "los_bitmap.h" diff --git a/en/device-dev/kernel/kernel-small-apx-dll.md b/en/device-dev/kernel/kernel-small-apx-dll.md index c22f755c10..7862c000c8 100644 --- a/en/device-dev/kernel/kernel-small-apx-dll.md +++ b/en/device-dev/kernel/kernel-small-apx-dll.md @@ -1,5 +1,11 @@ # Doubly Linked List +- [Basic Concepts](#section1990715203418) +- [Available APIs](#section848334511411) +- [How to Develop](#section01781261552) + - [Development Example](#section8354175218128) + + ## Basic Concepts A doubly linked list is a linked data structure that consists of a set of sequentially linked records called nodes. Each node contains a pointer to the previous node and a pointer to the next node in the sequence of nodes. The pointer head is unique. A doubly linked list allows access from a list node to its next node and also the previous node on the list. This data structure facilitates data search, especially traversal of a large amount of data. The symmetry of the doubly linked list also makes operations, such as insertion and deletion, easy. However, pay attention to the pointer direction when performing operations. @@ -9,7 +15,7 @@ A doubly linked list is a linked data structure that consists of a set of sequen The following table describes APIs available for the doubly linked list. For more details about the APIs, see the API reference. -

Function

API

Category

+ @@ -88,7 +94,7 @@ The following table describes APIs available for the doubly linked list. For mor -

Function

API

LOS_DL_LIST_IS_ON_QUEUE

Check whether the linked list node is in a doubly linked list.

+

Checks whether the linked list node is in a doubly linked list.

Obtaining structure information

@@ -163,14 +169,14 @@ The typical development process of the doubly linked list is as follows: ### Development Example -Example Description +**Example Description** This example implements the following: 1. Initialize a doubly linked list. 2. Add nodes. -3. Delete a node. -4. Check whether the operation is performed successfully. +3. Delete nodes. +4. Check the operation result. ``` #include "stdio.h" diff --git a/en/device-dev/kernel/kernel-small-apx-library.md b/en/device-dev/kernel/kernel-small-apx-library.md index 88ccd1b987..ffba0b91f7 100644 --- a/en/device-dev/kernel/kernel-small-apx-library.md +++ b/en/device-dev/kernel/kernel-small-apx-library.md @@ -1,15 +1,25 @@ # Standard Library +- [Standard Library API Framework](#section149319478561) +- [Development Example](#section20874620185915) +- [Differences from the Linux Standard Library](#section6555642165713) + - [Process](#section11299104511409) + - [Memory](#section175754484116) + - [File System](#section118191113134220) + - [Signal](#section195939264421) + - [Time](#section20825124304213) + + 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 **Figure 1** POSIX framework -![](figure/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. -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. +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 @@ -166,7 +176,7 @@ ERROROUT: } /* - * Sample code main function + * Main function */ int main(int argc, char *argv[]) { @@ -193,9 +203,9 @@ This section describes the key differences between the standard library carried ### Process -1. The OpenHarmony user-space processes support only static priorities, which range from 10 \(highest\) to 31 \(lowest\). -2. The OpenHarmony user-space threads support only static priorities, which range from 0 \(highest\) to 31 \(lowest\). -3. The OpenHarmony process scheduling support **SCHED\_RR** only, and thread scheduling support **SCHED\_RR** or **SCHED\_FIFO**. +1. 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**. ### Memory @@ -225,7 +235,7 @@ int main(int argc, char *argv[]) perror("mmap"); exit(EXIT_FAILURE); } - close(fd); /* OpenHarmony does not support closing fd immediately after the mapping is successful. */ + close(fd); /* OpenHarmony does not support close fd immediately after the mapping is successful. */ ... exit(EXIT_SUCCESS); } @@ -262,7 +272,7 @@ int main(int argc, char *argv[]) **User directory**: The user directory refers to the **/storage** directory. You can create, read, and write files in this directory, but cannot mount devices. -Except 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. +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 diff --git a/en/device-dev/kernel/kernel-small-basic-atomic.md b/en/device-dev/kernel/kernel-small-basic-atomic.md index 84335a2133..6ab30f5b86 100644 --- a/en/device-dev/kernel/kernel-small-basic-atomic.md +++ b/en/device-dev/kernel/kernel-small-basic-atomic.md @@ -1,10 +1,18 @@ # Atomic Operation +- [Basic Concepts](#section1792118384594) +- [Working Principles](#section1786635117596) +- [Development Guidelines](#section2911115308) + - [Available APIs](#section335914201010) + - [How to Develop](#section12207371304) + - [Development Example](#section8538651511) + + ## 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 same 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 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. -Although you can enable or disable interrupts to ensure that the multi-task execution results meet expectation, the system performance is affected. +Although you can enable or disable interrupts to ensure that the multi-task execution results meet expectations, 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. @@ -46,7 +54,7 @@ The following table describes the APIs available for the OpenHarmony LiteOS-A ke **Table 1** Atomic operation APIs -

Category

+ diff --git a/en/device-dev/kernel/kernel-small-basic-inner-reflect.md b/en/device-dev/kernel/kernel-small-basic-inner-reflect.md index 4d3e9b6f0c..e98b00d361 100644 --- a/en/device-dev/kernel/kernel-small-basic-inner-reflect.md +++ b/en/device-dev/kernel/kernel-small-basic-inner-reflect.md @@ -1,22 +1,29 @@ # Virtual-to-Physical Mapping +- [Basic Concepts](#section9108144913615) +- [Working Principles](#section12392621871) +- [Development Guidelines](#section10264102013713) + - [Available APIs](#section195320251578) + - [How to Develop](#section152774210712) + + ## Basic Concepts -The Memory Management Unit \(MMU\) is used to map the virtual addresses in the process space and the actual physical addresses and specify corresponding access permissions and cache attributes. When a program is executed, the CPU accesses the virtual memory, locates the corresponding physical memory based on the MMU page table entry, and executes the code or performs data read/write operations. The page tables of the MMU store the mappings between virtual and physical addresses and the access permission. A page table is created when each process is created. The page table contains page table entries \(PTEs\), and each PTE describes a mapping between a virtual address region and a physical address region. The MMU has a Translation Lookaside Buffer \(TLB\) to perform address translation. During address translation, the MMU first searches the TLB for the corresponding PTE. If a match is found, the address can be returned directly. The following figure illustrates how the CPU accesses the memory or peripherals. +The Memory Management Unit \(MMU\) is used to map the virtual addresses in the process space and the actual physical addresses and specify corresponding access permissions and cache attributes. When a program is executed, the CPU accesses the virtual memory, locates the corresponding physical memory based on the MMU page table entry, and executes the code or performs data read/write operations. The page tables of the MMU store the mappings between virtual and physical addresses and the access permission. A page table is created when each process is created. The page table contains page table entries \(PTEs\), and each PTE describes a mapping between a virtual address region and a physical address region. The MMU has a Translation Lookaside Buffer \(TLB\) for address translation. During address translation, the MMU first searches the TLB for the corresponding PTE. If a match is found, the address can be returned directly. The following figure illustrates how the CPU accesses the memory or peripherals. **Figure 1** CPU accessing the memory or peripheral -![](figure/cpu-accessing-the-memory-or-peripheral.png "cpu-accessing-the-memory-or-peripheral") +![](figures/cpu-accessing-the-memory-or-peripheral.png "cpu-accessing-the-memory-or-peripheral") ## Working Principles -Virtual-to-physical address mapping is a process of establishing page tables. The MMU has multiple levels of page tables. The LiteOS-A kernel uses the level-2 page tables to describe the process space. Each level-1 PTE descriptor occupies 4 bytes, which indicate a mapping record of 1 MiB memory space. The 1 GiB user space of the LiteOS-A kernel has 1024 level-1 PTEs. When a user process is created, a 4 KiB memory block is requested from the memory as the storage area of the level-1 page table. The level-2 page table dynamically request memory based on requirements of the process. +Virtual-to-physical address mapping is a process of establishing page tables. The MMU supports multi-level page tables. The LiteOS-A kernel uses the level-2 page tables to describe the process space. Each level-1 PTE descriptor occupies 4 bytes, which indicate a mapping record of 1 MiB memory space. The 1 GiB user space of the LiteOS-A kernel has 1024 level-1 PTEs. When a user process is created, a 4 KiB memory block is requested from the memory as the storage area of the level-1 page table. Memory is dynamically allocated for the level-2 page table based on requirements of the process. - When a user program is loaded and started, the code segment and data segment are mapped to the virtual memory space \(for details, see [Dynamic Loading and Linking](kernel-small-bundles-linking.md)\). At that time, no physical page is mapped. - When the program is executed, as shown by the bold arrow in the following figure, the CPU accesses the virtual address and checks for the corresponding physical memory in the MMU. If the virtual address does not have the corresponding physical address, a page missing fault is triggered. The kernel requests the physical memory, writes the virtual-physical address mapping and the related attributes to the page table, and caches the PTE in the TLB. Then, the CPU can directly access the actual physical memory. - If the PTE already exists in the TLB, the CPU can access the physical memory without accessing the page table stored in the memory. **Figure 2** CPU accessing the memory -![](figure/cpu-accessing-the-memory.png "cpu-accessing-the-memory") +![](figures/cpu-accessing-the-memory.png "cpu-accessing-the-memory") ## Development Guidelines @@ -25,7 +32,7 @@ Virtual-to-physical address mapping is a process of establishing page tables. Th **Table 1** APIs of the virtual-to-physical address mapping module -

Function

API

Category

+ @@ -77,5 +84,5 @@ To use virtual-to-physical address mapping APIs: 3. Call **LOS\_ArchMmuUnmap** to remove the mapping. >![](../public_sys-resources/icon-note.gif) **NOTE:** ->The preceding APIs can be used after the MMU initialization is complete and the page tables of the related process are created. The MMU initialization is complete during system startup. Page tables are created when the processes are created. You do not need to perform any operation. +>The preceding APIs can be used after the MMU initialization is complete and the page tables of the related process are created. The MMU initialization is complete during system startup, and page tables are created when the processes are created. You do not need to perform any operation. diff --git a/en/device-dev/kernel/kernel-small-basic-interrupt.md b/en/device-dev/kernel/kernel-small-basic-interrupt.md index 17bffb46fc..d7e0c6a695 100644 --- a/en/device-dev/kernel/kernel-small-basic-interrupt.md +++ b/en/device-dev/kernel/kernel-small-basic-interrupt.md @@ -1,24 +1,30 @@ # Interrupt and Exception Handling +- [Basic Concepts](#section439816296117) +- [Working Principles](#section2792838318) +- [Development Guidelines](#section15415165510110) + - [Available APIs](#section57441612024) + - [How to Develop](#section64332181221) + - [Development Example](#section204698276478) + - [Verification](#section1466144215476) + ## 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 to a high-priority condition requiring the interruption of the current 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\) 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 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. ## 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. By using 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. +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 interrupts the normal running process of the CPU to handle exceptions, such as, undefined instruction exception, 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. +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. 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 - - -![](figure/en-us_image_0000001173449871.png) +**Figure 1** Interrupt vector table +![](figures/interrupt-vector-table.png "interrupt-vector-table") ## Development Guidelines @@ -27,7 +33,7 @@ The following uses the ARMv7-a architecture as an example. The interrupt vector Exception handling is an internal mechanism and does not provide external APIs. The following table describes APIs available for the interrupt module. -

Function

API

Category

+ @@ -51,12 +57,12 @@ Exception handling is an internal mechanism and does not provide external APIs. - -

Function

API

LOS_IntUnLock

Enables all interrupts of the current processor.

+

Enables all interrupts of the current processor.

LOS_IntLock

Disables all interrupts for the current processor.

+

Disables all interrupts for the current processor.

LOS_IntRestore

@@ -113,7 +119,7 @@ static UINT32 Example_Interrupt(VOID) return LOS_NOK; } - /* Delay 50 ticks. When a hardware interrupt occurs, the HwiUsrIrq function will be called.*/ + /* Delay 50 ticks. When a hardware interrupt occurs, call the HwiUsrIrq function.*/ LOS_TaskDelay(50); /* Delete an interrupt./ diff --git a/en/device-dev/kernel/kernel-small-basic-memory-heap.md b/en/device-dev/kernel/kernel-small-basic-memory-heap.md index 3ef8088c85..cb1745a27b 100644 --- a/en/device-dev/kernel/kernel-small-basic-memory-heap.md +++ b/en/device-dev/kernel/kernel-small-basic-memory-heap.md @@ -1,27 +1,37 @@ # Heap Memory Management +- [Basic Concepts](#section449414395916) +- [Working Principles](#section465085575911) +- [Development Guidelines](#section577019272015) + - [When to Use](#section326917198583) + - [Available APIs](#section1032331584) + - [How to Develop](#section07271773592) + - [Development Example](#section84931234145913) + - [Verification](#section165233233917) + + ## Basic Concepts Memory management module, one of the core modules of the OS, manages the memory resources of the system. Memory management involves memory initialization, allocation, and release. The heap memory management of the OpenHarmony LiteOS-A provides functions such as memory initialization, allocation, and release. While the OS is running, the heap memory management module manages the memory usage of users and the OS by allocating and releasing memory. This helps achieve the optimal memory usage and usage efficiency and minimize memory fragments. ## Working Principles -Heap memory management allows memory blocks of any size to be allocated from a large contiguous memory \(memory pool or heap memory\) configured in the system based on user demands when memory resources are sufficient. The memory block can be released for further use when not required. Heap memory management is a type of dynamic memory management. Compared with static memory management, dynamic memory management allows memory allocation on demand but causes fragmentation of memory. The heap memory of the OpenHarmony LiteOS-A has optimized the memory space partitioning based on the Two-Level Segregate Fit \(TLSF\) algorithm to achieve higher performance and minimize fragmentation. [Figure 1](#fig14558185217397) shows the core algorithm of the heap memory management. +Heap memory management, a type of dynamic memory management, allows memory blocks of any size to be allocated from a large contiguous memory \(memory pool or heap memory\) configured in the system based on user demands when memory resources are sufficient. The memory block can be released for further use when not required. Compared with static memory management, dynamic memory management allows memory allocation on demand but causes fragmentation of memory. The heap memory of the OpenHarmony LiteOS-A has optimized the memory space partitioning based on the Two-Level Segregate Fit \(TLSF\) algorithm to achieve higher performance and minimize fragmentation. [Figure 1](#fig14558185217397) shows the core algorithm of the heap memory management. -**Figure 1** Heap memory core algorithm -![](figure/heap-memory-core-algorithm.png "heap-memory-core-algorithm") +**Figure 1** Dynamic memory algorithm for small systems +![](figures/dynamic-memory-algorithm-for-small-systems.png "dynamic-memory-algorithm-for-small-systems") Multiple free lists are used for management based on the size of the free memory block. The free memory blocks are divided into two parts: \[4, 127\] and \[27, 231\], as indicated by the size class in the above figure. -1. The memory in the range of \[4, 127\] \(lower part in the figure\) is equally divided into 31 parts. The size of the memory block corresponding to each part is a multiple of 4 bytes. Each part corresponds to a free list and a bit that indicates whether the free list is empty. The value **1** indicates that the free list is not empty. There are 31 bits corresponding to the 31 memory parts in the range of \[4, 127\]. -2. The memory greater than 127 bytes is managed in power of two increments. The size of each range is \[2^n, 2^\(n+1\) -1\], where n is an integer in \[7, 30\]. This range is divided into 24 parts, each of which is further divided into 8 second-level \(L2\) ranges, as shown in Size Class and Size SubClass in the upper part of the figure. Each L2 range corresponds to a free list and a bit that indicates whether the free list is empty. There are a total of 192 \(24 x 8\) L2 ranges, corresponding to 192 free lists and 192 bits. +1. The memory in the range of \[4, 127\] \(lower part in [Figure 1](#fig14558185217397)\) is equally divided into 31 parts. The size of the memory block corresponding to each part is a multiple of 4 bytes. Each part corresponds to a free list and a bit that indicates whether the free list is empty. The value **1** indicates that the free list is not empty. There are 31 bits corresponding to the 31 memory parts in the range of \[4, 127\]. +2. The memory greater than 127 bytes is managed in power of two increments. The size of each range is \[2^n, 2^\(n+1\) -1\], where n is an integer in \[7, 30\]. This range is divided into 24 parts, each of which is further divided into 8 second-level \(L2\) ranges, as shown in Size Class and Size SubClass in the upper part of [Figure 1](#fig14558185217397). Each L2 range corresponds to a free list and a bit that indicates whether the free list is empty. There are a total of 192 \(24 x 8\) L2 ranges, corresponding to 192 free lists and 192 bits. For example, insert 40-byte free memory to a free list. The 40-byte free memory corresponds to the 10th free list in the range of \[40, 43\], and the 10th bit indicates the use of the free list. The system inserts the 40-byte free memory to the 10th free list and determines whether to update the bitmap flag. When 40-byte memory is requested, the system obtains the free list corresponding to the memory block of the requested size based on the bitmap flag, and then obtains a free memory node from the free list. If the size of the allocated node is greater than the memory requested, the system splits the node and inserts the remaining node to the free list. If 580-byte free memory needs to be inserted to a free list, the 580-byte free memory corresponds to the 47th \(31 + 2 x 8\) free list in L2 range \[2^9, 2^9+2^6\], and the 47th bit indicates the use of the free list. The system inserts the 580-byte free memory to the 47th free list and determines whether to update the bitmap flag. When 580-byte memory is requested, the system obtains the free list corresponding to the memory block of the requested size based on the bitmap flag, and then obtains a free memory node from the free list. If the size of the allocated node is greater than the memory requested, the system splits the node and inserts the remaining node to the free list. If the corresponding free list is empty, the system checks for a free list meeting the requirements in a larger memory range. In actual application, the system can locate the free list that meets the requirements at a time. -The following figure shows the memory management structure. +[Figure 2](#fig5395115964114) shows the memory management structure. -**Figure 2** Dynamic memory management structure -![](figure/dynamic-memory-management-structure-20.png "dynamic-memory-management-structure-20") +**Figure 2** Dynamic memory management structure for system systems +![](figures/dynamic-memory-management-structure-for-system-systems.png "dynamic-memory-management-structure-for-system-systems") - Memory pool header @@ -36,7 +46,7 @@ The following figure shows the memory management structure. ### When to Use -Heap memory management is mainly used to dynamically allocate and manage memory ranges requested by users. Heap memory management is mainly used in scenarios where users need to use memory blocks of different sizes. You can obtain a memory block of a specified size by using a dynamic memory application function of the operating system. Once the memory is used up, the memory release function is used to release the occupied memory so that the memory can be reused. +Heap memory management is mainly used to dynamically allocate and manage memory ranges requested by users. Heap memory management is mainly used in scenarios where users need to use memory blocks of different sizes. You can obtain a memory block of a specified size by using a dynamic memory application function of the OS. Once the memory is used up, the memory release function is used to release the occupied memory so that the memory can be reused. ### Available APIs @@ -45,7 +55,7 @@ The following table describes APIs available for OpenHarmony LiteOS-A heap memor **Table 1** Heap memory management APIs -

Category

+ @@ -151,7 +161,7 @@ The typical development process of dynamic memory is as follows: ### Development Example -The example below implements the following: +This example implements the following: 1. Initialize a dynamic memory pool. 2. Allocate a memory block from the dynamic memory pool. diff --git a/en/device-dev/kernel/kernel-small-basic-memory-physical.md b/en/device-dev/kernel/kernel-small-basic-memory-physical.md index ca11ce794c..cb47d9ba64 100644 --- a/en/device-dev/kernel/kernel-small-basic-memory-physical.md +++ b/en/device-dev/kernel/kernel-small-basic-memory-physical.md @@ -1,15 +1,24 @@ # Physical Memory Management +- [Basic Concepts](#section210891719217) +- [Working Principles](#section111355315213) +- [Development Guidelines](#section393116496217) + - [Available APIs](#section13210155619214) + - [How to Develop](#section178441091231) + - [Development Example](#section1258174015319) + - [Verification](#section515091342819) + + ## Basic Concepts -Physical memory is one of the most important resources on a computer. It is the memory space that is provided by the physical memory devices and can be directly addressed through the CPU bus. The physical memory provides temporary storage space for the OS and programs. The LiteOS-A kernel manages the physical memory by memory paging. Except the memory occupied by the kernel heap, other available memory is divided into page frames in the unit of 4 KiB. Memory is allocated and reclaimed by page frame. The kernel uses the buddy algorithm to manage free pages to reduce the fragmentation rate and improve the memory allocation and release efficiency. However, a small block may block the merge of a large block, causing a failure in allocating a large memory block. +Physical memory is one of the most important resources on a computer. It is the memory space that is provided by the physical memory devices and can be directly addressed through the CPU bus. The physical memory provides temporary storage space for the OS and programs. The LiteOS-A kernel manages the physical memory via memory paging. Except the memory occupied by the kernel heap, other available memory is divided into page frames in the unit of 4 KiB. Memory is allocated and reclaimed by page frame. The kernel uses the buddy algorithm to manage free pages to reduce the fragmentation rate and improve the memory allocation and release efficiency. However, a small block may block the merge of a large block, causing a failure to allocate a large memory block. ## Working Principles As shown in the following figure, the physical memory distribution of the LiteOS-A kernel consists of the kernel image, kernel heap, and physical pages. For details about the kernel heap, see "Heap Memory Management." **Figure 1** Physical memory usage distribution -![](figure/physical-memory-usage-distribution.png "physical-memory-usage-distribution") +![](figures/physical-memory-usage-distribution.png "physical-memory-usage-distribution") The buddy algorithm divides all free page frames into 9 memory block groups, each of which contains 2N page frames. For example, the memory block in group 0 has 20, that is, 1 page frame. The memory block in the eighth group has 28, that is, 256 page frames. Memory blocks of the same size are added to the same linked list for management. @@ -18,7 +27,7 @@ The buddy algorithm divides all free page frames into 9 memory block groups, eac When 12 KiB memory \(3 page frames\) is requested, the list in group 3 \(with 8 page frames\) meets the requirement. After 12 KiB memory is allocated, 20 KiB memory \(5 page frames\) is left. The 5 page frames can be divided into 4 \(22\) page frames and 1 \(20\) page frame. The 4 page frames have no buddy in the list, and therefore are inserted into list 2. The 1 page frame has a buddy in list 0. If the addresses of the two \(20\) memory blocks are contiguous, the memory blocks are merged as 2 page frames \(21\) and inserted to list 2. If the addresses are not contiguous, the two \(20\) page frames are left in list 0. **Figure 2** Requesting memory - ![](figure/requesting-memory.png "requesting-memory") + ![](figures/requesting-memory.png "requesting-memory") - Releasing memory @@ -26,7 +35,7 @@ The buddy algorithm divides all free page frames into 9 memory block groups, eac When 12 KiB memory \(3 page frames\) is released, the 3 page frames can be divided into 2 \(21\) page frames and 1 \(20\) page frame. The 2 page frames can be merged with the memory in linked list 1 if their addresses are contiguous and inserted to list 2. The one page frame can be merged with the memory in linked list 0 if their addresses are contiguous and inserted to list 1. In this way, the memory is released based on the buddy mechanism. **Figure 3** Releasing memory - ![](figure/releasing-memory.png "releasing-memory") + ![](figures/releasing-memory.png "releasing-memory") ## Development Guidelines @@ -36,7 +45,7 @@ The buddy algorithm divides all free page frames into 9 memory block groups, eac **Table 1** Physical memory management module APIs -

Function

API

Category

+ @@ -95,7 +104,7 @@ The buddy algorithm divides all free page frames into 9 memory block groups, eac ### How to Develop -APIs need to be called to request memory. Heap management APIs are recommended for requesting small amount of memory. Physical memory management APIs are recommended for requesting 4 KiB or larger memory. +Use different APIs to request memory. Heap management APIs are recommended for requesting small amount of memory. Physical memory management APIs are recommended for requesting 4 KiB or larger memory. >![](../public_sys-resources/icon-note.gif) **NOTE:** >- APIs used for requesting physical memory can be used only after memory initialization is complete by calling **OsSysMemInit**. diff --git a/en/device-dev/kernel/kernel-small-basic-memory-virtual.md b/en/device-dev/kernel/kernel-small-basic-memory-virtual.md index ec3672be5b..f5fa060ecb 100644 --- a/en/device-dev/kernel/kernel-small-basic-memory-virtual.md +++ b/en/device-dev/kernel/kernel-small-basic-memory-virtual.md @@ -1,12 +1,19 @@ # Virtual Memory Management +- [Basic Concepts](#section650193717411) +- [Working Principles](#section072885512412) +- [Development Guidelines](#section20956116050) + - [Available APIs](#section166137221657) + - [How to Develop](#section8752103914513) + + ## Basic Concepts -Virtual memory management is a technology used by computer systems to manage memory. Each process has a continuous virtual address space. The size of the virtual address space is determined by the number of CPU bits. The maximum addressing space for a 32-bit hardware platform ranges from 0 GiB to 4 GiB. The 4 GiB space is divided into two parts: 3 GiB higher-address space for the LiteOS-A kernel and 1 GiB lower-address space for processes. The virtual address space of each process space is independent, and the code and data do not affect each other. +Virtual memory management is a technology used by computer systems to manage memory. Each process has a continuous virtual address space. The size of the virtual address space is determined by the number of CPU bits. The maximum addressing space for a 32-bit hardware platform ranges from 0 GiB to 4 GiB. The 4 GiB space is divided into two parts: 3 GiB higher-address space for the LiteOS-A kernel and 1 GiB lower-address space for user-mode processes. The virtual address space of each process space is independent, and the code and data do not affect each other. The system divides the virtual memory into memory blocks called virtual pages. The size of a virtual page is generally 4 KiB or 64 KiB. The virtual page of the LiteOS-A kernel is 4 KiB by default. You can configure memory management units \(MMUs\) as required. The minimum unit of the virtual memory management is a page. A virtual address region in the LiteOS-A kernel can contain one virtual page or multiple virtual pages with contiguous addresses. Similarly, the physical memory is also divided by page, and each memory block is called page frame. The virtual address space is divided as follows: 3 GiB \(**0x40000000** to **0xFFFFFFFF**\) for the kernel space and 1 GiB \(**0x01000000** to **0x3F000000**\) for the user space. The following tables describe the virtual address plan. You can view or configure virtual addresses in **los\_vm\_zone.h**. -**Table 1** Kernel-space addresses +**Table 1** Kernel-mode addresses

Function

API

Zone

@@ -41,7 +48,7 @@ The system divides the virtual memory into memory blocks called virtual pages. T
-**Table 2** User-space virtual addresses +**Table 2** User-mode virtual addresses - - - - @@ -85,22 +92,22 @@ The system divides the virtual memory into memory blocks called virtual pages. T ## Working Principles -In virtual memory management, the virtual address space is contiguous, but the mapped physical memory is not necessarily contiguous, as shown in the following figure. When an executable program is loaded and runs, the CPU accesses the code or data in the virtual address space in the following two cases: +In virtual memory management, the virtual address space is contiguous, but the mapped physical memory is not necessarily contiguous, as depicted in the following figure. When an executable program is loaded and runs, the CPU accesses the code or data in the virtual address space in the following two cases: - If the page \(for example, V0\) containing the virtual address accessed by the CPU is mapped to a physical page \(for example, P0\), the CPU locates the page table entry corresponding to the process \(for details, see [Virtual-to-Physical Mapping](kernel-small-basic-inner-reflect.md)"\), accesses the physical memory based on the physical address information in the page table entry, and returns the content. - If the page \(for example, V2\) containing the virtual address accessed by the CPU is not mapped to a physical page, the system triggers a page missing fault, requests a physical page, copies the corresponding information to the physical page, and updates the start address of the physical page to the page table entry. Then, the CPU can access specific code or data by executing the instruction for accessing the virtual memory again. **Figure 1** Mapping between the virtual and physical memory addresses -![](figure/mapping-between-the-virtual-and-physical-memory-addresses.png "mapping-between-the-virtual-and-physical-memory-addresses") +![](figures/mapping-between-the-virtual-and-physical-memory-addresses.png "mapping-between-the-virtual-and-physical-memory-addresses") ## Development Guidelines ### Available APIs -**Table 3** Virtual memory management module APIs +**Table 3** APIs of the virtual memory management module -

Zone

@@ -54,28 +61,28 @@ The system divides the virtual memory into memory blocks called virtual pages. T

Code segment

User-space code segment address range

+

User-mode code segment address range

Cache

Heap

User-space heap address range

+

User-mode heap address range

Cache

Stack

User-space stack address range

+

User-mode stack address range

Cache

Shared library

Address range for loading the user-space shared library, including the address range mapped by mmap.

+

Address range for loading the user-mode shared library, including the address range mapped by mmap.

Cache

Category

+ @@ -139,12 +146,12 @@ In virtual memory management, the virtual address space is contiguous, but the m - - - - - - - - - - - - - -

Function

API

LOS_RegionFind

Checks whether a virtual address region exists in the process space based on the start address.

+

Searches for and returns the virtual address region corresponding to the specified address in the process space.

LOS_RegionRangeFind

Checks whether a virtual address region exists in the process space based on the address region.

+

Searches for and returns the virtual address region corresponding to the specified address range in the process space.

LOS_IsRegionFileValid

@@ -174,7 +181,7 @@ In virtual memory management, the virtual address space is contiguous, but the m

LOS_IsRegionTypeFile

Checks whether it is a file memory mapping.

+

Checks whether the address region is a file memory mapping.

LOS_IsRegionPermUserReadOnly

@@ -194,7 +201,7 @@ In virtual memory management, the virtual address space is contiguous, but the m

LOS_IsRegionTypeDev

Checks whether it is device memory mapping.

+

Checks whether the address region is device memory mapping.

LOS_SetRegionTypeDev

@@ -204,7 +211,7 @@ In virtual memory management, the virtual address space is contiguous, but the m

LOS_IsRegionTypeAnon

Checks whether it is an anonymous mapping.

+

Checks whether the address region is an anonymous mapping.

LOS_SetRegionTypeAnon

@@ -260,29 +267,29 @@ In virtual memory management, the virtual address space is contiguous, but the m

LOS_KernelMalloc

Requests memory less than 16 KiB from the heap memory pool; otherwise, requests multiple contiguous physical memory pages.

+

Allocates memory from the heap memory pool if the requested memory is less than 16 KiB; allocates multiple contiguous physical pages for memory allocation if the requested memory is greater than 16 KiB.

LOS_KernelMallocAlign

Requests memory with alignment attributes according to the following rules: obtain memory less than 16 KiB from the heap memory pool; otherwise, request multiple contiguous physical memory pages.

+

Allocates memory with alignment attributes. The allocation rule is the same as that of the LOS_KernelMalloc API.

LOS_KernelFree

Releases kernel heap memory.

+

Releases the memory requested by LOS_KernelMalloc and LOS_KernelMallocAlign.

LOS_KernelRealloc

Reallocates the kernel memory space.

+

Reallocates the memory requested by LOS_KernelMalloc and LOS_KernelMallocAlign.

Others

+

Others

LOS_PaddrQuery

Obtains the physical IP address based on the virtual address.

+

Obtains the physical address based on the virtual address.

LOS_VmSpaceFree

@@ -300,11 +307,6 @@ In virtual memory management, the virtual address space is contiguous, but the m

Maps the physical address region with the specified length to a virtual address region. You need to request the physical address region before the operation.

LOS_UserSpaceVmAlloc

-

Requests an address region in the user process space based on information such as the address, size, and permission.

-
@@ -319,8 +321,8 @@ To use APIs related to virtual memory: - Call **LOS\_RegionFind** and **LOS\_RegionRangeFind** to check whether the corresponding address region exists. - Call **LOS\_RegionFree** to release a virtual address region. -3. Call **vmalloc** and memory requesting APIs to apply for memory in the kernel as required. +3. Call **vmalloc** and memory requesting APIs to apply for memory in the kernel as demanded. >![](../public_sys-resources/icon-note.gif) **NOTE:** ->The physical memory requested by using the memory requesting APIs must be contiguous. If the system cannot provide a large number of contiguous memory blocks, the request fails. Therefore, the memory requesting APIs are recommended for requesting small memory blocks. Non-contiguous physical memory can be obtained by using **vmalloc**. However, the memory is allocated in the unit of pages \(4096 bytes/page in the current system\). If you want memory that is an integer multiple of a page, you can use **vmalloc**. For example, you can use **vmalloc** to request memory for file reading in a file system, which demands a large cache. +>The physical memory requested by using the memory requesting APIs must be contiguous. If the system cannot provide a large number of contiguous memory blocks, the request fails. Therefore, the memory requesting APIs are recommended for requesting small memory blocks. **vmalloc** is recommended for requesting non-contiguous physical memory. However, the memory is allocated in the unit of pages \(4096 bytes/page in the current system\). If you want memory that is an integer multiple of a page, you can use **vmalloc**. For example, you can use **vmalloc** to request memory for file reading in a file system, which demands a large cache. diff --git a/en/device-dev/kernel/kernel-small-basic-process-process.md b/en/device-dev/kernel/kernel-small-basic-process-process.md index 3a413924de..bc06994143 100644 --- a/en/device-dev/kernel/kernel-small-basic-process-process.md +++ b/en/device-dev/kernel/kernel-small-basic-process-process.md @@ -1,37 +1,44 @@ # Process +- [Basic Concepts](#section89346055119) +- [Working Principles](#section174514474512) +- [Development Guidelines](#section159637182521) + - [Available APIs](#section1153124135212) + - [How to Develop](#section1533674618526) + + ## 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-space processes. The kernel space 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 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. -- The OpenHarmony process module allows multiple processes to run simultaneously, switch, and communicate, facilitating your management over service programs. -- The OpenHarmony processes use the preemption scheduling mechanism. The process with a higher priority is scheduled over the process with a lower priority. Time slice round-robin is used to schedule processes with the same priority. -- The OpenHarmony 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 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\). - 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-space process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other. -- The user-space root process **init** is created by the kernel. Other user-space processes are created by the **init** process via the **fork** call. +- 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. **Process States:** - Init: The process is being created. -- Ready: The process is in the Ready queue and waits for being scheduled by the CPU. +- Ready: The process is in the Ready queue and waits for scheduling by the CPU. - 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. - Zombies: The process stops running and waits for the parent process to reclaim its control block resources. -**Figure 1** Process state transition -![](figure/process-state-transition.png "process-state-transition") +**Figure 1** Process state transition +![](figures/process-state-transition.png "process-state-transition") **Process State Transition:** - Init→Ready: - When a process is created, the process enters the Init state to start initialization after obtaining the process control block. After the process is initialized, the process is inserted into the scheduling queue and therefore enters the Ready state. + 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. - Ready→Running: - 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. However, 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: @@ -50,7 +57,7 @@ A process is the minimum unit for system resource management. The process module 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. - 2. If a process has the **LOS\_SCHED\_RR** scheduling policy and shares the same priority with 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** 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: @@ -59,16 +66,14 @@ A process is the minimum unit for system resource management. The process module ## Working Principles -The OpenHarmony process module is used to isolate user-space processes and supports the following functions: creating and exiting user-space processes, reclaiming process resources, setting and obtaining scheduling parameters and process group IDs, and obtaining process IDs. - -A user-space process is created by forking a parent process. During forking, the virtual memory space of the parent process is cloned to the child process. When the child process is running, the content of the parent process is copied to the virtual memory space of the child process as required through the copy-on-write mechanism. - -A process is only a resource management unit, and the actual running is executed by threads in the process. When threads in different processes switch with each other, the process space is switched. +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. -**Figure 2** Process management +A user-mode process is created by forking a parent process. During forking, the virtual memory space of the parent process is cloned to the child process. When the child process is running, the content of the parent process is copied to the virtual memory space of the child process as required through the copy-on-write mechanism. +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/en-us_image_0000001127519136.png) +**Figure 2** Process management +![](figures/process-management.png "process-management") ## Development Guidelines @@ -77,7 +82,7 @@ A process is only a resource management unit, and the actual running is executed **Table 1** Process management module APIs -

Category

+ @@ -111,7 +116,7 @@ A process is only a resource management unit, and the actual running is executed -

Function

API

LOS_Wait

Waits for the specified child process to terminate and reclaims its resources.

+

Waits for the specified child process to terminate, and reclaims its resources.

Process group

@@ -162,10 +167,10 @@ A process is only a resource management unit, and the actual running is executed ### How to Develop -Kernel-space processes cannot be created. Therefore, kernel-space 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:** >- 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-space processes cannot be created. ->- The thread created by calling a user-space process in the kernel space is a KProcess, not a user-space process. +>- 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. diff --git a/en/device-dev/kernel/kernel-small-basic-process-scheduler.md b/en/device-dev/kernel/kernel-small-basic-process-scheduler.md index 72c5b2dcb8..32892cb91e 100644 --- a/en/device-dev/kernel/kernel-small-basic-process-scheduler.md +++ b/en/device-dev/kernel/kernel-small-basic-process-scheduler.md @@ -1,8 +1,15 @@ # Scheduler +- [Basic Concepts](#section123882355719) +- [Working Principles](#section143015396572) +- [Development Guidelines](#section10604192145816) + - [Available APIs](#section207985910582) + - [How to Develop](#section1015110331584) + + ## Basic Concepts -The OpenHarmony LiteOS-A kernel uses the preemptive scheduling mechanism for tasks. The task with a higher priority is scheduled over the task with a lower priority. Time slice round-robin is used to schedule tasks with the same priority. 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. @@ -14,24 +21,20 @@ Threads are the minimum scheduling units in the OpenHarmony. 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. -**Figure 1** Schematic diagram of scheduling priority bucket queues - - -![](figure/en-us_image_0000001127520662.png) +**Figure 1** 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. -**Figure 2** Scheduling process - - -![](figure/en-us_image_0000001176974089.png) +**Figure 2** Scheduling process +![](figures/scheduling-process.png "scheduling-process") ## Development Guidelines ### Available APIs -

Category

+ diff --git a/en/device-dev/kernel/kernel-small-basic-process-thread.md b/en/device-dev/kernel/kernel-small-basic-process-thread.md index 6f8776607d..9a2b06d76b 100644 --- a/en/device-dev/kernel/kernel-small-basic-process-thread.md +++ b/en/device-dev/kernel/kernel-small-basic-process-thread.md @@ -1,30 +1,39 @@ # Task +- [Basic Concepts](#section138411646175417) +- [Working Principles](#section1381918945512) +- [Development Guidelines](#section10649727135519) + - [Available APIs](#section78333315555) + - [How to Develop](#section16229657115514) + - [Development Example](#section2809723165612) + + ## 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. -A task represents a thread in the OpenHarmony kernel, and tasks in the processes of the same priority are scheduled and run in a unified manner. +In the OpenHarmony kernel, a task represents a thread. -Tasks in the OpenHarmony kernel use the preemptive scheduling mechanism, either round-robin \(RR\) scheduling or First In First Out \(FIFO\) scheduling. +Tasks in the processes of the same priority in the OpenHarmony kernel are scheduled and run in a unified manner. -Tasks in the OpenHarmony kernel are assigned 32 priorities, ranging from **0** \(highest\) to **31** \(lowest\). +The tasks in the kernel use the preemptive scheduling mechanism, either round-robin \(RR\) scheduling or First In First Out \(FIFO\) scheduling. -In the same process, a higher-priority process can preempt resources of a lower-priority process. The lower-priority process can be scheduled only after the higher-priority process is blocked or terminated. +Tasks are assigned 32 priorities, ranging from **0** \(highest\) to **31** \(lowest\). -**Task States:** +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. -- Init: The task is being created. +**Task Status Description** -- Ready: The task is in the Ready queue and waits for being scheduled by the CPU. +- Init: The task is being created. +- Ready: The task is in the Ready queue and waits for scheduling by the CPU. - 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\). -- Exit: The task stops running 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 -![](figure/task-state-transition.png "task-state-transition") +![](figures/task-state-transition.png "task-state-transition") -**Task State Transition:** +**Task State Transition** - Init→Ready: @@ -40,33 +49,33 @@ In the same process, a higher-priority process can preempt resources of a lower- - 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 changes 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: - A task may also be blocked \(suspended\) in the Ready state. The blocked task will change from the Ready state to the Blocked state and is deleted from the Ready queue. The task will not be scheduled until it is restored. + 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: - After a task with a higher priority is created or restored, tasks will be scheduled. The task with the highest priority in the Ready queue will change to the Running state. The originally running task will change from the Running state to the Ready state and be 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: - When a running task is terminated, its state changes from Running to Exit. If the task is set with a detach attribute \(**LOS\_TASK\_STATUS\_DETACHED**\), it will be directly destroyed after the running is complete. + 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 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 places the task entry function in the corresponding position so that the function will be executed when the task enters the Running state for the first time. +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. ## Development Guidelines ### Available APIs -

Function

API

Category

+ @@ -74,115 +83,125 @@ When a task is created, the system initializes the task stack and presets the co - - + + + - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -194,19 +213,18 @@ The typical task development process is as follows: 1. Call **LOS\_TaskCreate** to create a task. - Specify the execution entry function for the task. - - - Specify the task name. + - Specifies the task name. - Specify the task stack size. - Specify the priority of the task. - - Specify the task attribute, that is, whether to support the **LOS\_TASK\_STATUS\_DETACHED** attribute. + - 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. 2. Run the service code to implement task scheduling. -3. After the task execution is complete, the task resources are automatically reclaimed if the **LOS\_TASK\_STATUS\_DETACHED** attribute is set. If the **LOS\_TASK\_STATUS\_DETACHED** attribute is not set, call the **LOS\_TaskDelete** API to reclaim the task resources. +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:** ->- The kernel space has the highest permission and can operate tasks in any process. ->- The task created by calling a user-space process in the kernel space is a KProcess, not a user-space process. +>- 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 @@ -227,7 +245,7 @@ UINT32 ExampleTaskHi(VOID) PRINTK("Delay Task Failed.\n"); 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"); /* Suspend the task.*/ ret = LOS_TaskSuspend(g_taskHiID); @@ -273,7 +291,7 @@ UINT32 ExampleTaskCaseEntry(VOID) initParam.usTaskPrio = TSK_PRIOR_HI; initParam.pcName = "HIGH_NAME"; initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; - initParam.uwResved = LOS_TASK_STATUS_DETACHED; + 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.*/ ret = LOS_TaskCreate(&g_taskHiID, &initParam); @@ -290,7 +308,7 @@ UINT32 ExampleTaskCaseEntry(VOID) initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; 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 task with a lower priority. The task will not be executed immediately after being created, because task scheduling is locked.*/ ret = LOS_TaskCreate(&g_taskLoID, &initParam); if (ret!= LOS_OK) { LOS_TaskUnlock(); @@ -301,7 +319,12 @@ UINT32 ExampleTaskCaseEntry(VOID) /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed.*/ LOS_TaskUnlock(); - + ret = LOS_TaskJoin(g_taskHiID, NULL); + if (ret != LOS_OK) { + PRINTK("Join ExampleTaskHi Failed!\n"); + } else { + PRINTK("Join ExampleTaskHi Success!\n"); + } while(1){}; return LOS_OK; } @@ -319,5 +342,6 @@ TaskHi LOS_TaskDelay Done. TaskHi LOS_TaskSuspend Success. TaskHi LOS_TaskResume Success. TaskHi LOS_TaskDelete Success. +Join ExampleTaskHi Success! ``` diff --git a/en/device-dev/kernel/kernel-small-basic-process.md b/en/device-dev/kernel/kernel-small-basic-process.md index 5bd51676cf..86a31d5ac9 100644 --- a/en/device-dev/kernel/kernel-small-basic-process.md +++ b/en/device-dev/kernel/kernel-small-basic-process.md @@ -2,7 +2,7 @@ - **[Process](kernel-small-basic-process-process.md)** -- **[Thread](kernel-small-basic-process-thread.md)** +- **[Task](kernel-small-basic-process-thread.md)** - **[Scheduler](kernel-small-basic-process-scheduler.md)** diff --git a/en/device-dev/kernel/kernel-small-basic-softtimer.md b/en/device-dev/kernel/kernel-small-basic-softtimer.md index e07578d741..2616bbe0bb 100644 --- a/en/device-dev/kernel/kernel-small-basic-softtimer.md +++ b/en/device-dev/kernel/kernel-small-basic-softtimer.md @@ -1,8 +1,16 @@ # Software Timer +- [Basic Concepts](#section4118241563) +- [Working Principles](#section31079397569) +- [Development Guidelines](#section18576131520577) + - [Available APIs](#section3138019145719) + - [How to Develop](#section1344817403575) + - [Development Example](#section114416313585) + + ## 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 Huawei LiteOS 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. 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 supports the following functions: @@ -53,7 +61,7 @@ The following table describes APIs available for the OpenHarmony LiteOS-A softwa **Table 1** Software timer APIs -

Function

API

Task creation and deletion

+

Task creation and deletion

LOS_TaskCreateOnly

+

LOS_TaskCreateOnly

+

Creates a task and places the task in the Init state without scheduling.

+

LOS_TaskCreate

Creates a task and places the task in the Init state but not be scheduled.

+

Creates a task and places it in the Init state for scheduling.

LOS_TaskCreate

+

LOS_TaskDelete

Creates a task and places the task in the Init state and be scheduled.

+

Deletes the specified task.

LOS_TaskDelete

+

Task status control

Deletes the specified task.

+

LOS_TaskResume

+

Resumes a suspended task.

Task status control

+

LOS_TaskSuspend

+

Suspends the specified task.

LOS_TaskResume

+

LOS_TaskJoin

Resumes a suspended task.

+

Suspends this task till the specified task is complete and the task control block resources are reclaimed.

LOS_TaskSuspend

+

LOS_TaskDetach

Suspends the specified task.

+

Changes the task attribute from joinable to detach. After the task of the detach attribute is complete, the task control block resources will be automatically reclaimed.

LOS_TaskDelay

+

LOS_TaskDelay

Delays a task.

+

Delays a task.

LOS_TaskYield

+

LOS_TaskYield

Adjusts the scheduling sequence of tasks that call the task priority.

+

Adjusts the scheduling sequence of tasks that call the task priority.

Task scheduling control

+

Task scheduling control

LOS_TaskLock

+

LOS_TaskLock

Locks task scheduling.

+

Locks task scheduling.

LOS_TaskUnlock

+

LOS_TaskUnlock

Unlocks task scheduling.

+

Unlocks task scheduling.

Task priority control

+

Task priority control

LOS_CurTaskPriSet

+

LOS_CurTaskPriSet

Sets the priority for the current task.

+

Sets the priority for the current task.

LOS_TaskPriSet

+

LOS_TaskPriSet

Sets the priority of the specified task.

+

Sets the priority for a specified task.

LOS_TaskPriGet

+

LOS_TaskPriGet

Obtains the priority of the specified task.

+

Obtains the priority of a specified task.

Obtaining task information

+

Obtaining task information

LOS_CurTaskIDGet

+

LOS_CurTaskIDGet

Obtains the ID of the current task.

+

Obtains the ID of the current task.

LOS_TaskInfoGet

+

LOS_TaskInfoGet

Obtains information about the specific task.

+

Obtains information about the specified task.

Binding tasks to CPU cores

+

Binding tasks to CPU cores

LOS_TaskCpuAffiSet

+

LOS_TaskCpuAffiSet

Binds a specified task to a specified CPU. It is used only in multi-core scenarios.

+

Binds a specified task to the specified CPU. It is used only in multi-core scenarios.

LOS_TaskCpuAffiGet

+

LOS_TaskCpuAffiGet

Obtains the core binding information of a specified task. It is used only in multi-core scenarios.

+

Obtains the core binding information of the specified task. It is used only in multi-core scenarios.

Task scheduling parameter control

+

Task scheduling parameter control

LOS_GetTaskScheduler

+

LOS_GetTaskScheduler

Obtains the scheduling policy of the specified task.

+

Obtains the scheduling policy of the specified task.

LOS_SetTaskScheduler

+

LOS_SetTaskScheduler

Sets the scheduling parameters, including the priority and scheduling policy, for the specified task.

+

Sets the scheduling parameters, including the priority and scheduling policy, for the specified task.

Maximum number of tasks supported

+

Maximum number of tasks supported

LOS_GetSystemTaskMaximum

+

LOS_GetSystemTaskMaximum

Obtains the maximum number of tasks supported by the system.

+

Obtains the maximum number of tasks supported by the system.

Category

+ @@ -126,7 +134,7 @@ 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. +- The maximum length of the software timer queue \(**OS\_SWTMR\_HANDLE\_QUEUE\_SIZE**\) is configured. **Sample Code** @@ -165,7 +173,7 @@ void Timer_example(void) /* 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. */ LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); - + /* Create a periodic software timer and execute callback function 2 every 100 ticks. */ LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); PRINTK("create Timer1 success\n"); diff --git a/en/device-dev/kernel/kernel-small-basic-time.md b/en/device-dev/kernel/kernel-small-basic-time.md index 9ad0294a85..e6d49f7012 100644 --- a/en/device-dev/kernel/kernel-small-basic-time.md +++ b/en/device-dev/kernel/kernel-small-basic-time.md @@ -1,5 +1,12 @@ # Time Management +- [Basic Concepts](#section12903185785119) +- [Development Guidelines](#section430981720522) + - [Available APIs](#section1040142705214) + - [How to Develop](#section1381224710522) + - [Development Example](#section1344610245416) + + ## 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. @@ -29,7 +36,7 @@ The following table describes APIs available for the OpenHarmony LiteOS-A time m **Table 1** APIs of the time management module -

Function

API

Category

+ @@ -78,7 +85,7 @@ The following table describes APIs available for the OpenHarmony LiteOS-A time m Prerequisites: -- **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**, that is, the number of ticks per second in the system is configured. +- **LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND**, that is, the number of ticks per second in the system, is configured. - **OS\_SYS\_CLOCK**, that is, system clock \(in Hz\), is configured. **Sample Code** diff --git a/en/device-dev/kernel/kernel-small-basic-trans-event.md b/en/device-dev/kernel/kernel-small-basic-trans-event.md index 6515858ca6..33d824f7e8 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-event.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-event.md @@ -1,15 +1,30 @@ # Event +- [Basic Concepts](#section122115620816) +- [Working Principles](#section94611116593) + - [Event Control Block](#section1161415384467) + - [Working Principles](#section187761153144617) + +- [Development Guidelines](#section44744471891) + - [Available APIs](#section172373513919) + - [How to Develop](#section1118215161013) + +- [Development Example](#section5837165132911) + - [Example Description](#section128221510145718) + - [Sample Code](#section71507479577) + - [Verification](#section16570171645813) + + ## Basic Concepts An event is a mechanism for communication between tasks. It can be used to synchronize tasks. -In multi-task environment, synchronization is required between tasks. Events implement the following types of synchronization: +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. - Many-to-many synchronization: Multiple tasks wait for the triggering of multiple events. -The events provided by the OpenHarmony LiteOS-A event module have 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. - 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. @@ -27,8 +42,8 @@ The events provided by the OpenHarmony LiteOS-A event module have the following * Event control block data structure */ typedef struct tagEvent { - 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*/ + 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 */ } EVENT_CB_S, *PEVENT_CB_S; ``` @@ -43,15 +58,15 @@ typedef struct tagEvent { 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: - **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. -- **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. +- **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 event**: 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**: 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. **Destroying an event**: Destroy the specified event control block. -**Figure 1** Event working mechanism -![](figure/event-working-mechanism-21.png "event-working-mechanism-21") +**Figure 1** Event working mechanism for small systems +![](figures/event-working-mechanism-for-small-systems.png "event-working-mechanism-for-small-systems") ## Development Guidelines @@ -62,7 +77,7 @@ The following table describes APIs available for the OpenHarmony LiteOS-A event **Table 1** Event module APIs -

Function

API

Category

+ @@ -74,7 +89,7 @@ The following table describes APIs available for the OpenHarmony LiteOS-A event -

Function

API

LOS_EventInit

Initialize an event control block.

+

Initializes an event control block.

Reading/Writing events

@@ -128,15 +143,15 @@ The typical event development process is as follows: >- 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. -### Development Example +## 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. +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. 1. Create the **Example\_Event** task in the **Example\_TaskEntry** task with a higher priority than the **Example\_TaskEntry** task. -2. Run the **Example\_Event** task to read event **0x00000001**. Task switching occurs to execute the **Example\_TaskEntry** task. -3. Run the **Example\_TaskEntry** task to write event **0x00000001**. Task switching occurs to execute the **Example\_Event** task. +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. diff --git a/en/device-dev/kernel/kernel-small-basic-trans-mutex.md b/en/device-dev/kernel/kernel-small-basic-trans-mutex.md index fb52d778c7..1d9c5c1a14 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-mutex.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-mutex.md @@ -1,8 +1,16 @@ # Mutex +- [Basic Concepts](#section85865329185) +- [Working Principles](#section8547454201819) +- [Development Guidelines](#section2038861117194) + - [Available APIs](#section11168318131917) + - [How to Develop](#section4201191122116) + - [Development Example](#section10679328202117) + + ## Basic Concepts -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 can protect the shared resources via exclusive access. +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: @@ -12,7 +20,7 @@ A mutex has three attributes: protocol attribute, priority upper limit attribute - 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 copied 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, the 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 @@ -27,7 +35,7 @@ The type attribute of a mutex specifies whether to check for deadlocks and wheth - 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 cause 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 @@ -40,8 +48,8 @@ In a multi-task environment, multiple tasks may access the same shared resource. 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 -![](figure/mutex-working-mechanism-23.png "mutex-working-mechanism-23") +**Figure 1** Mutex working mechanism for small systems +![](figures/mutex-working-mechanism-for-small-systems.png "mutex-working-mechanism-for-small-systems") ## Development Guidelines @@ -50,7 +58,7 @@ When non-shared resources are accessed by a task, the mutex is locked. Other tas **Table 1** Mutex module APIs -

Category

+ @@ -79,7 +87,7 @@ When non-shared resources are accessed by a task, the mutex is locked. Other tas -

Function

API

LOS_MuxTrylock

Attempts to request the specified mutex without blocking.

+

Attempts to request the specified mutex in non-block mode.

LOS_MuxUnlock

diff --git a/en/device-dev/kernel/kernel-small-basic-trans-queue.md b/en/device-dev/kernel/kernel-small-basic-trans-queue.md index d7366c33aa..e62b6452be 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-queue.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-queue.md @@ -1,5 +1,20 @@ # Queue +- [Basic Concepts](#section81171363232) +- [Working Principles](#section1074515132316) + - [Queue Control Block](#section194431851201315) + - [Working Principles](#section89875741418) + +- [Development Guidelines](#section827981242419) + - [Available APIs](#section19327151642413) + - [How to Develop](#section1390154210243) + +- [Development Example](#section27132341285) + - [Example Description](#section197311443141017) + - [Sample Code](#section972214490107) + - [Verification](#section19287165416106) + + ## 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. @@ -10,7 +25,7 @@ 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: -- Messages are queued in first-in-first-out \(FIFO\) mode and can be read and written asynchronously. +- Messages are queued in FIFO mode and can be read and written asynchronously. - Both the read queue and write queue support the timeout mechanism. - 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. @@ -54,7 +69,7 @@ Each queue control block contains information about the queue status. - 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 -![](figure/reading-and-writing-data-in-a-queue.png "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. @@ -63,7 +78,7 @@ The preceding figure illustrates how to write data to the tail node only. Writin ### Available APIs -

Category

+ diff --git a/en/device-dev/kernel/kernel-small-basic-trans-rwlock.md b/en/device-dev/kernel/kernel-small-basic-trans-rwlock.md index c2d17c8e1a..389a713074 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-rwlock.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-rwlock.md @@ -1,8 +1,15 @@ # RW Lock +- [Basic Concepts](#section4692105214260) +- [Working Principles](#section1239111562720) +- [Development Guidelines](#section11643194275) + - [Available APIs](#section15335332122717) + - [How to Develop](#section14774114882714) + + ## Basic Concepts -Similar to a mutex, a read-write lock \(RW lock\) can be used to synchronize tasks in the same process. Different from a mutex, an RW lock allows concurrent access for read operations, while write operations require exclusive access. +Similar to a mutex, a read-write lock \(RW lock\) can be used to synchronize tasks in the same process. Different from a mutex, an RW lock allows concurrent access for read operations and exclusive access for write operations. An RW lock has three states: locked in read mode, locked in write mode, and unlocked. @@ -30,7 +37,7 @@ How does an RW lock implement lock in read mode and lock in write mode to contro **Table 1** Read/write lock module APIs -

Function

API

Category

+ @@ -107,7 +114,7 @@ If a lock in read mode is requested: If a lock in write mode is requested: -- If the lock is not held or if the task that holds the lock in read mode is the same as the task that requests the lock in write mode, the task acquires the lock in write mode immediately. +- If the lock is not held or if the task that holds the lock in read mode is the one that requests the lock in write mode, the task acquires the lock in write mode immediately. - If the lock already has a lock in read mode and the read task has a higher priority, the current task is suspended until the lock in read mode is released. 3. There are three types of locks in read mode and write mode: non-block mode, permanent block mode, and scheduled block mode. The difference lies in the task suspension time. diff --git a/en/device-dev/kernel/kernel-small-basic-trans-semaphore.md b/en/device-dev/kernel/kernel-small-basic-trans-semaphore.md index ee057e79c0..b701c8d2fb 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-semaphore.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-semaphore.md @@ -1,5 +1,16 @@ # Semaphore +- [Basic Concepts](#section1577111168131) +- [Working Principles](#section118423019134) +- [Development Guidelines](#section01419503131) + - [Available APIs](#section1232345431312) + - [How to Develop](#section154261711141419) + - [Development Example](#section658135571417) + - [Example Description](#section125244411653) + - [Sample Code](#section1742105514512) + - [Verification](#section11297301617) + + ## Basic Concepts Semaphore is a mechanism for implementing inter-task communication. It implements synchronization between tasks or exclusive access to shared resources. @@ -9,14 +20,14 @@ In the data structure of a semaphore, there is a value indicating the number of - **0**: The semaphore is unavailable. Tasks waiting for the semaphore may exist. - Positive number: The semaphore is available. -The semaphore for synchronization is different from the semaphore for mutex: +The semaphore for exclusive access is different from the semaphore for synchronization: -- Semaphore used for exclusive access: The initial semaphore counter value is not 0, indicating the number of shared resources available. The semaphore counter value must be acquired before a shared resource is used, and released after the resource is used. 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. In this way, task synchronization is implemented. +- 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 -Semaphore control block +**Semaphore Control Block** ``` /** @@ -31,7 +42,7 @@ typedef struct { } LosSemCB; ``` -Working Principles +**Working Principles** Semaphore allows only a specified number of tasks to access a shared resource at a time. When the number of tasks accessing the resource reaches the limit, other tasks will be blocked until the semaphore is released. @@ -45,11 +56,11 @@ Semaphore allows only a specified number of tasks to access a shared resource at - 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 adds 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, 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. - Semaphore release - When a semaphore is released, if there is no task waiting for it, the counter is increased by 1. Otherwise, the first task in the wait queue is woken up. + 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. - Semaphore deletion @@ -58,8 +69,8 @@ Semaphore allows only a specified number of tasks to access a shared resource at The following figure illustrates the semaphore working mechanism. -**Figure 1** Semaphore working mechanism -![](figure/semaphore-working-mechanism-22.png "semaphore-working-mechanism-22") +**Figure 1** Semaphore working mechanism for small systems +![](figures/semaphore-working-mechanism-for-small-systems.png "semaphore-working-mechanism-for-small-systems") ## Development Guidelines @@ -68,7 +79,7 @@ The following figure illustrates the semaphore working mechanism. **Table 1** Semaphore module APIs -

Function

API

Category

+ diff --git a/en/device-dev/kernel/kernel-small-basic-trans-user-mutex.md b/en/device-dev/kernel/kernel-small-basic-trans-user-mutex.md index 268b48749d..1d6064c08d 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-user-mutex.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-user-mutex.md @@ -1,30 +1,33 @@ # Futex +- [Basic Concepts](#section643519912920) +- [Working Principles](#section16834132502910) + ## Basic Concepts -Fast userspace mutex \(futex\) is a system call capability provided by the kernel. It is a user-space lock that combines basic components and user-space lock logic. It is a lock used by both user space and kernel space, for example, userspace mutex, barrier and cond synchronization lock, and RW lock. The user-space part implements lock logic, and the kernel-space part implements lock scheduling. +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-space thread requests a lock, the lock status is first checked in user space. If no lock contention occurs, the user-space 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-space 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 -When thread scheduling is required to resolve lock contention or lock release in user space, the futex system call is triggered to pass the user-space lock address to the kernel. The user-space 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-space 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-space locks and the input parameters in the futex system call. +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. **Figure 1** Futex design -![](figure/futex-design.jpg "futex-design") +![](figures/futex-design.jpg "futex-design") -As shown in 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-space 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. **Table 1** Futex module APIs -

Function

API

Category

+ @@ -57,5 +60,5 @@ The following table describes the APIs available for the futex module.

Function

API

>![](../public_sys-resources/icon-note.gif) **NOTE:** ->The futex system call and user-space logic form a user-space lock. Therefore, you are advised to use the locks via the user-space POSIX APIs. +>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. diff --git a/en/device-dev/kernel/kernel-small-basic-trans-user-signal.md b/en/device-dev/kernel/kernel-small-basic-trans-user-signal.md index 7af7fa7eb6..f559f6ea27 100644 --- a/en/device-dev/kernel/kernel-small-basic-trans-user-signal.md +++ b/en/device-dev/kernel/kernel-small-basic-trans-user-signal.md @@ -1,5 +1,8 @@ # Signal +- [Basic Concepts](#section172788254307) +- [Working Principles](#section1249693812301) + ## 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. @@ -8,10 +11,10 @@ Signal is a common inter-process asynchronous communication mechanism. It uses s The following table describes the APIs available for signal operations. -**Table 1** Signal operation process and APIs \(user-space APIs\) +**Table 1** Signal operation process and APIs \(user-mode APIs\) -

Category

+ @@ -54,14 +57,14 @@ The following table describes the APIs available for signal operations. -

Function

API

None

Triggered by a system call or an interrupt. Before the switching between the kernel space and user space, the specified function in user space is entered, and the corresponding callbacks are processed. After that, the original user-space program continues to run.

+

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.

>![](../public_sys-resources/icon-note.gif) **NOTE:** ->The signal mechanism enables communication between user-space programs. The user-space POSIX APIs listed in the above table are recommended. +>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. >``` >void *signal(int sig, void (*func)(int))(int); @@ -75,7 +78,7 @@ The following table describes the APIs available for signal operations. >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**, **COTINUE**, and **COREDUMP** defined in the POSIX standard. ->b. The SIGSTOP, SIGKILL, and SIGCONT signals cannot be shielded. +>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. diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-new.md b/en/device-dev/kernel/kernel-small-bundles-fs-new.md index 2f80522411..749d7441a8 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-new.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-new.md @@ -1,5 +1,10 @@ # File System Adaptation +- [Basic Concepts](#section19480121811422) +- [Adapting the Mount API](#section147051940104212) +- [Adapting the Lookup API](#section11930181394317) +- [Summary and Precautions](#section5617183014319) + ## Basic Concepts The purpose of interconnecting with the VFS layer is to implement API functions defined by the VFS layer. You can adapt some APIs based on the file system features and service requirements. Basically, file read and write must be supported. The minimum file system adaptation is as follows: @@ -24,7 +29,7 @@ FSMAP_ENTRY(yourfs_fsmap, "your fs name", g_yourFsMountOps, TRUE, TRUE); // Regi ``` >![](../public_sys-resources/icon-note.gif) **NOTE:** ->1. The **open** and **close** APIs are not necessarily implemented because they are used to operate files and are imperceptible to the underlying file system. You need to implement these APIs only when special operations need to be performed during the open and close operations on the file system. +>1. The **open** and **close** APIs are not necessarily implemented because they are used to operate files and are imperceptible to the underlying file system. You need to implement them only when special operations need to be performed during the open and close operations on the file system. >2. Basic file system knowledge is required for file system adaptation. You need to have a deep understanding of the principles and implementation of the target file system. This section does not include the file system basics in detail. If you have any questions during the adaptation process, refer to the code in the **kernel/liteos\_a/fs** directory. ## Adapting the Mount API @@ -49,7 +54,7 @@ The parameter **struct Vnode \*blkDriver** specifies the driver node, which ca The parameter **const void \*data** specifies the data passed by the **mount** command and can be processed according to the requirements of the file system. -The following uses JFFS2 as an example to describe how the adapt the **mount** API: +The following uses JFFS2 as an example to describe how to adapt the **mount** API: ``` int VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data) @@ -63,7 +68,7 @@ int VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data) LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER); - /* Obtain information required by the file system from the driver node, for example, the partition ID for the JFFS2. */ + /* Obtain information required by the file system from the driver node, for example, the partition ID for JFFS2. */ p = (mtd_partition *)((struct drv_data *)blkDriver->data)->priv; mtd = (struct MtdDev *)(p->mtd_info); @@ -127,7 +132,7 @@ Summary: ## Adapting the **Lookup** API -**Lookup** is used to search for files. The function prototype of **Lookup** is: +**Lookup** is used to search for files. The function prototype of **Lookup** is as follows: ``` int (*Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode); @@ -157,7 +162,7 @@ int VfsJffs2Lookup(struct Vnode *parentVnode, const char *path, int len, struct return -ENOENT; } - /* Check whether the located target has an existing vnode, which corresponds to VfsHashInsert mentioned earlier. */ + /* Check whether the located target has an existing Vnode, which corresponds to VfsHashInsert mentioned earlier. */ (void)VfsHashGet(parentVnode->originMount, node->i_ino, &newVnode, NULL, NULL); LOS_MuxUnlock(&g_jffs2FsLock); if (newVnode) { @@ -208,10 +213,10 @@ The general adaptation procedure is as follows: 2. Implement the API based on the private data. 3. Encapsulate the result in the format required by the Vnode or other APIs and return the result to the upper layer. -The core logic is how to use the private data to implement API functions. These APIs implement common functions of the file systems and are generally implemented before the files systems are ported. Therefore, the key is to determine the private data required by the file system and store the data in Vnode for later use. Generally, the private data is information that can uniquely locate a file on a storage medium. Most file systems have similar data structures, for example, the inode data structure in JFFS2. +The core logic is how to use the private data to implement API functions. These APIs implement common functions of the file systems and are generally implemented before the files systems are ported. Therefore, the key is to determine the private data required by the file system and store the data in the Vnode for later use. Generally, the private data is information that can uniquely locate a file on a storage medium. Most file systems have similar data structures, for example, the inode data structure in JFFS2. >![](../public_sys-resources/icon-caution.gif) **CAUTION:** ->1. When a file is accessed, the **Lookup** API of the file system is not necessrily called. The **Lookup** API is called only when the path cache is invalid. +>1. When a file is accessed, the **Lookup** API of the file system is not necessarily called. The **Lookup** API is called only when the PathCache is invalid. >2. Do not directly return the Vnode located by using **VfsHashGet** as the result. The information stored in the Vnode may be invalid. Update the fields and return it. >3. Vnodes are automatically released in the background based on memory usage. If data needs to be stored persistently, do not save it only in Vnodes. >4. The **Reclaim** API is automatically called when a Vnode is released. Release the resources used by the private data in this API. diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-support-fat.md b/en/device-dev/kernel/kernel-small-bundles-fs-support-fat.md index 42076a621f..fc4e7dc85a 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-support-fat.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-support-fat.md @@ -1,16 +1,22 @@ # FAT +- [Basic Concepts](#section621393911385) +- [Working Principles](#section10796155213381) +- [Development Guidelines](#section144094483919) + - [How to Develop](#section139086116394) + + ## 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. The FAT file system supports multiple formats, such as FAT12, FAT16, and FAT32. The numbers 12, 16, and 32 indicate the number of bytes of the FAT table entries, respectively, and also restrict the maximum file size in the system. The FAT file system supports multiple media, especially removable storage 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. +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, the number of the next cluster of the file, and 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, and also restrict the maximum file size in the system. 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. -The OpenHarmony kernel supports FAT12, FAT16, and FAT32 file systems. These file systems have a small amount of code, feature small code volume and resource usage, 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 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. ## Working Principles This document does not include the FAT design and physical layout. You can find a lot of reference on the Internet. -The OpenHarmony LiteOS-A kernel uses block cache \(Bcache\) to improve the FAT performance. When read and write operations are performed, Bcache caches the sectors close to the read and write sectors to reduce the number of I/Os and improve performance. The basic cache unit of Bcache is block. The size of each block is the same. By default, there are 28 blocks, and each block caches data of 64 sectors. When the Bcache dirty block rate \(number of dirty sectors/total number of sectors\) reaches the threshold, writeback is triggered. If the dirty block rate does not reach the threshold, cached data is not written back to disks. You can call **sync** and **fsync** to write data to disks if you want. Some FAT APIs \(such as **close** and **umount**\) may also trigger writeback operations. However, you are advised not to use these APIs to trigger writeback. +The OpenHarmony LiteOS-A kernel uses block cache \(Bcache\) to improve FAT performance. When read and write operations are performed, Bcache caches the sectors close to the read and write sectors to reduce the number of I/Os and improve performance. The basic cache unit of Bcache is block. The size of each block is the same. By default, there are 28 blocks, and each block caches data of 64 sectors. When the Bcache dirty block rate \(number of dirty sectors/total number of sectors\) reaches the threshold, writeback is triggered and cached data is written back to disks. You can manually call **sync** and **fsync** to write data to disks if you want. Some FAT APIs \(such as **close** and **umount**\) may also trigger writeback operations. However, you are advised not to use them to trigger writeback. ## Development Guidelines @@ -32,8 +38,8 @@ mount("/dev/mmcblk0p0", "/mnt", "vfat", 0, NULL); >- When multi-partition is enabled and there are multiple partitions, the device node **/dev/mmcblk0** \(primary device\) registered by card 0 and **/dev/mmcblk0p0** \(secondary device\) are the same device. In this case, you cannot perform operations on the primary device. >- Before removing an SD card, close the open files and directories and unmount the related nodes. Otherwise, SD card exceptions or memory leaks may occur. >- Before performing the **format** operation, unmount the mount point. ->- After the Bcache function takes effect, note the following: +>- After the Bcache feature takes effect, note the following: > - When **MS\_NOSYNC** is carried in the **mount** function, FAT does not proactively write the content in the cache back to the storage device. The FAT-related APIs **open**, **close**, **unlink**, **rename**, **mkdir**, **rmdir**, and **truncate** do not automatically perform the **sync** operation, which improves the operation speed. However, the upper layer must actively invoke the **sync** operation to synchronize data. Otherwise, data loss may occur. -> - Bcache provides scheduled write-back. After **LOSCFG\_FS\_FAT\_CACHE\_SYNC\_THREAD** is enabled in **menuconfig**, the OpenHarmony kernel creates a scheduled task to write the Bcache data back to disks. By default, the kernel checks the dirty block rate in the Bcache every 5 seconds. If the dirty block rate exceeds 80%, the **sync** operation will be performed to write all dirty data in the Bcache to disks. You can call **LOS\_SetSyncThreadPrio**, **LOS\_SetSyncThreadInterval**, and **LOS\_SetDirtyRatioThreshold** to set the task priority, flush interval, and dirty block rate threshold, respectively. +> - Bcache provides scheduled writeback. After **LOSCFG\_FS\_FAT\_CACHE\_SYNC\_THREAD** is enabled in **menuconfig**, the OpenHarmony kernel creates a scheduled task to write the Bcache data back to disks. By default, the kernel checks the dirty block rate in the Bcache every 5 seconds. If the dirty block rate exceeds 80%, the **sync** operation will be performed to write all dirty data in the Bcache to disks. You can call **LOS\_SetSyncThreadPrio**, **LOS\_SetSyncThreadInterval**, and **LOS\_SetDirtyRatioThreshold** to set the task priority, flush interval, and dirty block rate threshold, respectively. > - The cache has 28 blocks by default, and each block has 64 sectors. diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md b/en/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md index 8d4dc1fbf4..e266e552ca 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md @@ -1,16 +1,20 @@ # JFFS2 +- [Basic Concepts](#section11411110155919) +- [Working Principles](#section23911025195913) +- [Development Guidelines](#section179711119014) + ## Basic Concepts Journalling Flash File System Version 2 \(JFFS2\) is a log-structured file system designed for Memory Technology Devices \(MTDs\). -JFFS2 is used on the NOR flash memory of the OpenHarmony. JFFS2 is readable and writable, supports data compression, provides crash/power failure protection, and supports wear leveling. There are many differences between flash memory and disk media. Running a disk file system on a flash memory device will lead to performance and security problems. JFFS2 is a file system optimized for flash memory. +JFFS2 is used on the NOR flash memory of the OpenHarmony. JFFS2 is readable and writable, supports data compression, provides crash/power failure protection, and supports wear leveling. There are many differences between flash memory and disk media. Running a disk file system on a flash memory device will cause performance and security problems. JFFS2 is a file system optimized for flash memory. ## Working Principles This document does not include the physical layout of JFFS2 on storage devices and JFFS2 specifications. For details, see the [official JFFS2 specification document](https://sourceware.org/jffs2/). -The following describes several important mechanisms and features of JFFS2 that developers may concern. +The following describes several important mechanisms and features of JFFS2 that you may concern. 1. Mount mechanism and speed: According to the JFFS2 design, all files are divided into nodes of different sizes based on certain rules and stored on the flash memory device in sequence. In the mount process, all node information needs to be obtained and cached in the memory. Therefore, the mount speed is in linear proportion to the flash device capacity and the number of files. This is a native design issue of JFFS2. To increase the mount speed, you can select **Enable JFFS2 SUMMARY** during kernel compilation. If this option is selected, information required by the mount operation will be stored to the flash memory in advance. When the mount operation is performed, this information can be read and parsed quickly, ensuring relatively constant mount speed. However, this space-for-time practice consumes about 8% extra space. 2. Wear leveling: Due to the physical attributes of flash memory devices, read and write operations can be performed only on blocks of a specific size. To prevent certain blocks from being severely worn, wear leveling is used on written blocks in JFFS2 to ensure relatively balanced writes on all blocks. This prolongs the overall service life of the flash memory devices. @@ -81,7 +85,7 @@ This function has the following parameters: - **unsigned long mountflags** specifies the mount flag, which is **0** by default. - **const void \*data** specifies the data, which is **NULL** by default. -You can also run the **mount** command in **shell** to mount a JFFS2 partition. You do not need to specify the last two parameters. +You can also run the **mount** command in **shell** to mount a JFFS2 partition. In this case, you do not need to specify the last two parameters. Run the following command: diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md b/en/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md index 5a08916a7c..fc24e1bcb1 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md @@ -1,5 +1,9 @@ # NFS +- [Basic Concepts](#section195414101464) +- [Working Principles](#section165621321194618) +- [Development Guidelines](#section7454935184611) + ## Basic Concepts NFS allows you to share files across hosts and OSs over a network. You can treat NFS as a file system service, which is equivalent to folder sharing in the Windows OS to some extent. diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md b/en/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md index 63d58d6db4..75902b5ea9 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md @@ -1,8 +1,14 @@ # procfs +- [Basic Concepts](#section146801917174017) +- [Working Principles](#section479762916408) +- [Development Guidelines](#section1221174524014) + - [Development Example](#section52016575401) + + ## Basic Concepts -The proc filesystem \(procfs\) is a virtual file system that displays process or other system information in a file-like structure. It is more convenient to obtain system information in file operation mode compared with API calling mode. +The proc filesystem \(procfs\) is a virtual file system that displays process or other system information in a file-like structure. It is more convenient to obtain system information in file operation mode than API calling mode. ## Working Principles @@ -10,7 +16,7 @@ In the OpenHarmony kernel, procfs is automatically mounted to the **/proc** di ## Development Guidelines -To create a procfs file, you need to use **ProcMkdir** to create a directory and use **CreateProcEntry** to create a file. The development of the file node function is to hook the read and write functions to the file created by **CreateProcEntry**. When the procfs file is read or written, the hooked functions will be called to implement customized functions. +To create a procfs file, you need to use **ProcMkdir** to create a directory and use **CreateProcEntry** to create a file. The development of the file node function is to hook the read and write functions to the file created by **CreateProcEntry**. When the procfs file is read or written, the hooked functions will be called to implement custom functions. ### Development Example @@ -54,14 +60,14 @@ void HelloWorldInit(void) return; } - /*Create the world file. */ + /* Create the world file. */ struct ProcDirEntry *entry = CreateProcEntry("world", 0, dir); if (entry == NULL) { PRINT_ERR("create entry failed!\n"); return; } - /* Hook the customized read and write APIs to the file. */ + /* Hook the custom read and write APIs to the file. */ entry->procFileOps = &HELLO_WORLD_OPS; } ``` diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md b/en/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md index d6b263a303..854086afd3 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md @@ -1,8 +1,12 @@ # Ramfs +- [Basic Concepts](#section9507151014420) +- [Working Principles](#section1859711263447) +- [Development Guidelines](#section163554380448) + ## Basic Concepts -Ramfs is a RAM-based file system whose size can be dynamically adjusted. Ramfs does not have a backing store. Directory entries and page caches are allocated when files are written into ramfs. However, data is not written back to any other storage medium, and data is lost after a power outage. +Ramfs is a RAM-based file system whose size can be dynamically adjusted. Ramfs does not have a backing store. Directory entries and page caches are allocated when files are written into ramfs. However, data is not written back to any other storage medium. This means that data will be lost after a power outage. ## Working Principles @@ -42,7 +46,7 @@ Delete a file: unlink(pathname) ``` -Deletes a directory: +Delete a directory: ``` rmdir(pathname) diff --git a/en/device-dev/kernel/kernel-small-bundles-fs-virtual.md b/en/device-dev/kernel/kernel-small-bundles-fs-virtual.md index 126599e338..a98ff3cd6c 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs-virtual.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs-virtual.md @@ -1,5 +1,13 @@ # Virtual File System +- [Basic Concepts](#section1253851143520) +- [Working Principles](#section14915913123510) +- [Development Guidelines](#section1759563620358) + - [Available APIs](#section17865142133511) + - [How to Develop](#section64113023616) + - [Development Example](#section236041883618) + + ## Basic Concepts 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 file operation interface. Different types of file systems provide different interfaces. If there are multiple types of file systems in the system, different and non-standard interfaces are required for accessing these file systems. The VFS can be introduced as an abstract layer in the system to harmonize the differences between these heterogeneous file systems. In this way, the system does not need to care about the storage medium and file system type at the bottom layer when accessing a file system. @@ -17,23 +25,23 @@ The VFS layer uses function pointers to call different interfaces for different 2. Vnode: A Vnode is an abstract encapsulation of a specific file or directory at the VFS layer. It shields the differences between different file systems and implements unified resource management. Vnodes include the following types: - Mount point: used to mount a specific file system, for example, **/** and **/storage**. - - Device node: mapping to a device in the **/dev** directory, for example, **/dev/mmcblk0** + - Device node: mapping to a device in the **/dev** directory, for example, **/dev/mmcblk0**. - File/Directory node: corresponds to a file or directory in a file system, for example, **/bin/init**. - Vnodes are managed using the hash and least recently used \(LRU\) mechanisms. After a system is started, the Vnode cache is preferentially searched in the hash linked list for an access request for a file or directory. If the cache is not hit, the target file or directory is searched in the corresponding file system, and the corresponding Vnode is created and cached. When the number of cached Vnodes reaches the upper limit, the Vnodes that are not accessed for a long time will be deleted. The mount point Vnodes and device node Vnodes are not deleted. The default number of Vnodes in the system is 512. You can configure the value in **LOSCFG\_MAX\_VNODE\_SIZE**. Increasing the value can improve search performance but cause high memory usage. The following figure shows the process of creating a Vnode. + Vnodes are managed using the hash and least recently used \(LRU\) mechanisms. After a system is started, the Vnode cache is preferentially searched in the hash linked list for an access request for a file or directory. If the cache is not hit, the target file or directory is searched in the corresponding file system, and the corresponding Vnode is created and cached. When the number of cached Vnodes reaches the upper limit, the Vnodes that are not accessed for a long time will be deleted. The mount point Vnodes and device node Vnodes are not deleted. The default number of Vnodes in the system is 512. You can configure the number in **LOSCFG\_MAX\_VNODE\_SIZE**. Increasing the value can improve search performance but causes high memory usage. The following figure shows the process of creating a Vnode. **Figure 1** Process of creating a Vnode - ![](figure/process-of-creating-a-vnode.png "process-of-creating-a-vnode") + ![](figures/process-of-creating-a-vnode.png "process-of-creating-a-vnode") 1. PathCache: The PathCache is a path cache. It is stored in a hash table. Based on the address of the parent Vnode and the file name of the child node in the PathCache, the Vnode corresponding to the child node can be quickly found. The following figure shows how a file or directory is located. **Figure 2** Process of locating a file - ![](figure/process-of-locating-a-file.png "process-of-locating-a-file") + ![](figures/process-of-locating-a-file.png "process-of-locating-a-file") -1. PageCache: The PageCache is a cache of files in the kernel. Currently, the PageCache can cache only binary files. When a file is accessed for the first time, the file is mapped to the memory using **mmap**. When the file is accessed the next time, the file can be directly read from the PageCache, accelerating the read and write speed of the file. In addition, page cache helps implement IPC based on files. -2. FD management: A FD uniquely identifies an open file or directory in an OS. The OpenHarmony has 896 FDs, which include the following: +1. PageCache: The PageCache is a cache of files in the kernel. Currently, the PageCache can cache only binary files. When a file is accessed for the first time, the file is mapped to the memory using **mmap**. When the file is accessed the next time, the file can be directly read from the PageCache. This accelerates the file read and write speed. In addition, PageCache helps implement IPC based on files. +2. FD management: An FD uniquely identifies an open file or directory in an OS. The OpenHarmony has 896 FDs in the following categories: - 512 file descriptors - 128 socket descriptors @@ -47,12 +55,12 @@ The VFS layer uses function pointers to call different interfaces for different ### Available APIs -In the following table, "×" indicates that the corresponding file system does not support the API. +In the following table, "√" indicates that the corresponding file system supports the API, and "×" indicates that the corresponding file system does not support the API. **Table 1** File system APIs -

Category

+ @@ -224,7 +232,7 @@ In the following table, "×" indicates that the corresponding file system does n - diff --git a/en/device-dev/kernel/kernel-small-bundles-fs.md b/en/device-dev/kernel/kernel-small-bundles-fs.md index f052b6075d..5ad3391eef 100644 --- a/en/device-dev/kernel/kernel-small-bundles-fs.md +++ b/en/device-dev/kernel/kernel-small-bundles-fs.md @@ -2,10 +2,10 @@ A file system \(often abbreviated to FS\) provides an input and output manner for an OS. It implements the interaction with internal and external storage devices. -The file system provides standard POSIX operation APIs for the upper-layer system through the C library. For details, see the API reference of the C library. The VFS virtual layer in kernel space shields the differences between file systems. The basic architecture is as follows: +The file system provides standard POSIX operation APIs for the upper-layer system through the C library. For details, see the API reference of the C library. The Virtual File System \(VFS\) layer in kernel mode shields the differences between file systems. The basic architecture is as follows: **Figure 1** Overall file system architecture -![](figure/overall-file-system-architecture.png "overall-file-system-architecture") +![](figures/overall-file-system-architecture.png "overall-file-system-architecture") - **[Virtual File System](kernel-small-bundles-fs-virtual.md)** diff --git a/en/device-dev/kernel/kernel-small-bundles-ipc.md b/en/device-dev/kernel/kernel-small-bundles-ipc.md index 1a3c66aa9d..1d906c36d8 100644 --- a/en/device-dev/kernel/kernel-small-bundles-ipc.md +++ b/en/device-dev/kernel/kernel-small-bundles-ipc.md @@ -1,14 +1,20 @@ # LiteIPC +- [Basic Concepts](#section1980994712918) +- [Working Principles](#section849811592918) +- [Development Guidelines](#section17571315171017) + - [Available APIs](#section725022011103) + + ## 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\). +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 -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 space. The message queue provides the upper-layer user-space programs with the read operation \(receiving IPC messages\) and the write operations \(sending IPC messages\) through LiteIPC device files. +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 @@ -17,7 +23,7 @@ ServiceManager registers the task that needs to receive IPC messages as a Servic **Table 1** LiteIPC module APIs \(for LiteOS-A internal use only\) -

Function

API

symlink

Creates a soft link.

+

Creates a soft link (also called symbolic link).

Category

+ diff --git a/en/device-dev/kernel/kernel-small-bundles-linking.md b/en/device-dev/kernel/kernel-small-bundles-linking.md index 6e8c8df34f..1d7956e2af 100644 --- a/en/device-dev/kernel/kernel-small-bundles-linking.md +++ b/en/device-dev/kernel/kernel-small-bundles-linking.md @@ -1,69 +1,60 @@ # Dynamic Loading and Linking +- [Basic Concepts](#section208951139453) +- [Working Principles](#section14140155320511) +- [Development Guidelines](#section133501496612) + - [Available APIs](#section874113201669) + - [How to Develop](#section196712561563) + + ## 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. **Advantages of Dynamic Linking** -1. Dynamic linking allows multiple applications to share code. The minimum loading unit is page. It saves disk and memory space than static 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. 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. ## Working Principles **Figure 1** Dynamic loading process -![](figure/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\). 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. **Figure 2** Program execution process -![](figure/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. -2. The kernel calls **map\_pages** to search for and map the existing page cache. -3. If the memory does not have the required code or data when the program is executed, a page missing interrupt is triggered to read the content of the ELF file into the memory and add the memory block to the page cache. -4. Map the memory blocks of the file read to the virtual address region. +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. +4. Map the physical memory blocks of the file read to the virtual address region. 5. The program continues to run. -The program is executed with continuous page missing interrupts. - ## Development Guidelines ### Available APIs -LOS\_DoExecveFile - -**Function prototype:** - -INT32 LOS\_DoExecveFile\(const CHAR \*fileName, CHAR \* const \*argv, CHAR \* const \*envp\); - -**Function**: Executes a new user program based on **fileName**. - -**Parameter Description** +**Table 1** APIs of the kernel loader module - -

Function

API

Parameter

+ + - + - - - - - - - - @@ -71,5 +62,5 @@ INT32 LOS\_DoExecveFile\(const CHAR \*fileName, CHAR \* const \*argv, CHAR \* co ### How to Develop -The kernel cannot directly call the **LOS\_DoExecveFile** API to start a new process. This API is generally called through the **execve** API to create a new process using the system call mechanism. +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. diff --git a/en/device-dev/kernel/kernel-small-bundles-share.md b/en/device-dev/kernel/kernel-small-bundles-share.md index 4a9a4865c2..90410e8ab6 100644 --- a/en/device-dev/kernel/kernel-small-bundles-share.md +++ b/en/device-dev/kernel/kernel-small-bundles-share.md @@ -1,14 +1,17 @@ # Virtual Dynamic Shared Object +- [Basic Concepts](#section174577181688) +- [Working Principles](#section546363114810) + ## Basic Concepts -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 and provides them to the application program. That is why the VDSO is called a virtual dynamic shared library. +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. -The VDSO mechanism allows OpenHarmony user-space 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 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\). ## 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-space applications. By linking **vdso.so**, the applications can directly access this mapped memory instead of invoking system calls, accelerating application execution. +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: @@ -16,7 +19,7 @@ VDSO can be divided into: - Code page: provides the logic for shielding system calls. **Figure 1** VDSO system design -![](figure/vdso-system-design.jpg "vdso-system-design") +![](figures/vdso-system-design.jpg "vdso-system-design") The VDSO mechanism involves the following steps: diff --git a/en/device-dev/kernel/kernel-small-bundles-system.md b/en/device-dev/kernel/kernel-small-bundles-system.md index 8093033233..ddca52646a 100644 --- a/en/device-dev/kernel/kernel-small-bundles-system.md +++ b/en/device-dev/kernel/kernel-small-bundles-system.md @@ -1,21 +1,28 @@ # System Call +- [Basic Concepts](#section889710401734) +- [Working Principles](#section195177541314) +- [Development Guidelines](#section193492047135419) + - [How to Develop](#section7165741122210) + - [Development Example](#section107131418224) + + ## Basic Concepts -The OpenHarmony LiteOS-A isolates the user space and kernel space. User-space programs cannot directly access kernel resources. System calls provide a channel for user-space programs to access kernel resources and interact with the kernel. +The OpenHarmony LiteOS-A isolates the user space and kernel space. User-mode programs cannot directly access kernel resources. System calls provide a channel for user-mode programs to access kernel resources and interact with the kernel. ## Working Principles -As shown in the following figure, a user program calls the System API \(a POSIX interface provided by the system\) to access kernel resources and interacts with the kernel. An SVC/SWI exception is triggered inside the POSIX interface to complete switching of the system from the user space to the kernel space. Then, the kernel Syscall Handler \(unified system call interface\) parses parameters received and distributes the parameters to the specific kernel functions for processing. +As shown in the following figure, a user-space program calls the System API \(a POSIX interface provided by the system\) to access kernel resources and interacts with the kernel. An SVC/SWI exception is triggered inside the POSIX interface to complete switching of the system from the user mode to the kernel mode. Then, the kernel Syscall Handler \(unified system call interface\) parses parameters received and distributes the parameters to the specific kernel functions for processing. **Figure 1** System call -![](figure/system-call.png "system-call") +![](figures/system-call.png "system-call") The Syscall Handler is implemented by the **OsArmA32SyscallHandle** function in **kernel/liteos\_a/syscall/los\_syscall.c**. This function is called when a system software interrupt occurs. The input parameters of system calls are parsed according to the list in **kernel/liteos\_a/syscall/syscall\_lookup.h** so that the specific kernel functions are executed. >![](../public_sys-resources/icon-note.gif) **NOTE:** ->- System calls implement basic interaction between user-space programs and the kernel. You are advised to use the POSIX APIs provided by the kernel instead of system call APIs. If you want to add system call APIs, see the development guide. ->- For details about the system call APIs provided by the kernel for the user space, see **kernel/liteos\_a/syscall/syscall\_lookup.h**. For details about the system call functions provided by the kernel, see **kernel/liteos\_a/syscall/los\_syscall.h**. +>- System calls implement basic interaction between user-mode programs and the kernel. You are advised to use the POSIX APIs provided by the kernel instead of system call APIs. If you want to add system call APIs, see the development guide. +>- For details about the system call APIs provided by the kernel for the user mode, see **kernel/liteos\_a/syscall/syscall\_lookup.h**. For details about the system call functions provided by the kernel, see **kernel/liteos\_a/syscall/los\_syscall.h**. ## Development Guidelines @@ -24,7 +31,7 @@ The Syscall Handler is implemented by the **OsArmA32SyscallHandle** function i The typical development process of adding a system call API is as follows: 1. Determine and add the new system call number to the LibC library. -2. Add the declaration and implementation of the new user-space function API to the LibC library. +2. Add the declaration and implementation of the new user-mode function API to the LibC library. 3. Add the new system call number and the declaration of the corresponding kernel processing function to the kernel system call header file. 4. Add the kernel processing function corresponding to the system call to the kernel. @@ -63,13 +70,13 @@ The typical development process of adding a system call API is as follows: ... ``` -2. Add the declaration and implementation of the new user-space API to the LibC library. +2. Add the declaration and implementation of the new user-mode API to the LibC library. ``` #include "stdio_impl.h" #include "syscall.h" ... - /* Add the implementation of the new user-space system call API.*/ + /* Add the implementation of the new user-mode system call API.*/ void newSyscallSample(int num) { printf("user mode: num = %d\n", num); @@ -159,10 +166,10 @@ The typical development process of adding a system call API is as follows: **Verification** -The user-space program calls the **newSyscallSample\(10\)** API. The output is as follows: +The user-mode program calls the **newSyscallSample\(10\)** API. The output is as follows: ``` -/* The output in both user-space and kernel-space APIs indicates that the new system call is enabled. */ +/* The output in both user-mode and kernel-mode APIs indicates that the new system call is enabled. */ user mode: num = 10 kernel mode: num = 10 ``` diff --git a/en/device-dev/kernel/kernel-small-bundles.md b/en/device-dev/kernel/kernel-small-bundles.md index 1d1e7ad20e..755e2693bd 100644 --- a/en/device-dev/kernel/kernel-small-bundles.md +++ b/en/device-dev/kernel/kernel-small-bundles.md @@ -1,4 +1,4 @@ -# Extension Components +# Extended Components - **[System Call](kernel-small-bundles-system.md)** diff --git a/en/device-dev/kernel/kernel-small-debug-memory-corrupt.md b/en/device-dev/kernel/kernel-small-debug-memory-corrupt.md index ca9c332a51..32b0c74cf5 100644 --- a/en/device-dev/kernel/kernel-small-debug-memory-corrupt.md +++ b/en/device-dev/kernel/kernel-small-debug-memory-corrupt.md @@ -1,5 +1,12 @@ # Memory Corruption Check +- [Basic Concepts](#section17368154517335) +- [Function Configuration](#section4696190123420) +- [Development Guidelines](#section672362973417) + - [How to Develop](#section026014863416) + - [Development Example](#section186311302356) + + ## 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. @@ -21,7 +28,7 @@ This check only detects the corrupted memory node and provides information about ### How to Develop -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, 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 diff --git a/en/device-dev/kernel/kernel-small-debug-memory-info.md b/en/device-dev/kernel/kernel-small-debug-memory-info.md index 42b50c6b7c..d87652c782 100644 --- a/en/device-dev/kernel/kernel-small-debug-memory-info.md +++ b/en/device-dev/kernel/kernel-small-debug-memory-info.md @@ -1,5 +1,12 @@ # Memory Information Statistics +- [Basic Concepts](#section52691565235) +- [Function Configuration](#section470611682411) +- [Development Guidelines](#section9368374243) + - [How to Develop](#section679912407257) + - [Development Example](#section1025453412611) + + ## 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. diff --git a/en/device-dev/kernel/kernel-small-debug-memory-leak.md b/en/device-dev/kernel/kernel-small-debug-memory-leak.md index 91daa09ebc..4934e5eab7 100644 --- a/en/device-dev/kernel/kernel-small-debug-memory-leak.md +++ b/en/device-dev/kernel/kernel-small-debug-memory-leak.md @@ -1,8 +1,15 @@ # Memory Leak Check +- [Basic Concepts](#section1026719436293) +- [Function Configuration](#section13991354162914) +- [Development Guidelines](#section95828159308) + - [How to Develop](#section369844416304) + - [Development Example](#section460801313313) + + ## 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 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 @@ -22,7 +29,14 @@ Correctly setting this macro can ignore invalid LRs and reduce memory consumptio 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. -The node information output by calling **LOS\_MemUsedNodeShow** is in the following format: 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 node information output by calling **LOS\_MemUsedNodeShow** is in the following format: + +- 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. ``` node size LR[0] LR[1] LR[2] @@ -41,9 +55,9 @@ node size LR[0] LR[1] LR[2] This example implements the following: -1. Calls **OsMemUsedNodeShow** to print information about all nodes. -2. Simulates a memory leak by requesting memory without releasing it. -3. Calls **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. +3. Call **OsMemUsedNodeShow** to print information about all nodes. 4. Compare the logs to obtain information about the node where a memory leak occurred. 5. Locate the code based on the LR address. diff --git a/en/device-dev/kernel/kernel-small-debug-memory.md b/en/device-dev/kernel/kernel-small-debug-memory.md index ad6093e6fa..cc8bc8d2c5 100644 --- a/en/device-dev/kernel/kernel-small-debug-memory.md +++ b/en/device-dev/kernel/kernel-small-debug-memory.md @@ -1,4 +1,4 @@ -# Memory Debugging +# Kernel-Mode Memory Debugging - **[Memory Information Statistics](kernel-small-debug-memory-info.md)** diff --git a/en/device-dev/kernel/kernel-small-debug-process-cpu.md b/en/device-dev/kernel/kernel-small-debug-process-cpu.md index 9409a744de..54507fed19 100644 --- a/en/device-dev/kernel/kernel-small-debug-process-cpu.md +++ b/en/device-dev/kernel/kernel-small-debug-process-cpu.md @@ -1,12 +1,20 @@ # CPUP +- [Basic Concepts](#section17683419227) +- [Working Principles](#section593718536227) +- [Development Guidelines](#section11284210152311) + - [Available APIs](#section3745151592312) + - [How to Develop](#section122901429182316) + - [Development Example](#section1765785212310) + + ## 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 the CPU usage of each task/process/interrupt 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 - 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 a 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 @@ -14,25 +22,25 @@ The central processing unit percent \(CPUP\) includes the system CPUP, process C - 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 a 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 - Task 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 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 provides the following types of CPUP information: +OpenHarmony provides the following types of CPUP information: - System CPUP - Process CPUP - Task CPUP - Interrupt CPUP -You can calculate the CPUP 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 @@ -49,7 +57,7 @@ Interrupt CPUP = Total running time of the interrupt/Total running time of the s **Table 1** CPUP module APIs -

Function

Description

+

API

+

Description

fileName

-

Name of a binary executable file. It can be a path name.

-

argv

-

Parameters, ended with NULL, required for program execution. If no parameter is required, set this parameter to NULL.

+

Module initialization

envp

+

LOS_DoExecveFile

New environment variables, ended with NULL, required for program execution. If no new environment variable is required, set this parameter to NULL.

+

Executes the specified user program based on the input parameters.

Category

+ @@ -103,7 +111,7 @@ The typical CPUP development process is as follows. - If the process is not created, return an error code. 3. Call **LOS\_GetAllProcessCpuUsage** to obtain the CPUP of all processes. - - If the CPUP is 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 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. @@ -111,8 +119,8 @@ The typical CPUP development process is as follows. - If the task is not created, return an error code. 5. Call **LOS\_GetAllIrqCpuUsage** to obtain the CPUP of all interrupts. - - 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 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. ### Development Example @@ -123,11 +131,11 @@ This example implements the following: 2. Obtain the CPUP of the current system. 3. Obtain the historical system CPUP in different modes. 4. Obtain the CPUP of the created test task. -5. Obtains the CPUP of the created test task in different modes. +5. Obtain the CPUP of the created test task in different modes. Prerequisites -Enable the cpup control switch in the **menuconfig** configuration. +The CPUP control is enabled in the **menuconfig** configuration. **Sample Code** diff --git a/en/device-dev/kernel/kernel-small-debug-shell-build.md b/en/device-dev/kernel/kernel-small-debug-shell-build.md index 2fc4049ea4..c6758e46cf 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-build.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-build.md @@ -1,8 +1,14 @@ # Shell Command Programming Example +- [Example Description](#section87143612316) +- [Static Registration](#section1660495712314) +- [Static Registration Programming Example](#section1233411684113) +- [Dynamic Registration](#section6804126192412) +- [Dynamic Registration Programming Example](#section2335121613418) + ## Example Description -This section describes how to add a shell command **test** using static registration and dynamic registration, respectively. +This section describes how to add a shell command **test** using static registration and dynamic registration. ## Static Registration diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md index d225ad7dcd..bb52c6ead0 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md @@ -1,5 +1,12 @@ # cpup +- [Command Function](#section1842161614217) +- [Syntax](#section5629527427) +- [Parameters](#section133651361023) +- [Usage](#section156611948521) +- [Example](#section68501605319) +- [Output](#section19871522144219) + ## Command Function This command is used to query the CPU usage \(CPU percent\) of the system. @@ -23,14 +30,14 @@ cpup \[_mode_\] \[_taskID_\] - - @@ -40,9 +47,9 @@ cpup \[_mode_\] \[_taskID_\] ## Usage -- If the parameters are not specified, the CPU usage within the last 10 seconds is displayed. -- If only the **mode** parameter is specified, the CPU usage within the specified period is displayed. -- If both the **mode** and **taskID** parameters are specified, the CPU usage of the specified task within the given period 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 both **mode** and **taskID** are specified, the CPU usage of the specified task within the given period is displayed. ## Example @@ -50,6 +57,11 @@ Run **cpup 1 5**. ## Output -**Figure 1** CPU usage -![](figure/cpu-usage.png "cpu-usage") +CPU usage of task 5 in the last one second: + +``` +OHOS # cpup 1 5pid 5 + +CpuUsage in 1s: 0.0 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-date.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-date.md index e39a88797d..247af2bf57 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-date.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-date.md @@ -1,22 +1,22 @@ # date +- [Command Function](#section56472016338) +- [Syntax](#section16635112512316) +- [Parameters](#section15896030039) +- [Usage](#section116361036636) +- [Example](#section021711411237) +- [Output](#section17950184414312) + ## Command Function -This command is used to query and set the system date and time. +This command is used to query the system date and time. ## Syntax -date - -date --help - -date +\[_Format_\] - -date -s_ _\[_YY/MM/DD_\] - -date_ _-s_ _\[_hh:mm:ss_\]__ - -date -r \[_Filename_\] +- date +- date --help +- date +\[_Format_\] +- date -u ## Parameters @@ -31,39 +31,25 @@ date -r \[_Filename_\] - - - - - - - - - - - - - - - - - @@ -71,17 +57,20 @@ date -r \[_Filename_\] ## Usage -- If the **date** parameter is not specified, the current system date and time are displayed by default. -- The **--help**, **+Format**, **-s**, and **-r** parameters are mutually exclusive. +- If no parameter is specified, the system UTC date and time are displayed by default. +- The **--help**, **+Format**, and **-u** parameters are mutually exclusive. +- Currently, this command cannot be used to set the time or date. ## Example -Example: - Run **date +%Y--%m--%d**. ## Output -**Figure 1** System date printed based on the specified format -![](figure/system-date-printed-based-on-the-specified-format.png "system-date-printed-based-on-the-specified-format") +System date in the specified format: + +``` +OHOS:/$ date +%Y--%m--%d +1970--01--01 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md index ea6c7385a2..7d97c15989 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md @@ -1,8 +1,15 @@ # dmesg +- [Command Function](#section4643204919313) +- [Syntax](#section6553153635) +- [Parameters](#section208971157532) +- [Usage](#section213115219413) +- [Example](#section13736564418) +- [Output](#section194005101413) + ## Command Function -This command is used to control the dmesg buffer of the kernel. +This command is used to display system boot and running information. ## Syntax @@ -45,14 +52,14 @@ dmesg \> \[_fileA_\] - - @@ -73,7 +80,7 @@ dmesg \> \[_fileA_\] - @@ -87,20 +94,22 @@ dmesg \> \[_fileA_\] Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg -- If the parameters are not 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. 1. Before writing content to a file, ensure that the file system has been mounted. - 2. Disabling the serial port printing will adversely affect the 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 -Example: - -Run **dmesg \> /usr/dmesg.log**. +Run **dmesg\> dmesg.log**. ## Output -**Figure 1** Writing dmesg content to a file -![](figure/writing-dmesg-content-to-a-file.png "writing-dmesg-content-to-a-file") +Writing the content in the buffer to the **dmesg.log** file: + +``` +OHOS # dmesg > dmesg.log +Dmesg write log to dmesg.log success +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md index 302490df49..dcfa9e2fd5 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md @@ -1,8 +1,15 @@ # exec +- [Command Function](#section4643204919313) +- [Syntax](#section6553153635) +- [Parameters](#section208971157532) +- [Usage](#section213115219413) +- [Example](#section13736564418) +- [Output](#section194005101413) + ## Command Function -This command is a built-in shell command used to execute user-space programs. +This command is a built-in shell command used to execute user-mode programs. ## Syntax diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-free.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-free.md index 5dd95c0de6..ad01ce8a0b 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-free.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-free.md @@ -1,12 +1,19 @@ # free +- [Command Function](#section175151514841) +- [Syntax](#section8488721749) +- [Parameters](#section27272181949) +- [Usage](#section148661259410) +- [Example](#section68081530242) +- [Output](#section171235517543) + ## Command Function -This command is used to display the system memory usage and the sizes of the **text**, **data**, **rodata**, and **bss** segments. +This command is used to display the memory usage in the system. ## Syntax -free \[_-k | -m_\] +free \[_-b | -k | -m | -g | -t_\] ## Parameters @@ -21,25 +28,53 @@ free \[_-k | -m_\] - + + + + + + + + + + + + - - - - - - - - + + + + @@ -55,56 +90,56 @@ Run **free**, **free -k**, and **free -m**, respectively. ## Output -**Figure 1** Displaying the memory usage in three units -![](figure/displaying-the-memory-usage-in-three-units.png "displaying-the-memory-usage-in-three-units") +``` +OHOS:/$ free + total used free shared buffers +Mem: 2819652 2754468 65184 0 0 +-/+ buffers/cache: 2754468 65184 +Swap: 0 0 0 +OHOS:/$ free -k + total used free shared buffers +Mem: 2753 2692 60 0 0 +-/+ buffers/cache: 2692 60 +Swap: 0 0 0 +OHOS:/$ free -m + total used free shared buffers +Mem: 2 2 0 0 0 +-/+ buffers/cache: 2 0 +Swap: 0 0 0 +``` **Table 2** Output -

Function

API

mode

  • Default: displays the CPU usage of the system within the last 10 seconds.
  • 0: displays the CPU usage within the last 10 seconds.
  • 1: displays the CPU usage of the system within the last 1 second.
  • Other value: displays the total CPU usage since the system is started.
+
  • Displays the CPU usage of the system within the last 10 seconds by default.
  • 0: displays the CPU usage within the last 10 seconds.
  • 1: displays the CPU usage within the last 1 second.
  • Other value: displays the total CPU usage since the system is started.

[0,0xFFFFFFFF]

taskID

Task ID

+

Specifies the task ID.

[0,0xFFFFFFFF]

--help

-

Displays the help information.

-

N/A

+

--help

+Format

-

Prints the date and time based on Format.

-

Placeholders listed in --help.

-

-s YY/MM/DD

-

Sets the system date and separates the year, month, and day by slashes (/).

+

Displays help information.

>= 1970/01/01

+

N/A

-s hh:mm:ss

+

+Format

Sets the system time and separates the hour, minute, and second by colons (:).

+

Prints the date and time in the specified Format.

N/A

+

Placeholders listed in --help

-r Filename

+

-u

Queries the modification time of the Filename file.

+

Displays UTC instead of the current time zone.

N/A

+

N/A

-D/-E

Enables or disables printing to the console.

+

Disables or enables printing to the console.

N/A

-L/-U

Enables or disables printing via the serial port.

+

Disables or enables printing via the serial port.

N/A

> fileA

Writes the content in the buffer to a file.

+

Writes the content in the buffer to the specified file.

N/A

No parameter

+

No parameter

+

Displays the memory usage in bytes.

+

N/A

+

--help/-h

+

Displays the parameters supported by the free command.

+

N/A

+

-b

+

Displays the memory usage in bytes.

+

N/A

+

-k

Displays the size in bytes.

+

Displays the memory usage in KiB.

N/A

+

N/A

-k

+

-m

Displays the size in KiB.

+

Displays the memory usage in MiB.

N/A

+

N/A

-m

+

-g

Displays the size in MiB.

+

Displays the memory usage in GiB.

N/A

+

N/A

+

-t

+

Displays the memory usage in TiB.

+

N/A

Output

+ - - - - - - - - - - - - - - - - - - - diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-help.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-help.md index 691461db47..34789511fa 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-help.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-help.md @@ -1,8 +1,15 @@ # help +- [Command Function](#section991211345413) +- [Syntax](#section19103204016410) +- [Parameters](#section1533416233432) +- [Usage](#section4156445417) +- [Example](#section12776124712417) +- [Output](#section092662412544) + ## Command Function -This command is used to display all commands in the OS. +This command is used to display all commands in the OS and some Toybox commands. ## Syntax @@ -22,18 +29,33 @@ Run **help**. ## Output -Viewing all commands in the system +All commands in the system: ``` -OHOS # help -*******************shell commands:************************* +After shell prompt "OHOS # ": +Use ` [args ...]` to run built-in shell commands listed above. +Use `exec [args ...]` or `./ [args ...]` to run external commands. -arp cat cd chgrp chmod chown cp cpup -date dhclient dmesg dns format free help hwi -ifconfig ipdebug kill log ls lsfd memcheck mkdir -mount netstat oom partinfo partition ping ping6 pwd -reset rm rmdir sem statfs su swtmr sync -systeminfo task telnet tftp touch umount uname watch -writeproc +OHOS:/$ help +*******************shell commands:************************* +arp cat cat_logmpp cd chgrp chmod +chown cp cpup date dhclient dmesg +dns format free help hi3881 hwi +ifconfig ipdebug kill log ls lsfd +memcheck mkdir mount netstat oom panicreset +partinfo partition ping ping6 pmm pwd +reset rm rmdir sem shm stack +statfs su swtmr sync systeminfo task +telnet touch umount uname v2p vmm +watch writeproc +After shell prompt "OHOS # ": +Use ` [args ...]` to run built-in shell commands listed above. +Use `exec [args ...]` or `./ [args ...]` to run external commands. +*******************toybox commands:************************ +chgrp chmod chown cp date du free help ifconfig kill ls mkdir mount +mv ping ps reboot rm rmdir top touch umount uname +Use `toybox help [command]` to show usage information for a specific command. +Use `shell` to enter interactive legacy shell. +Use `alias` to display command aliases. ``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md index 1fff611d19..7c6bf50c2d 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md @@ -1,8 +1,15 @@ # hwi +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameters](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + ## Command Function -This command is used to query information about the interrupts. +This command is used to query information about interrupts. ## Syntax @@ -14,27 +21,95 @@ None ## Usage -- Run **hwi** to display the current interrupt ID, count of interrupts, and registered interrupt name. -- If **LOSCFG\_CPUP\_INCLUDE\_IRQ** is enabled, the processing time \(cycles\), CPU usage, and interrupt type of each interrupt are displayed. +- 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 -Enter **hwi**. +Run **hwi**. ## Output -1. Interrupt information \(**LOSCFG\_CPUP\_INCLUDE\_IRQ** disabled\) - - ![](figure/en-us_image_0000001179967527.png) - -2. Interrupt information \(**LOSCFG\_CPUP\_INCLUDE\_IRQ** enabled\) - - ![](figure/en-us_image_0000001133848164.png) +- Interrupt information \(**LOSCFG\_CPUP\_INCLUDE\_IRQ** disabled\): + + ``` + OHOS # hwi + InterruptNo Count Name + 0: 0: + 1: 1025641: + 2: 0: + 29: 824049: + 37: 0: rtc_alarm + 38: 24: uart_pl011 + 48: 3: GPIO + 59: 0: + 62: 530: MMC_IRQ + 63: 70: MMC_IRQ + 64: 280: ETH + 67: 58: tde + 68: 0: JPGE_0 + 69: 0: IVE + 70: 0: VGS + 72: 0: VEDU_0 + 73: 0: nnie0 + 74: 0: nnie_gdc0 + 75: 0: VPSS + 76: 0: VI_PROC0 + 77: 0: JPEGD_0 + 83: 49455: HIFB_SOFT_INT + 87: 0: AIO interrupt + 88: 0: VI_CAP0 + 89: 0: MIPI_RX + 90: 49455: VO int + 91: 49456: HIFB Int + 96: 17601: MMC_IRQ + 100: 0: SPI_HI35XX + 101: 0: SPI_HI35XX + 102: 0: SPI_HI35XX + ``` + +- Interrupt information \(**LOSCFG\_CPUP\_INCLUDE\_IRQ** enabled\): + + ``` + OHOS # hwi + InterruptNo Count ATime(us) CPUUSE CPUUSE10s CPUUSE1s Mode Name + 0: 0 0 0.0 0.0 0.0 normal + 1: 937031 0 0.1 0.1 0.1 normal + 2: 0 0 0.0 0.0 0.0 normal + 29: 726166 5 0.54 0.57 0.59 normal + 37: 0 0 0.0 0.0 0.0 normal rtc_alarm + 38: 17 5 0.0 0.0 0.0 normal uart_pl011 + 48: 3 4 0.0 0.0 0.0 normal GPIO + 59: 0 0 0.0 0.0 0.0 normal + 62: 531 1 0.0 0.0 0.0 normal MMC_IRQ + 63: 69 1 0.0 0.0 0.0 normal MMC_IRQ + 64: 292 2 0.0 0.0 0.0 normal ETH + 67: 54 76 0.0 0.0 0.0 shared tde + 68: 0 0 0.0 0.0 0.0 shared JPGE_0 + 69: 0 0 0.0 0.0 0.0 shared IVE + 70: 0 0 0.0 0.0 0.0 shared VGS + 72: 0 0 0.0 0.0 0.0 shared VEDU_0 + 73: 0 0 0.0 0.0 0.0 shared nnie0 + 74: 0 0 0.0 0.0 0.0 shared nnie_gdc0 + 75: 0 0 0.0 0.0 0.0 shared VPSS + 76: 0 0 0.0 0.0 0.0 shared VI_PROC0 + 77: 0 0 0.0 0.0 0.0 shared JPEGD_0 + 83: 45529 8 0.5 0.5 0.5 shared HIFB_SOFT_INT + 87: 0 0 0.0 0.0 0.0 shared AIO interrupt + 88: 0 0 0.0 0.0 0.0 shared VI_CAP0 + 89: 0 0 0.0 0.0 0.0 shared MIPI_RX + 90: 45534 11 0.6 0.7 0.7 shared VO int + 91: 45533 2 0.1 0.1 0.1 shared HIFB Int + 96: 17383 2 0.0 0.0 0.0 normal MMC_IRQ + 100: 0 0 0.0 0.0 0.0 normal SPI_HI35XX + 101: 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 -

Parameter

Description

total

-

Total size of the dynamic memory pool

-

used

-

Size of the used memory

-

free

-

Size of the unallocated memory

-

heap

+

total

Size of the allocated heap

+

Total size of the dynamic memory pool

text

+

used

Size of a code segment

+

Size of the used memory

data

+

free

Size of a data segment

+

Size of the unallocated memory

rodata

+

shared

Size of a read-only data segment

+

Size of the shared memory

bss

+

buffers

Size of the memory occupied by uninitialized global variables

+

Size of the buffer

- - @@ -35,9 +42,9 @@ log level \[_levelNum_\] - 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 + **Debug** ---\> **Enable a Debug Version** ---\> **Enable Shell** ---\> **Enable Shell lK** -- The **log level** command is used to configure log levels, which can be: +- The **log level** command is used to set the log level, which can be any of the following: TRACE\_EMG = 0, @@ -51,17 +58,21 @@ log level \[_levelNum_\] TRACE\_DEBUG = 5 - If the level is not within the valid range, a message will be displayed. + If the log level specified is not within the value range, a message will be displayed. -- If the **\[levelNum\]** parameter is not specified, the current log level and its usage are printed by default. +- If **\[levelNum\]** is not specified, this command queries the current log level. The usage method is also displayed. +- 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 -Example: - -Run **log level 4**. +Run **log level 3**. ## Output -![](figure/en-us_image_0000001179847649.png) +Setting the log print level to WARN: + +``` +OHOS # log level 3 +Set current log level WARN +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md index 19e400eb67..2436cc1ae3 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md @@ -1,8 +1,15 @@ # memcheck +- [Command Function](#section191633812516) +- [Syntax](#section428816435510) +- [Parameters](#section1939943304411) +- [Usage](#section228914491951) +- [Example](#section17373205314515) +- [Output](#section13406205385413) + ## Command Function -This command is used to check whether the dynamically requested 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 @@ -23,9 +30,36 @@ Run **memcheck**. ## Output -**Figure 1** No out-of-bounds memory access -![](figure/no-out-of-bounds-memory-access.png "no-out-of-bounds-memory-access") +Example 1: All nodes in the memory pool are complete. + +``` +OHOS # memcheck +system memcheck over, all passed! +``` + +Example 2: Out-of-bounds memory access is detected. -**Figure 2** Out-of-bounds memory access -![](figure/out-of-bounds-memory-access.png "out-of-bounds-memory-access") +``` +[L0S DLnkCheckMenl 349, memory check +stFreeNodeInfo.pstPrev:0x7e0d31f3 is out of legal mem range[0x80ba5f40, 0х83d00000] +cur node: 0x81f2ce0c +pre node: 0x81f28a98 +pre node was allocated by task:sofia +uwEхcTуpe = 0х2 +puмExcBuffAddr pc = 0x803ad7a4 +puwExcBuffAddr lr = 0x803ad7a4 +puwExcBuffAddr sp = 0х80cb7de0 +puwExcBuffAddr fp = 0x80cb7dec +*******backtrace begin******* +traceback 0 -- lr = 0х8037cb84 +traceback 0 -- fp = 0х80cb7e1c +traceback 1 -- lr = 0х8037033c +traceback 1 -- fp = 0х80cb7e24 +traceback 2 -- lr = 0x8000d108 +traceback 2 -- fp = 0х80cb7e94 +traceback 3 -- lr = 0х8037c7ac +traceback 3 -- fp = 0х80cb7ea4 +traceback 4 -- lr = 0x803ad9e8 +traceback 4 -- fp = 9x11111111 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md index 34bfe3ca1c..b3800327fa 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md @@ -1,8 +1,15 @@ # oom +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameters](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section387104374416) +- [Output](#section12742311179) + ## Command Function -This command is used to query and set the low memory threshold and the page cache reclaim threshold. +This command is used to query and set the low memory threshold and the PageCache reclaim threshold. ## Syntax @@ -45,7 +52,7 @@ oom -h | --help - @@ -62,15 +69,83 @@ oom -h | --help ## Usage -- If no parameter is specified, the current OOM configurations are displayed. +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 - >![](../public_sys-resources/icon-note.gif) **NOTE:** - >When the system memory is insufficient, the system displays a message indicating the insufficiency. +Run the following commands: +- oom +- oom -i 100 ## Output -![](figure/en-us_image_0000001134008030.png) +Example 1: displaying OOM configuration + +``` +OHOS:/$ oom +[oom] oom loop task status: enabled + oom low memory threshold: 0x80000(byte) + oom reclaim memory threshold: 0x500000(byte) + oom check interval: 100(microsecond) +``` + +Information displayed when the system memory is insufficient: + +``` +T:20 Enter:IT MEM 00M 001 +[oom] OS is in low memory state +total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte) ,free: 0x7f000(byte), low memory threshold: 0x80000(byte) +[oom] candidate victim process init pid: 1, actual phy mem byte:82602 +[oom] candidate victim process shell pid: 3, actual phy mem byte:14950e +[oom] candidate victim process testsuits app pid: 4, actual phy mem byte:1334598 +[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte:25951558 +[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem 25951558 +################excFrom: User!#################### +data abort fsr:0x817, far:0x225af000 +Abort caused by a write instruction. Translation fault, page +excType: data abort +processName = UserProcess12 +processID = 12 +process aspace = 0х01000000 -> 0х3f000000 +taskName = threado +taskID = 22 +task user stack = 0х20e17000 -> 0х20e21000 +pc = 0x93969dc in /usr/bin/testsuits app ---> 0x19f9dc +ulr = 0x93969cc in /usr/bin/testsuits app ---> 0x19f9cc +usp = 0х20e20c68fp = 0x20e20c8c +R0 = 0х20e35000 +R1 = 0x225af000 +R2 = 0x0 +R3 = 0х28e35000 +R4 = 0х0 +R5 = 0х9500000 +R6 = 0х14 +R7 = 0х97822c4 +R8 = 0x970cfa8 +R9 = 0x9090909 +R10 = 0xa0a0a0a +R11 = 0x20e20c8c +R12 = 0х0 +CPSR = 0х80000010 +*******backtrace beain******* +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 2 -- 1r = 0x9396ab0 fp = 0x20e20cec lr in /usr/bin/testsuits app -> 0х19fab0 +traceback 3 -- lr = 0x9393eb4 fp = 0x20e20cf4 lr in /usr/bin/testsuits ap --> 0x19ceb4 +traceback 4 -- lr = 0x92427d4 fp = 0x20e20d44 lr in /usr/bin/testsuits app --> 0x4b7d4 +traceback 5 -- 1r = 0x20c4df50 fp = 0хb0b0b0b 1r in /1ib/libc.so - -> 0x62f50 +``` + +Example 2: setting the OOM check interval to 100 ms + +``` +OHOS:/$ oom -i 100 +[oom] set oom check interval (100)ms successful +``` **Table 2** Output @@ -84,13 +159,13 @@ oom -h | --help - - - + + + + - - - - - - - - - - - - - - - - - + + + + @@ -72,19 +89,27 @@ ping _-k_ ## Usage -- Run the **ping** command by setting a destination IP address to check whether the network connection to the destination IP address is normal. +- 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 no route is available to the destination IP address, an error message is displayed. -- This command can be used only after the TCP/IP protocol stack is enabled. +- This command can be used only after the TCP/IP stack is enabled. ## Example -Run **ping 192.168.1.10**. +Run **ping 192.168.1.3**. ## Output -**Figure 1** Output of pinging the IP address of the TFTP server - - -![](figure/snipaste_2021-01-26_10-38-58-26.png) +Pinging a TFTP server IP address: + +``` +OHOS:/$ ping 192.168.1.3 +Ping 192.168.1.3 (192.168.1.3): 56(84) bytes. +84 bytes from 192.168.1.3: icmp_seq=0 ttl=0 time=0 ms +84 bytes from 192.168.1.3: icmp_seq=0 ttl=0 time=1 ms +84 bytes from 192.168.1.3: icmp_seq=0 ttl=0 time=0 ms +--- 192.168.1.3 ping statistics --- +3 packets transmitted, 3 received, 0% packet loss +round-trip min/avg/max = 0/0/0 ms +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-ping6.md b/en/device-dev/kernel/kernel-small-debug-shell-net-ping6.md index 1ea71d89db..4c91d848aa 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-ping6.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-ping6.md @@ -1,5 +1,12 @@ # ping6 +- [Command Function](#section1057291313393) +- [Syntax](#section199901315123919) +- [Parameters](#section4679319113919) +- [Usage](#section1127917226399) +- [Example](#section7211192553917) +- [Output](#section4846145221215) + ## Command Function This command is used to test an IPv6 network connection. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-telnet.md b/en/device-dev/kernel/kernel-small-debug-shell-net-telnet.md index 07ff48013d..5ab95a89bc 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-telnet.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-telnet.md @@ -1,5 +1,12 @@ # telnet +- [Command Function](#section3551830123913) +- [Syntax](#section14897133233918) +- [Parameters](#section977718353392) +- [Usage](#section134991538183916) +- [Example](#section1097414426398) +- [Output](#section11846624191310) + ## Command Function This command is used to enable or disable the Telnet server service. @@ -44,7 +51,7 @@ telnet \[_on | off_\] - Currently, multiple clients \(Telnet + IP\) cannot connect to the development board at the same time. >![](../public_sys-resources/icon-notice.gif) **NOTICE:** - >Telnet is used for debugging and disabled by default. Do not use it in formal products. + >Telnet is used for debugging and is disabled by default. Do not use it in formal products. ## Example @@ -53,6 +60,10 @@ Run **telnet on**. ## Output -**Figure 1** Output of **telnet on** -![](figure/output-of-telnet-on.png "output-of-telnet-on") +Command output: + +``` +OHOS # telnet on +OHOS # start telnet server successfully, waiting for connection. +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-tftp.md b/en/device-dev/kernel/kernel-small-debug-shell-net-tftp.md index 9bbf303d92..21983306a4 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-tftp.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-tftp.md @@ -1,5 +1,12 @@ # tftp +- [Command Function](#section15142134573911) +- [Syntax](#section20958174917394) +- [Parameters](#section576613532395) +- [Usage](#section149795134408) +- [Example](#section148921918114015) +- [Output](#section7872155631313) + ## 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. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net.md b/en/device-dev/kernel/kernel-small-debug-shell-net.md index 3b0fc77fc7..aa54200f33 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net.md @@ -4,8 +4,6 @@ - **[dhclient](kernel-small-debug-shell-net-dhclient.md)** -- **[dns](kernel-small-debug-shell-net-dns.md)** - - **[ifconfig](kernel-small-debug-shell-net-ifconfig.md)** - **[ipdebug](kernel-small-debug-shell-net-ipdebug.md)** diff --git a/en/device-dev/kernel/kernel-small-debug-shell-overview.md b/en/device-dev/kernel/kernel-small-debug-shell-overview.md index 23af000c4d..a69788187b 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-overview.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-overview.md @@ -1,14 +1,16 @@ # Introduction to the Shell -The shell provided by the OpenHarmony kernel supports commonly used debugging commands. You can also add and custom commands to the shell of the OpenHarmony kernel to address your service needs. The common debugging commands include the following: +- [Important Notes](#section12298165312328) + +The shell provided by the OpenHarmony kernel supports commonly used debugging commands. You can also add and customize commands to the shell of the OpenHarmony kernel to address your service needs. The common debugging commands include the following: - System commands: commands used to query information, such as system tasks, semaphores, system software timers, CPU usage, and interrupts. - File commands: commands used to manage files and directories, such as **ls** and **cd**. -- Network commands: commands used to query the IP addresses of other devices connected to the development board, querying the IP address of the local device, testing network connectivity, and setting the access point \(AP\) and station modes of the development board. +- Network commands: commands used to query the IP addresses of other devices connected to the development board, querying the IP address of the local device, testing network connectivity, and setting the access point \(AP\) and station \(STA\) modes of the development board. - For details about how to add a command, [Shell Command Development Guidelines](kernel-small-debug-shell-guide.md) and [Shell Command Programming Example](kernel-small-debug-shell-build.md). + For details about how to add a command, see [Shell Command Development Guidelines](kernel-small-debug-shell-guide.md) and [Shell Command Programming Example](kernel-small-debug-shell-build.md). ## Important Notes @@ -18,7 +20,7 @@ Note the following when using the shell: - You can use the **exec** command to run executable files. - The shell supports English input by default. To delete the Chinese characters entered in UTF-8 format, press the backspace key for three times. -- When entering shell commands, file names, and directory names, you can press **Tab** to enable automatic completion. If there are multiple completions, multiple items are printed based on the same characters they have. If more than 24 lines of completions are available, the system displays message "Display all num possibilities?\(y/n\)", asking you to determine whether to print all items. You can enter **y** to print all items or enter **n** to exit the printing. If more than 24 lines are printed after your selection, the system displays "--More--". In this case, you can press **Enter** to continue the printing or press **q** \(or **Ctrl+c**\) to exit. +- When entering shell commands, file names, and directory names, you can press **Tab** to enable automatic completion. If there are multiple completions, multiple items are printed based on the same characters they have. If more than 24 lines of completions are available, the system displays the message "Display all num possibilities?\(y/n\)", asking you to determine whether to print all items. You can enter **y** to print all items or enter **n** to exit the printing. If more than 24 lines are printed after your selection, the system displays "--More--". In this case, you can press **Enter** to continue the printing or press **q** \(or **Ctrl+c**\) to exit. - The shell working directory is separated from the system working directory. You can run commands such as **cd** and **pwd** on the shell to perform operations on the shell working directory, and run commands such as **chdir** and **getcwd** to perform operations on the system working directory. Pay special attention when an input parameter in a file system operation command is a relative path. diff --git a/en/device-dev/kernel/kernel-small-debug-shell.md b/en/device-dev/kernel/kernel-small-debug-shell.md index 796f477418..20453c4715 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell.md +++ b/en/device-dev/kernel/kernel-small-debug-shell.md @@ -10,6 +10,6 @@ - **[Magic Key](kernel-small-debug-shell-magickey.md)** -- **[User-Space Exception Information](kernel-small-debug-shell-error.md)** +- **[User-Mode Exception Information](kernel-small-debug-shell-error.md)** diff --git a/en/device-dev/kernel/kernel-small-debug-trace-other-faqs.md b/en/device-dev/kernel/kernel-small-debug-trace-other-faqs.md index 3c264d713d..23ec4cbd34 100644 --- a/en/device-dev/kernel/kernel-small-debug-trace-other-faqs.md +++ b/en/device-dev/kernel/kernel-small-debug-trace-other-faqs.md @@ -1,16 +1,19 @@ # Common Fault Locating Methods -## Locating the Fault based on Exception Information +- [Locating the Fault Based on Exception Information](#section695838161711) +- [Checking Memory Pool Integrity](#section362917569179) +- [Locating Memory Overwriting for a Global Variable](#section18971311121816) -When the system is suspended unexpectedly, information about key registers is displayed on the serial port, as shown in the following figure. The information can be used to locate the function where the exception occurs and the related call stack. +## Locating the Fault Based on Exception Information -Exception information +When the system is suspended unexpectedly, information about key registers is displayed on the serial port, as shown in the following figure. The information can be used to locate the function where the exception occurs and the related call stack. -![](figure/en-us_image_0000001173429547.png) +**Figure 1** Exception information +![](figures/exception-information.png "exception-information") The exception information in the preceding figure is described as follows: -①: indicates that the exception occurs in the kernel space. +①: indicates that the exception is in kernel mode. ②: indicates the exception type. The value of **far** is the address accessed by the CPU when the exception occurs. @@ -24,7 +27,7 @@ You also need to check the **OHOS\_Image.asm** file \(assembly file correspond You may not directly locate the fault only with the exception information. Sometimes, the fault cannot be located due to incorrect register values. If you suspect that the fault is caused by heap memory overwriting, you can call **LOS\_MemIntegrityCheck** to check the memory pool integrity. The **LOS\_MemIntegrityCheck** function traverses all nodes in the dynamic memory pool of the system. If all nodes are normal, the function returns **0** and no information is printed. Otherwise, error information is printed. This function uses **\(VOID \*\)OS\_SYS\_MEM\_ADDR** as the input parameter. -Generally, **LOS\_MemIntegrityCheck** is called before and after the suspected service logic code to locate the heap memory overwriting. If the service code is correct, **LOS\_MemIntegrityCheck** can be called successfully. By doing this, you can narrow down and locate the fault. +Generally, **LOS\_MemIntegrityCheck** is called before and after the suspected service logic code to locate the heap memory overwriting. If the service code is correct, **LOS\_MemIntegrityCheck** can be called successfully. By doing this, you can improve the troubleshooting efficiency. ## Locating Memory Overwriting for a Global Variable diff --git a/en/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md b/en/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md index 2029dff707..30a55b45f4 100644 --- a/en/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md +++ b/en/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md @@ -1,12 +1,17 @@ # Dying Gasp +- [When to Use](#section158501652121514) +- [Available APIs](#section1186411122215) +- [Parameters](#section1083765723015) +- [How to Develop](#section783435801510) + ## When to Use -For a device without a serial port, save the exception information to a non-volatile storage medium to facilitate fault location during system running. +For a device without a serial port, the dying gasp saves the exception information to a non-volatile storage medium to facilitate fault location during system running. ## Available APIs -The system provides a mechanism to save printed exception information to a non-volatile storage medium. You can register the hook functions for printing information when the read and write operations are abnormal. In this way, fault information can be saved on different storage media, facilitating fault locating for devices without serial ports. The API is **LOS\_ExcInfoRegHook**. This function is declared in **los\_config.h**. The function prototype is as follows: +The system provides a mechanism to save printed exception information to a non-volatile storage medium. You can register the hook function of the information printed when the read and write operations are abnormal. In this way, fault information can be saved on different storage media, facilitating fault locating for devices without serial ports. The API is **LOS\_ExcInfoRegHook**. This function is declared in **los\_config.h**. The function prototype is as follows: ``` typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf); @@ -85,7 +90,7 @@ VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_writ The dying gasp function depends on the macro **LOSCFG\_SAVE\_EXCINFO**. Before using this function, choose **Debug**-\> **Enable Saving Exception Information** in the configuration items to enable this macro. If this macro is disabled, this function cannot be used. Then, call **LOS\_ExcInfoRegHook** in **SystemInit** to register the position, size, memory buffer, and access function for accessing the exception information. When an exception occurs in the system, the system saves the exception information in the memory buffer passed in the registration, and then calls the registered access function to write the exception information to the physical storage medium. >![](../public_sys-resources/icon-note.gif) **NOTE:** ->- The location registered to storing the exception information cannot overlap with other storage locations. +>- The location registered to store the exception information cannot overlap with other storage locations. >- The registered memory buffer should be greater than or equal to 16 KiB. Otherwise, the exception information stored may be incomplete. >- The exception information can be accessed successfully only when the driver of the storage medium corresponding to the registered read/write function is normal. diff --git a/en/device-dev/kernel/kernel-small-debug-trace.md b/en/device-dev/kernel/kernel-small-debug-trace.md index 09d86ed17d..915532ce6a 100644 --- a/en/device-dev/kernel/kernel-small-debug-trace.md +++ b/en/device-dev/kernel/kernel-small-debug-trace.md @@ -1,98 +1,429 @@ # Trace -## Basic Concepts +- [Basic Concepts](#section531482192018) +- [Working Principles](#section5125124532010) +- [Available APIs](#section17747184017458) + - [Kernel Mode](#section104473014465) + - [User Mode](#section1996920294531) + +- [Development Guidelines](#section10302175017543) + - [Kernel-mode Development Process](#section04021008552) -Trace is a functional framework provided by the kernel for tracing key processes of modules. You can implement trace at key positions for modules based on mechanism requirements, and export the traced information as files or in other modes for further analysis. +- [Kernel-mode Programming Example](#section112034213583) +- [Kernel-mode Sample Code](#section10348549155812) +- [Verification](#section8601444165916) -The requirements for trace are as follows: +## Basic Concepts -1. The information needs to be recorded as soon as possible to minimize the impact on the system time sequence. -2. Use as little space as possible to store as much as possible data to reduce memory consumption. +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. ## Working Principles -Initialize the trace function at the beginning of the kernel startup. When the modules that support the trace function are initialized, register the trace type and callback functions. The position of the trace point that triggers trace recording can be determined by each module. +The kernel provides a hook framework to embed hooks in the main process of each module. In the initial startup phase of the kernel, the trace function is initialized and the trace handlers are registered with the hooks. + +When a hook is triggered, the trace module encapsulates the input information and adds the trace frame header information, including the event type, ID of the running CPU, ID of the running task, and relative timestamp. -When a trace point is triggered, the trace module encapsulates the input information and adds the trace frame header information, including the trace type, ID of the running CPU, ID of the running task, relative timestamp of the running task, and ID of the running process. Then, the trace frame is recorded in a pre-requested cyclic buffer. +The trace module provides two working modes: offline mode and online mode. -If too many frames are recorded in the cyclic buffer, earlier frames will be overwritten to ensure that the information in the buffer is always the latest. The traced data in the cyclic buffer can be exported, for example, by using file dumping, for further analysis. The exported files are sorted by timestamp. +In offline mode, trace frames are stored in a circular buffer. If too many frames are stored in the circular buffer, earlier frames will be overwritten to ensure that the information in the buffer is always the latest. Data in the circular buffer can be exported by running the shell command for further analysis. The exported information is sorted by timestamp. -![](figure/en-us_image_0000001127390512.png) +![](figures/kernel-small-mode-process-4.png) -## Usage +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. -1. Configure the trace macro **LOSCFG\_KERNEL\_TRACE**, which is disabled by default. You can enable it by choosing **Kernel** \> **Enable Trace Feature** on the **menuconfig**. -2. Call **OsTraceInit** to complete trace initialization. -3. Define the traceframe structure of the module in **los\_trace\_frame.h**, and implement the trace callback function of the module in **los\_trace\_frame.c**. -4. Call **LOS\_TraceReg** to register trace in the initialization or earlier phase for the modules to be traced. -5. Enable the trace function at the position where the tracing starts and disable the trace function at the position where the tracing stops. -6. Call **LOS\_Trace2File** to export traced data to a file. -7. Perform further data analysis based on the frame header and frame body structure. +## **Available APIs** -**Available APIs** +### Kernel Mode -The following table describes APIs available for the OpenHarmony LiteOS-A trace framework. For more details about the APIs, see the API reference. +The trace module of the OpenHarmony LiteOS-A kernel provides the following functions. For details about the APIs, see the [API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h) reference. -**Table 1** Trace Interface Description +**Table 1** Trace module APIs - -

Output

+ @@ -47,7 +122,7 @@ Enter **hwi**. - - - - diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md index 8ca3ab7cb4..a6752e9588 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md @@ -1,12 +1,19 @@ # kill +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameters](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + ## Command Function -This command is used to send a specific signal to a specified process. +This command is used to send a signal to a specified process. ## Syntax -kill \[_signo_ | _-signo_\] \[_pid_\] +kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._ ## Parameters @@ -21,55 +28,122 @@ kill \[_signo_ | _-signo_\] \[_pid_\] - + + + + + + + + - - - - - + + + +

Parameter

Description

Count

Count of interrupts

+

Number of interrupts

Name

@@ -55,9 +130,9 @@ Enter **hwi**.

Registered interrupt name

CYCLECOST

+

ATime

Interrupt processing time (in cycles)

+

Interrupt handling time

CPUUSE

@@ -77,7 +152,7 @@ Enter **hwi**.

mode

Interrupt mode, which can be any of the following:

+

Interrupt type, which can be any of the following:

  • normal: non-shared interrupt.
  • shared: shared interrupt.

signo

+

--help

+

Displays the parameters supported by the kill command.

+

N/A

+

-l

+

Lists the names and numbers of signals.

+

N/A

+

-s

Specifies the signal ID.

+

Sends signals

[1,30]

+

N/A

pid

+

signo

Specifies the process ID.

+

Specifies the signal number.

[1,MAX_INT]

+

[1,30]

+

pid

+

Specifies the process ID.

+

[1,MAX_INT]

>![](../public_sys-resources/icon-notice.gif) **NOTICE:** ->The valid range of the **signo** value is \[0, 64\], and the recommended value range is \[1, 30\]. Other values in the valid range are reserved. +>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 -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\]. +- 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 -1. Query the process list and determine the PID \(7\) of the process to be killed. - -**Figure 1** Querying PIDs -![](figure/querying-pids.png "querying-pids") - -2. Run **kill 14 7** to send signal 14 \(the default behavior of **SIGALRM** is to terminate the process\) to process 7 **helloworld\_d** \(user-space\). Then query the current process list. Process 7 has been terminated. The result of the **kill 14 7** command is the same as that of the **kill -14 7** command. - -**Figure 2** Command output -![](figure/command-output.png "command-output") +- Query the process list before killing process 42. + + ``` + OHOS:/$ ps + allCpu(%): 4.67 sys, 195.33 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4db02 0.0 init + 2 -1 2 0 Pending 0xdabc08 0 0xdabc08 1.14 KProcess + 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d24c2 0.0 foundation + 4 1 4 8 Pending 0x362000 0xbb000 0x5c6ff 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x1484f0 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11bca0 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa1cdf 0.88 wms_server + 8 1 8 2 Pending 0x1f5000 0x48000 0x47dc2 0.2 mksh + 10 5 5 101 Pending 0x11ec000 0x2f9000 0x206047 0.93 com.huawei.launcher + 12 1 12 0 Pending 0x4d4000 0x112000 0xe0882 0.0 deviceauth_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 + 15 1 15 0 Pending 0x61f000 0x13b000 0x168071 0.45 softbus_server + 42 8 42 2 Pending 0x1c1000 0x3a000 0x1106a 0.9 test_demo + 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. + + ``` + OHOS:/$ kill -s 9 42 + OHOS:/$ + [1] + Killed ./nfs/test_demo + OHOS:/$ ps + allCpu(%): 4.73 sys, 195.27 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4e01c 0.0 init + 2 -1 2 0 Pending 0xda5fa4 0 0xda5fa4 1.14 KProcess + 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d29dc 0.0 foundation + 4 1 4 8 Pending 0x362000 0xbb000 0x5cc19 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x148a0a 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.89 wms_server + 8 1 8 2 Pending 0x1f5000 0x48000 0x482dc 0.2 mksh + 10 5 5 101 Pending 0x11ec000 0x2f9000 0x206561 0.93 com.huawei.launcher + 12 1 12 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_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 + 15 1 15 0 Pending 0x61f000 0x13b000 0x16858b 0.51 softbus_server + 45 8 45 2 Running 0x1d7000 0x3a000 0x1e9f5 0.0 toybox + ``` + +- Run the **kill -100 31** command. ## Output -The command output is as follows: +**Example 1**: The signal is successfully sent to process 42. + +``` +OHOS:/$ kill -s 9 42 +OHOS:/$ +[1] + Killed ./nfs/test_demo +``` -**Figure 3** Sending a signal to a specified process -![](figure/sending-a-signal-to-a-specified-process.png "sending-a-signal-to-a-specified-process") +Process 42 is killed. -The signal is successfully sent if no error is reported. +**Example 2**: The signal fails to be sent to process 31. -**Figure 4** Signal sending failure -![](figure/signal-sending-failure.png "signal-sending-failure") +``` +OHOS:/$ kill -100 31 +kill: Unknown signal '(null)' +``` -The signal fails to send due to invalid parameters. Check the signal ID and PID for fault. +**Unknown signal '\(null\)'** is displayed because the **signo** value **100** exceeds the value range \[0, 64\]. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-log.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-log.md index 175315bf64..66ae0755be 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-log.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-log.md @@ -1,8 +1,15 @@ # log +- [Command Function](#section128219131856) +- [Syntax](#section3894181710519) +- [Parameters](#section7693122310515) +- [Usage](#section1982111281512) +- [Example](#section176301333259) +- [Output](#section14354765415) + ## Command Function -This command is used to modify and query log configurations. +This command is used to set and query log configuration. ## Syntax @@ -23,9 +30,9 @@ log level \[_levelNum_\]

levelNum

Specifies the print level of logs.

+

Specifies the level of logs to print.

[0x0, 0x5]

+

[0,5]

-r [mem byte]

Sets the page cache reclaim threshold.

+

Sets the PageCache reclaim threshold.

Ranging from the low memory threshold to the maximum available system memory

[oom] OS is in low memory state

total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)

The memory usage of the OS is low.

-

The available physical memory in the entire OS is 0x1bcf000 bytes, 0x1b50000 bytes have been used, and 0x7f000 bytes are available. The current low memory threshold is 0x80000 bytes.

+

The operating system has low memory.

+

The available physical memory in the operating system is 0x1bcf000 bytes, 0x1b50000 bytes have been used, and 0x7f000 bytes are available. The current low memory threshold is 0x80000 bytes.

[oom] candidate victim process init pid: 1, actual phy mem byte: 82602

The memory usage of each process is printed. The init process uses 82602 bytes, and the shared memory is calculated based on the proportion.

+

Memory usage of each process. The physical memory occupied by the init process is 82602 bytes.

[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558

diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md index 5cea14e507..1ccae97356 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md @@ -1,8 +1,15 @@ # pmm +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameters](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + ## Command Function -This command is used to check the usage of the physical pages and page cache of the system memory. +This command is used to check the usage of the physical pages of the system memory and the page cache. ## Syntax @@ -22,13 +29,37 @@ Run **pmm**. ## Output -**Figure 1** Viewing the usage of physical pages -![](figure/viewing-the-usage-of-physical-pages.png "viewing-the-usage-of-physical-pages") +Usage of physical pages: + +``` +OHOS # pmm + phys_seg base size free_pages + -------- ------- ---------- --------- + 0x4065552c 0x809b0000 0x07550000 22344 +order = 0, free_count = 16 +order = 1, free_count = 12 +order = 2, free_count = 8 +order = 3, free_count = 6 +order = 4, free_count = 13 +order = 5, free_count = 16 +order = 6, free_count = 12 +order = 7, free_count = 4 +order = 8, free_count = 79 +active anon 0 +inactive anon 0 +active file 1385 +inactice file 84 +pmm pages: total = 30032, used = 7688, free = 22344 +pathCache number = 325 +pathCache memory size = 17621(B) +Vnode number = 67 +Vnode memory size = 10720(B) +``` **Table 1** Output - - - - - - - - - - - - - - - - - - - - -

Output

+ @@ -76,9 +107,9 @@ Run **pmm**. - diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md new file mode 100644 index 0000000000..46769ef3e3 --- /dev/null +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md @@ -0,0 +1,33 @@ +# reboot + +- [Command Function](#section20643141481314) +- [Syntax](#section1075441721316) +- [Parameters](#section1472810220135) +- [Usage](#section186772414131) +- [Example](#section4764192791314) +- [Output](#section5791253155517) + +## Command Function + +This command is used to restart a device. + +## Syntax + +reboot + +## Parameters + +None + +## Usage + +After the **reboot** command is executed, the device restarts immediately. + +## Example + +reboot + +## Output + +None + diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md index b4df72c4ad..601e31f1b6 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md @@ -1,5 +1,12 @@ # reset +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameters](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + ## Command Function This command is used to restart a device. @@ -18,7 +25,7 @@ After the **reset** command is executed, the device restarts immediately. ## Example -reset +Run **reset**. ## Output diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md index fe4a6baa37..bc05dc4b3e 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md @@ -1,5 +1,12 @@ # sem +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameters](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section1975118519456) + ## Command Function This command is used to query information about kernel semaphores. @@ -25,12 +32,12 @@ sem \[_ID__ / fulldata_\] - - @@ -40,8 +47,8 @@ sem \[_ID__ / fulldata_\] ## Usage -- If the parameters are not specified, this command displays the number of used semaphores and the total number of semaphores. -- If the **ID** parameter is specified, semaphores of the specified ID are displayed. +- 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. - 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 @@ -49,12 +56,37 @@ sem \[_ID__ / fulldata_\] ## Example -Run **sem fulldata**. +- Run **sem**. +- Configure **LOSCFG\_DEBUG\_SEMAPHORE** and run **sem fulldata**. ## Output -**Figure 1** Querying information about all semaphores in use -![](figure/querying-information-about-all-semaphores-in-use.png "querying-information-about-all-semaphores-in-use") +Example 1: brief semaphore information + +``` +OHOS # sem + SemID Count + ---------- ----- + 0x00000000 1 + SemID Count + ---------- ----- + 0x00000001 0 + SemID Count + ---------- ----- + 0x00000002 0 + SemID Count + ---------- ----- + 0x00000003 1 + SemID Count + ---------- ----- + 0x00000004 0 + SemID Count + ---------- ----- + 0x00000005 1 + SemID Count + ---------- ----- + 0x00000006 0 +``` **Table 2** Output @@ -72,7 +104,7 @@ Run **sem fulldata**. - @@ -80,5 +112,76 @@ Run **sem fulldata**. >![](../public_sys-resources/icon-note.gif) **NOTE:** >The **ID** value can be in decimal or hexadecimal format. ->When the **ID** value is within the range of \[0, 1023\], semaphore information of the specified ID is displayed. If the semaphore ID 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. +>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 + +``` +OHOS # sem fulldata +Used Semaphore List: + SemID Count OriginalCount Creater(TaskEntry) LastAccessTime + ------ ------ ------------- ------------------ -------------- + 0xb 0x0 0x0 0x404978fc 0xa1 + 0xc 0x0 0x0 0x404978fc 0xa1 + 0xd 0x0 0x0 0x404978fc 0x12c + 0x10 0x0 0x0 0x404978fc 0x195 + 0xf 0x0 0x0 0x404978fc 0x195 + 0x11 0x0 0x0 0x4041a998 0x1d5 + 0x15 0x0 0x0 0x404978fc 0x273 + 0x14 0x0 0x0 0x404978fc 0x273 + 0x18 0x0 0x0 0x404978fc 0x352 + 0x17 0x0 0x0 0x404978fc 0x352 + 0x16 0x0 0x0 0x404978fc 0x352 + 0x1d 0x1 0x1 0x404978fc 0x385 + 0x1e 0x1 0x1 0x404978fc 0x388 + 0x1f 0x1 0x1 0x404978fc 0x38d + 0x20 0x1 0x1 0x404978fc 0x38f + 0x21 0x1 0x1 0x404978fc 0x392 + 0x3d 0x1 0x1 0x404978fc 0x395 + 0x3b 0x1 0x1 0x404978fc 0x395 + 0x3c 0x1 0x1 0x404978fc 0x395 + 0x39 0x1 0x1 0x404978fc 0x395 + 0x3a 0x1 0x1 0x404978fc 0x395 + 0x33 0x1 0x1 0x404978fc 0x395 + 0x35 0x1 0x1 0x404978fc 0x395 + 0x34 0x1 0x1 0x404978fc 0x395 + 0x38 0x1 0x1 0x404978fc 0x395 +``` + +**Table 3** Output description + + +

Parameter

Description

pmm pages

total: indicates the total number of physical pages.

-

used: indicates the number of used physical pages.

-

free: indicates the number of free physical pages.

+

total: total number of physical pages.

+

used: number of used physical pages.

+

free: number of free physical pages.

Specifies the semaphore ID.

[0, 0xFFFFFFFF]

+

[0, 1023] or [0x0, 0x3FF]

fulldata

Queries information about all the semaphores in use. The information to be printed includes SemID, Count, OriginalCount, Creater(TaskEntry), and LastAccessTime.

+

Queries information about all the semaphores in use. The information includes SemID, Count, OriginalCount, Creater(TaskEntry), and LastAccessTime.

N/A

Count

Number of used semaphores

+

Number of times that the semaphore is used

+ + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

SemID

+

Semaphore ID

+

Count

+

Number of times that the semaphore is used

+

OriginalCount

+

Original count of the semaphore

+

Creater

+

Address of the entry function of the thread used to create the semaphore

+

LastAccessTime

+

Last time when the semaphore was accessed

+
diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md index 3cb06ac71b..161fd252a7 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md @@ -1,5 +1,12 @@ # stack +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameters](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + ## Command Function This command is used to check the usage of each stack in the system. @@ -22,15 +29,22 @@ Run **stack**. ## Output -**Figure 1** System stack usage - +System stack usage: -![](figure/en-us_image_0000001133848370.png) +``` +OHOS # stack + stack name cpu id stack addr total size used size + ---------- ------ --------- -------- -------- + svc_stack 1 0x405c4000 0x2000 0x484 + svc_stack 0 0x405c6000 0x2000 0xae4 + exc_stack 1 0x405c8000 0x1000 0x0 + exc_stack 0 0x405c9000 0x1000 0x0 +``` **Table 1** Output - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -127,28 +131,28 @@ ifconfig ## Usage -- This command can be used only after the TCP/IP protocol stack is enabled. -- Detecting the IP address conflict takes a period of time. Each time you run the **ifconfig** command to set an IP address, there is a delay of about 2 seconds. +- 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. ## Example -1. ifconfig eth0 192.168.100.31 netmask 255.255.255.0 gateway 192.168.100.1 hw ether 00:49:cb:6c:a1:31 -2. ifconfig -a -3. ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d -4. ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d +- 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 eth0 inet6 add 2001:a:b:c:d:e:f:d +- ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d ## Output -1. Set network parameters. +- Example 1: setting 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 ip:192.168.100.31 netmask:255.255.255.0 gateway:192.168.100.1 - HWaddr 00:49:cb:6c:a1:31 MTU:1500 Running Default Link UP - lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 - ip6: ::1/64 - HWaddr 00 MTU:0 Running Link UP + 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 + lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP + eth0 ip:192.168.100.31 netmask:255.255.255.0 gateway:192.168.100.1 + HWaddr 00:49:cb:6c:a1:31 MTU:1500 Running Default Link UP ``` The following table describes the output parameters. @@ -162,50 +166,50 @@ ifconfig - - - - - - - - - - - - - - - -

Output

+ diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-su.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-su.md index 49f296dbf7..68360718de 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-su.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-su.md @@ -1,8 +1,15 @@ # su +- [Command Function](#section297810431676) +- [Syntax](#section157131147876) +- [Parameters](#section04145521671) +- [Usage](#section14615155610719) +- [Example](#section13338150985) +- [Output](#section125021924194613) + ## Command Function -This command is used to switch the user. +This command is used to switch the user account. ## Syntax @@ -40,8 +47,8 @@ su \[_uid_\] \[_gid_\] ## Usage -- The **su** command is used to switch to user **root** by default. The default value for both **uid** and **gid** is **0**. -- If the **uid** and **gid** parameters are specified, this command can switch to the user with the specified **uid** and **gid**. +- 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 the input parameter is out of the range, an error message will be printed. ## Example @@ -50,6 +57,17 @@ Run **su 1000 1000**. ## Output -**Figure 1** Switching to the user whose **uid** and **gid** are both **1000** -![](figure/switching-to-the-user-whose-uid-and-gid-are-both-1000.png "switching-to-the-user-whose-uid-and-gid-are-both-1000") +Switching to the user with both **uid** and **gid** of **1000**: + +``` +OHOS # ls +Directory /data/system/param: +-rw-r--r-- 0 u:0 g:0 hello_1.txt +OHOS # su 1000 1000 +OHOS # touch hello 2.txt +OHOS # ls +Directory /data/system/param: +-rw-r--r-- O u:1000 g:1000 hello 2.txt +-гw-r--r-- 0 u:0 g:0 hello_1.txt +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md index b5aea0c05c..73676a220a 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md @@ -1,5 +1,12 @@ # swtmr +- [Command Function](#section166171064814) +- [Syntax](#section424011111682) +- [Parameters](#section1268410459465) +- [Usage](#section169806213815) +- [Example](#section16676026389) +- [Output](#section1541991614710) + ## Command Function This command is used to query information about system software timers. @@ -38,15 +45,42 @@ swtmr \[_ID_\] ## Example -Run **swtmr** and **swtmr 1**. +Run the following commands: -## Output +- swtmr +- swtmr 1 -**Figure 1** Querying information about all software timers -![](figure/querying-information-about-all-software-timers.png "querying-information-about-all-software-timers") +## Output -**Figure 2** Querying information about software timer 1 -![](figure/querying-information-about-software-timer-1.png "querying-information-about-software-timer-1") +Example 1: information about all software timers + +``` +OHOS # swtmr +SwTmrID State Mode Interval Count Arg handlerAddr +---------- ------- ------- --------- ------- ---------- -------- +0x00000000 Ticking Period 100 77 0x40802a50 0x4037b8a0 +SwTmrID State Mode Interval Count Arg handlerAddr +---------- ------- ------- --------- ------- ---------- -------- +0x00000001 Ticking Period 1000 876 0x00000000 0x4037fc04 +SwTmrID State Mode Interval Count Arg handlerAddr +---------- ------- ------- --------- ------- ---------- -------- +0x00000002 Ticking Period 100 76 0x00000000 0x403727f4 +SwTmrID State Mode Interval Count Arg handlerAddr +---------- ------- ------- --------- ------- ---------- -------- +0x00000016 Ticking NSD 10 6 0x8021e000 0x401fe7d8 +SwTmrID State Mode Interval Count Arg handlerAddr +---------- ------- ------- --------- ------- ---------- -------- +0x00000079 Ticking NSD 30000 1749 0x406189d8 0x40160e1c +``` + +Example 2: information about software timer 1 + +``` +OHOS # swtmr 1 +SwTmrID State Mode Interval Count Arg handlerAddr +---------- ------- ------- --------- ------- ---------- -------- +0x00000001 Ticking Period 1000 841 0x00000000 0x4037fc04 +``` **Table 2** Output @@ -76,7 +110,7 @@ Run **swtmr** and **swtmr 1**. - - - diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md index f1ef069637..d28355447b 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md @@ -1,8 +1,15 @@ # systeminfo +- [Command Function](#section863016434820) +- [Syntax](#section139791817795) +- [Parameters](#section19472339164813) +- [Usage](#section285522592) +- [Example](#section9471171015105) +- [Output](#section1657011114915) + ## Command Function -This command is used to display the resource usage of the current OS, including tasks, semaphores, mutexes, queues, and timers. +This command is used to display the resource usage of the current operating system, including tasks, semaphores, mutexes, queues, and software timers. ## Syntax @@ -22,13 +29,22 @@ Run **systeminfo**. ## Output -**Figure 1** Usage of system resources -![](figure/usage-of-system-resources.png "usage-of-system-resources") +Usage of system resources: + +``` +OHOS:/$ systeminfo + Module Used Total Enabled +-------------------------------------------- + Task 96 256 YES + Sem 435 1024 YES + Queue 13 1024 YES + SwTmr 20 1024 YES +``` **Table 1** Output -

Parameter

Description

Interval

Number of ticks used by the software timer

+

Number of ticks for the software timer

Count

@@ -86,12 +120,12 @@ Run **swtmr** and **swtmr 1**.

Arg

Input parameter passed

+

Input parameter

handlerAddr

Callback address

+

Address of the callback

- + + + + - + + - - - - - - - - - - @@ -52,15 +68,31 @@ uname \[_-a | -s | -t | -v | --help_\] ## Usage -The **uname** command displays the name of the current OS by default. The **uname -a | -t| -s| -v** command displays the name of the in-use OS in the standard output. These parameters are mutually exclusive. +- 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**. ## Example -Run **uname -a**. +Run the following commands: + +- uname -a +- uname -ms ## Output -Querying system information +Example 1: all information of the operating system + +``` +OHOS:/$ uname -a +Huawei LiteOS hisilicon 2.0.0.37 Huawei LiteOS 2.0.0.37 Oct 21 2021 17:39:32 Cortex-A7 +OHOS:/$ +``` + +Example 2: operating system name and architecture -![](figure/en-us_image_0000001179967909.png) +``` +OHOS:/$ uname -ms +Huawei LiteOS Cortex-A7 +OHOS:/$ +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md index 2a3437608c..3a207165b8 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md @@ -1,14 +1,20 @@ # vmm +- [Command Function](#section445335110416) +- [Syntax](#section1795712553416) +- [Parameters](#section92544592410) +- [Usage](#section104151141252) +- [Example](#section11545171957) +- [Output](#section075617368542) + ## Command Function -This command is used to query the virtual memory usage of a process. +This command is used to query the virtual memory used by a process. ## Syntax -vmm \[_-a / -h / --help_\] - -vmm \[_pid_\] +- vmm \[_-a / -h / --help_\] +- vmm \[_pid_\] ## Parameters @@ -49,7 +55,7 @@ vmm \[_pid_\] ## Usage -By default, the virtual memory usage of all processes is displayed. +By default, this command displays the virtual memory usage of all processes. ## Example @@ -57,8 +63,31 @@ Run **vmm 3**. ## Output -**Figure 1** Virtual memory usage of the process with PID 3 -![](figure/virtual-memory-usage-of-the-process-with-pid-3.png "virtual-memory-usage-of-the-process-with-pid-3") +Virtual memory usage of process 3: + +``` +OHOS # vmm 3 + PID aspace name base size pages + ---- ------ ---- ---- ----- ---- + 3 0x408c0118 foundation 0x01000000 0x3e000000 800 + region name base size mmu_flags pages pg/ref + ------ ---- ---- ---- --------- ----- ----- + 0x408cb364 /bin/foundation 0x06da3000 0x00001000 CH US RD 1 1 + 0x408cb80c /bin/foundation 0x06da4000 0x00001000 CH US RD EX 1 1 + 0x408cb720 /bin/foundation 0x06da5000 0x00001000 CH US RD 1 1 + 0x408cb9a8 /bin/foundation 0x06da6000 0x00001000 CH US RD WR 1 1 + 0x413efde4 HEAP 0x12b43000 0x00015000 CH US RD WR 19 19 + 0x408c3d34 /lib/libc.so 0x23b08000 0x0004a000 CH US RD 25 2 + 0x408cbd44 /lib/libc.so 0x23b52000 0x00068000 CH US RD EX 58 10 + 0x408c3dc0 /lib/libc.so 0x23bba000 0x00002000 CH US RD WR 2 2 + 0x408cc128 /lib/libc.so 0x23bbc000 0x00002000 CH US RD WR 2 2 + 0x408d1634 MMAP 0x23bbe000 0x00005000 CH US RD WR 5 5 + 0x408c4e10 VDSO 0x23bc3000 0x00002000 CH US RD EX 2 2 + 0x408dbaec /lib/libc++.so 0x23bc5000 0x00046000 CH US RD 51 5 + 0x408deba8 /lib/libc++.so 0x23c0b000 0x0009f000 CH US RD EX 29 10 + 0x408debf4 /lib/libc++.so 0x23caa000 0x00006000 CH US RD 6 6 + 0x408c3ce0 /lib/libc++.so 0x23cb0000 0x00001000 CH US RD WR 1 1 +``` **Table 2** Basic process information @@ -105,7 +134,7 @@ Run **vmm 3**. **Table 3** Virtual memory region information -

Output

+ diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-task.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-task.md index 4e6a7ce549..702530ad0a 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-task.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-task.md @@ -1,5 +1,12 @@ # task +- [Command Function](#section0533181714106) +- [Syntax](#section1014412308101) +- [Parameters](#section116057158506) +- [Usage](#section2053502951112) +- [Example](#section12629113381116) +- [Output](#section19299103465015) + ## Command Function This command is used to query information about processes and threads. @@ -33,7 +40,7 @@ task/task -a ## Usage -- If the parameter is not specified, partial task information is printed by default. +If no parameter is specified, partial task information is displayed by default. ## Example @@ -41,8 +48,33 @@ Run **task**. ## Output -**Figure 1** Querying partial task information -![](figure/querying-partial-task-information.png "querying-partial-task-information") +Task information \(partial\): + +``` +OHOS # task + allCpu(%): 3.54 sys, 196.46 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4dc8b 0.0 init + 2 -1 2 0 Pending 0x193318e 0 0x193318e 1.11 KProcess + 3 1 3 7 Pending 0x730000 0x1a2000 0x1d34f6 0.0 foundation + 4 1 4 8 Pending 0x35e000 0xb8000 0x56777 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x1487ce 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11c518 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa1ddf 0.89 wms_server + 8 1 1 1000 Running 0x2bf000 0x8f000 0x2a8c6 0.0 shell + 9 5 5 101 Pending 0x11ea000 0x2f9000 0x20429d 0.97 com.huawei.launcher + 11 1 11 0 Pending 0x4d4000 0x112000 0xe0ad7 0.0 deviceauth_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 + 14 1 14 0 Pending 0x61f000 0x13b000 0x16841c 0.50 softbus_server + TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName + 23 1 0x3 -1 Pending 0x3000 0xe44 0.0 0 init + 1 2 0x1 -1 Pending 0x4000 0x2c4 0.37 0 Swt_Task + 2 2 0x3 -1 Pending 0x4000 0x204 0.0 0 system_wq + 3 2 0x2 -1 Pending 0x4000 0x514 0.65 0 Swt_Task + 4 2 0x3 -1 Pending 0x1000 0x36c 0.0 0 ResourcesTask + 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread +``` **Table 2** Output diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-top.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-top.md new file mode 100644 index 0000000000..9826e59c8e --- /dev/null +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-top.md @@ -0,0 +1,179 @@ +# top + +- [Command Function](#section20643141481314) +- [Syntax](#section1075441721316) +- [Parameters](#section1472810220135) +- [Usage](#section186772414131) +- [Example](#section4764192791314) +- [Output](#section5791253155517) + +## Command Function + +This command is used to query process and thread information. + +## Syntax + +top \[_-a_\] + +## Parameters + +**Table 1** Parameter description + + +

Parameter

Description

+ + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Default Value

+

Value Range

+

--help

+

Displays the parameters supported by the top command.

+

N/A

+
  

-a

+

Displays detailed information.

+

N/A

+
  
+ +## Usage + +If no parameter is specified, this command displays process and thread information of some tasks by default. + +## Example + +Run **top**. + +## Output + +Command output + +``` +OHOS:/$ top + allCpu(%): 4.68 sys, 195.32 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4e01c 0.0 init + 2 -1 2 0 Pending 0xd838c0 0 0xd838c0 1.16 KProcess + 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d29dc 0.0 foundation + 4 1 4 8 Pending 0x362000 0xbb000 0x5cc19 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x148a0a 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.87 wms_server + 8 1 8 2 Pending 0x1f5000 0x48000 0x462dc 0.0 mksh + 9 5 5 101 Pending 0x11ea000 0x2f9000 0x204561 0.94 com.huawei.launcher + 11 1 11 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_service + 12 1 12 0 Pending 0x34f000 0xbd000 0x51cb3 0.0 sensor_service + 13 1 13 2 Pending 0x34e000 0xb3000 0x5269e 0.0 ai_server + 14 1 14 0 Pending 0x61f000 0x13b000 0x16858b 0.45 softbus_server + 43 8 43 2 Running 0x1d7000 0x3a000 0x1e9f5 0.0 toybox + TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName + 23 1 0x3 -1 Pending 0x3000 0xcf4 0.0 0 init + 1 2 0x1 -1 Pending 0x4000 0x2c4 0.33 0 Swt_Task + 2 2 0x3 -1 Pending 0x4000 0x204 0.0 0 system_wq + 3 2 0x2 -1 Pending 0x4000 0x514 0.75 0 Swt_Task + 4 2 0x3 -1 Pending 0x1000 0x3ac 0.0 0 ResourcesTask + 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread + 8 2 0x3 -1 Pending 0x4e20 0xa6c 0.0 0 PlatformWorkerThread + 9 2 0x3 -1 Pending 0x4e20 0xbf4 0.0 0 PlatformWorkerThread + 10 2 0x3 -1 Pending 0x3000 0x4dc 0.0 0 bcache_async_task + 11 2 0x3 -1 PendTime 0x4000 0x3e4 0.5 0 hi_vdec_thread + 12 2 0x3 -1 Pending 0x2710 0x224 0.0 0 LiteOS usb pnp notify handle kt + 13 2 0x3 -1 Pending 0x3000 0x37c 0.0 0 bcache_async_task + 14 2 0x3 -1 Pending 0x4000 0x204 0.0 0 vibrator_queue + 15 2 0x3 -1 Pending 0x20000 0x35c 0.0 0 eth_irq_Task + 16 2 0x3 -1 PendTime 0x2000 0x354 0.0 0 MessageDispatcher + 18 2 0x3 -1 Pending 0x2710 0x200 0.0 0 GPIO_IRQ_TSK_0_4 + 19 2 0x3 -1 Pending 0x4000 0x204 0.0 0 dispWQ + 20 2 0x3 -1 Pending 0x4000 0x204 0.0 0 hdf_sensor_test_work_queue + 21 2 0x3 -1 PendTime 0x6000 0x40c 0.2 0 tcpip_thread + 22 2 0x3 -1 Pending 0x4000 0x36c 0.0 0 SendToSer + 61 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_GIANT_Task + 63 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_NGIAN_ISOC_Task + 64 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_NGIAN_BULK_TasK +``` + +**Table 2** Output description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

PID

+

Process ID

+

PPID

+

Parent process ID

+

PGID

+

Process group ID

+

UID

+

User ID

+

Status

+

Current task status

+

CPUUSE10s

+

CPU usage within last 10 seconds

+

PName

+

Process name

+

TID

+

Task ID

+

StackSize

+

Size of the task stack

+

WaterLine

+

Peak value of the stack used

+

MEMUSE

+

Memory usage

+

TaskName

+

Task name

+
+ diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md index 243b928c16..78cb1416ad 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md @@ -1,12 +1,18 @@ # uname +- [Command Function](#section107697383115) +- [Syntax](#section162824341116) +- [Usage](#section2652124861114) +- [Example](#section0107995132) +- [Output](#section1215113245511) + ## Command Function -This command is used to display the name, version creation time, system name, and version information of the current OS. +This command is used to display the name, version creation time, system name, and version information of the current operating system. ## Syntax -uname \[_-a | -s | -t | -v | --help_\] +uname \[_-a | -s | -r | -m | -n | -v | --help_\] **Table 1** Parameters @@ -17,34 +23,44 @@ uname \[_-a | -s | -t | -v | --help_\]

No parameter

+

--help

+

Displays help information.

+

No parameter

+

Displays the operating system name by default.

Displays the OS name by default.

+

-a

+

Displays all information.

-a

+

-s

Displays all information.

+

Displays the operating system name.

-t

+

-r

Displays the time when the version was created.

+

Displays the kernel release version.

-s

+

-m

Displays the OS name.

+

Displays the operating system architecture name.

-v

+

-n

Displays the version information.

+

Displays the network domain name of the host.

--help

+

-v

Displays the help information.

+

Displays version information.

- - - - - - - - - - - - - - - - - - - - - - - - - @@ -87,45 +54,36 @@ dhclient -sd <_dns\_ip_\> ## Usage -dhclient eth0 - -dhclient -x eth0 - -dhclient -gb eth0 - -dhclient -sv MFSI - -dhclient -gv - -dhclient -gd 0 +Run the following commands: -dhclient -sd 8.8.8.8 +- dhclient eth0 +- dhclient -x eth0 ## Example -![](figure/en-us_image_0000001179848731.png) - -## Output - -**Table 2** Output description - - -

Output

+ diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md index 94cc69f072..65d163661a 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md @@ -1,14 +1,20 @@ # watch +- [Command Function](#section20643141481314) +- [Syntax](#section1075441721316) +- [Parameters](#section1472810220135) +- [Usage](#section186772414131) +- [Example](#section4764192791314) +- [Output](#section5791253155517) + ## Command Function -This command is used to periodically monitor the execution result of a command. +This command is used to periodically run the specified command and display its execution result. ## Syntax -watch - -watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] +- watch +- watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] ## Parameters @@ -27,7 +33,7 @@ watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] - @@ -36,7 +42,7 @@ watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] - @@ -75,19 +81,52 @@ watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] ## Usage -You can run the **watch --over** command to stop the currently running command monitoring. +You can run the **watch --over** command to stop monitoring of the specified command. ## Example -Example: - -watch -n 2 -c 6 task - -## Output Description - -**Figure 1** **task** command monitoring result -![](figure/task-command-monitoring-result.png "task-command-monitoring-result") - ->![](../public_sys-resources/icon-note.gif) **NOTE:** ->In this example, the **task** command has been executed every 2 seconds for six times, and the preceding figure shows the output of the last execution. +Run **watch -n 2 -c 6 task**. + +## Output + +Example: The **task** command is executed six times at an interval of 2 seconds. + +``` +OHOS # watch -n 2 -c 6 task +Thu Jan 1 23:57:13 1970 +OHOS # + allCpu(%): 3.55 sys, 196.45 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4dc8b 0.0 init + 2 -1 2 0 Running 0x19524f2 0 0x19524f2 1.14 KProcess + 3 1 3 7 Pending 0x730000 0x1a2000 0x1d34f6 0.0 foundation + 4 1 4 8 Pending 0x35e000 0xb8000 0x56777 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x1487ce 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11c518 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa1ddf 0.95 wms_server + 8 1 1 1000 Running 0x2bf000 0x8f000 0x2a8c6 0.0 shell + 9 5 5 101 Pending 0x11ea000 0x2f9000 0x20429d 1.2 com.huawei.launcher + 11 1 11 0 Pending 0x4d4000 0x112000 0xe0ad7 0.0 deviceauth_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 + 14 1 14 0 Pending 0x61f000 0x13b000 0x16841c 0.51 softbus_server + TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName + 23 1 0x3 -1 Pending 0x3000 0xe44 0.0 0 init + 1 2 0x1 -1 Pending 0x4000 0x2c4 0.64 0 Swt_Task + 2 2 0x3 -1 Pending 0x4000 0x204 0.0 0 system_wq + 3 2 0x2 -1 Pending 0x4000 0x514 0.40 0 Swt_Task + 4 2 0x3 -1 Pending 0x1000 0x36c 0.0 0 ResourcesTask + 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread + 8 2 0x3 -1 Pending 0x4e20 0xa6c 0.0 0 PlatformWorkerThread + 9 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread + 10 2 0x3 -1 PendTime 0x4000 0x3e4 0.5 0 hi_vdec_thread + 11 2 0x3 -1 Pending 0x3000 0x4cc 0.0 0 bcache_async_task + 12 2 0x3 -1 Pending 0x2710 0x224 0.0 0 LiteOS usb pnp notify handle kt + 13 2 0x3 -1 Pending 0x4000 0x204 0.0 0 vibrator_queue + 14 2 0x3 -1 Pending 0x3000 0x37c 0.0 0 bcache_async_task + 15 2 0x3 -1 Pending 0x20000 0x3e4 0.0 0 eth_irq_Task + 16 2 0x3 -1 PendTime 0x2000 0x3a4 0.0 0 MessageDispatcher + 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 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-cmd.md b/en/device-dev/kernel/kernel-small-debug-shell-cmd.md index 3de879965b..7d486f835f 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-cmd.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-cmd.md @@ -44,4 +44,8 @@ - **[watch](kernel-small-debug-shell-cmd-watch.md)** +- **[reboot](kernel-small-debug-shell-cmd-reboot.md)** + +- **[top](kernel-small-debug-shell-cmd-top.md)** + diff --git a/en/device-dev/kernel/kernel-small-debug-shell-error.md b/en/device-dev/kernel/kernel-small-debug-shell-error.md index 617269e698..7dd0c56ef7 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-error.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-error.md @@ -1,6 +1,6 @@ -# User-Space Exception Information +# User-Mode Exception Information -During the running of the user space, the following system exception may occur: +During the running of the user mode, the following system exception may occur: ``` ##################excFrom: User!#################### @@ -58,7 +58,7 @@ traceback 0 -- lr = 0x229123a4 fp = 0x0 lr in /lib/libc.so --> 0x213a4 system memcheck over, all passed! ``` -The following information is included: +The system exception includes the following information: 1. Basic information about the user-mode exception: @@ -131,6 +131,6 @@ The following information is included: system memcheck over, all passed! ``` - Based on the preceding information, you can analyze the causes of the user-space exception. + Based on the preceding information, you can analyze the causes of the user-mode exception. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-cat.md b/en/device-dev/kernel/kernel-small-debug-shell-file-cat.md index ba509bf07b..b3c4600aae 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-cat.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-cat.md @@ -1,5 +1,12 @@ # cat +- [Command Function](#section16710153391315) +- [Syntax](#section1699392313158) +- [Parameters](#section1677217374136) +- [Usage](#section186772414131) +- [Example](#section12158131814561) +- [Output](#section183926225561) + ## Command Function This command is used to display the content of a text file. @@ -41,6 +48,10 @@ Run **cat hello-harmony.txt**. ## Output -**Figure 1** Displaying the content of **hello-harmony.txt** -![](figure/displaying-the-content-of-hello-harmony-txt.png "displaying-the-content-of-hello-harmony-txt") +Content of **hello-harmony.txt** + +``` +OHOS # cat hello-harmony.txt +OHOS # Hello Harmony ;) +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-cd.md b/en/device-dev/kernel/kernel-small-debug-shell-file-cd.md index 83730053a5..8730d3dfc6 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-cd.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-cd.md @@ -1,5 +1,12 @@ # cd +- [Command Function](#section11690184921316) +- [Syntax](#section75695409569) +- [Parameters](#section71961353181311) +- [Usage](#section3629759111317) +- [Example](#section211620301412) +- [Output](#section1968117214577) + ## Command Function This command is used to change the current working directory. @@ -23,7 +30,7 @@ cd \[_path_\] - @@ -33,18 +40,25 @@ cd \[_path_\] ## Usage -- If the **path** parameter is not specified, the system switches to the root directory. -- If the **path** parameter is specified, the system switches to the specified path. +- If **path** is not specified, this command switches to the root 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 two dots \(..\) represents the parent directory. +- You can run **cd -** to alternate between two directories that are recently accessed. ## Example -Run **cd**. +Run **cd ..**. ## Output -**Figure 1** Changing the directory -![](figure/changing-the-directory.png "changing-the-directory") +Parent directory information: + +``` +OHOS:/nfs$ cd ../ +OHOS:/$ ls +bin etc nfs sdcard system tmp vendor +dev lib proc storage test usr +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md b/en/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md index 6f8f01ec96..e80f1ee4cc 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md @@ -1,16 +1,23 @@ # chgrp +- [Command Function](#section6103119161418) +- [Syntax](#section186958132141) +- [Parameters](#section81796174141) +- [Usage](#section14330152417140) +- [Example](#section951823119149) +- [Output](#section14271133125715) + ## Command Function -This command is used to change a file group. +This command is used to change the file group. ## Syntax chgrp \[_group_\] \[_pathname_\] -## Parameter Description +## Parameters -**Table 1** Parameters +**Table 1** Parameter description

Parameter

Description

-c / --count

Specifies the number of times that the command is executed.

+

Specifies the number of times that the specified command is executed.

0xFFFFFF

-n / --interval

Specifies the interval for periodically running the command, in seconds.

+

Specifies the interval (in seconds) for periodically running the specified command.

1s

path

Specifies the file path.

+

Specifies the target file path.

You must have the execution (search) permission for the specified directory.

- @@ -40,14 +47,23 @@ chgrp \[_group_\] \[_pathname_\] ## Usage -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. ## Example -Run **chgrp 100 hello-harmony.txt**. +Run **chgrp 100 testfile**. ## Output -**Figure 1** Changing the group of the **hello-harmony.txt** file to **100** -![](figure/changing-the-group-of-the-hello-harmony-txt-file-to-100.png "changing-the-group-of-the-hello-harmony-txt-file-to-100") +Changing the group ID of the **testfile** file in the **dev/** directory to **100** + +``` +OHOS:/dev$ ll testfile +-rw-r--r-- 0 0 0 0 1970-01-01 00:00 testfile +OHOS:/dev$ chgrp 100 testfile +OHOS:/dev$ ll testfile +-rw-r--r-- 0 0 100 0 1970-01-01 00:00 testfile +OHOS:/dev$ +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-chmod.md b/en/device-dev/kernel/kernel-small-debug-shell-file-chmod.md index 656b85c073..ebf41f5105 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-chmod.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-chmod.md @@ -1,38 +1,45 @@ # chmod +- [Command Function](#section13992936121418) +- [Syntax](#section63342439147) +- [Parameter Description](#section894414671411) +- [Usage](#section182415221419) +- [Example](#section8518195718147) +- [Output](#section127391818158) + ## Command Function -This command is used to change the file operation permission. +This command is used to change file operation permissions. ## Syntax -chmod \[_mode_\] \[_pathname_\] +chmod \[_mode_\] \[_filename_\] ## Parameter Description **Table 1** Parameters -

Parameter

@@ -23,7 +30,7 @@ chgrp \[_group_\] \[_pathname_\]

group

Specifies the file group.

+

Specifies the target file group.

[0, 0xFFFFFFFF]

- - - @@ -41,7 +48,7 @@ partition \[_nand / spinor_\] ## Usage - The **partition** command is used to query flash partition information. -- The NAND flash partition information can be viewed only when the YAFFS file system is enabled. The spinor flash partition information can be viewed only when the JFFS or ROMFS file system is enabled. +- The NAND flash partition information can be queried only when the Yet Another Flash File System \(YAFFS\) is enabled. The SPI NOR flash partition information can be queried only when the Journaling Flash File System \(JFFS\) or ROM filesystem \(romfs\) is enabled. ## Example @@ -49,7 +56,10 @@ Run **partition spinor**. ## Output -Viewing spinor flash partition information +SPI NOR flash partition information: -![](figure/en-us_image_0000001179848349.png) +``` +OHOS # partition spinor +spinor partition num:0, blkdev name:/dev/spinorblk0, mountpt:/, startaddr:0x00500000, length:0x00a00000 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-pwd.md b/en/device-dev/kernel/kernel-small-debug-shell-file-pwd.md index 45105c3d9e..be084dd5a2 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-pwd.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-pwd.md @@ -1,5 +1,12 @@ # pwd +- [Command Function](#section197737712267) +- [Syntax](#section1544061016267) +- [Parameters](#section599112120262) +- [Usage](#section66901116152615) +- [Example](#section7427181922612) +- [Output](#section116313389418) + ## Command Function This command is used to display the current path. @@ -14,7 +21,7 @@ None ## Usage -The **pwd** command writes the full path name of the current directory \(from the root directory\) to the standard output. All 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 @@ -22,6 +29,10 @@ Run **pwd**. ## Output -**Figure 1** Displaying the current path -![](figure/displaying-the-current-path.png "displaying-the-current-path") +Current path: + +``` +OHOS:/sdcard/nfs$ pwd +/sdcard/nfs +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-rm.md b/en/device-dev/kernel/kernel-small-debug-shell-file-rm.md index 8163d8398e..6d095508ab 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-rm.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-rm.md @@ -1,12 +1,19 @@ # rm +- [Command Function](#section181141523142613) +- [Syntax](#section8800926132619) +- [Parameters](#section15476229152617) +- [Usage](#section10578163215262) +- [Example](#section18548133511263) +- [Output](#section1565323814265) + ## Command Function This command is used to delete a file or folder. ## Syntax -rm \[_-r_\] \[_dirname / filename_\] +rm \[_-fv_\] _FILE or rm_ \[_-rv_\] \[_PATH_ | _filename_\]... ## Parameters @@ -21,18 +28,32 @@ rm \[_-r_\] \[_dirname / filename_\] - + + + + - - - - - + + + + @@ -40,21 +61,40 @@ rm \[_-r_\] \[_dirname / filename_\] ## Usage -- The **rm** command deletes only one file or directory at a time. -- The **rm -r** command can be used to delete a non-empty directory. +- 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. +- If the **rm** command without **-f** is used to delete a file that does not exist, an error will be reported. ## Example -Example: +Run the following commands: -1. Run **rm log1.txt**. -2. Run **rm -r sd**. +- rm testfile +- rm -r testpath/ ## Output -**Figure 1** Deleting the **log1.txt** file -![](figure/deleting-the-log1-txt-file.png "deleting-the-log1-txt-file") - -**Figure 2** Deleting the **sd** directory -![](figure/deleting-the-sd-directory.png "deleting-the-sd-directory") +Example 1: deleting **testfile** + +``` +OHOS:/$ ls +bin etc proc storage testfile usr +dev lib sdcard system userdata vendor +OHOS:/$ rm testfile +OHOS:/$ ls +bin etc proc storage userdata vendor +dev lib sdcard system usr +``` + +Example 2: deleting **testpath**, a non-empty directory + +``` +OHOS:/$ ls +bin etc proc storage testpath usr +dev lib sdcard system userdata vendor +OHOS:/$ rm -r testpath/ +OHOS:/$ ls +bin etc proc storage userdata vendor +dev lib sdcard system usr +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md b/en/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md index d100ced24c..faf656c5e4 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md @@ -1,12 +1,19 @@ # rmdir +- [Command Function](#section1839611420266) +- [Syntax](#section329574512266) +- [Parameters](#section15865747102620) +- [Usage](#section107857508261) +- [Example](#section11196165315262) +- [Output](#section1073811415613) + ## Command Function This command is used to delete a directory. ## Syntax -rmdir \[_dir_\] +rmdir \[_-p_\] \[_dirname..._\] ## Parameters @@ -21,11 +28,32 @@ rmdir \[_dir_\] - + + + + + + - + + - + + + + @@ -43,6 +71,13 @@ Run **rmdir dir**. ## Output -**Figure 1** Deleting directory **dir** -![](figure/deleting-directory-dir.png "deleting-directory-dir") +Deleting the directory **dir**: + +``` +OHOS:/test$ mkdir dir +OHOS:/test$ ls +dir +OHOS:/test$ rmdir dir/ +OHOS:/test$ ls +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-statfs.md b/en/device-dev/kernel/kernel-small-debug-shell-file-statfs.md index 075b20bd91..06d2354bc3 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-statfs.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-statfs.md @@ -1,5 +1,11 @@ # statfs +- [Command Function](#section153921657152613) +- [Syntax](#section135391102717) +- [Parameters](#section074312314279) +- [Usage](#section133816772712) +- [Example](#section526149182717) + ## Command Function This command is used to print information about a file system, such as the type, total size, and available size. @@ -25,7 +31,7 @@ statfs \[_directory_\] - @@ -41,6 +47,19 @@ The following uses the NFS as an example: Run **statfs /nfs**. -**Figure 1** Output of the statfs command -![](figure/output-of-the-statfs-command.png "output-of-the-statfs-command") +**statfs** command output + +``` +OHOS # statfs ./nfs +statfs got: + f_type = 26985 + cluster_size = 512 + total_clusters = 1579575176 + free_clusters = 499254808 + avail_clusters = 499254808 + f_namelen = 255 +./nfs + total size: 808742490112 Bytes + free size: 255618461696 Bytes +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-sync.md b/en/device-dev/kernel/kernel-small-debug-shell-file-sync.md index d702ed80a7..6e8c72e286 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-sync.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-sync.md @@ -1,5 +1,12 @@ # sync +- [Command Function](#section1285017122274) +- [Syntax](#section4731516162712) +- [Parameters](#section9352418122714) +- [Usage](#section10725192142717) +- [Example](#section414434814354) +- [Output](#section19618121710317) + ## Command Function This command is used to synchronize cached data \(data in the file system\) to an SD card. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-touch.md b/en/device-dev/kernel/kernel-small-debug-shell-file-touch.md index c8254e3635..8120954bea 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-touch.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-touch.md @@ -1,5 +1,12 @@ # touch +- [Command Function](#section17541924112716) +- [Syntax](#section866182711274) +- [Parameters](#section268912296270) +- [Usage](#section412093332714) +- [Example](#section414434814354) +- [Output](#section1028419515711) + ## Command Function - This command is used to create an empty file in a specified directory. @@ -22,11 +29,18 @@ touch \[_filename_\] - + + - + + - @@ -35,18 +49,43 @@ touch \[_filename_\] ## Usage - The **touch** command creates an empty file that is readable and writeable. -- The **touch** command creates only one file at a time. +- You can use the **touch** command to create multiple files at a time. >![](../public_sys-resources/icon-notice.gif) **NOTICE:** - >If you run the **touch** command to create a file in a path 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** path, 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. ## Example -Run **touch file.c**. +Run the following commands: + +- touch file.c +- touch testfile1 testfile2 testfile3 ## Output -**Figure 1** Creating **file.c** -![](figure/creating-file-c.png "creating-file-c") +Example 1: creating the **file.c** file + +``` +OHOS:/tmp$ ls +OHOS:/tmp$ touch file.c +OHOS:/tmp$ ls +file.c +OHOS:/tmp$ ll +total 0 +-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 file.c* +``` + +Example 2: creating three files \(**testfile1**, **testfile2**, and **testfile3**\) + +``` +*OHOS:/tmp$ +OHOS:/tmp$ touch testfile1 testfile2 testfile3 +OHOS:/tmp$ ll +total 0 +-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 testfile1* +-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 testfile2* +-rwxrwxrwx 1 0 0 0 1979-12-31 00:00 testfile3* +OHOS:/tmp$ +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-umount.md b/en/device-dev/kernel/kernel-small-debug-shell-file-umount.md index c7c2bbf193..59740a6970 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-umount.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-umount.md @@ -1,12 +1,19 @@ # umount +- [Command Function](#section365125133520) +- [Syntax](#section9615254123512) +- [Parameters](#section63446577355) +- [Usage](#section92931509368) +- [Example](#section144311323616) +- [Output](#section360525113611) + ## Command Function This command is used to unmount a specified file system. ## Syntax -umount \[_dir_\] +umount \[_-a \[-t TYPE\]_\] \[_dir_\] ## Parameters @@ -21,11 +28,32 @@ umount \[_dir_\] - + + + + + + + + - - + + + + @@ -37,12 +65,26 @@ By specifying the **dir** parameter in the **unmount** command, you can unmo ## Example -Run **umount /bin1/vs/sd**. +Run the following commands: + +- umount ./nfs +- umount -a -t nfs ## Output -Unmounting the file system from **/bin1/vs/sd** +**unmount** command output: + +Example 1: unmounting the file system from **./nfs** + +``` +OHOS:/$ umount ./nfs/ +umount ok +``` + +Example 2: unmounting all NFS directories -**Figure 1** Unmounting result -![](figure/unmounting-result.png "unmounting-result") +``` +OHOS:/$ umount -a -t nfs +umount ok +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-write.md b/en/device-dev/kernel/kernel-small-debug-shell-file-write.md index bb16d5bbe1..1957be6872 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-write.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-write.md @@ -1,5 +1,12 @@ # writeproc +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameters](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) +- [Output](#section12742311179) + ## 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. @@ -40,7 +47,7 @@ writeproc <_data_\> \>\> /proc/<_filename_\> ## Usage -The proc file implements its own **write** command. Calling the **writeproc** command will pass the input parameter to the **write** command. +The proc file implements its own **write** command. Calling the **writeproc** command will pass the input parameters to the **write** command. >![](../public_sys-resources/icon-note.gif) **NOTE:** >The procfs file system does not support multi-thread access. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file.md b/en/device-dev/kernel/kernel-small-debug-shell-file.md index 93d1834422..52a4812f6c 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file.md @@ -42,4 +42,8 @@ - **[umount](kernel-small-debug-shell-file-umount.md)** +- **[du](kernel-small-debug-shell-file-du.md)** + +- **[mv](kernel-small-debug-shell-file-mv.md)** + diff --git a/en/device-dev/kernel/kernel-small-debug-shell-guide.md b/en/device-dev/kernel/kernel-small-debug-shell-guide.md index 7a921ef64e..588af244e9 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-guide.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-guide.md @@ -1,5 +1,7 @@ # Shell Command Development Guidelines +- [Development Guidelines](#section13408945163812) + ## Development Guidelines You can perform the following operations to add shell commands: diff --git a/en/device-dev/kernel/kernel-small-debug-shell-magickey.md b/en/device-dev/kernel/kernel-small-debug-shell-magickey.md index f3c32b24b2..55133e1e74 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-magickey.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-magickey.md @@ -1,10 +1,13 @@ # Magic Key +- [When to Use](#section2350114718546) +- [How to Use](#section3305151511559) + ## When to Use When the system does not respond, you can use the magic key to check whether the system is locked and interrupted \(the magic key also does not respond\) or view the system task running status. -If an interrupt is 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. +If an interrupt is 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. ## How to Use @@ -17,11 +20,11 @@ The magic key depends on the **LOSCFG\_ENABLE\_MAGICKEY** macro. Before using The magic key cannot be used if this macro is disabled. >![](../public_sys-resources/icon-note.gif) **NOTE:** ->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 type a question mark \(?\) to view help information. 2. 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. +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 the magic key, press **Ctrl+R** again. If "Magic key off" is displayed, the magic key is disabled. @@ -37,5 +40,5 @@ You can use the magic key combinations as follows: >![](../public_sys-resources/icon-notice.gif) **NOTICE:** ->If special characters need to be entered through the UART or USB-to-virtual serial port if magic key is enabled, 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 the original design. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-arp.md b/en/device-dev/kernel/kernel-small-debug-shell-net-arp.md index 9650aaf328..c34a87ecc6 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-arp.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-arp.md @@ -1,8 +1,14 @@ # arp +- [Command Function](#section201149459368) +- [Syntax](#section579813484364) +- [Parameters](#section168065311366) +- [Usage](#section19190125723612) +- [Example](#section10383416372) + ## Command Function -On an Ethernet, hosts communicate with each other using MAC addresses \(non-IP addresses\). Therefore, IP addresses must be converted into MAC addresses so that hosts can communicate with each other on a LAN \(Ethernet\). To resolve this issue, the host stores a table containing the mapping between IP addresses and MAC addresses, that is, the ARP cache table. When the host needs to send an IP packet to the destination IP address on a LAN, the host can query the destination MAC address from the ARP cache table. The ARP cache table is maintained by the TCP/IP protocol 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 @@ -27,7 +33,7 @@ arp \[_-i IF_\] -d _IPADDR_ - @@ -59,50 +65,50 @@ arp \[_-i IF_\] -d _IPADDR_ ## Usage -- The **arp** command is used to query and modify the ARP cache table of the TCP/IP protocol 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 protocol stack is enabled. +- 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 -Example: - -1. Run **arp**. - - **Figure 1** Printing the entire ARP cache table - - - ![](figure/snipaste_2021-01-26_10-38-58.png) - - **Table 2** Output description - - -

Parameter

+ - - - - - - - - @@ -40,14 +47,23 @@ chmod \[_mode_\] \[_pathname_\] ## Usage -Specify \[_mode_\] to change the file permission. +- 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. ## Example -Run **chmod 666 hello-harmony.txt**. +Change the permissions on the **hello-harmony.txt** file to **644** and **777**. ## Output -**Figure 1** Changing the permission for the **hello-harmony.txt** file to **666** -![](figure/changing-the-permission-for-the-hello-harmony-txt-file-to-666.png "changing-the-permission-for-the-hello-harmony-txt-file-to-666") +Modifying the permissions on the **hello-harmony.txt** file in the **/dev** directory: + +``` +OHOS:/dev$ chmod 644 hello-harmony.txt +OHOS:/dev$ ll hello-harmony.txt +-rw-r--r-- 0 0 0 0 1970-01-01 00:00 hello-harmony.txt +OHOS:/dev$ chmod 777 hello-harmony.txt +OHOS:/dev$ ll hello-harmony.txt +-rwxrwxrwx 0 0 0 0 1970-01-01 00:00 hello-harmony.txt +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-chown.md b/en/device-dev/kernel/kernel-small-debug-shell-file-chown.md index f8a13edb7a..87588554cc 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-chown.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-chown.md @@ -1,12 +1,19 @@ # chown +- [Command Function](#section247414691513) +- [Syntax](#section14773151018159) +- [Parameters](#section598731391517) +- [Usage](#section16524152071510) +- [Example](#section17901152561510) +- [Output](#section15513163115816) + ## Command Function -This command is used to change the owner and group of a specified file. +This command is used to change the owner of a file. ## Syntax -chown \[_owner_\] \[_group_\] \[_pathname_\] +chown \[_owner_\] \[_pathname_\] ## Parameters @@ -21,26 +28,18 @@ chown \[_owner_\] \[_group_\] \[_pathname_\] - - - - - - - - - - @@ -48,16 +47,22 @@ chown \[_owner_\] \[_group_\] \[_pathname_\] ## Usage -- By specifying the **owner** and **group** parameters in this command, you can change the owner and group of the file. -- If **owner** or **group** is **-1**, the owner or group of the file will not be changed. -- The **group** parameter can be left blank. +This command does not apply to the FAT file system. ## Example -Run **chown 100 200 hello-harmony.txt**. +Run **chown 100 testfile**. ## Output -**Figure 1** Changing the owner and group of the hello-harmony.txt file to 100 and 200 respectively -![](figure/changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively.png "changing-the-owner-and-group-of-the-hello-harmony-txt-file-to-100-and-200-respectively") +Changing the UID of the **testfile** file in **/dev** to **100**: + +``` +OHOS:/dev$ touch testfile +OHOS:/dev$ ll testfile +-rw-r--r-- 0 0 100 0 1970-01-01 00:00 testfile +OHOS:/dev$ chown 100 testfile +OHOS:/dev$ ll testfile +-rw-r--r-- 0 100 100 0 1970-01-01 00:00 testfile +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-cp.md b/en/device-dev/kernel/kernel-small-debug-shell-file-cp.md index 69e530cf25..93119d0a80 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-cp.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-cp.md @@ -1,5 +1,12 @@ # cp +- [Command Function](#section6841203041513) +- [Syntax](#section24286359150) +- [Parameters](#section558617385152) +- [Usage](#section16128156162) +- [Example](#section19354171211618) +- [Output](#section16754183195914) + ## Command Function This command is used to create a copy for a file. @@ -21,18 +28,25 @@ cp \[_SOURCEFILE_\] \[_DESTFILE_\] - + + - + + - - - - @@ -41,21 +55,33 @@ cp \[_SOURCEFILE_\] \[_DESTFILE_\] ## Usage - The name of the source file cannot be the same as that of the destination file in the same path. -- The source file must exist and cannot be a directory. -- The source file path supports wildcards asterisk \(\*\) and question mark\(?\). The asterisk \(\*\) indicates any number of characters, and the question mark \(?\) indicates any single character. The destination path does not support wildcards. If the source path matches multiple files, the destination path must be a directory. -- If the destination file path 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. -- Currently, this command can be used to copy only one file. If more than two parameters are specified, only the first two parameters take effect. +- **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. +- If **DESTFILE** specifies 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. -When important system resources are copied, unexpected results such as a system breakdown may occur. For example, when the **/dev/uartdev-0** file is copied, the system may stop responding. +>![](../public_sys-resources/icon-notice.gif) **NOTICE:** +>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 -Run **cp hello-harmony.txt ./tmp/**. +Run **cp hello-OHOS.txt hello-harmony.txt ./tmp/**. ## Output -**Figure 1** File copying result -![](figure/file-copying-result.png "file-copying-result") +Copying **hello-OHOS.txt** and **hello-harmony.txt** to **/tmp/**: + +``` +OHOS:/$ ls +bin hello-OHOS.txt proc system vendor +dev hello-harmony.txt sdcard userdata +etc lib storage usr +OHOS:/$ mkdir tmp +OHOS:/$ cp hello-OHOS.txt hello-harmony.txt tmp/ +OHOS:/$ ll tmp +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-harmony.txt* +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-du.md b/en/device-dev/kernel/kernel-small-debug-shell-file-du.md new file mode 100644 index 0000000000..9a53aaa356 --- /dev/null +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-du.md @@ -0,0 +1,93 @@ +# du + +- [Command Function](#section201149459368) +- [Syntax](#section579813484364) +- [Parameters](#section168065311366) +- [Usage](#section19190125723612) +- [Example](#section10383416372) +- [Output](#section16633113552815) + +## Command Function + +This command is used to query the disk space occupied by a file. + +## Syntax + +du \[_-kKmh_\] \[_file..._\] + +## Parameters + +**Table 1** Parameter description + + +

Parameter

Description

+

Description

Value Range

+

Value Range

mode

+

mode

Specifies the permission for a file or directory. The value is an octal number, representing the permission of User (owner), Group (group), or Other (other groups).

+

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]

+

[0,777]

pathname

+

filename

Specifies the file path.

+

Specifies the file name.

An existing file

+

An existing file

owner

-

Specifies the file owner.

-

[0, 0xFFFFFFFF]

+

owner

group

-

Specifies the file group.

+

Specifies the file owner.

Left blank

-

[0, 0xFFFFFFFF]

+

[0,0xFFFFFFFF]

pathname

+

pathname

Specifies the file path.

+

Specifies the file path.

An existing file

+

An existing file

SOURCEFILE

+

--help

+

Displays help information.

+

N/A

Specifies the path to the source file.

+

SOURCEFILE

+

Specifies the path of the source file.

Currently, only files are supported. Directories are not supported.

+

This command does not support copy of a directory, but supports copy of multiple files at a time.

DESTFILE

+

DESTFILE

Specifies the path to the destination file.

+

Specifies the destination file path.

Both directories and files are supported.

+

Both a directory and a file are supported.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

--help

+

Displays the parameters supported by the du command.

+

N/A

+

-k

+

Displays the occupied blocks, each of which is 1024 bytes by default.

+

N/A

+

-K

+

Displays the occupied blocks, each of which is 512 bytes (POSIX).

+

N/A

+

-m

+

Displays the disk space in MB.

+

N/A

+

-h

+

Displays the disk space in human-readable format K, M, and G, for example, 1K, 243M, or 2G.

+

N/A

+

file

+

Specifies the target file.

+

N/A

+
+ +## Usage + +- 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. + +## Example + +Run **du -h testfile**. + +## Output + +Command output + +``` +OHOS:/$ du -h testfile +1.8K testfile +``` + diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-format.md b/en/device-dev/kernel/kernel-small-debug-shell-file-format.md index 5fff38b11e..b2a5c18f55 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-format.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-format.md @@ -1,8 +1,15 @@ # format +- [Command Function](#section1922331919169) +- [Syntax](#section249226169) +- [Parameters](#section985173416177) +- [Usage](#section1510162714162) +- [Example](#section25691431161611) +- [Output](#section17368112365920) + ## Command Function -This command is used to format a disk. +This command is used for disk formatting. ## Syntax @@ -26,14 +33,14 @@ format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\]

sectors

Specifies the size of the allocated memory unit or sector. The value 0 indicates that the parameter is null. (The value must be 0 or a power of 2. 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.)

+

Specifies the size of the allocated memory unit or sector. The value 0 indicates null. (The value must be 0 or a power of 2. 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.)

option

Specifies the formatting option for selecting the file system type. The options are as follows:
  • 0x01: FMT_FAT
  • 0x02: FMT_FAT32
  • 0x07: FMT_ANY
  • 0x08: FMT_ERASE (not supported by the USB flash drive)
+
Specifies the file system type. The options are as follows:
  • 0x01: FMT_FAT
  • 0x02: FMT_FAT32
  • 0x07: FMT_ANY
  • 0x08: FMT_ERASE (not supported by the USB flash drive)
-

Other values are invalid. The system will automatically select the formatting mode. If the low-level formatting bit is 1 during the formatting of a USB flash drive, an error message is printed.

+

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.

label

@@ -46,9 +53,9 @@ format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] ## Usage -- The **format** command is used to format a disk. You can find the device name in the **dev** directory. A storage card must be installed before the formatting. -- This command can be used to format only the USB flash drive, SD card, and MMC, but not the NAND flash and NOR flash. -- The **sectors** parameter must be set to a valid value. An invalid value may cause exceptions. +- 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. +- An invalid **sectors** value may cause exceptions. ## Example @@ -56,7 +63,11 @@ Run **format /dev/mmcblk0 128 2**. ## Output -Formatting result +Formatting an MMC: -![](figure/en-us_image_0000001134008686.png) +``` +OHOS # format /dev/mmcblk1 128 2 +Format to FAT32, 128 sectors per cluster. +format /dev/mmcblk1 Success +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-ls.md b/en/device-dev/kernel/kernel-small-debug-shell-file-ls.md index becd75f244..d171d10e01 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-ls.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-ls.md @@ -1,16 +1,26 @@ # ls +- [Command Function](#section6538163771614) +- [Syntax](#section45881743111616) +- [Parameters](#section17528148171617) +- [Usage](#section041212533166) +- [Example](#section986105716167) +- [Output](#section2036124918592) + ## Command Function This command is used to display the content of a specified directory. ## Syntax -ls \[_path_\] +ls \[_-ACHLSZacdfhiklmnopqrstux1_\] \[_--color_\[_=auto_\]\] \[_directory..._\] + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>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 -**Table 1** Parameter description +**Table 1** Command parameter description - + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

@@ -21,15 +31,245 @@ ls \[_path_\]

path

+

--help

+

Displays parameters supported by the ls command and their usage.

+

N/A

+

-a

+

Displays all files, including .hidden files.

+

N/A

+

-b

+

Escapes non-graphical characters.

+

N/A

+

-c

+

Uses ctime as the file timestamp. This parameter must be used together with -l.

+

N/A

+

-d

If path is left blank, the content of the current directory is displayed.

-

If the path value is an invalid file name, the following failure message is displayed:

-

ls error: No such directory

-

If the path value is a valid directory, the content of this directory is displayed.

+

Displays only the directory, rather than listing the content of the directory.

Left blank

-

A valid directory

+

N/A

+

-i

+

Displays the node ID of a file.

+

N/A

+

-p

+

Adds a slash (/) after the directory.

+

N/A

+

-q

+

Displays non-printable characters, such as "?".

+

N/A

+

-s

+

Provides information about the memory occupied by the directory and its members, in 1024 bytes.

+

N/A

+

-u

+

Uses the last access time of the file as the timestamp. This option is used together with -l.

+

N/A

+

-A

+

Lists all files except implied . and ..

+

N/A

+

-H

+

Follows symbolic links listed in the command line.

+

N/A

+

-L

+

Follows symbolic links.

+

N/A

+

-Z

+

Displays security context.

+

N/A

+

path

+

If path is left blank, the content of the current directory is displayed.

+

If path is an invalid file name, the following failure message is displayed:

+

ls error: No such directory

+

If path is a valid directory, the content of that directory is displayed.

+

Left blank or a valid directory

+
+ +**Table 2** Output parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-1

+

Lists one file per line.

+

N/A

+

-c

+

Lists entries by column.

+

N/A

+

-g

+

Like -l, but do not list owner.

+

N/A

+

-h

+

Displays the total size of files in the directory, in KiB.

+

N/A

+

-l

+

Displays detailed information about files in the directory.

+

N/A

+

-m

+

Fills width with a list of entries separated by a comma.

+

N/A

+

-n

+

Like -l, but lists numeric user and group IDs.

+

N/A

+

-o

+

Like -l, but do not list group information.

+

N/A

+

-x

+

Lists entries by line, instead of by column.

+

N/A

+

-ll

+

Lists the file time attribute as ns.

+

N/A

+

--color

+

Colorizes the output.

+

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.

+
+ +**Table 3** Sorting parameters \(sorted by the initial letter by default\) + + + + + + + + + + + + + + + + + + + + + + @@ -37,16 +277,44 @@ ls \[_path_\] ## Usage -- This command can be used to display the content of the current directory. -- This command can also display the size of a file. -- The **ls** command with the **proc** directory passed cannot calculate the file size, and **0** is displayed in the command output. +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 -Run **ls**. +Run the following commands: + +- ls +- ll ## Output -**Figure 1** Displaying content of the current directory -![](figure/displaying-content-of-the-current-directory.png "displaying-content-of-the-current-directory") +Example 1: **ls** command output + +``` +OHOS:/$ ls +bin etc nfs sdcard system usr +dev lib proc storage userdata vendor +``` + +Example 2: **ll** command output + +``` +OHOS:/$ ll +total 20 +drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 bin/ +drwxr-xr-x 0 0 0 0 1970-01-01 00:00 dev/ +drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 etc/ +drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 lib/ +drwxrwxrwx 0 0 0 4096 2021-10-25 02:17 nfs/ +dr-xr-xr-x 0 0 0 0 1970-01-01 00:00 proc/ +drwxrwxrwx 1 0 0 4096 1979-12-31 00:00 sdcard/ +drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 storage/ +drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 system/ +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 vendor/ +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md b/en/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md index ffc723559e..2b03724a71 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md @@ -1,5 +1,11 @@ # lsfd +- [Command Function](#section2053406181716) +- [Syntax](#section523771017172) +- [Usage](#section27241213201719) +- [Example](#section442617197173) +- [Output](#section42491639151813) + ## Command Function This command is used to display the file descriptors and names of the files that are open. @@ -18,6 +24,42 @@ Run **lsfd**. ## Output -**Figure 1** Command output -![](figure/command-output-24.png "command-output-24") +Example: **lsfd** command output + +``` +OHOS # lsfd + fd filename + 3 /dev/console1 + 4 /dev/hilog + 5 /dev/hilog + 6 /dev/hilog + 7 /dev/lite_ipc + 8 /dev/hilog + 9 /dev/lite_ipc + 10 /dev/vb + 11 /dev/hilog + 12 /dev/vo + 13 /dev/hilog + 14 /dev/hilog + 15 /dev/sys + 16 /dev/lite_ipc + 17 /dev/lite_ipc + 18 /dev/hi_tde + 19 /dev/fb0 + 20 /dev/vo + 21 /dev/mmz_userdev + 22 /dev/hi_tde + 23 /dev/lite_ipc + 24 /dev/hdf/hdf_input_event1 + 25 /dev/lite_ipc + 26 /dev/mmz_userdev + 27 /dev/lite_ipc + 28 /dev/hilog + 29 /dev/hilog + 30 /dev/hdf/hdf_sensor_manager_ap + 31 /dev/hilog + 32 /dev/lite_ipc + 33 /dev/lite_ipc + 34 /dev/lite_ipc +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md b/en/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md index 27e29b3f1d..124ef5042d 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md @@ -1,12 +1,19 @@ # mkdir +- [Command Function](#section1083613274175) +- [Syntax](#section820913118178) +- [Parameters](#section1256834121718) +- [Usage](#section1294234115172) +- [Example](#section1113345211713) +- [Output](#section10142201012) + ## Command Function This command is used to create a directory. ## Syntax -mkdir \[_directory_\] +mkdir \[_-vp_\] \[_-m mode_\] \[_dirname..._\] ## Parameters @@ -21,11 +28,39 @@ mkdir \[_directory_\] - + + + + + + + + + + - + + + + + + - @@ -33,15 +68,51 @@ mkdir \[_directory_\] ## Usage -- If the **mkdir** command is followed by the name of the directory to be created, the directory is created in the current directory. -- If the **mkdir** command is followed by a path and the name of the directory to be created, the directory is created in the specified path. +>![](../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 -Run **mkdir share**. +Run the following commands: + +- mkdir testpath +- mkdir -m 777 testpath +- mkdir -pv testpath01/testpath02/testpath03 ## Output -**Figure 1** Creating the share directory -![](figure/creating-the-share-directory.png "creating-the-share-directory") +``` +OHOS:/tmp$ mkdir testpath +OHOS:/tmp$ ll +total 2 +drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/ +``` + +Example 2: creating a directory with specified permissions + +``` +OHOS:/tmp$ mkdir -m 777 testpath +OHOS:/tmp$ ll +total 2 +drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/ +``` + +Example 3: creating directories recursively + +``` +OHOS:/tmp$ mkdir -pv testpath01/testpath02/testpath03 +mkdir: created directory 'testpath01' +mkdir: created directory 'testpath01/testpath02' +mkdir: created directory 'testpath01/testpath02/testpath03' +OHOS:/tmp$ ll +total 2 +drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath01/ +OHOS:/tmp$ ll testpath01/ +total 2 +drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath02/ +OHOS:/tmp$ ll testpath01/testpath02/ +total 2 +drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath03/ +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-mount.md b/en/device-dev/kernel/kernel-small-debug-shell-file-mount.md index a67bd4799b..60b96c53e1 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-mount.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-mount.md @@ -1,12 +1,19 @@ # mount +- [Command Function](#section11631837182) +- [Syntax](#section1697638111820) +- [Parameters](#section1650151221819) +- [Usage](#section124541520171912) +- [Example](#section7424625171917) +- [Output](#section14757018116) + ## Command Function This command is used to mount a device to a specified directory. ## Syntax -mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] +mount \[_-f_\] \[_-t TYPE_\] \[_-o OPTION,_\] \[\[_DEVICE_\] _DIR_\] ## Parameters @@ -21,35 +28,47 @@ mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] - + + + + + + + + - - - - - - - - - - - @@ -57,15 +76,24 @@ mount <_device_\> <_path_\> <_name_\> \[_uid gid_\] ## Usage -By specifying the device to be mounted, 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 -Run **mount /dev/mmcblk0p0 /bin1/vs/sd vfat**. +Run **mount -t nfs 192.168.1.3:/nfs nfs**. ## Output -Mounting **/dev/mmcblk0p0** to the **/bin1/vs/sd** directory +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 -![](figure/en-us_image_0000001134008688.png) +``` +OHOS:/$ mkdir nfs +OHOS:/$ mount -t nfs 192.168.1.3:/nfs nfs +Mount nfs on 192.168.1.3:/nfs, uid:0, gid:0 +Mount nfs finished. +OHOS:/$ ls nfs/ +16d.xml gpio_test ohos_test.txt userfs_vfat.img +OHOS_Image.bin hello rootfs_vfat.img +dev_tools mksh_rootfs_vfat.img test_demo +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-mv.md b/en/device-dev/kernel/kernel-small-debug-shell-file-mv.md new file mode 100644 index 0000000000..72bd8fef12 --- /dev/null +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-mv.md @@ -0,0 +1,134 @@ +# mv + +- [Command Function](#section201149459368) +- [Syntax](#section579813484364) +- [Parameters](#section168065311366) +- [Usage](#section19190125723612) +- [Example](#section10383416372) +- [Output](#section131601649114511) + +## Command Function + +This command is used to move files. + +## Syntax + +mv \[_-fivn_\] _SOURCE... DEST_ + +## Parameters + +**Table 1** Parameter description + + +

Parameter

+

Description

+

Value Range

+

-f

+

Do not sort.

+

N/A

+

-r

+

Reverse order while sorting.

+

N/A

+

-t

+

Sort by time, newest first.

+

N/A

+

-S

+

Sort by file size, largest first.

+

N/A

directory

+

--help

+

Displays the parameters supported by the mkdir command.

+

N/A

+

-m

+

Sets the permissions on the directory to create.

+

N/A

+

-p

+

Creates parent and child directories recursively.

+

N/A

Specifies the directory to create.

+

-v

+

Prints detailed information about the directory creation process.

+

N/A

+

directory

+

Specifies the directory to create.

N/A

+

N/A

device

+

--help

+

Displays the parameters supported by the mount command.

+

N/A

+

-f

+

Fakes mounting the file system (no mounting is actually performed).

+

N/A

+

-t

Specifies the path of the device to be mounted. The format is the path of the device.

+

Specifies the file system type.

A device in the system

+

vfat, yaffs, jffs, ramfs, nfs, procfs, romfs

path

+

-o

Specifies the directory of the device.

-

You must have the execution (search) permission for the specified directory.

+

Specifies the mount options.

N/A

+

N/A

name

+

DEVICE

Specifies the file system type.

+

Specifies the device to mount (in the format of the device directory).

vfat, yaffs, jffs, ramfs, nfs, procfs, romfs

+

A device in the system

uid gid

+

DIR

uid indicates the user ID.

-

gid indicates the group ID.

-

This parameter is optional. The default values are uid:0 and gid:0.

+

Specifies the directory.

+

You must have the execution (search) permission on the specified directory.

N/A

+

N/A

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Value Range

+

-help

+

Displays help information.

+

N/A

+

-f

+

Forcibly overwrites the target file.

+

N/A

+

-i

+

Provides a prompt before moving a file that would overwrite an existing file. Enter y to overwrite the file or enter n to cancel the operation.

+

N/A

+

-n

+

Do not overwrite any existing file or directory.

+

N/A

+

-v

+

This parameter does not take effect although it is supported by the latest Toybox code.

+

N/A

+

SOURCE

+

Specifies the path of the source file.

+

This command cannot be used to move a directory. It can be used to move multiple files at a time.

+

DEST

+

Specifies the destination file path.

+

Both a directory and a file are supported.

+
+ +## Usage + +- **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 file, the directory for this file must exist. +- If the destination file already exists, it will be overwritten. + +## Example + +Run the following commands: + +- mv -i test.txt testpath/ +- mv test?.txt testpath/ \(Move **test3.txt**, **testA.txt**, and **test\_.txt**\) + +## Output + +Example 1: moving a file + +``` +OHOS:/$ touch test.txt +OHOS:/$ mkdir testpath +OHOS:/$ touch testpath/test.txt +OHOS:/$ mv -i test.txt testpath/ +mv: overwrite 'testpath//test.txt' (Y/n):y +OHOS:/$ ls +bin etc proc storage testpath usr +dev lib sdcard system userdata vendor +OHOS:/$ cp testpath/test.txt ./ +OHOS:/$ ls +bin etc proc storage test.txt userdata vendor +dev lib sdcard system testpath usr +OHOS:/$ mv -i test.txt testpath/ +mv: overwrite 'testpath//test.txt' (Y/n):n +OHOS:/$ ls +bin etc proc storage test.txt userdata vendor +dev lib sdcard system testpath usr +``` + +Example 2: moving files using wildcards + +``` +OHOS:/$ ls +bin etc proc storage test.txt testA.txt testpath usr +dev lib sdcard system test3.txt test_.txt userdata vendor +OHOS:/$ mv test?.txt testpath/ +OHOS:/$ ls +bin etc proc storage test.txt userdata vendor +dev lib sdcard system testpath usr +OHOS:/$ ls testpath/ +test.txt test3.txt testA.txt test_.txt +``` + diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md b/en/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md index b1c8f51d04..74139c8711 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md @@ -1,5 +1,12 @@ # partinfo +- [Command Function](#section1777503617199) +- [Syntax](#section185501447132114) +- [Parameters](#section1304151212252) +- [Usage](#section4566131982520) +- [Example](#section4351134942514) +- [Output](#section66689331412) + ## Command Function This command is used to query information about the partitions of a hard disk or SD card identified by the system. @@ -41,5 +48,17 @@ Run **partinfo /dev/mmcblk0p0**. ## Output -![](figure/en-us_image_0000001133848906.png) +System partition information: + +``` +OHOS # partinfo /dev/mmcblk0p0 +part info : +disk id : 0 +part_id in system: 1 +part no in disk : 0 +part no in mbr : 0 +part filesystem : 00 +part sec start : 20480 +part sec count : 102400 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-file-partition.md b/en/device-dev/kernel/kernel-small-debug-shell-file-partition.md index eae2263e1a..03f51089fa 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-file-partition.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-file-partition.md @@ -1,5 +1,12 @@ # partition +- [Command Function](#section255095212257) +- [Syntax](#section10258056122515) +- [Parameters](#section177200581256) +- [Usage](#section17866411262) +- [Example](#section1927174202610) +- [Output](#section11321011223) + ## Command Function This command is used to query flash partition information. @@ -30,7 +37,7 @@ partition \[_nand / spinor_\]

spinor

Displays information about the spinor flash partition.

+

Displays information about the SPI NOR flash partition.

N/A

-r

+

-r

+

Deletes empty or non-empty directories.

+

N/A

+

-f

Deletes a directory. This parameter is optional. It is required if a directory is to be deleted.

+

Deletes a file or directory forcibly without confirmation. No error will be reported when a file that does not exist is to be deleted.

N/A

+

N/A

dirname/filename

+

-v

Specifies the name of the file or directory to be deleted. The value can be a path.

+

Displays the deletion process.

N/A

+

N/A

+

PATH/filename

+

Specifies the name of the file or directory to delete. The value can be a path.

+

N/A

dir

+

--help

+

Displays the parameters supported by the rmdir command.

+

N/A

+

-p

+

Deletes a path.

+

N/A

Specifies the name of the directory to be deleted. The directory must be empty. You can enter a path for this parameter.

+

--ignore-fail-on-non-empty

+

Suppresses the error message when a non-empty directory is to be deleted.

N/A

+

N/A

+

dir

+

Specifies the name of the directory to delete. The directory must be empty. A path is supported.

+

N/A

Specifies the file system directory.

The file system must exist and support the statfs command. Currently, the file systems JFFS2, FAT, and NFS are supported.

+

The file system must exist and support the statfs command. The supported file systems include JFFS2, FAT, and NFS.

filename

+

--help

+

Displays the parameters supported by the touch command.

+

N/A

Specifies the name of the file to be created.

+

filename

+

Specifies the name of the file to create.

N/A

+

N/A

dir

+

--help

+

Displays the parameters supported by the umount command.

+

N/A

+

-a

+

Unmounts all file systems mounted.

+

N/A

+

-t

Specifies the directory from which the file system is to be unmounted.

+

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.

Directory to which the file system is mounted

+

N/A

+

dir

+

Specifies the directory from which the file system is to be unmounted.

+

Directory mounted with the file system

No parameter

Prints the content of the entire ARP cache table.

+

Queries the content of the ARP cache table.

N/A

- - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Address

-

IPv4 address of a network device.

-

HWaddress

-

MAC address of a network device.

-

Iface

-

Name of the port used by the ARP entry.

-

Type

-

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.

-
+Run the **arp** command. + +ARP cache table: + +``` +OHOS # arp +Address HWaddress Iface Type +192.168.1.10 E6:2B:99:2C:4B:20 eth0 static +``` +**Table 2** Output description + + + + + + + + + + + + + + + + + + + +

Parameter

+

Description

+

Address

+

IPv4 address of a network device.

+

HWaddress

+

MAC address of a network device.

+

Iface

+

Name of the port used by the ARP entry.

+

Type

+

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.

+
diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md b/en/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md index 69684621fa..78249ea694 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md @@ -1,24 +1,19 @@ # dhclient +- [Command Function](#section366714216619) +- [Syntax](#section8833164614615) +- [Parameters](#section12809111019453) +- [Usage](#section15935131220717) +- [Example](#section79281818476) + ## Command Function -This command is used to set and view **dhclient** parameters. +This command is used to set and query **dhclient** parameters. ## Syntax -dhclient <_netif name_\> - -dhclient -x <_netif name_\> - -dhclient -gb <_netif name_\> - -dhclient -sv <_vendor_\> - -dhclient -gv - -dhclient -gd <_index_\> - -dhclient -sd <_dns\_ip_\> +- dhclient <_netif name_\> +- dhclient -x <_netif name_\> ## Parameters @@ -33,53 +28,25 @@ dhclient -sd <_dns\_ip_\>

<netif name>

-

Starts the DHCP request of the network interface card (NIC).

-

NIC name, eth0

-

-x <netif name>

+

-h | --help

Disables the DHCP function for the NIC.

+

Displays parameters supported by the dhclient command and their usage.

NIC name, eth0

+

N/A

-gb <netif name>

+

<netif name>

Checks whether the DHCP request of the NIC is complete.

+

Enables Dynamic Host Configuration Protocol (DHCP) for a network interface card (NIC).

NIC name, eth0

+

NIC name, eth0

-sv <vendor>

+

-x <netif name>

Sets the vendor information of a DHCP request.

+

Disables DHCP for a NIC.

Vendor information (The value is a string of 32 characters.)

-

-gv

-

Displays the vendor information in a DHCP request.

-

N/A

-

-gd <index>

-

Obtains information about the DNS server at the specified index.

-

Index, 0 or 1

-

-sd <dns_ip>

-

Specifies the IP address of the active DNS server.

-

IP address of the DNS server

+

NIC name, eth0

- - - - - - - - - - -

Parameter

-

Description

-

dhclient: set vendor info [MFSI] success

-

The MFSI information is successfully set.

-

dns[0]: 192.168.1.100

-

The IP address of the DNS server is 192.168.1.100.

-
+Example 1: enabling DHCP for eth0 + +``` +OHOS:/$ dhclient eth0 +OHOS:/$ ifconfig +lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP +eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 + HWaddr 42:da:81:bc:58:94 MTU:1500 Running Default Link UP +OHOS:/$ +``` + +Example 2: disabling DHCP for eth0 + +``` +OHOS:/$ dhclient -x eth0 +NetifStatusCallback(eth0): nsc event: 0xf0 +OHOS:/$ ifconfig +lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP +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 +``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-dns.md b/en/device-dev/kernel/kernel-small-debug-shell-net-dns.md deleted file mode 100644 index ae98208730..0000000000 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-dns.md +++ /dev/null @@ -1,86 +0,0 @@ -# dns - -## Command Function - -This command is used to query and set the IP address of a DNS server on a board. - -## Syntax - -dns <_1-2_\> <_IP_\> - -dns _-a_ - -## Parameters - -**Table 1** Parameter description - - - - - - - - - - - - - - - - - - - - -

Parameter

-

Description

-

Value Range

-

<1-2>

-

Specifies the DNS server to set the IP address.

-

1 or 2

-

<IP>

-

Specifies the IP address of the server.

-

N/A

-

-a

-

Displays the current settings.

-

N/A

-
- -## Usage - -None - -## Example - -Example: - -1. Check the current DNS settings. -2. Set the IP address of the alternate DNS server. -3. Check the settings. - -## Output - -1. Check the current DNS settings: - - ``` - OHOS # dns -a - dns1: 192.168.1.10 - dns2: 0.0.0.0 - ``` - -2. Set the IP address of the alternate DNS server: - - ``` - OHOS # dns 2 192.168.1.2 - ``` - -3. Check the settings: - - ``` - OHOS # dns -a - dns1: 192.168.1.10 - dns2: 192.168.1.2 - ``` - - diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md b/en/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md index 6eb720c01e..aa2b178e1b 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md @@ -1,27 +1,31 @@ # ifconfig +- [Command Function](#section174940284379) +- [Syntax](#section136073203715) +- [Parameters](#section6493235203710) +- [Usage](#section05763403371) +- [Example](#section168802042123717) +- [Output](#section124638211109) + ## Command Function This command can be used to: -- Query and set network interface card \(NIC\) parameters, such as the IP address, network mask, gateway, and MAC address. -- Disable or enable a NIC. +- 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. ## Syntax -ifconfig - -\[_-a_\] - -<_interface_\> <_address_\> \[_netmask _\] \[_gateway _\] - -\[_hw ether _\] \[_mtu _\] - -\[_inet6 add _\] +ifconfig \[option\] -\[_inet6 del _\] +option: -\[_up|down_\] +- \[_-a_\] +- <_interface_\> <_address_\> \[_netmask _\] \[_gateway _\] +- \[_hw ether _\] \[_mtu _\] +- \[_inet6 add _\] +- \[_inet6 del _\] +- \[_up|down_\] ## Parameters @@ -36,90 +40,90 @@ ifconfig

No parameter

+

No parameter

Displays the IP addresses, network masks, gateway, MAC addresses, MTU, and running status of all NICs.

+

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

+

N/A

-a

+

-a

Displays data sent and received by the protocol stack.

+

Displays data sent and received by the protocol stack.

N/A

+

N/A

interface

+

interface

Specifies the NIC name, for example, eth0.

+

Specifies the NIC name, for example, eth0.

N/A

+

N/A

address

+

address

Specifies the IP address, for example, 192.168.1.10. The NIC name must be specified.

+

Specifies the IP address, for example, 192.168.1.10. The NIC name must be specified.

N/A

+

N/A

netmask

+

netmask

Specifies the subnet mask, for example, 255.255.255.0.

+

Specifies the subnet mask, for example, 255.255.255.0.

N/A

+

N/A

gateway

+

gateway

Specifies the gateway, for example, 192.168.1.1.

+

Specifies the gateway, for example, 192.168.1.1.

N/A

+

N/A

hw ether

+

hw ether

Specifies the MAC address, for example, 00:11:22:33:44:55. Currently, only the ether hardware type is supported.

+

Specifies the MAC address, for example, 00:11:22:33:44:55. Currently, only the ether hardware type is supported.

N/A

+

N/A

mtu

+

mtu

Specifies the maximum transmission unit (MTU) size, for example, 1000.

+

Specifies the MTU size, for example, 1000.

  • For IPv4:

    [68,1500]

    -
  • For IPv6:

    [1280, 1500]

    +
  • IPv4:

    [68,1500]

    +
  • IPv6:

    [1280, 1500]

add

+

add

Specifies the IPv6 address, for example, 2001:a:b:c:d:e:f:d. The NIC name and inet6 must be specified.

+

Specifies the IPv6 address, for example, 2001:a:b:c:d:e:f:d. The NIC name and inet6 must be specified.

N/A

+

N/A

del

+

del

Deletes an IPv6 address. The NIC name and inet6 must be specified.

+

Deletes an IPv6 address. You need to specify the NIC name and add the inet6 option. For details, see the example.

N/A

+

N/A

up

+

up

Enables the data processing function of the NIC. The NIC name must be specified.

+

Enables the data processing function of the NIC. The NIC name must be specified.

N/A

+

N/A

down

+

down

Disables the data processing function of the NIC. The NIC name must be specified.

+

Disables the data processing function of the NIC. The NIC name must be specified.

N/A

+

N/A

ip

+

ip

IP address of the board

+

IP address of the board

netmask

+

netmask

Subnet mask

+

Subnet mask

gateway

+

gateway

Gateway

+

Gateway

HWaddr

+

HWaddr

MAC address of the board

+

MAC address of the board

MTU

+

MTU

Maximum transmission unit

+

Maximum transmission unit

Running/Stop

+

Running/Stop

Indicates whether the NIC is running.

+

Indicates whether the NIC is running.

Default

+

Default

The NIC is connected to the default gateway.

+

Indicates that the NIC is connected to the default gateway.

Link UP/Down

+

Link UP/Down

Connection status of the NIC

+

Connection status of the NIC

-2. Obtain protocol stack statistics. +- Example 2: obtaining protocol stack statistics ``` OHOS # ifconfig -a @@ -226,86 +230,90 @@ ifconfig

RX packets

+

RX packets

Number of normal packets received at the IP layer.

+

Number of normal packets received at the IP layer.

RX error

+

RX error

Number of error packets received at the IP layer. The errors include the length, verification, IP option, and IP header protocol errors.

+

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.

RX dropped

+

RX dropped

Number of packets discarded at the IP layer. Packets are discarded due to packet errors, packet forwarding failures, and disabled local NICs.

+

Number of packets discarded at the IP layer. Packets are discarded due to packet errors, packet forwarding failures, and disabled local NICs.

RX overrun

+

RX overrun

Number of packets that the MAC layer fails to deliver to the upper-layer protocol stack. The failure is mainly caused by resource insufficiency at the protocol stack.

+

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.

RX bytes

+

RX bytes

Total length of normal packets received at the IP layer, excluding the length of the fragments that are not reassembled.

+

Total length of normal packets received at the IP layer, excluding the length of the fragments that are not reassembled.

TX packets

+

TX packets

Number of packets that have been normally sent or forwarded at the IP layer.

+

Number of packets that have been normally sent or forwarded at the IP layer.

TX error

+

TX 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.

+

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.

TX dropped

+

TX dropped

Number of packets that the MAC layer discards due to sending failures, for example, the NIC driver fails to process the packets.

+

Number of packets that the MAC layer discards due to delivery failures, for example, the NIC driver fails to process the packets.

TX overrun

+

TX overrun

Reserved.

+

Reserved.

TX bytes

+

TX bytes

Total length of the packets successfully sent or forwarded at the IP layer.

+

Total length of the packets successfully sent or forwarded at the IP layer.

-3. Set the IPv6 address information. +- Example 3: setting an IPv6 address ``` - OHOS # ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d - OHOS # ifconfig - eth1 ip:192.168.3.60 netmask:255.255.255.0 gateway:0.0.0.0 - HWaddr 00:0e:c6:a8:5a:c2 MTU:1500 Running Link UP - eth0 ip:192.168.2.60 netmask:255.255.255.0 gateway:0.0.0.0 - ip6: 2001:A:B:C:D:E:F:D/64 - HWaddr 46:44:02:02:03:03 MTU:1500 Running Link UP - lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 - ip6: ::1/64 - HWaddr 00 MTU:16436 Running Link UP + OHOS:/$ ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d + NetifStatusCallback(eth0): nsc event: 0x8 + NetifStatusCallback(eth0): nsc status changed: 0 + NetifStatusCallback(eth0): nsc event: 0x200 + NetifStatusCallback(eth0): nsc event: 0x8 + NetifStatusCallback(eth0): nsc status changed: 1 + NetifStatusCallback(eth0): nsc event: 0x200 + NetifStatusCallback(eth0): nsc event: 0x200 + OHOS:/$ ifconfig + lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP + eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 + ip6: 2001:A:B:C:D:E:F:D/64 + HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP ``` -4. Delete the IPv6 address information. +- Example 4: deleting an IPv6 address ``` - OHOS # ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d - OHOS # ifconfig - eth1 ip:192.168.3.60 netmask:255.255.255.0 gateway:0.0.0.0 - HWaddr 00:0e:c6:a8:5a:c2 MTU:1500 Running Link UP - eth0 ip:192.168.2.60 netmask:255.255.255.0 gateway:0.0.0.0 - HWaddr 46:44:02:02:03:03 MTU:1500 Running Link UP - lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 - ip6: ::1/64 - HWaddr 00 MTU:16436 Running Link UP + OHOS:/$ ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d + NetifStatusCallback(eth0): nsc event: 0x200 + OHOS:/$ ifconfig + lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP + 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 ``` diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md b/en/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md index 73b6125314..a60ad4db5e 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md @@ -1,20 +1,25 @@ # ipdebug +- [Command Function](#section10191115553720) +- [Syntax](#section124061758123713) +- [Example](#section171837113810) +- [Output](#section561416467104) + ## Command Function -**ipdebug** is a console command and is used for IPv6 information debugging. It can display IPv6 address prefixes, neighbor entries, destination cache entries, and default routing 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 ipdebug -## Usage +## Example Run the **ipdebug** command. ## Output -The **ipdebug** output is as follows: +**ipdebug** command output: ``` OHOS # ipdebug diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-netstat.md b/en/device-dev/kernel/kernel-small-debug-shell-net-netstat.md index 4907fae1f1..c99cd1a796 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-netstat.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-netstat.md @@ -1,8 +1,15 @@ # netstat +- [Command Function](#section13469162113816) +- [Syntax](#section795712373812) +- [Parameters](#section17629431193817) +- [Usage](#section5277153519380) +- [Example](#section108141437163820) +- [Output](#section1357015107117) + ## 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. It is used to display the statistics related to the TCP and UDP protocols and 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 and can be used to check the network connection to each port on the device \(board\). ## Syntax @@ -14,19 +21,32 @@ None ## Usage -Run the command directly. +netstat ## Example Run **netstat**. -**Figure 1** Output information - - -![](figure/snipaste_2021-01-26_10-38-58-25.png) - ## Output +**netstat** print information + +``` +OHOS # netstat +========== total sockets 128 ====== unused sockets 119 ========== +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 192.168.1.10:578 192.168.1.3:2049 ESTABLISHED +tcp 0 0 192.168.1.10:58653 0.0.0.0:0 LISTEN +tcp 0 0 192.168.1.10:58652 0.0.0.0:0 LISTEN +tcp 0 0 192.168.1.10:58651 0.0.0.0:0 LISTEN +Proto Recv-Q Send-Q Local Address Foreign Address +udp 0 0 127.0.0.1:62177 127.0.0.1:62178 +udp 0 0 0.0.0.0:5684 0.0.0.0:0 +udp 0 0 127.0.0.1:62179 127.0.0.1:62180 +udp 0 0 127.0.0.1:62180 127.0.0.1:62179 +udp 0 0 127.0.0.1:62178 127.0.0.1:62177 +``` + **Table 1** Output description diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md b/en/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md index 0baa7a3cb0..b2ad34fa98 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md @@ -1,5 +1,12 @@ # ntpdate +- [Command Function](#section38494293815) +- [Syntax](#section5503114413387) +- [Parameters](#section136934472383) +- [Usage](#section121401651173816) +- [Example](#section3431554203811) +- [Output](#section18638194610115) + ## Command Function This command is used to synchronize system time from the server. diff --git a/en/device-dev/kernel/kernel-small-debug-shell-net-ping.md b/en/device-dev/kernel/kernel-small-debug-shell-net-ping.md index e41d792631..f9252678e1 100644 --- a/en/device-dev/kernel/kernel-small-debug-shell-net-ping.md +++ b/en/device-dev/kernel/kernel-small-debug-shell-net-ping.md @@ -1,16 +1,19 @@ # ping +- [Command Function](#section119672573385) +- [Syntax](#section869419010390) +- [Parameters](#section9877183173918) +- [Usage](#section1097046193914) +- [Example](#section14564129113911) +- [Output](#section1621732891215) + ## Command Function -This command is used to test an IPv4 network connection. +This command is used to test an IPv4 connection. ## Syntax -ping_ _\[_-n cnt_\] \[_-w interval_\] \[_-l data\_len_\]_ _ - -ping \[_-t_\] \[_-w interval_\] __ - -ping _-k_ +ping _\[-4\] \[-c cnt\] \[-f\] \[-i interval\] \[-q\] \[-s size\] _ ## Parameters @@ -25,46 +28,60 @@ ping _-k_

IP

+

--help

+

Displays the parameters supported by the ping command.

+

N/A

+

-4

Specifies the IPv4 address whose network connectivity is to be tested.

+

Forcibly pings the destination address using the IPv4 protocol.

N/A

+

0-65500

-n cnt

+

-c CNT

Specifies the number of execution times. If this parameter is not specified, the default value is 4.

+

Specifies the number of execution times. The default value is 3.

1-65535

+

1-65535

-w interval

+

-f

Specifies the interval (in ms) between two ping packets.

+

Pings an IPv4 address in implicit mode. The default parameter configuration is equivalent to -c 15 -i 0.2.

>0

+

N/A

-l data_len

+

-i interval

Specifies the data length of the ICMP echo request packet, excluding the ICMP packet header.

+

Specifies the interval (in ms) for sending a ping packet.

0-65500

+

1-200

-t

+

-q

Specifies a permanent ping thread, which will be killed until the ping -k command is executed.

+

Implicitly pings an IPv4 address. If the host is active, the ping stops after true is received.

N/A

+

N/A

-k

+

-s SIZE

Kills the ping thread and stops the ping operation.

+

Specifies the size of a ping packet, in bytes. The default size is 56 bytes.

N/A

+

0-4088

+

IP

+

Specifies the IPv4 address to test.

+

N/A

Category

+ + - - - - - - - - + + + - - - - - + + + - - + - - - - -

Function

API

+

API

Description

+

Description

Tracing information

+

Starting and stopping trace

LOS_Trace

+

LOS_TraceStart

Traces information.

+

Starts trace.

Registration and unregistration

+

LOS_TraceStop

LOS_TraceReg

+

Stops trace.

Registers the trace type.

+

Managing trace records

+

LOS_TraceRecordDump

+

Exports data in the trace buffer.

LOS_TraceUnreg

+

LOS_TraceRecordGet

Unregisters the trace type.

+

Obtains the start address of the trace buffer.

Switch

+

LOS_TraceReset

LOS_TraceTypeSwitch

+

Clears events in the trace buffer.

Enables or disables the specified type of trace.

+

Filtering trace records

+

LOS_TraceEventMaskSet

+

Sets the event mask to trace only events of the specified modules.

LOS_TraceSwitch

+

Masking events of specified interrupt IDs

Enables or disables the trace function.

+

LOS_TraceHwiFilterHookReg

+

Registers a hook to filter out events of specified interrupt IDs.

Data export

+

Performing function instrumentation

LOS_TraceBufDataGet

+

LOS_TRACE_EASY

Exports trace data to the heap cache. (The cache space is allocated internally and must be released explicitly.)

+

Performs simple instrumentation.

LOS_Trace2File

+

LOS_TRACE

Saves the trace data to the file system (depending on the file system).

+

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 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. + - **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. + + Example: + + ``` + Perform simple instrumentation for reading and writing files fd1 and fd2. + Set TYPE to 1 for read operations and 2 for write operations. + Insert the following to the position where the fd1 file is read: + 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. + - 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. + - The **IDENTITY** and **Params** are the same as those of simple instrumentation. + + Example: + + ``` + 1. Set the event mask (module-level event type) in enum LOS_TRACE_MASK. + Format: TRACE_#MOD#_FLAG (MOD indicates the module name) + Example: + 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:** + >The trace event types and parameters can be modified 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**. +- 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. + + The sample code is as follows: + + ``` + BOOL Example_HwiNumFilter(UINT32 hwiNum) + { + if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { + return TRUE; + } + return FALSE; + } + LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); + ``` + + +The interrupt events with interrupt ID of **TIMER\_INT** or **DMA\_INT** are not traced. + +### User Mode + +The trace character device is added in **/dev/trace**. You can use **read\(\)**, **write\(\)**, and **ioctl\(\)** on the device node to read, write, and control trace in user mode. + +- **read\(\)**: reads the trace data in user mode. +- **write\(\)**: writes an event in user mode. +- **ioctl\(\)**: performs user-mode trace operations, including: + +``` +#define TRACE_IOC_MAGIC 'T' +#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) +#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) +#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) +#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) +#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) +``` + +The operations specified by the input parameter of **ioctl\(\)** correspond to **LOS\_TraceStart**, **LOS\_TraceStop**, **LOS\_TraceReset**, **LOS\_TraceRecordDump**, and **LOS\_TraceEventMaskSet**, respectively. + +For more details, see [User-mode Programming Example](https://gitee.com/openharmony/docs/blob/70744e1e0e34d66e11108a00c8db494eea49dd02/en/device-dev/kernel/kernel-small-debug-trace.md#section4.2.2). + +## Development Guidelines + +### Kernel-mode Development Process + +The typical trace process is as follows: + +1. Configure the macro related to the trace module. + + Configure the trace 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

+

menuconfig Option

+

Description

+

Value

+

LOSCFG_KERNEL_TRACE

+

Enable Trace Feature

+

Specifies whether to enable the trace feature.

+

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 work mode ->Online mode

+

Specifies whether to enable the offline trace mode.

+

YES/NO

+

LOSCFG_TRACE_CLIENT_INTERACT

+

Enable Trace Client Visualization and Control

+

Specifies whether to enable interaction with Trace IDE (dev tools), including data visualization and process control.

+

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 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 max params

+

Specifies the maximum number of parameters for event recording.

+

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\). +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 Trace IDE.\) + +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\_TraceEventMaskSet —— trace\_mask +- LOS\_TraceStart —— trace\_start +- LOS\_TraceStop —— trace\_stop +- LOS\_TraceRecordDump —— trace\_dump + +## Kernel-mode Programming Example + +This example implements the following: + +1. Create a trace task. +2. Set the event mask. +3. Start trace. +4. Stop trace. +5. Output trace data in the specified format. + +## Kernel-mode Sample Code + +The code is as follows: + +``` +#include "los_trace.h" +UINT32 g_traceTestTaskId; +VOID Example_Trace(VOID) +{ + UINT32 ret; + LOS_TaskDelay(10); + /* Start trace. */ + ret = LOS_TraceStart(); + if (ret != LOS_OK) { + dprintf("trace start error\n"); + return; + } + /* Trigger a task switching event.*/ + LOS_TaskDelay(1); + LOS_TaskDelay(1); + LOS_TaskDelay(1); + /* Stop trace.*/ + LOS_TraceStop(); + LOS_TraceRecordDump(FALSE); +} +UINT32 Example_Trace_test(VOID){ + UINT32 ret; + TSK_INIT_PARAM_S traceTestTask; + /* Create a trace task. */ + memset(&traceTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + traceTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Trace; + traceTestTask.pcName = "TestTraceTsk"; /* Trace task name*/ + traceTestTask.uwStackSize = 0x800; + traceTestTask.usTaskPrio = 5; + traceTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_traceTestTaskId, &traceTestTask); + if(ret != LOS_OK){ + dprintf("TraceTestTask create failed .\n"); + return LOS_NOK; + } + /* Trace is started by default. Therefore, you can stop trace, clear the buffer, and then restart trace. */ + LOS_TraceStop(); + LOS_TraceReset(); + /* Enable trace of the Task module events. */ + LOS_TraceEventMaskSet(TRACE_TASK_FLAG); + return LOS_OK; +} +LOS_MODULE_INIT(Example_Trace_test, LOS_INIT_LEVEL_KMOD_EXTENDED); +``` + +## Verification + +The output is as follows: + +``` +*******TraceInfo begin******* +clockFreq = 50000000 +CurEvtIndex = 7 +Index Time(cycles) EventType CurTask Identity params +0 0x366d5e88 0x45 0x1 0x0 0x1f 0x4 0x0 +1 0x366d74ae 0x45 0x0 0x1 0x0 0x8 0x1f +2 0x36940da6 0x45 0x1 0xc 0x1f 0x4 0x9 +3 0x3694337c 0x45 0xc 0x1 0x9 0x8 0x1f +4 0x36eea56e 0x45 0x1 0xc 0x1f 0x4 0x9 +5 0x36eec810 0x45 0xc 0x1 0x9 0x8 0x1f +6 0x3706f804 0x45 0x1 0x0 0x1f 0x4 0x0 +7 0x37070e59 0x45 0x0 0x1 0x0 0x8 0x1f +*******TraceInfo end******* +``` + +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**. +- **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**. + +The following uses output No. 0 as an example. + +``` +Index Time(cycles) EventType CurTask Identity params +0 0x366d5e88 0x45 0x1 0x0 0x1f 0x4 +``` + +- **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. +- For details about the meanings of **Identity** and **params**, see the **TASK\_SWITCH\_PARAMS** macro. + +``` +#define TASK_SWITCH_PARAMS(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\)**. + >![](../public_sys-resources/icon-note.gif) **NOTE:** ->- The frame buffer is a cyclic buffer. When it is full, a subsequent write will cause overwrite of the oldest data. You can configure the buffer size in the **LOS\_TRACE\_BUFFER\_SIZE** macro in **los\_config.h**. The default size is **512** KiB. ->- Although trace has completed the assembly and recording as soon as possible, it still has impact on the overall performance of the system. ->- Trace supports concurrent recording of multiple modules. You can reduce the data analysis volume by enabling or disabling the trace function for different modules on demand. ->- The task, memory, and liteipc modules of the kernel support the trace recording function. +>The number of **param**s 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**. diff --git a/en/device-dev/kernel/kernel-small-debug-user-faqs.md b/en/device-dev/kernel/kernel-small-debug-user-faqs.md index 63450c50a2..ec114f13d9 100644 --- a/en/device-dev/kernel/kernel-small-debug-user-faqs.md +++ b/en/device-dev/kernel/kernel-small-debug-user-faqs.md @@ -1,5 +1,9 @@ # Typical Memory Problems +- [Use After Free \(UAF\)](#section4427132815445) +- [Double Free](#section827194818458) +- [Heap Memory Node Corrupted](#section1763741216461) + ## Use After Free \(UAF\) - Requested memory block less than or equal to 0x1c000 bytes: diff --git a/en/device-dev/kernel/kernel-small-debug-user-function.md b/en/device-dev/kernel/kernel-small-debug-user-function.md index dfb9857307..873cc69210 100644 --- a/en/device-dev/kernel/kernel-small-debug-user-function.md +++ b/en/device-dev/kernel/kernel-small-debug-user-function.md @@ -1,5 +1,9 @@ # Working Principles +- [Memory Leak Check](#section142061581018) +- [Heap Memory Statistics](#section136902041337) +- [Memory Integrity Check](#section196491231761) + ## Memory Leak Check The memory debugging module maintains 128 \(that is the maximum number of threads supported in the system\) linked lists for each process. The index of each linked list is the thread ID. @@ -9,12 +13,12 @@ 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. **Figure 1** Heap memory node linked list -![](figure/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. [Figure 2](#fig716011269106) shows the heap memory node information. **Figure 2** Heap memory node information -![](figure/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. @@ -23,7 +27,7 @@ When memory is released, the input parameter pointer in the **free** API is us 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 lines for a memory leak -![](figure/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 @@ -36,12 +40,12 @@ You can collect statistics on the percentage of heap memory requested by each th 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/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. **Figure 5** Process of releasing memory - ![](figure/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. @@ -49,6 +53,6 @@ You can collect statistics on the percentage of heap memory requested by each th 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. **Figure 6** Layout of the memory allocated by using the **mmap** mechanism of **malloc** - ![](figure/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png "layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc") + ![](figures/layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc.png "layout-of-the-memory-allocated-by-using-the-mmap-mechanism-of-malloc") diff --git a/en/device-dev/kernel/kernel-small-debug-user-guide-use-api.md b/en/device-dev/kernel/kernel-small-debug-user-guide-use-api.md index 890dc3b9f2..5ed8806902 100644 --- a/en/device-dev/kernel/kernel-small-debug-user-guide-use-api.md +++ b/en/device-dev/kernel/kernel-small-debug-user-guide-use-api.md @@ -1,5 +1,10 @@ # Calling APIs +- [Sample Code](#section5490173592518) +- [Compilation](#section534302242515) +- [Debugging Information](#section1017419992515) +- [Call Stack Parsing](#section1485163282417) + ## Sample Code The sample code explicitly calls the related APIs of the memory debugging module to check the memory. diff --git a/en/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md b/en/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md index 37672c6b3d..5d6a69f907 100644 --- a/en/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md +++ b/en/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md @@ -1,5 +1,11 @@ # Using the CLI +- [Sample Code](#section13793104782316) +- [Compilation](#section1676431122320) +- [Running the mwatch Command](#section1703415132311) +- [Call Stack Parsing](#section1880675510221) +- [Running the mrecord Command](#section071022822210) + In addition to calling APIs to check the memory used by user-mode processes, you can run CLI commands to collect memory statistics, check for memory leaks, and check memory integrity. ``` diff --git a/en/device-dev/kernel/kernel-small-debug.md b/en/device-dev/kernel/kernel-small-debug.md index a9ffe18bdf..cea060e9cd 100644 --- a/en/device-dev/kernel/kernel-small-debug.md +++ b/en/device-dev/kernel/kernel-small-debug.md @@ -4,9 +4,15 @@ - **[Trace](kernel-small-debug-trace.md)** +- **[perf](kernel-mini-memory-perf.md)** + +- **[LMS](kernel-small-memory-lms.md)** + - **[Process Commissioning](kernel-small-debug-process.md)** -- **[Memory Debugging](kernel-small-debug-memory.md)** +- **[Kernel-Mode Memory Debugging](kernel-small-debug-memory.md)** + +- **[User-Mode Memory Debugging](kernel-small-debug-user.md)** - **[Other Kernel Debugging Methods](kernel-small-debug-other.md)** diff --git a/en/device-dev/kernel/kernel-small-memory-lms.md b/en/device-dev/kernel/kernel-small-memory-lms.md new file mode 100644 index 0000000000..c18b5bf620 --- /dev/null +++ b/en/device-dev/kernel/kernel-small-memory-lms.md @@ -0,0 +1,499 @@ +# LMS + +- [Basic Concepts](#section531482192018) +- [Working Principles](#section5125124532010) +- [Available APIs](#section17747184017458) + - [Kernel Mode](#section104473014465) + - [User Mode](#section58151229172811) + +- [Development Guidelines](#section10302175017543) + - [Kernel-mode Development Process](#section04021008552) + +- [Kernel-mode Development Example](#section112034213583) +- [Kernel-mode Sample Code](#section10348549155812) + - [Kernel-mode Verification](#section61719481795) + - [User-mode Development Process](#section1425821711114) + - [User-mode Development Example](#section3470546163) + - [User-Mode Sample Code](#section183253286161) + - [User-mode Verification](#section5665123516214) + + +## 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. + +The LMS module of the OpenHarmony LiteOS-A kernel provides the following functions: + +- 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 when libc frequently accessed functions, including **memset**, **memcpy**, **memmove**, **strcat**, **strcpy**, **strncat** and **strncpy**, are called. + +## 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. + +- 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. +- 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. + +## Available APIs + +### Kernel Mode + +The LMS module of the OpenHarmony LiteOS-A kernel provides the following APIs. For more details about the APIs, see the [API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_lms.h) reference. + +**Table 1** LMS module APIs + + + + + + + + + + + + + + + + + + + + + + + + +

Function

+

API

+

Description

+

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.

+

Deleting a memory pool from the LMS check linked list

+

LOS_LmsCheckPoolDel

+

Cancels the validity check on the specified memory pool.

+

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.

+

Disabling protection of a specified memory chunk

+

LOS_LmsAddrDisableProtect

+

Unlocks a memory chunk to make it readable and writable.

+
+ +### User Mode + +The user mode provides only the LMS check library. It does not provide external APIs. + +## Development Guidelines + +### Kernel-mode Development Process + +The typical process for enabling LMS is as follows: + +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**. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Macro

+

menuconfig Option

+

Description

+

Value

+

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_LOAD_CHECK

+

Enable lms read check

+

Whether to enable LMS read 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

+
+ +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") { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + ] + } else { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + ] + } + ``` + +3. Recompile the code and check the serial port output. The memory problem detected will be displayed. + +## Kernel-mode Development Example + +This example implements the following: + +1. Create a task for LMS. +2. Construct a buffer overflow error and a UAF error. +3. Add "-fsanitize=kernel-address", execute the compilation, and check the output. + +## Kernel-mode Sample Code + +The code is as follows: + +``` +#define PAGE_SIZE (0x1000U) +#define INDEX_MAX 20 +UINT32 g_lmsTestTaskId; +char g_testLmsPool[2 * PAGE_SIZE]; +STATIC VOID testPoolInit(void) +{ + UINT32 ret = LOS_MemInit(g_testLmsPool, 2 * PAGE_SIZE); + if (ret != 0) { + PRINT_ERR("%s failed, ret = 0x%x\n", __FUNCTION__, ret); + return; + } +} +static VOID LmsTestOsmallocOverflow(VOID) +{ + PRINTK("\n######%s start ######\n", __FUNCTION__); + UINT32 i; + CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); + PRINTK("str[%2d]=0x%2x ", INDEX_MAX, str[INDEX_MAX]); /* trigger heap overflow at str[INDEX_MAX] */ + PRINTK("\n######%s stop ######\n", __FUNCTION__); +} +static VOID LmsTestUseAfterFree(VOID) +{ + PRINTK("\n######%s start ######\n", __FUNCTION__); + UINT32 i; + CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); + LOS_MemFree(g_testLmsPool, str); + PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */ + PRINTK("\n######%s stop ######\n", __FUNCTION__); +} +VOID LmsTestCaseTask(VOID) +{ + testPoolInit(); + LmsTestOsmallocOverflow(); + LmsTestUseAfterFree(); +} +UINT32 Example_Lms_test(VOID){ + UINT32 ret; + TSK_INIT_PARAM_S lmsTestTask; + /* Create a task for LMS. */ + memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask; + lmsTestTask.pcName = "TestLmsTsk"; /* Task name. */ + lmsTestTask.uwStackSize = 0x800; + lmsTestTask.usTaskPrio = 5; + lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_lmsTestTaskId, &lmsTestTask); + if(ret != LOS_OK){ + PRINT_ERR("LmsTestTask create failed .\n"); + return LOS_NOK; + } + return LOS_OK; +} +LOS_MODULE_INIT(Example_Lms_test, LOS_INIT_LEVEL_KMOD_EXTENDED); +``` + +### Kernel-mode Verification + +The output is as follows: + +``` +######LmsTestOsmallocOverflow start ###### +[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected Start ***** +[ERR][KProcess:LmsTestCaseTask]Heap buffer overflow error detected +[ERR][KProcess:LmsTestCaseTask]Illegal READ address at: [0x4157a3c8] +[ERR][KProcess:LmsTestCaseTask]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2] +OsBackTrace fp = 0x402c0f88 +runTask->taskName = LmsTestCaseTask +runTask->taskID = 2 +*******backtrace begin******* +traceback fp fixed, trace using fp = 0x402c0fd0 +traceback 0 -- lr = 0x400655a4 fp = 0x402c0ff8 +traceback 1 -- lr = 0x40065754 fp = 0x402c1010 +traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 +traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca +[LMS] Dump info around address [0x4157a3c8]: + [0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1 + [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 + [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 + [0x4157a3c8]: [ba] dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: [2] 2 + [0x4157a3d0]: 2c 1a 00 00 00 00 00 00 | [0x4157be3d | 0]: 2 3 + [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 + [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 + [0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3 + [0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3 +[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected End ***** +str[20]=0xffffffba +######LmsTestOsmallocOverflow stop ###### +###### LmsTestUseAfterFree start ###### +[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected Start ***** +[ERR][KProcess:LmsTestCaseTask]Use after free error detected +[ERR][KProcess:LmsTestCaseTask]Illegal READ address at: [0x4157a3d4] +[ERR][KProcess:LmsTestCaseTask]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3] +OsBackTrace fp = 0x402c0f90 +runTask->taskName = LmsTestCaseTask +runTask->taskID = 2 +*******backtrace begin******* +traceback fp fixed, trace using fp = 0x402c0fd8 +traceback 0 -- lr = 0x40065680 fp = 0x402c0ff8 +traceback 1 -- lr = 0x40065758 fp = 0x402c1010 +traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 +traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca +[LMS] Dump info around address [0x4157a3d4]: + [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 + [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 + [0x4157a3c8]: ba dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: 2 2 + [0x4157a3d0]: 2c 1a 00 00 [00] 00 00 00 | [0x4157be3d | 0]: 2 [3] + [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 + [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 + [0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2 + [0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3 + [0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3 +[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected End ***** +str[ 0]=0x 0 +######LmsTestUseAfterFree stop ###### +``` + +The key output information is as follows: + +- Error type: + - Heap buffer overflow + - UAF + +- Incorrect operations: + - Illegal read + - Illegal write + - Illegal double free + +- Context: + - Task information \(**taskName** and **taskId**\) + - Backtrace + +- Memory information of the error addresses: + - Memory value and the value of the corresponding shadow memory + - 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\) + + +### 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**. + +``` +if ("$ohos_build_compiler_specified" == "gcc") { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-funwind-tables", + "-fasynchronous-unwind-tables", + ] + } else { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + "-funwind-tables", + "-fasynchronous-unwind-tables", + ] + } + ldflags = [ + "-rdynamic", + "-lunwind", + "-lusrlms", + "-Wl,--wrap=realloc", + "-Wl,--wrap=calloc", + "-Wl,--wrap=malloc", + "-Wl,--wrap=free", + "-Wl,--wrap=valloc", + "-Wl,--wrap=aligned_alloc", + "-Wl,--wrap=memset", + "-Wl,--wrap=memcpy", + "-Wl,--wrap=memmove", + "-Wl,--wrap=strcpy", + "-Wl,--wrap=strcat", + ] + deps = [ "//kernel/liteos_a/kernel/extended/lms/usr:usrlmslib" ] +``` + +### User-mode Development Example + +This example implements the following: + +1. Construct a buffer overflow error and a UAF error. +2. Modify the build script and perform the build again. + +### User-Mode Sample Code + +The code is as follows: + +``` +static void BufWriteTest(void *buf, int start, int end) +{ + for (int i = start; i <= end; i++) { + ((char *)buf)[i] = 'a'; + } +} +static void BufReadTest(void *buf, int start, int end) +{ + char tmp; + for (int i = start; i <= end; i++) { + tmp = ((char *)buf)[i]; + } +} +static void LmsMallocTest(void) +{ + printf("\n-------- LmsMallocTest Start --------\n"); + char *buf = (char *)malloc(16); + BufReadTest(buf, -1, 16); + free(buf); + printf("\n-------- LmsMallocTest End --------\n"); +} +static void LmsFreeTest(void) +{ + printf("\n-------- LmsFreeTest Start --------\n"); + char *buf = (char *)malloc(16); + free(buf); + BufReadTest(buf, 1, 1); + free(buf); + printf("\n-------- LmsFreeTest End --------\n"); +} +int main(int argc, char * const * argv) +{ + printf("\n############### Lms Test start ###############\n"); + char *tmp = (char *)malloc(5000); + LmsMallocTest(); + LmsFreeTest(); + printf("\n############### Lms Test End ###############\n"); +} +``` + +### User-mode Verification + +The output is as follows: + +``` +***** Lite Memory Sanitizer Error Detected ***** +Heap buffer overflow error detected! +Illegal READ address at: [0x1f8b3edf] +Shadow memory address: [0x3d34d3ed : 6] Shadow memory value: [2] +Accessable heap addr 0 +Heap red zone 2 +Heap freed buffer 3 +Dump info around address [0x1f8b3edf]: + [0x1f8b3eb8]: 74 55 8b 1f 74 55 8b 1f | [0x3d34d3eb | 4]: 0 0 + [0x1f8b3ec0]: f8 9c 8b 1f 00 00 00 00 | [0x3d34d3ec | 0]: 0 0 + [0x1f8b3ec8]: 00 00 00 00 9c fc fc fc | [0x3d34d3ec | 4]: 0 0 + [0x1f8b3ed0]: 21 00 00 00 41 00 00 00 | [0x3d34d3ed | 0]: 0 0 + [0x1f8b3ed8]: 60 55 8b 1f 60 55 8b [1f]| [0x3d34d3ed | 4]: 2 [2] + [0x1f8b3ee0]: 50 4e 0b 00 00 00 00 00 | [0x3d34d3ee | 0]: 0 0 + [0x1f8b3ee8]: 09 00 00 00 00 00 00 00 | [0x3d34d3ee | 4]: 0 0 + [0x1f8b3ef0]: 00 00 00 00 08 03 09 00 | [0x3d34d3ef | 0]: 2 2 + [0x1f8b3ef8]: 00 00 00 00 00 00 00 00 | [0x3d34d3ef | 4]: 2 2 +***** Lite Memory Sanitizer Error Detected End ***** +Backtrace() returned 5 addresses + #01: [0x4d6c] -> ./sample_usr_lms + #02: <(null)+0x2004074>[0x4074] -> ./sample_usr_lms + #03: <(null)+0x2003714>[0x3714] -> ./sample_usr_lms + #04: [0x363c] -> ./sample_usr_lms + #05: <(null)+0x1f856f30>[0x56f30] -> /lib/libc.so +-------- LMS_malloc_test End -------- +***** Lite Memory Sanitizer Error Detected ***** +Use after free error detected! +Illegal Double free address at: [0x1f8b3ee0] +Shadow memory address: [0x3d34d3ee : 0] Shadow memory value: [3] +Accessable heap addr 0 +Heap red zone 2 +Heap freed buffer 3 +Dump info around address [0x1f8b3ee0]: + [0x1f8b3ec0]: f8 9c 8b 1f 00 00 00 00 | [0x3d34d3ec | 0]: 0 0 + [0x1f8b3ec8]: 00 00 00 00 fc fd fc fc | [0x3d34d3ec | 4]: 0 0 + [0x1f8b3ed0]: 21 00 00 00 20 01 00 00 | [0x3d34d3ed | 0]: 0 0 + [0x1f8b3ed8]: 60 55 8b 1f 60 55 8b 1f | [0x3d34d3ed | 4]: 2 2 + [0x1f8b3ee0]: [20] 60 9a 1f 40 61 9a 1f | [0x3d34d3ee | 0]: [3] 3 + [0x1f8b3ee8]: 60 62 9a 1f 80 63 9a 1f | [0x3d34d3ee | 4]: 3 3 + [0x1f8b3ef0]: 20 40 8b 1f 20 20 8b 1f | [0x3d34d3ef | 0]: 3 3 + [0x1f8b3ef8]: 00 00 00 00 00 00 00 00 | [0x3d34d3ef | 4]: 3 3 + [0x1f8b3f00]: 00 00 00 00 00 00 00 00 | [0x3d34d3f0 | 0]: 3 3 +***** Lite Memory Sanitizer Error Detected End ***** +Backtrace() returned 5 addresses + #01: [0x4d6c] -> ./sample_usr_lms + #02: [0x5548] -> ./sample_usr_lms + #03: <(null)+0x2003fc4>[0x3fc4] -> ./sample_usr_lms + #04: [0x3664] -> ./sample_usr_lms + #05: <(null)+0x1f856f30>[0x56f30] -> /lib/libc.so +-------- LMS_free_test End -------- +``` + +The Backtrace output contains the names of the files where the addresses are located. You can locate the code line corresponding to the address in the related file. + diff --git a/en/device-dev/kernel/kernel-small-overview.md b/en/device-dev/kernel/kernel-small-overview.md index c2d1a278e9..bb4c1f6425 100644 --- a/en/device-dev/kernel/kernel-small-overview.md +++ b/en/device-dev/kernel/kernel-small-overview.md @@ -1,10 +1,16 @@ # Kernel Overview +- [Overview](#section6614133913129) +- [Kernel Architecture](#section827143517385) + ## Overview -The OpenHarmony lightweight kernel is a next-generation kernel developed based on the lightweight IoT operating system Huawei LiteOS. Two types of kernels are available: LiteOS-M and LiteOS-A. The LiteOS-M kernel is designed for lightweight systems, which support MCU memory of hundreds of KB and MPU isolation. FreeRTOS and ThreadX are counterparts in the industry. The LiteOS-A kernel is ideal for small systems, which support memory in MB and MMU isolation. Similar kernels include Zircon and Darwin. This development guide applies to the LiteOS-A kernel. +The OpenHarmony lightweight kernel is a next-generation kernel that evolved from the kernel of Huawei LiteOS, a lightweight IoT operating system. The kernel comes with two patterns: LiteOS-M and LiteOS-A. The LiteOS-M kernel is designed for the mini system, which supports KB-level MCU memory and MPU isolation. Typical counterparts in the industry include FreeRTOS and ThreadX. The LiteOS-A kernel is ideal for the small system, which supports MB-level memory and MMU isolation. Equivalent kernels include Zircon and Darwin. + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>OpenHarmony provides different kernels for different systems. The small system supports LiteOS and Linux. This document applies to the LiteOS-A kernel. For details about operations related to the Linux kernel, see [Linux Kernel Overview](kernel-standard-overview.md). -To adapt to the rapid development of the IoT industry, the OpenHarmony lightweight kernel is continuously optimized and expanded to provide application developers with friendly development experience and unified and open ecosystem capabilities. The LiteOS-A has the following new features: +To keep pace with the rapid development of the IoT industry, the OpenHarmony lightweight kernel is continuously optimized and expanded to provide application developers with friendly development experience and unified and open ecosystem capabilities. The LiteOS-A has the following new features: - Diversified kernel mechanisms @@ -25,37 +31,35 @@ To adapt to the rapid development of the IoT industry, the OpenHarmony lightweig ## Kernel Architecture -The lightweight kernel consists of the basic kernel, extension components, HDF, and POSIX interface. Different from the microkernel which is running in the user space, the extended functions, such as file system and network protocols, of the lightweight kernel are running in the kernel address space. The direct function calling between components is much faster than inter-process communication \(IPC\) or remote procedure calls \(RPCs\). - -**Figure 1** Architecture of the OpenHarmony LiteOS-A kernel - +The lightweight kernel consists of the basic kernel, extended components, HDF, and POSIX APIs. Different from the microkernel which is running in the user mode, the extended functions, such as the file system and network protocols, of the lightweight kernel are running in the kernel address space. The direct function calling between components is much faster than inter-process communication \(IPC\) or remote procedure calls \(RPCs\). -![](figure/en-us_image_0000001191018697.png) +**Figure 1** Architecture of the OpenHarmony LiteOS-A kernel +![](figures/architecture-of-the-openharmony-liteos-a-kernel.png "architecture-of-the-openharmony-liteos-a-kernel") - The basic kernel implements basic kernel mechanisms, such as scheduling, memory management, and interrupts. -- Extended components include file systems, network protocols, and security functions. +- Extended components include file systems, network protocols, permission management, and more. - The HDF provides a unified standard framework for peripheral drivers. -- The POSIX interface allows POSIX-compliant applications to be easily ported to the OpenHarmony. +- The POSIX APIs allow POSIX-compliant applications to be easily ported to the OpenHarmony. **Basic Kernel** The basic kernel implements the following mechanisms: -- Process management: supports processes and threads and task-based process implementation. Processes have independent 4 GiB address space. -- Multi-core scheduling: supports task and affinity-based interrupt-core binding settings. -- Real-time scheduling: Tasks are scheduled based on priorities. The tasks of the same priority are scheduled by using the time slice round-robin. -- Virtual memory: supports page fault. The kernel space is statically mapped to 0-1 GiB addresses, and the user space is mapped to 1-4 GiB addresses. +- Process management: manages processes and threads and supports task-based process implementation. Processes have independent 4 GiB address space. +- Multi-core scheduling: supports CPU affinity settings, allowing the binding and unbinding of a task or interrupt to one or more CPU cores. +- Real-time scheduling: schedules tasks based on priorities. The tasks of the same priority are scheduled by using the time slice polling. +- Virtual memory: supports static mapping of the kernel space to 0-1 GiB addresses, and mapping of the user space to 1-4 GiB addresses. - Kernel communication: supports events, semaphores, mutexes, and queues. -- Time management: supports software timers and system clock. +- Time management: supports software timers and the system clock. **File systems** -The LiteOS-A supports multiple file systems, such as FAT, JFFS2, NFS, ramfs, and procfs, and provides complete POSIX standard APIs externally. The VFS layer is used as the unified adaptation layer framework, which facilitates the porting of new file systems. Each file system can automatically use the rich functions provided by the VFS layer. +The LiteOS-A supports multiple file systems, such as FAT, JFFS2, NFS, ramfs, and procfs, and provides complete standard POSIX APIs. The VFS layer is used as the unified adaptation layer framework, which facilitates the porting of new file systems. Each file system can automatically use the rich functions provided by the VFS layer. The following features are supported: - Complete POSIX API support -- File-level cache \(page cache\) +- File-level cache \(PageCache\) - Disk-level cache \(Bcache\) - Directory cache \(path cache\) - DAC capability @@ -64,7 +68,7 @@ The following features are supported: **Network Protocols** -The LiteOS-A network protocols are constructed based on the open-source lightweight IP \(lwIP\) and have also optimized the RAM usage and improved the transmission performance over LWIP. +The LiteOS-A network protocols are constructed based on the open-source lightweight IP \(lwIP\), optimizing the RAM usage while improving the transmission performance over lwIP. - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, and PPPoE - API: socket API @@ -83,12 +87,12 @@ The LiteOS-A integrates the HDF framework. The HDF framework provides a more pre - Unified hardware driver interface \(HDI\) - Power management and plug and play \(PnP\) -**Extension Components** +**Extended Components** -Extension components provide optional but important mechanism for extending kernel functions. +Extended components provide optional but important mechanism for extending kernel functions. - Dynamic linking: supports standard Executable and Linkable Format \(ELF\) execution and randomization of loading addresses. -- IPC: supports LiteIPC and standard mechanisms such as Mqueue, Pipe, Fifo, and Signal. +- IPC: supports LiteIPC and standard mechanisms such as Mqueue, Pipe, FIFO, and Signal. - System calling: supports 170+ system calls and the virtual dynamic shared object \(vDSO\) mechanism. -- Permission management: supports process-based privilege division and control, and file owner, group, and owner \(UGO\) permission configuration. +- Permission management: supports process-based privilege division and control, and file user, group, and other \(UGO\) permission configuration. diff --git a/en/device-dev/kernel/kernel-small-start-kernel.md b/en/device-dev/kernel/kernel-small-start-kernel.md index a581433d65..8c04d2e0fe 100644 --- a/en/device-dev/kernel/kernel-small-start-kernel.md +++ b/en/device-dev/kernel/kernel-small-start-kernel.md @@ -1,13 +1,16 @@ -# Startup in Kernel Space +# Startup in Kernel Mode -## Kernel Startup Process +- [Kernel Startup Process](#section9882154318299) +- [Programming Example](#section19145114703217) + - [Example Description](#section1045483642518) -The kernel startup process consists of the assembly startup and C language startup, as shown in the following figure. The assembly startup involves 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 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 following table describes each phase. -**Figure 1** 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 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. [Table 1](#table38544719428) describes each phase. -![](figure/en-us_image_0000001178856385.png) +**Figure 1** Kernel startup process +![](figures/kernel-startup-process-2.png "kernel-startup-process-2") **Table 1** Startup framework levels @@ -92,7 +95,7 @@ The kernel startup process consists of the assembly startup and C language start ### Example Description -Add a kernel module and register the initialization function of the module to the kernel startup process 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. **Sample Code** @@ -108,7 +111,7 @@ unsigned int OsSampleModInit(void) ...... } ... -/* Register the new module at the target level of the startup framework. */ +/* Register the new module at the target level of the kernel startup framework. */ LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED); ``` @@ -122,9 +125,9 @@ cpu 1 entering scheduler cpu 0 entering scheduler ``` -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. +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. >![](../public_sys-resources/icon-note.gif) **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. ->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 takes 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. diff --git a/en/device-dev/kernel/kernel-small-start-user.md b/en/device-dev/kernel/kernel-small-start-user.md index 52876cae72..d8fd726a89 100644 --- a/en/device-dev/kernel/kernel-small-start-user.md +++ b/en/device-dev/kernel/kernel-small-start-user.md @@ -1,11 +1,17 @@ -# Startup in User Space +# Startup in User Mode -## Startup of the Root Process in User Space +- [Startup of the Root Process in User Mode](#section79911135647) + - [Startup Process of the Root Process](#section1184317581349) + - [Responsibilities of the Root Process](#section1590220321759) -The root process is the first user-space process in the system. The process ID is 1. The root process is the ancestor of all user-space processes. +- [Running Programs in User Mode](#section194576310611) + +## 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. **Figure 1** Process tree -![](figure/process-tree.png "process-tree") +![](figures/process-tree.png "process-tree") ### Startup Process of the Root Process @@ -23,7 +29,7 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) } ``` -During system startup, **OsUserInitProcess** is called to start the **init** process. The process is as follows: +During system startup, **OsUserInitProcess** is called to start the **init** process. The procedure is as follows: 1. The kernel calls **OsLoadUserInit** to load the code. 2. A process space is created to start the **/bin/init** process. @@ -38,12 +44,12 @@ During system startup, **OsUserInitProcess** is called to start the **init** - Monitors the process for reclaiming the orphan process and clears the zombie processes in child processes. -## Running Programs in User Space +## Running Programs in User Mode -Common compilation modes of user-space programs include: +Common compilation modes of user-mode programs include: -1. [Compilation using the framework](../quick-start/quickstart-lite-steps-hi3516-running.md) -2. Manual compilation +1. [Compilation based on the framework](../quick-start/quickstart-lite-steps-hi3516-running.md) +2. Manual compilation Example: @@ -51,14 +57,14 @@ Common compilation modes of user-space programs include: clang --target=arm-liteos --sysroot=prebuilts/lite/sysroot -o helloworld helloworld.c ``` - Before running the **clang** command, install the LLVM compiler. For details, see [Installing LLVM](../quick-start/quickstart-lite-env-setup-linux.md). + Before running the **clang** command, install the LLVM compiler. For details, see [Installing LLVM](../quick-start/quickstart-lite-package-environment.md#section711117144296). - **--target=arm-liteos**: specifies that the compilation platform is arm-liteos. + **--target=arm-liteos**: specifies the compilation platform, which is arm-liteos. **--sysroot=$\{YOUR\_ROOT\_PATH\}/prebuilts/lite/sysroot**: specifies the directory in which you can search for the header file and the dependent standard libraries. -A user-space 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. diff --git a/en/device-dev/kernel/kernel-small-start.md b/en/device-dev/kernel/kernel-small-start.md index 2e297b9b9a..72217136ac 100644 --- a/en/device-dev/kernel/kernel-small-start.md +++ b/en/device-dev/kernel/kernel-small-start.md @@ -1,7 +1,7 @@ # Kernel Startup -- **[Startup in Kernel Space](kernel-small-start-kernel.md)** +- **[Startup in Kernel Mode](kernel-small-start-kernel.md)** -- **[Startup in User Space](kernel-small-start-user.md)** +- **[Startup in User Mode](kernel-small-start-user.md)** diff --git a/en/device-dev/kernel/kernel-small.md b/en/device-dev/kernel/kernel-small.md index c742df10d5..03e02571e4 100644 --- a/en/device-dev/kernel/kernel-small.md +++ b/en/device-dev/kernel/kernel-small.md @@ -6,7 +6,7 @@ - **[Basic Kernel](kernel-small-basics.md)** -- **[Extension Components](kernel-small-bundles.md)** +- **[Extended Components](kernel-small-bundles.md)** - **[Debugging and Tools](kernel-small-debug.md)** diff --git a/en/device-dev/kernel/kernel-standard-build.md b/en/device-dev/kernel/kernel-standard-build.md index a9a7d06996..cdb6f59c83 100644 --- a/en/device-dev/kernel/kernel-standard-build.md +++ b/en/device-dev/kernel/kernel-standard-build.md @@ -1,11 +1,16 @@ -# Guidelines for Building the Linux Kernel +# Guidelines for Compiling and Building the Linux Kernel -The following uses the Hi3516D V300 development board and Ubuntu x86 server as an example. +- [Example 1](#section19369206113115) -Perform a full build for the project to generate the **uImage** kernel image. +## Example 1 + +The following uses the Hi3516D V300 board and Ubuntu x86 server as an example. + +Perform a full build for the project to generate the **uImage** kernel image. ``` ./build.sh --product-name Hi3516DV300 # Build the Hi3516D V300 image. - --build-target build_kernel # Build the uImage kernel image of Hi3516D V300. - --gn-args linux_kernel_version=\"linux-5.10\" # Build the specified kernel version. + --build-target build_kernel # Build the uImage kernel image of the Hi3516D V300 board. + --gn-args linux_kernel_version=\"linux-5.10\" # Build the specified kernel version. ``` + diff --git a/en/device-dev/kernel/kernel-standard-overview.md b/en/device-dev/kernel/kernel-standard-overview.md index 4af04f3a59..0bb067e3ff 100644 --- a/en/device-dev/kernel/kernel-standard-overview.md +++ b/en/device-dev/kernel/kernel-standard-overview.md @@ -1,5 +1,8 @@ # Linux Kernel Overview +- [Linux Kernel Versions](#section152847516485) +- [OpenHarmony Kernel Version Selection](#section2716416191715) + OpenHarmony adopts the Linux kernel as the basic kernel for standard-system devices \(reference memory ≥ 128 MiB\) so that appropriate OS kernels can be selected for the devices subject to resource limitations and therefore provide basic capabilities for upper-layer apps. ## Linux Kernel Versions @@ -12,4 +15,5 @@ The LTS version provides long-term kernel maintenance \(in fixing bugs and secur ## OpenHarmony Kernel Version Selection -Select an appropriate LTS kernel version as the Linux kernel for OpenHarmony. Currently, Linux-4.19 and Linux-5.10 are supported. +The Linux kernel in OpenHarmony selects appropriate LTS versions as its basic versions. Currently, it supports Linux-4.19 and Linux-5.10. + diff --git a/en/device-dev/kernel/kernel-standard-patch.md b/en/device-dev/kernel/kernel-standard-patch.md index 6b159f0997..2b9dcfa3b6 100644 --- a/en/device-dev/kernel/kernel-standard-patch.md +++ b/en/device-dev/kernel/kernel-standard-patch.md @@ -1,35 +1,39 @@ -# Applying Patches on OpenHarmony Development Boards - -1. Apply HDF patches. - - Apply the HDF kernel patches matching your kernel version. For details, see the method in **kernel.mk** in the **kernel/linux/build** repository. - - ``` - $(OHOS_BUILD_HOME)/drivers/adapter/khdf/linux/patch_hdf.sh $(OHOS_BUILD_HOME) $(KERNEL_SRC_TMP_PATH) $(HDF_PATCH_FILE) - ``` - -2. Apply the chip driver patches. - - The following uses Hi3516D V300 as an example. - - Place the patches for the chip component in the corresponding path based on the path and naming rules for the patches of the chip component in **kernel.mk** in the **kernel/linux/build** repository. - - ``` - DEVICE_PATCH_DIR := $(OHOS_BUILD_HOME)/kernel/linux/patches/${KERNEL_VERSION}/$(DEVICE_NAME)_patch - DEVICE_PATCH_FILE := $(DEVICE_PATCH_DIR)/$(DEVICE_NAME).patch - ``` - -3. Modify the **config** file to build. - - Place the **config** file for the chip component in the corresponding path based on the path and naming rules of the chip component in **kernel.mk** in the **kernel/linux/build** repository. - - ``` - KERNEL_CONFIG_PATH := $(OHOS_BUILD_HOME)/kernel/linux/config/${KERNEL_VERSION} - DEFCONFIG_FILE := $(DEVICE_NAME)_$(BUILD_TYPE)_defconfig - ``` - - > **Note**: - > - >In the OpenHarmony project build process, patches are installed after **kernel/linux/linux-\*\.\*** is copied. Before using the version-level build command of OpenHarmony, ensure that the **kernel/linux/linux-\*\.\*** source code is available. - > - >The kernel built is generated in the **kernel** directory under the **out** directory. Modify the **config** file based on the kernel built, and copy the generated **.config** file to the corresponding path in the **config** repository. Then, the configuration takes effect. +# Guidelines for Using Patches on OpenHarmony Development Boards + +1. Apply the HDF patches. + + Apply the HDF patches based on the kernel version in the **kernel/linux/build** repository. For details, see the method for applying the HDF patch in **kernel.mk**. + + ``` + $(OHOS_BUILD_HOME)/drivers/adapter/khdf/linux/patch_hdf.sh $(OHOS_BUILD_HOME) $(KERNEL_SRC_TMP_PATH) $(HDF_PATCH_FILE) + ``` + +2. Apply the chip driver patches. + + The following uses Hi3516D V300 as an example: + + In the **kernel/linux/build** repository, place the chip module patches in the corresponding path based on the patch path and naming rules for the chip module in **kernel.mk**. + + ``` + DEVICE_PATCH_DIR := $(OHOS_BUILD_HOME)/kernel/linux/patches/${KERNEL_VERSION}/$(DEVICE_NAME)_patch + DEVICE_PATCH_FILE := $(DEVICE_PATCH_DIR)/$(DEVICE_NAME).patch + ``` + + ``` + + ``` + +3. Modify the **config** file to be built. + + In the **kernel/linux/build** repository, place the chip module **config** file in the corresponding path based on the file path and naming rules for the chip module in **kernel.mk**. + + ``` + KERNEL_CONFIG_PATH := $(OHOS_BUILD_HOME)/kernel/linux/config/${KERNEL_VERSION} + DEFCONFIG_FILE := $(DEVICE_NAME)_$(BUILD_TYPE)_defconfig + ``` + + >![](../public_sys-resources/icon-notice.gif) **NOTICE:** + >In the OpenHarmony project build process, patches are applied after the code environment of **kernel/linux/linux-\*.\*** is copied. Before running the OpenHarmony version-level build command, ensure that the source code environment of **kernel/linux/linux-\*.\*** is available. + >After the build is complete, the kernel is generated in the kernel directory in the **out** directory. Modify the **config** file based on the kernel generated, and copy the generated **.config** file to the corresponding path in the **config** repository. Then, the configuration takes effect. + + diff --git a/en/device-dev/kernel/kernel-standard.md b/en/device-dev/kernel/kernel-standard.md index 3e0b536437..d9e58952f0 100644 --- a/en/device-dev/kernel/kernel-standard.md +++ b/en/device-dev/kernel/kernel-standard.md @@ -1,4 +1,4 @@ -# Kernel for Standard Systems +# Kernel for Standard Systems - **[Linux Kernel Overview](kernel-standard-overview.md)** diff --git a/en/device-dev/kernel/kernel.md b/en/device-dev/kernel/kernel.md index 3e6887e216..f633268641 100644 --- a/en/device-dev/kernel/kernel.md +++ b/en/device-dev/kernel/kernel.md @@ -4,6 +4,6 @@ - **[Kernel for Small Systems](kernel-small.md)** -- **[Kernel for Standard Systems](kernel-standard.md)** +- **[User-Mode Memory Debugging](kernel-small-debug-user.md)** diff --git a/en/readme.md b/en/readme.md index b0e668e5f9..afa3cfb8e5 100644 --- a/en/readme.md +++ b/en/readme.md @@ -11,8 +11,8 @@ This project stores OpenHarmony documentation, including the quick start guide, - **overview**: [device development overview](device-dev/Readme-EN.md) - **quick-start**: [quick start guide](device-dev/quick-start/Readme-EN.md) \(covering environment setup, source code acquisition, build, and burning\) - Basic development capabilities - - **Kernel**: [Kernel for Mini Systems](device-dev/kernel/kernel-lite-mini.md) - - **Kernel:**[Kernel for Small Systems](device-dev/kernel/kernel-lite-small.md) + - **Kernel**: [Kernel for Mini Systems](device-dev/kernel/kernel-mini.md) + - **Kernel:**[Kernel for Small Systems](device-dev/kernel/kernel-small.md) - **Drivers**: [drivers](device-dev/driver/Readme-EN.md) - **Subsystems**: [subsystems](device-dev/subsystems/Readme-EN.md) \(such as compilation and building, graphics, DFX, and XTS\) - **Security**: [privacy and security](device-dev/security/Readme-EN.md) diff --git a/zh-cn/device-dev/kernel/Readme-CN.md b/zh-cn/device-dev/kernel/Readme-CN.md index d24803e5af..69a2a9ca7c 100755 --- a/zh-cn/device-dev/kernel/Readme-CN.md +++ b/zh-cn/device-dev/kernel/Readme-CN.md @@ -1,196 +1,180 @@ -# 内核使用指南 +# kernel -- [轻量系统内核](kernel-mini.md) - - [内核概述](kernel-mini-overview.md) - - [基础内核](kernel-mini-basic.md) - - [中断管理](kernel-mini-basic-interrupt.md) - - [基本概念](kernel-mini-basic-interrupt-concept.md) - - [开发指导](kernel-mini-basic-interrupt-guide.md) - - [任务管理](kernel-mini-basic-task.md) - - [基本概念](kernel-mini-basic-task-basic.md) - - [开发指导](kernel-mini-basic-task-guide.md) - - [内存管理](kernel-mini-basic-memory.md) - - [基本概念](kernel-mini-basic-memory-basic.md) - - [静态内存](kernel-mini-basic-memory-static.md) - - [动态内存](kernel-mini-basic-memory-dynamic.md) - - [内核通信机制](kernel-mini-basic-ipc.md) - - [事件](kernel-mini-basic-ipc-event.md) - - [基本概念](kernel-mini-basic-ipc-event-basic.md) - - [开发指导](kernel-mini-basic-ipc-event-guide.md) - - [互斥锁](kernel-mini-basic-ipc-mutex.md) - - [基本概念](kernel-mini-basic-ipc-mutex-basic.md) - - [开发指导](kernel-mini-basic-ipc-mutex-guide.md) - - [消息队列](kernel-mini-basic-ipc-queue.md) - - [基本概念](kernel-mini-basic-ipc-queue-basic.md) - - [开发指导](kernel-mini-basic-ipc-queue-guide.md) - - [信号量](kernel-mini-basic-ipc-sem.md) - - [基本概念](kernel-mini-basic-ipc-sem-basic.md) - - [开发指导](kernel-mini-basic-ipc-sem-guide.md) - - [时间管理](kernel-basic-mini-time.md) - - [基本概念](kernel-mini-basic-time-basic.md) - - [开发指导](kernel-mini-basic-time-guide.md) - - [软件定时器](kernel-mini-basic-soft.md) - - [基本概念](kernel-mini-basic-soft-basic.md) - - [开发指导](kernel-mini-basic-soft-guide.md) - - [扩展组件](kernel-mini-extend.md) - - [C++支持](kernel-mini-extend-support.md) - - [CPU占用率](kernel-mini-extend-cpup.md) - - [基本概念](kernel-mini-extend-cpup-basic.md) - - [开发指导](kernel-mini-extend-cpup-guide.md) - - [基本概念](kernel-mini-extend-dynamic-loading-basic.md) - - [开发指导](kernel-mini-extend-dynamic-loading-guide.md) - - [文件系统](kernel-mini-extend-file.md) - - [FAT](kernel-mini-extend-file-fat.md) - - [LittleFS](kernel-mini-extend-file-lit.md) - - [基本概念](kernel-mini-extend-file-littlefs-basic.md) - - [开发指导](kernel-mini-extend-file-littlefs-guide.md) - - [内核调测](kernel-memory-inner.md) - - [内存调测](kernel-mini-memory-debug.md) - - [内存信息统计](kernel-mini-memory-debug-mes.md) - - [内存泄漏检测](kernel-mini-imemory-debug-det.md) - - [踩内存检测](kernel-mini-memory-debug-cet.md) - - [异常调测](kernel-mini-memory-exception.md) - - [Trace调测](kernel-mini-memory-trace.md) - - [LMS调测](kernel-mini-debug-lms.md) - - [附录](kernel-mini-app.md) - - [内核编码规范](kernel-mini-appx-code.md) - - [基本数据结构](kernel-mini-appx-data.md) - - [双向链表](kernel-mini-appx-data-list.md) - - [标准库支持](kernel-mini-appx-lib.md) - - [CMSIS支持](kernel-mini-appx-lib-cmsis.md) - - [POSIX支持](kernel-mini-appx-lib-posix.md) -- [小型系统内核](kernel-small.md) - - [内核概述](kernel-small-overview.md) - - [内核启动](kernel-small-start.md) - - [内核态启动](kernel-small-start-kernel.md) - - [用户态启动](kernel-small-start-user.md) - - [基础内核](kernel-small-basics.md) - - [中断及异常处理](kernel-small-basic-interrupt.md) - - [进程管理](kernel-small-basic-process.md) - - [进程](kernel-small-basic-process-process.md) - - [任务](kernel-small-basic-process-thread.md) - - [调度器](kernel-small-basic-process-scheduler.md) - - [内存管理](kernel-small-basic-memory.md) - - [堆内存管理](kernel-small-basic-memory-heap.md) - - [物理内存管理](kernel-small-basic-memory-physical.md) - - [虚拟内存管理](kernel-small-basic-memory-virtual.md) - - [虚实映射](kernel-small-basic-inner-reflect.md) - - [内核通信机制](kernel-small-basic-trans.md) - - [事件](kernel-small-basic-trans-event.md) - - [信号量](kernel-small-basic-trans-semaphore.md) - - [互斥锁](kernel-small-basic-trans-mutex.md) - - [消息队列](kernel-small-basic-trans-queue.md) - - [读写锁](kernel-small-basic-trans-rwlock.md) - - [用户态快速互斥锁](kernel-small-basic-trans-user-mutex.md) - - [信号](kernel-small-basic-trans-user-signal.md) - - [时间管理](kernel-small-basic-time.md) - - [软件定时器](kernel-small-basic-softtimer.md) - - [原子操作](kernel-small-basic-atomic.md) - - [扩展组件](kernel-small-bundles.md) - - [系统调用](kernel-small-bundles-system.md) - - [动态加载与链接](kernel-small-bundles-linking.md) - - [虚拟动态共享库](kernel-small-bundles-share.md) - - [轻量级进程间通信](kernel-small-bundles-ipc.md) - - [文件系统](kernel-small-bundles-fs.md) - - [虚拟文件系统](kernel-small-bundles-fs-virtual.md) - - [支持的文件系统](kernel-small-bundles-fs-support.md) - - [FAT](kernel-small-bundles-fs-support-fat.md) - - [JFFS2](kernel-small-bundles-fs-support-jffs2.md) - - [NFS](kernel-small-bundles-fs-support-nfs.md) - - [Ramfs](kernel-small-bundles-fs-support-ramfs.md) - - [Procfs](kernel-small-bundles-fs-support-procfs.md) - - [适配新的文件系统](kernel-small-bundles-fs-new.md) - - [调测与工具](kernel-small-debug.md) - - [Shell](kernel-small-debug-shell.md) - - [Shell介绍](kernel-small-debug-shell-overview.md) - - [Shell命令开发指导](kernel-small-debug-shell-guide.md) - - [Shell命令编程实例](kernel-small-debug-shell-build.md) - - [Shell命令使用详解](kernel-small-debug-shell-details.md) - - [系统命令](kernel-small-debug-shell-cmd.md) - - [cpup](kernel-small-debug-shell-cmd-cpup.md) - - [date](kernel-small-debug-shell-cmd-date.md) - - [dmesg](kernel-small-debug-shell-cmd-dmesg.md) - - [exec](kernel-small-debug-shell-cmd-exec.md) - - [free](kernel-small-debug-shell-cmd-free.md) - - [help](kernel-small-debug-shell-cmd-help.md) - - [hwi](kernel-small-debug-shell-cmd-hwi.md) - - [kill](kernel-small-debug-shell-cmd-kill.md) - - [log](kernel-small-debug-shell-cmd-log.md) - - [memcheck](kernel-small-debug-shell-cmd-memcheck.md) - - [oom](kernel-small-debug-shell-cmd-oom.md) - - [pmm](kernel-small-debug-shell-cmd-pmm.md) - - [reset](kernel-small-debug-shell-cmd-reset.md) - - [sem](kernel-small-debug-shell-cmd-sem.md) - - [stack](kernel-small-debug-shell-cmd-stack.md) - - [su](kernel-small-debug-shell-cmd-su.md) - - [swtmr](kernel-small-debug-shell-cmd-swtmr.md) - - [systeminfo](kernel-small-debug-shell-cmd-sysinfo.md) - - [task](kernel-small-debug-shell-cmd-task.md) - - [uname](kernel-small-debug-shell-cmd-uname.md) - - [vmm](kernel-small-debug-shell-cmd-vmm.md) - - [watch](kernel-small-debug-shell-cmd-watch.md) - - [文件命令](kernel-small-debug-shell-file.md) - - [cat](kernel-small-debug-shell-file-cat.md) - - [cd](kernel-small-debug-shell-file-cd.md) - - [chgrp](kernel-small-debug-shell-file-chgrp.md) - - [chmod](kernel-small-debug-shell-file-chmod.md) - - [chown](kernel-small-debug-shell-file-chown.md) - - [cp](kernel-small-debug-shell-file-cp.md) - - [format](kernel-small-debug-shell-file-format.md) - - [ls](kernel-small-debug-shell-file-ls.md) - - [lsfd](kernel-small-debug-shell-file-lsfd.md) - - [mkdir](kernel-small-debug-shell-file-mkdir.md) - - [mount](kernel-small-debug-shell-file-mount.md) - - [partinfo](kernel-small-debug-shell-file-partinfo.md) - - [partition](kernel-small-debug-shell-file-partition.md) - - [pwd](kernel-small-debug-shell-file-pwd.md) - - [rm](kernel-small-debug-shell-file-rm.md) - - [rmdir](kernel-small-debug-shell-file-rmdir.md) - - [statfs](kernel-small-debug-shell-file-statfs.md) - - [sync](kernel-small-debug-shell-file-sync.md) - - [touch](kernel-small-debug-shell-file-touch.md) - - [writeproc](kernel-small-debug-shell-file-write.md) - - [umount](kernel-small-debug-shell-file-umount.md) - - [网络命令](kernel-small-debug-shell-net.md) - - [arp](kernel-small-debug-shell-net-arp.md) - - [dhclient](kernel-small-debug-shell-net-dhclient.md) - - [ifconfig](kernel-small-debug-shell-net-ifconfig.md) - - [ipdebug](kernel-small-debug-shell-net-ipdebug.md) - - [netstat](kernel-small-debug-shell-net-netstat.md) - - [ntpdate](kernel-small-debug-shell-net-ntpdate.md) - - [ping](kernel-small-debug-shell-net-ping.md) - - [ping6](kernel-small-debug-shell-net-ping6.md) - - [telnet](kernel-small-debug-shell-net-telnet.md) - - [tftp](kernel-small-debug-shell-net-tftp.md) - - [魔法键使用方法](kernel-small-debug-shell-magickey.md) - - [用户态异常信息说明](kernel-small-debug-shell-error.md) - - [Trace调测](kernel-small-debug-trace.md) - - [Perf调测](kernel-small-debug-perf.md) - - [LMS调测](kernel-small-debug-lms.md) - - [进程调测](kernel-small-debug-process.md) - - [CPU占用率](kernel-small-debug-process-cpu.md) - - [内存调测](kernel-small-debug-memory.md) - - [内存信息统计](kernel-small-debug-memory-info.md) - - [内存泄漏检测](kernel-small-debug-memory-leak.md) - - [踩内存检测](kernel-small-debug-memory-corrupt.md) - - [用户态内存调测](kernel-small-debug-user.md) - - [基本概念](kernel-small-debug-user-concept.md) - - [运行机制](kernel-small-debug-user-function.md) - - [使用指导](kernel-small-debug-user-guide.md) - - [接口说明](kernel-small-debug-user-guide-api.md) - - [使用说明](kernel-small-debug-user-guide-use.md) - - [接口调用方式](kernel-small-debug-user-guide-use-api.md) - - [命令行参数方式](kernel-small-debug-user-guide-use-cli.md) - - [常见问题场景](kernel-small-debug-user-faqs.md) - - [其他内核调测手段](kernel-small-debug-other.md) - - [临终遗言](kernel-small-debug-trace-other-lastwords.md) - - [常见问题定位方法](kernel-small-debug-trace-other-faqs.md) - - [附录](kernel-small-apx.md) - - [基本数据结构](kernel-small-apx-structure.md) - - [双向链表](kernel-small-apx-dll.md) - - [位操作](kernel-small-apx-bitwise.md) - - [标准库](kernel-small-apx-library.md) -- [标准系统内核](kernel-standard.md) - - [Linux内核概述](kernel-standard-overview.md) - - [OpenHarmony开发板Patch使用指导](kernel-standard-patch.md) - - [Linux内核编译与构建指导](kernel-standard-build.md) \ No newline at end of file +- 内核 + - 轻量系统内核 + - [内核概述](kernel-mini-overview.md) + - 基础内核 + - [中断管理](kernel-mini-basic-interrupt.md) + - [任务管理](kernel-mini-basic-task.md) + - 内存管理 + - [基本概念](kernel-mini-basic-memory-basic.md) + - [静态内存](kernel-mini-basic-memory-static.md) + - [动态内存](kernel-mini-basic-memory-dynamic.md) + - 内核通信机制 + - [事件](kernel-mini-basic-ipc-event.md) + - [互斥锁](kernel-mini-basic-ipc-mutex.md) + - [消息队列](kernel-mini-basic-ipc-queue.md) + - [信号量](kernel-mini-basic-ipc-sem.md) + - [时间管理](kernel-basic-mini-time.md) + - [软件定时器](kernel-mini-basic-soft.md) + - 扩展组件 + - [C++支持](kernel-mini-extend-support.md) + - [CPU占用率](kernel-mini-extend-cpup.md) + - [动态加载](kernel-mini-extend-dynamic-loading.md) + - 文件系统 + - [FAT](kernel-mini-extend-file-fat.md) + - [LittleFS](kernel-mini-extend-file-lit.md) + - 内核调测 + - 内存调测 + - [内存信息统计](kernel-mini-memory-debug-mes.md) + - [内存泄漏检测](kernel-mini-imemory-debug-det.md) + - [踩内存检测](kernel-mini-memory-debug-cet.md) + - [异常调测](kernel-mini-memory-exception.md) + - [Trace调测](kernel-mini-memory-trace.md) + - [LMS调测](kernel-mini-memory-lms.md) + - 附录 + - [内核编码规范](kernel-mini-appx-code.md) + - 基本数据结构 + - [双向链表](kernel-mini-appx-data-list.md) + - 标准库支持 + - [CMSIS支持](kernel-mini-appx-lib-cmsis.md) + - [POSIX支持](kernel-mini-appx-lib-posix.md) + - 小型系统内核 + - [内核概述](kernel-small-overview.md) + - 内核启动 + - [内核态启动](kernel-small-start-kernel.md) + - [用户态启动](kernel-small-start-user.md) + - 基础内核 + - [中断及异常处理](kernel-small-basic-interrupt.md) + - 进程管理 + - [进程](kernel-small-basic-process-process.md) + - [任务](kernel-small-basic-process-thread.md) + - [调度器](kernel-small-basic-process-scheduler.md) + - 内存管理 + - [堆内存管理](kernel-small-basic-memory-heap.md) + - [物理内存管理](kernel-small-basic-memory-physical.md) + - [虚拟内存管理](kernel-small-basic-memory-virtual.md) + - [虚实映射](kernel-small-basic-inner-reflect.md) + - 内核通信机制 + - [事件](kernel-small-basic-trans-event.md) + - [信号量](kernel-small-basic-trans-semaphore.md) + - [互斥锁](kernel-small-basic-trans-mutex.md) + - [消息队列](kernel-small-basic-trans-queue.md) + - [读写锁](kernel-small-basic-trans-rwlock.md) + - [用户态快速互斥锁](kernel-small-basic-trans-user-mutex.md) + - [信号](kernel-small-basic-trans-user-signal.md) + - [时间管理](kernel-small-basic-time.md) + - [软件定时器](kernel-small-basic-softtimer.md) + - [原子操作](kernel-small-basic-atomic.md) + - 扩展组件 + - [系统调用](kernel-small-bundles-system.md) + - [动态加载与链接](kernel-small-bundles-linking.md) + - [虚拟动态共享库](kernel-small-bundles-share.md) + - [轻量级进程间通信](kernel-small-bundles-ipc.md) + - 文件系统 + - [虚拟文件系统](kernel-small-bundles-fs-virtual.md) + - 支持的文件系统 + - [FAT](kernel-small-bundles-fs-support-fat.md) + - [JFFS2](kernel-small-bundles-fs-support-jffs2.md) + - [NFS](kernel-small-bundles-fs-support-nfs.md) + - [Ramfs](kernel-small-bundles-fs-support-ramfs.md) + - [Procfs](kernel-small-bundles-fs-support-procfs.md) + - [适配新的文件系统](kernel-small-bundles-fs-new.md) + - 调测与工具 + - Shell + - [Shell介绍](kernel-small-debug-shell-overview.md) + - [Shell命令开发指导](kernel-small-debug-shell-guide.md) + - [Shell命令编程实例](kernel-small-debug-shell-build.md) + - Shell命令使用详解 + - 系统命令 + - [cpup](kernel-small-debug-shell-cmd-cpup.md) + - [date](kernel-small-debug-shell-cmd-date.md) + - [dmesg](kernel-small-debug-shell-cmd-dmesg.md) + - [exec](kernel-small-debug-shell-cmd-exec.md) + - [free](kernel-small-debug-shell-cmd-free.md) + - [help](kernel-small-debug-shell-cmd-help.md) + - [hwi](kernel-small-debug-shell-cmd-hwi.md) + - [kill](kernel-small-debug-shell-cmd-kill.md) + - [log](kernel-small-debug-shell-cmd-log.md) + - [memcheck](kernel-small-debug-shell-cmd-memcheck.md) + - [oom](kernel-small-debug-shell-cmd-oom.md) + - [pmm](kernel-small-debug-shell-cmd-pmm.md) + - [reset](kernel-small-debug-shell-cmd-reset.md) + - [sem](kernel-small-debug-shell-cmd-sem.md) + - [stack](kernel-small-debug-shell-cmd-stack.md) + - [su](kernel-small-debug-shell-cmd-su.md) + - [swtmr](kernel-small-debug-shell-cmd-swtmr.md) + - [systeminfo](kernel-small-debug-shell-cmd-sysinfo.md) + - [task](kernel-small-debug-shell-cmd-task.md) + - [uname](kernel-small-debug-shell-cmd-uname.md) + - [vmm](kernel-small-debug-shell-cmd-vmm.md) + - [watch](kernel-small-debug-shell-cmd-watch.md) + - [reboot](kernel-small-debug-shell-cmd-reboot.md) + - [top](kernel-small-debug-shell-cmd-top.md) + - 文件命令 + - [cat](kernel-small-debug-shell-file-cat.md) + - [cd](kernel-small-debug-shell-file-cd.md) + - [chgrp](kernel-small-debug-shell-file-chgrp.md) + - [chmod](kernel-small-debug-shell-file-chmod.md) + - [chown](kernel-small-debug-shell-file-chown.md) + - [cp](kernel-small-debug-shell-file-cp.md) + - [format](kernel-small-debug-shell-file-format.md) + - [ls](kernel-small-debug-shell-file-ls.md) + - [lsfd](kernel-small-debug-shell-file-lsfd.md) + - [mkdir](kernel-small-debug-shell-file-mkdir.md) + - [mount](kernel-small-debug-shell-file-mount.md) + - [partinfo](kernel-small-debug-shell-file-partinfo.md) + - [partition](kernel-small-debug-shell-file-partition.md) + - [pwd](kernel-small-debug-shell-file-pwd.md) + - [rm](kernel-small-debug-shell-file-rm.md) + - [rmdir](kernel-small-debug-shell-file-rmdir.md) + - [statfs](kernel-small-debug-shell-file-statfs.md) + - [sync](kernel-small-debug-shell-file-sync.md) + - [touch](kernel-small-debug-shell-file-touch.md) + - [writeproc](kernel-small-debug-shell-file-write.md) + - [umount](kernel-small-debug-shell-file-umount.md) + - [du](kernel-small-debug-shell-file-du.md) + - [mv](kernel-small-debug-shell-file-mv.md) + - 网络命令 + - [arp](kernel-small-debug-shell-net-arp.md) + - [dhclient](kernel-small-debug-shell-net-dhclient.md) + - [ifconfig](kernel-small-debug-shell-net-ifconfig.md) + - [ipdebug](kernel-small-debug-shell-net-ipdebug.md) + - [netstat](kernel-small-debug-shell-net-netstat.md) + - [ntpdate](kernel-small-debug-shell-net-ntpdate.md) + - [ping](kernel-small-debug-shell-net-ping.md) + - [ping6](kernel-small-debug-shell-net-ping6.md) + - [telnet](kernel-small-debug-shell-net-telnet.md) + - [tftp](kernel-small-debug-shell-net-tftp.md) + - [魔法键使用方法](kernel-small-debug-shell-magickey.md) + - [用户态异常信息说明](kernel-small-debug-shell-error.md) + - [Trace](kernel-small-debug-trace.md) + - [Perf调测](kernel-mini-memory-perf.md) + - [LMS调测](kernel-small-memory-lms.md) + - 进程调测 + - [CPU占用率](kernel-small-debug-process-cpu.md) + - 内核态内存调测 + - [内存信息统计](kernel-small-debug-memory-info.md) + - [内存泄漏检测](kernel-small-debug-memory-leak.md) + - [踩内存检测](kernel-small-debug-memory-corrupt.md) + - 用户态内存调测 + - [基本概念](kernel-small-debug-user-concept.md) + - [运行机制](kernel-small-debug-user-function.md) + - 使用指导 + - [接口说明](kernel-small-debug-user-guide-api.md) + - 使用说明 + - [接口调用方式](kernel-small-debug-user-guide-use-api.md) + - [命令行参数方式](kernel-small-debug-user-guide-use-cli.md) + - [常见问题场景](kernel-small-debug-user-faqs.md) + - 其他内核调测手段 + - [临终遗言](kernel-small-debug-trace-other-lastwords.md) + - [常见问题定位方法](kernel-small-debug-trace-other-faqs.md) + - 附录 + - 基本数据结构 + - [双向链表](kernel-small-apx-dll.md) + - [位操作](kernel-small-apx-bitwise.md) + - [标准库](kernel-small-apx-library.md) + - 标准系统内核 + - [Linux内核概述](kernel-standard-overview.md) + - [开发板Patch使用指导](kernel-standard-patch.md) + - [Linux内核编译与构建指导](kernel-standard-build.md) diff --git a/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001134008688.png b/zh-cn/device-dev/kernel/figure/zh-cn_image_0000001134008688.png deleted file mode 100644 index 4dd18910133bf0d47064fa2a3b481ae3ecfa3239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3407 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 l*xMD_;?X~yXd#<_W;)%Yl_F;}=98641 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
DYiIU+)w3t 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 EALft9X#fBK diff --git "a/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" "b/zh-cn/device-dev/kernel/figure/\345\212\250\346\200\201\345\206\205\345\255\230\346\240\270\345\277\203\347\256\227\346\263\225.png" deleted file mode 100644 index 226466c21b0f7375c9ef70f340ad573f2916a674..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58123 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 At^fc4 diff --git "a/zh-cn/device-dev/kernel/figure/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" "b/zh-cn/device-dev/kernel/figure/\345\275\223\345\211\215\346\262\241\346\234\211\345\206\205\345\255\230\350\266\212\347\225\214.png" deleted file mode 100755 index ea030c6de270bdc55c4d6e43c8ce332dd5a9231b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2156 zcmV-y2$T1TP)$$+9ec zwgsqN*L6n!)CTGU>H`%YP~%jLqX4Rti28sA$Pa*IKbm=&%_pcy0%=JRwm=5ld==acz3c-q^^Ui&^CoI(9>b9w^ZoxFZ>Cx6#T6(oMw{?G0o&#zx+Iu2r38N46e zsv-pB#S~W(0zb=I`S%*df|Ub?kJH7(E1Am5!tdFqX*SC;n`xvR!D5zWf_;2%21}>w ziH}w(30{ydn7 zAc69^O+4o42ol${k8=5(`DeGCnRo@mbUj`Z5PI*{Uml;6*aR`>Fq#6Llc?dzNZ4{T zCN42ZAvoieL}dnU;!jp0XlUf;>!3$xR|=K(8&?wcJqePVu8O!#Jt_d~^MN0DxE+XCw3*{0mdd&MLx_4)V2$5>k)DiouQn9MlKY2dX|$CB8ZWs{T5Qs}J1n0}2v4i>ME%4^(}iN>miS z9fj3~YQtCe0R@SN&m#DAS*09a9`r_bNWWD3?5C>iAXtG96|8H|NPCc%fhF zP=bMOp9K^oZnxn*z*QOtiGB|qo<+vff&?k{$O=u*G61O_k9IyQUsn<$*h}Le(bI8# z<=+L6z!wC;o^`cjH)2fW>*OWB>F3ZLaO^7km#}20o7a>+$YoyP3SAd#l#;D zxwrcGT9w}#pZ9!locwFgwgc%Kh1b?|sDPahBCRJ;u@SwcS*oXz`F6za^IONyJE)zd zrqN7u@B#K8n6=shK6UzjNc4w#8+@+>0ur6&q({#;j-g&iRF8!27xb&f59Lj&@k!%a zi65))0Ct}Z>B?V2qwOmz3ID0``t=|+I7T%IHck<(3S@q(NW>F6to`2LhI$Uz(apIB z39Tm)+Z^o_*`FL5>uE%v)jNkIItF;eUwAFt-a{XsMH5h2C)7_mAI1sf65z%4IxN2g z0unt12mWpOpdLxiepUUX_>t)8w?Et0@}u$b`t1M-DzY+|KB|@k1DF_)8+C(6oe=oR zphb}IM!>dlIfQM)b<%;0##Eh10Ho{_)5o(NO&s5(9g-92NA|15PYeA@|B2cU`q`pI zz7P|{l)s^;W#H_~t5JzJ+-}f4h)x-&5cw-0VT~M?pleNsoKr&Q?gkRKwl6tXjt>2B z&fD1koTIY-d+SL^`q?(am~U2<+6oNa>N8ka}vHPbYfA;AHIpFsB^(qrP z32iq!oydP{`yqf(a2Ns8^V>qz?3 z_6KBV^cO)OH%=}3SUzbcZ_v-TRgAwPUGU#bPAOi=h-2UolxipNr^jU_-Cz((N6UOd zxfcGMF@49$0dJ}2kPS{AU>tmK9t4?N+qeAHdJhQ*f*z!MwSA^n6>Cb(P{D#K|j(c=pw`-hJEAF`&OiDo^(F=UmzrcSt_9MBJi}C!a zep38MboP%mr&p*)!t}KL#QvEva*FqmnWak3rT+$H2Qf42xARjaXTP+rX2(NO*=PoU z;38cz9olBc8$e>49lo~xG`kGhb!?vp1p48Ec+0=mv#>l{`U(P8egKJhYglk>)?+=^ zo^G%VKS@O6#^}B=&QZB-(j0ld%7X% zm(tVtljv3d_5MT2W*2+Ao^C*gb4Gw`oBb%zT4pT0r`^_n&sIBU^56Es+$8YZI^DPZ zYn=8)2l2iJ+pbhp{(Wph!ImZ)U%|Et5)MS%HpBhzh`%?(T?3?g@1OGz1qpTfKj-wX iFng)FFZ>(M1oUMU56MY9eN$M2$|Oj9x<2D5G~HdKtYX zgu!5RVHjfG_}}&3UGJ^?);i~WyZrXvU)g8xvreS0wkq{?*6Tz>MAYhPO8P`Z*U*Gp ziGqaid}%IGNl;w#(pP;-R58M~Nnl7F6tonGh^pdlTv(G4_!C`C17*Sp3Y`Il&x(kF z3D3-eB2d`8*Sq(i@EQJ3lc4Z9!Uc?;<>Kby3!4Lm%>u*cY#p3H1Uh^+?n^3P#QeR8 zc>)+Y_v=a+HcPe{@hb)0DV*hzCsF z@ugt>rIIi{-grQOL3+1dsk6t&!ds06PQ*pva;4Km z;Gz--S;)HH5=oKQN$$YihFo>XFZkH%q=8Ls1Z`zs9M$g zJYpuimj8tLQ+0^B;6dTU+!rvfDh3IY6t|u5yB%&Lpy<4UY;w)D_)ywin9mkIy{5R( zn|rm-iDzdTn8VziAV2X1jS)1m39|7sT9F``JRA!+oQOS|lOG>H{9;N|#l2bE-Mr(& zic7MeM_Wgw>`0Z5(Id~&bsPr8C#`g2I`MpmB)!?E{&3>44DZ{Qs?y2wS-|*|+ zIGh7N4i}ax?Q6FF6w&Pfi_{Ha)7T!3E(pCn4m}C}>No$E#xQBI6Q(|OljIa+E|(~l zC={w4_~SA}j>BpsbniU_Ggjc@V~}ZhcM{VjoRjQuFpF{$X}jd($S!|AV*S|ZRF3j4 zmYCm6ya{g8tlD#HsM3%eS@p6(@V$aSkJczMu>9VD1ebuFbx;D%GA*igbSx z3g!`*uJt7CaPAGofbp&SW^{bPvQj>5HxTMVHAbe765$ zw8s#JH{)}rrdgDcy&B`T0XKI} zuYpI+xmKvbpK@Zb2L&Koxrh)s-;4VtvCuV!*SIFt1M1zEPQ4*fJ7W~|J)Bt$aNVlX zV_9rA0#P<0ur>2e;vWbKte4SWqE~PLn)=Q*$+# zay(d9hp-XYN)F&=>fZCQYMwB|r z%|QT^`7w4vK+A_lD$$~6x}ccdgouzaaF1(z#0VE@*Q{Yzpw>iKZWBM}-?LnHG(sH{ zo6tDgOVbmb*2e;QIVhI1Ih z6OhnoBgYvkgfP_vF^C>kMK1ll{pGkox-KmDW%`Y!HyZ>m>LrdrWq3)Je!o}n;k*>t z7aNt1{oUC)O3R$T-2-0H>R;gA_x8uTRc|a!9*251k-ug|gcr4Cb4EGRCij0Rs080` z{*7+% zE$2OThFt=)$S9-rcH&~7RFYqs><`Pqv@T059})OI>$`(5#19$p%L<6R zpr=BV&Y$uA@scXW&LW8)j&(ULe(2viZfncwP&qxwATIZ6 z2=awpMEdyiK8_Tc|BwgkIugFvXAY%aIS!xL7YnWR3fZ|V1>4dKaan$4Me`{=f;&G% z3f5K!0S%t8_H#x}lSEYvt}CIQXOJ{}FJev^Hff&92L2T&^cds*#LaA3kgfzzMEi&; zo!dlAv_&ZW9_*Kw9cJx-bb|%r$mh4MY}iC~57P$4vn22Prds<6 zJfwQy5uF2(0;-C{H8_aV$fk^l(|m>IH^T@&GYzKu_$6(u-PUGnX>rWwE%2)AE5b%byOdvYWb5ytjoyhUrN z#=eht0RH}4nGmLk3Zf_pdZuy!)38B^+oJbVe+lNlARcE4y6G~KX&3G?6F}LVlCc+k zS3c3nrAKA2k;JcYsy>U?bKXivEe!b}8`ZlB6^={{OYD7Ft|zB#!~RDm-flJPno>oN z)izVxl+a)ueR3(2yc@8=E|^w`I3`d$ox*wg8X*L(O&J77(;&I-hguK&cEEN5#TTwQ z*Ae0pf)aCNWQ2e~`0)&0?`>e!O8&zEIG1@aUn1_#uI;0|8P4y{sF z!@w?>PsddNq5XYV5jPv5+>GoRw<`OKwcUGF(#G}Tpg68Mk6|0yOLK^rwxyC}B42C) z|7v`7@pyfU3@V;PVF`;hUkbA83}U<FniBlnqJCgnh?lk0?_X$5N;XD@Sg!t>GSlegTcv38Tl3?K z`ZK9#gN8w?NTQMwgjz(8W9dcfvh)2&aUoH*vZ(#i-!&zO$_CVyQrDv3_8Ake4O2Vf zajHf5nsE1vd0rCfzibx%cmS_0J!h^O=Zk4Js{55Rj*CyWk1ON~LZX+`A&otDhQqqm z&(l&~)hteo`yV_YE5T)S=AAUTkMm-t$jD$*Kc(NR2A!m}SJFBf)QF(5zZMwd!DWqD zmlR^x!**ImU2u6L_BW7h9<@2JP+Qqwz%qXn9krG>NnZZ>`wQ1LS6?g*nZ(f1i3K&%{9H}dv;Mv>>auOvr2f_yc(;ASv5@OR>vimtTOuTB-$iG1SQNzm zDGfg39f*vnqQ}RME7lCo)5Ojdlvg=7P3m0HUkKKzvYenHHS(7!I}TLarmy-6g9fZL z6uyo%-*)?w3XZRXXgArj_=#W6U(z$g!Lh#?7iu-{HLv*T^ly5`p;*WC9doeo$2c=Yb^ClmqguK zA)M5ZrG=nhC13X+88Doh@yO_D`8_Of>RB{Qm3mDh95sugS<;Gg58yoKVZMi038At- zE%W`vfl?C0l5w=(_qC*wY1HcyM8h_RkI5eAJ(~ZXSTGmE=4Wra^^N5txD)?bOr-Pe zk>Z=sp~L8Ald))NeP;)MZ6dZ0zu=>`1|h{Dr{uo^Yc05lq+%8wOR0Kx$@;e{!f^na z8A04?1<%x?^RuAS8pb$tnl?N zD!qkXG_|Y|m_8N_LaDv8D6ucAFJ|kR)fgu0obV#D^ZX*{%n?N~h+=&?ok9N384wO5 z=qv0_V09_k{8w$qQT7}~{p*PTQvgQn6mbuRO@b#itqt)KXl5Oxt+ICl|A#@Y9Oapf z1*`SFn0c=*RQd46xp{gRlxbiGRykVhG~_^b?n1!|J?ZAVDXCHj2>>OdWrrm7rj~h_ z3Hq@uFX7I{Cqa9KYws8M;J7kejF#P=?#bL0T`|606I40si>w^wp?f1eL<&Fs3EuW{ z{l7E#_jESiJ}gvhw4(~vs`^h;{WtKxUF=G2ef7DHS#+{zxRF1%t}P}8bKRB177Sw@ zV>bmH!3!>I)u(B+Ystmeu_W;S$7c?FG>d{el1FLrhB9*>R|G#ocBU|RlrHo_{VqA< z&_}3Snw0E0T_~-}Q&JvQIycFVM2@k+zeSY;$H0vv`RK{&HZ~$SDPd(L=Q7)XuFfE{ zT%c+cEwRVl!3MU6BMhg&KUJ&>ZnV+ikq=hmJrud#$S=`Xj`}?Q{vH}eyd9JvZ%OL8 zrI>5@>>izzKslhp^f;1S8eS=BeR?ctmwLbR#~6OM{qqtDw8A_K6iZQ1uIq`GZ{(nP z#n<6kt`ewZAa67){lm;%tZQFsUE<>Ce9Bohr69O}{f{m?`1hW>c*Urdu+hNLp#V#9 z6I)cZ!078YI)+&X^sQcZ*;oWfCKvYZ_r{|w)d5MpAKN!mGiP3hD|q}!o{FWY922L0 zGpyFIA!gn@hUS9zS=Z5$vGM%ooximu!$)F~?XH{5nMe-Io{-L76* zi8(0v&D`KE$#M-vXs8YD@*aVSvhVttJ;ghuQuw4&E# zd)@QfiNtL}zFNw)c02|qO=M$><$rz-cTSQ;L49te_oEjvs-EM`5bTLsXzD8tNSA2K zP}rcCcpsXVgMCr%>)o2J&A&yMnYxF^EDa}=f^tLroUz~a_$*>R!04iG-&4U4k1td@cfH=9uRSK)S=m5QhPo_Ythp|<4K_94&gB^4pB_2L z>GhG1EVb30xS^&|MZSO38yXIivq%;O!cj>h+3Rr@7RvxYYZR6fpJT<``0j5)dmmRt z`}@<-V0KjY(sxfii}n7ZZdKgEaK8vP-4ykw9id%oczO1hS#Y4Atrc3o_Gl_4ye5l_ z(=RYvzyg9($X#Tr8xdR#Tb{DmTgdgH4H~F9-+m;(5O+!C{*BD6`@sbVS}frHi+Diq zBX<_zz9sc}02KPecZnFaHM!oCu0Y>)BWxjLC94^~lPi7r531z`5+ZiE?34vCSotxh| zF#&CRJ)A|)dyk-t*}kdfsT?Mtu&;zUhe2O9$L})CxwMYbu}g7fbdK*EDMxt5dR^1N zX>KY|s2(^DqMzk|KUqQ7uFRXpxxe z#};KoIGXOw6ztjIu!wB8Sj4z2DySGNqe9Jp2Kil*JGpvc+?Sgc7RxpdsLK_}=+OP+ zw=P;9=*5!18%fk_#TIzbP))S4lajt6@-%#wV&J?51OSHcXeLh|>cj5{TN zu+L5}l4VpDCHk>{^%+n6f&_R=Wl==}5?1A^;^$dx7yQ;FhPeZ+15O-Y2E^7$7!YTE zZg!3$;emN{nI9@`V(V|CO3hpUuB}Ex3iDo(t__G~oPqByUlsZoc^UQ5ie=+lQ~6XzUB2FTXqb4dcM(c+CJH2!+?kU)xLreDw{luFT5Fx{Lr?@mE2z)Q7)~0Q z#?d>0G^HN8Csz&dHfg#IV7rE$(1|)^7p|SV{0HVGx|5QAU^KvqWkP`o@uM}5R}+-R zGA!|y%?`Zq(+}xbNBG{a9wz55H95-tDQY;Ed}*yoNcR8TO8?cLJ~qkvgSVny$%awp zlJn1*m{~BLG)f#pN7$nroT$=2UA4{aqwd^XJ8m{zn!y@Ybn!-qX8)DgB5Q3w+gAKC ztE9eB=1$-Urp6NzfeK#!*05cp0Dc3_ikPGLwOu2!f%VfNosg&A?vuUq(KnmDkqBnJ zUku?G+i#t+&UVf}!coyEl4w$o@%Q4M%brUIQLJ{A5CRlqj#U16H~-@{Aotj>_DgtZ edIIxTuKi(FuYG>70pTwyk-DbqhllB&mAq)?I;H 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 av%nGLqe%we*Pq=C0T=ZH=l}OpVe` zrX(a|rZ*u|g^2(4ysy5)|994Zt+UoSXPwsCJ6@mRdG6u5ujjt*+&HSGvUc^>)k~Hv zS*v>Fu+EYt%hQ%DS(?eP0-r>&EI2J$vSW$r;e*Fre;a5V6X z3%X{fDb!GRt@wL0x)Pz5@8i7BQ_ejtlpJcSa}7K_aQ=-kW!beopSOSCx|u&$&B3zy z;CZF${7six`vE2$9{>yaK%yK$F6Y-g}3%Y;V)e?XpL(dZ_n4Ws2X{=HE?uY`FRmS*sDP2n2a zhC`G2{rn43@p*4tiHu5WW8x{njTIt+TntNjd3n#*eT>_wx^efN)j`VM>L1-WR<2|J zGx5faRkHQHYJ2XeNmI!cxG(W&w_01_6)A4opNY=bT->8+xK3GF`I7+i>f36&zK^u2 zBsKiqYWvn!(pr40_|~=8cD$%zxb_!+fUwx*twAdeGQHVUA%g91SpM6V`pHUHN`+64 zbV`SP2|Er5bj9%}7^q zf=*hg&uX8g(bB;;dZS>yIA>{U<>6z8>w~u+uzK3|b-3+m$VyK4TRvFhrcIlqsYk-D zH#8iBm8jztoE0)Eg=bTB(u74tuQ> zdyRwLaV1k8uY}DK3$IM+q#e(T;t#NrjQ#ghc{llT6^-`BnYLt{;Zao#`LCzsA9rNe zO*?)hY&n&^!#+|u>0nBO)h$O74wJH2U$ijexCbYd{rRO4Zq<$SM2oo3&OJf7-(-WQ zWw#PzzY^{naiyrpCr~?NzrQy{oJ`EfMvsp><~nrM9guOK7M^jZ1dhvwB&mdi!AunV z=ykv7nmcN{?(%bsiHN*Bv|g@MF+^cr`nk&}Z+Ja5?c@VuCQ4}N22q!ei>%R3`5Gz5 zcRTh~Zn*qmM3RFA_? z-^su7icms5NlHKGV2fnTG+gG=FxwUyya>G;ys((^h-&KC#}e^aP2^OPPTJ#J zfTgG{BbQ<+JgTQEr#$}C=c%{(xf_KFI+;dKVR1{a;fUN@sS*ZGGc9=w8J4( zH^Fx!m*_Qt?hV*fclRBJl3NsUO>4VHkkdy|I;4ZM?0)=DYmhAH15nm+8ow4ZylI@ldrs4a5oCj&_u8VY5*jGnEzse#xr6mm|CKj0#|f4>@vha%DepGh*>;{QN8BJvxl1OIii%a3+9`kKt#s=2tcZWhX1;aCjT`I9^F!FC0?>NKhPo%DiS z-M0Gh;fTygOAEKj^vPeZ%w4)ce`28S!2BHNS<6dxTnobm&IL|A?9mlPv&)<;DiwxC z#pHj^uYLHro{RRJtas6|e*S{iU32q}l;OIum$g#d3t?VEHliJzaR=vyn^QwW(f{zQ8Q@KBmxJ4g)o(Z3{9v zL#rLze%xV?_1r}FK>rTB)J@E?)1>5s=V74=-<&;BGLtNeTRRAkaE^bY5 zrOaWosy#nTYabSJ`BnD+s8O+BjBXiWsrB@=ZP*a1bo>7erl+5Km;Y5wUQEqR>EIbh zALAo2DS}D|na<}NK6ZU{cG36;;5Mht$<_hUp(z5!Y#V*K)RmZ(ri--8r#$ZRE7G0I zqOxv-{&zYpc`Kfr+F(WC+?Xxv*61uj@6lO7Guj7ETr_k>HUd6TvS;OsMzfE~Cx8+> zZ8Jxa0<6CkFZ)G|*elF>q{~5~mWb^HM$u~GSG=29=_}xY&DZe0Q+`cp>2hE>SP1H^ zBfF`^bz^@3JYlB4xDf3jpJ?<8d_^r;F^mUZ3roXuqGlbUSsQiJr3%YTa|2qPn- zs{OoU;G-YsfRif)HL!m2loilln)(m8LT6zt0QdOr&0#z*iM5g&td7#K0`Uu3=9)ZKwMn2N<&La=TXZb2*Pm3^T-Dc~Ra5 z0l++}|1{Z{+2m|h4P&Yhk@Hc!8n}g%GxaFHFrYH==--y0T4vjL zb0AcOBeBCC-a2q;7%VyrX0M;*XI^cHvbcrHzDDlrn?q*4zP_JO?7ok7Y3CTApoF)A zlVABh%!SuiEkF38F8%~BLrLSiED1zzP$`ojF4+mrpYM+WC(9!osbRrH&bxj z%Ek-GR+4RJ`ngxY~{sLI!>&=@t!IKzD77u^BCb8&S?ICO4N9v%Imz5{S9Rp8#fvZg z|LkN=-}vGG$Jzwxe;m%(voiSQdaaU`4nEJD7t3@O&qMNqsjj8LG zUphnZYfWHk-e|DI*M3HNaZP>!deiqz(xr3UW#8PbD(^pmZ%Yk#^pY~P#?WnP}1%x0O`N5m67t+?LYZ+r4%emIq@jGnC^|5ar>YiMas z_VXE;T&g?PzQ6KK?r)M0M^rM_8hK9a0_Vu>$c_2ea|B3H)(@Ni+xaFRC3av^!9{AS zBQs*^Lt;yvu-kdxWqw-cr)nSY+i&kPJ>A^UWm!4#)y&0rVAH-V`xBf&e(ufbpBI-T zaO$eRpuP)Z=N|(%s44lQ!8rvjUt05Gu1IDKd`u_`N)3tY!w+V>ihgcv8`al#9NICT z{vfo!_iMh)_n+VPn0d~m+M9OVm#4ctVzu)m;?^3>#63eosjho!VMMa|;jn4ub_I#* z@Qy9}b;bG^1KL&yOfO@6c=oEGosq|9^YR3ly27WAK1wY#u`E7kBkeguft&V?eGLtF z|9hyL!i>a4Czq0srYk9@wklS2BXSZ{@x4Zd5wd}$VeX~K= z`ES{MjGo_@NoCKZY@>&fz71)KMLcYksh}FHlySQhOy2R_;cS`CrMY*4;VUgaX=rBO zS5Sd<)=w{cc)H0?Fhftfj#&G_k6%eDK?}tXdf$s{q>8=bw2Qr#E!bC#2(s1}T?nXq z$Jiy~9ya^sRLPs%gPs$0+Xkz*EF#MqI*ar>d!Qs?p=9W`XOG3)X}#?BxOlnxtB3eL zY1E##{h_&feo2{~w{6kjipA^`CGVTyaQoIL*tLIp1y;#+s_@0G>ntzD_EGMNNz^u~cvkv-F;vG^6f&*%ddM8|ly#gKI`r31PM-lqV=9j=|mC2{GMJr;;PlG;1&?!~>drsf+0UK)zR1JrH*Txt zJKLA`b$Rj3qug%9!O%;jo$MW2%0!Dfh&-|T3ptFe-AHG=`I3N_h&yY~%~r8r9$`e> z=X1cf6{%gtSBdvjx?IESURuwWByd9f9~qYd^i8fEJrNGnQDw2 z$*_bay{2BRkCv6L&E6M3fb2xFzwmH*sI(aOoQV4k`sG@b_};27jPYsKS_!eembo3J zbU>h9c0|BwbIx!jJR9X*yk{r5CtsPwFU8e9CiU%>FGX&f%hJ7Vi!J4TdX(o3Pc2j* zD~gZnW>qK%^^?E6XYnWyg!TCwnp#lVwK-)}Ep2?MXXR_ZUuhn%y5jJv_@YEhjOAI` zGOxKns(w>K()cZ$Bz`Vd94Qi9PHSUvu5fhmb&!+NOo8iH&JonI%#V$Cp8L_V>8y-n zu+hx)$nq%%dMz}Q5hciV34liN7!>z%o?gE2lg~bNpJnCqq4{pI-*xQ!U&?LM(?uXu z9&vt@3W8I~3fgL0|iCCYyaJNV?d) znYc;erwhlwgO~oS(?)TwSAoX&CK{iPJ9Fl3$rr_2yR zXF%ejljCV7`qn|!o=A2mdXe&So0V)ImtN-sKFdK3O)SQu_O(3n#_a{?pZ~(~zSp!8 zlM6@5x5StL&gYuf!a9!E)c5xDgQ^gK@iP6qaVh{8RxnZV(w)u1E#hyM6 zb0tG_6WSfG>%FXYI(>@=V(AX9f?o<`orA9_{NdQPBi7;BZ;ScnPJ*iX158bz4J*Ah z)wzeSZoJgFQMNVS_|I>viNO-anzJp;IrZK)s%T~1SE%?`_VgK;5(+k98hc=Ly23OS zpgdW~sx_W?phX9!(Y7^EH>#U?WdNjv0+(BD&5!z2L{Rss3uF7eyuLCgEaX35TzNA=CVxYTMM&uR!uWLk z!+UubZ-r1>P#6{&;M@ZJ`Og4c#R@+Tp%}`NqrQ7f5WvG}VYZp>Gp9nr6Z0(y>U4R` z^Q`yydeUrgKk5$ObFm94DKZ}Rgl!P8Ge4t1zo&(uK8C_NK13D09uO#%fy z>We)iuoLY|mhasgcjKn_p7obcexuTBTmD(HbVD&xgU>0*(!dQnJsc5&MUKjQg`qOl z7rMusZvHl@d%Aftkh62KaOBjHB4DOE^PJVQGHGO|nPlhtdcM)Z8z?chr`kejmsRFi z0r9i$)x^6TUU`;_++IltPv6TeobD%uJ=XaChWouWP?;=fICRnR{C;C56DT=pee!hQXQ!sgcoSL z4uvLIE@PeMqlh3^_-rjbykKcZqnbpvap_AVh z>mM^QjA1zOv0lRE==JtRp$6w!ojfihl}Yu5P1{{6wgM$5!d*I#7}YKEp54R~8LE8s zb>sQX2kQ<@zuh-WTx(cdS4W{@5AH+V;uR@feZP7ArQLaD)4y^#w9Epj=v4coqj>*o zSZ%sL;n|&pg*VEFMIXgUt618^RC$Ym0KUY|t|W#Ack<2jl&-PeT5z@e z5C=Ew<$*F?ylk8MsE;m5SmFXS#@q^k0pSA1rW(Q8Ve~g?E+=ad06O$Ydt!v0d-_`-b0 z15lZvF^4m?I^sZ)DHX3Hs57L(F7hqTcK5}Djb0eJ(Z3)t+>+|LJKlJrn~}8htlE~K zs<-EQ?xH_mL5NiT4f%`&cK9e)ya5lyVn_;kic$UjdG^KY2rJ*PVP*reaIRyGg4sm3 zI3aW)cKV>KOK^5rxbT3`mv-@M!GiEAwCswM);9_%VKIj7a=GmMDTQB zCfyWhC1~`+JfSF#YcxK|p`dD1&hs`Y|HNO0)$0l``NHYoTaRZ_PPk8W9whnu>rB&U zLXP)A5_@J{tq0gi-K-qXZqIg1*f17UL3+%qHoCfH_6dI)vpr%|!_@%IA32{B5Z?x5)OtZ|wlH=P3~ zlFv2Yj*oGIy2aTgRlKmG_@||xjO0&V?w0#hBZWZnyvjQfy((`OCkv7qtlrQ%%g(!I zNSnAIo~ZU@9D(tWkP_4Ks4d5sGmnzKurZrca;f7@niPn>@&=_13c))VAjq3t+wpgU z)tEhLLz6KDi!^jF(L;n5zlV$Q5OgyW(lB@9qm3&>D<@s0KSP<#_bXblY`$igQD8hI z8l=38yp=_bv?`}OJlV+<1O(k=8}Y4kb=2KvMHk1`MroYk3+QSGh|Wcxcqk@?CW&HTU`_NEM|S6A+K@tbJnd6s3&Q}i zY3O*0*q9?R1Q`b){dVVkyy_s+m_2QYECJZqPEFm6+x!7z9tmq|<6XeC2U?0LV>mz_ z%+M|xHAUB+NOPp!PJ~@dV{}cq@f~C${e25%_KJd7aZSu8++6cJCKxtUi0G*i9c|5` zUJ!}tj+&b;bdPY6nUIXzOzZFE*1g-%xW?T+>YoT~hm}`uxGBWLKD+Kz}-i6s_7(&eZRxUQwz{ zNmBLwfSOQJQbJRJZF11f7T45ggx*awiKNECqk=5ZEXdf4BRi4P`)#1alGHd*?HJ9= z#|LW&9)Hx*nr*p$aTenG4hDbXe1@fD9U=&G((tt?ClO<8ffU$58>T^QB|-|JOOq5d zo}YI>ffYT*OaydXeZb|*y;j?-quH%yXl(lsIf(?`-_Vy4Xe6zCxkw(+vgaxK<>=6w zRs@IAGYT>HuUoo1Xt_focyyL@v~|+n*gqZjNT7+#GzBR|Iq4<3;2091P68xBAtU^Sz2LFD3`@g!5_QrbWUxXRmv-u7z|aR8-k1f!%mXHUti&s) zi!e4qq#BG*Y~kRrNc;sH0o+Js?;Q+8ghCz*!2mTk=~;gdsu+1grDBJ|Pi~_*DfuZ| z!&)ayJz!`|M6Bprx`VL=Sq8e^^sxkpV|<#rwAr3KW}2FY9z7kPkR*_S=gJc1S1rtV zEvywXTU4@;+$^V|gh6eQ3z3~*peZtNz5q)g7BD(XGlbFxnm8aw10^{EH3aH_YIx?8 zHann}Vu<_?ehfAkq$_KupM>l*0j=vTJ;9lk1dpemL<~_dFCro=P}Ji`L)LY?#uKTK~Pqaqvo_& z#f;HifugJhbM!3Mq1I)e;SAqJH;K((Q*8gl1<-&dydpy{8MAxta)466`+kVW0y5ror^(!n%wz&p%<74T{?0{8(SSG?o938ib`V9=Z{% zW8OOVREiN|U#%pc0AWc~HS9b!-X+X!?Bz!0NW<#eBH71 zldG=%RgF;-+FTjxhA^W*WHoRdWrz$e!E}(1a|}?^vfg6{6e>-U#%xY+ToPuXFvmkz z#pLQ_kl3U5Fq4)dP$xqJs-r@YC?Ujr7$SNDYd~o>w893V@roL=LBPe*cvjs}^YMX@ zio$p=wbfP>vL0rjbjc5oJ!%1lrC>k!If|tl2Zf4C(PSgCfB$R6ojZ5J0VwAtkhSq5 zn!ZfNZGugq*3tZnp}nt|*aX}XX%eGTclmpCen0pECa9A^93o8U!9f$F3(wNzV1OG? zo6KDS@1z*p%NKsAtRgalMO{Ie&oc$-TGAuwnhQVV{&8FVq>qDaJ!{dptkHD&B<%xo zh?Wbln0`GUIg?cEaYw=JhXn6>Eit$Aw00=^wmqM=IZS|>qDyzI&19fvF67&6b(VUOWJTics18{c+0jzqGo2;Q!tq49=H^}wj7_(AdNWRM&1g1F`&nE4+(hIA;Vj846m=vtS<>?UdkK+OXQJJV@~ zO!A7!%4%Shw3%1v=_vxym^7dfiCo*(YlHyb?iJm<`ghC}5Y(RX=&ZsFtD6)CvUpY@ zM=|Kv3sL@KJiFXw=K9IJD0lgKXy1cmSS}iL225s++;q1$fwCGH0pTI|#B0G5o54U* z&6kenggD3{>1t9mV=HCn#!AdM+{X^S6*s3(b6`K1dP1c@W1@zPZWDogpA5 zn2@M;9DXlCrXvYsEW%z;Ye+!1WrSx0~>`8|vX(~`N&IvJ4G zc+4yg)W+t&!T-p>D5lE75iQcxQzQam4h*w^t-LRA6O;R&Gn*JB12SP|*8&$~x#o#j z2Fc#W+oV9y7q7zMb{#VfF)72encc%cI5J3gnNY%(p|1$c?_WC9wdoVCH8)K%D-{v7 zVV#ft}lCYE&dAqC;%^#5h|kE#L~Kn^xjidaB*IC;p>F;{9u3MTx(Zx zIp@!jb90@&Dl_p43K}DsLd6p+yQp11yXq$%7{&JJ6-$;mEVLRIeXV7k_O26||KwoQ zPma(KT*q*(B~n|q^SYUFNWuc-P@AyOd)tAJFY3Uks}$h)!u|!$D`QKyx18bpF+a;` z{q>2ULSH1encJwU314^jaz^RXyZH}`$^D_~{fup9>E@x_FY#ATpRCtZY3Kg%b%%lY zMQv>vbBn!Qx&OSFU`$_?DEF5#7q4EnszD^rQN_55VLSa}eNP2XH_VO~w@wMmDSn#` zJvA{pS@pKL*;i+EGV{1=+~lei-i84g8A4=^kFXZV+F171KJu=trrke&4@el8rFmz__9nQyp$#-KDyEdVbb1ry_ie z*`iXaUc6W`S!N>Ql+QkRA;u@Hif3eG#P!uj;S}pIt<+4rZQ9c8<;3$7B(;RuO0xuI zaRpDf>I8emK>;7KLN$Sbwqh@Z?c2AzGM4Pvc;hi}PBz~#_`LMZ)Mw9PWLqvevil7T zSjg7a)-rHiXKK;m(&LY;4rN{K!{DQM!NtXS?-t*eKJVVW>y} zo8W)iyx|80$`mt(!ZdiT&z;-3kB!kO4cq$p^Cy4u*kSGs8*eP9Ze(0B_~i@lKIYXM zf|ONxHX7bE*LO8+Nq+Dku(|mpOMr3`*{4QhpP`M7&3X2fxx{rbzF7Qm_MG6k}VNtSmFIXw-yj(ZEI^*^z!9FSv7%--%Er)4G)`PPzPf? zx1@xHU(9^{_D#gd&Tg;Uf9@=d^~T{NJRAF3bID6NS}u;mvH6FSj?qojGdMbGSrikq zRn}bTclY6rp_w;lPRLHwtfII&MzzWWrIwDGYWgHdZ1&8!(<)Q@<`W|&vBCOmY@E57 zNd&%H7td~quUdF5w``5KaJBVansE2-y}$08D;>Yhd{p1yh?44WC#vTj?w-m{d8OSX zs_?tKk92WKD)02`^()^`UD%NLG@}Qz0;NWOOLJCdy)o!@Jj2>3o|c}zi+vr<_kdh! zPHc8)$dn7KKdz@|s?YMDu9_SH1?Nj}54(Exw`(tVtdR*mgq==GNJ=^-KYRAf%FZqs zv5rWSNx&5Y4>B@%9~BoTXz+UL1UQRmh8qf1xT^_FAj@{I5={Cp`ToYo~CV0Eb>^+zyM~Uzo zgQT34?CfwW@z?IY#@#n6dY5}2WGwl!2wBM;%3yHrNwZaYRlk#=dQMJGoc5VB+gsG( zv_Mt-@8zFN=@RrS#@T!iT3YhazdGn zo8n1o*Fd;Y<`!wWDw9ni6*rWVYFO9#jWe!W=Op55e15NlghWGITeV_gVWGH$L}*J# z2Od)4Xk~3}oLFA2Ov8Qc^~mKKy)$QmRDQieu)0SL!H}t$S=IyKi`w| zbfQVy{$ustrxUG49hKfLdgFD^`j0>2e>M54L8NFhJluV7)^Db^Sgvw3e=ndQ_05oNecerxZ>%rLXmm7vp%jn)KY7# ziF3QL_UMi)mshqn9;jq3z7n<1b4u7xTl4Xo%xvAcj&PNk_NQm?sK>YL+LkZo#eShVO zwVj1QVuUmpkuONH8&H(V{oJic-S2%73F|vF8J`l09iths|Ew-w53;< zq#a*Pj}D%Vt7MS`X4(2rnx%seokiSC=4S*lDKa?joypU{jQ!o5oI5ig+S;sbY3qBJuI@?^;@Vp9#5L{o}7ch5gO-^D+W;0s?W*-SqSz z#0kp>!YA1h(Fg|q4YlP~1y=OBBHned=ZaiA z_6n{?Sbb;bS=o%CySHB9cU z$A{XQ&$m4j9e6T8^-dbT@?&{|*H@JH!o|}m zj5RoT94UHMdVhKM81rP)LqUtlAEJ_v_L<@@j)La_D@QZ9ALrionfpCpeSw|C`UQjS zcanVs&GcC)uCiJbyEYh!jK?OQXZI^G6IDHHYPxfFYLrh~Kxu#cfFc+Gv}&P0Sx+}1&b$WZ1E-4U%JYQ(cKF)3-8_WpRpF#hFM zu(^IzimEI}1v%AC-~%n*aA3A9=-MAUUL@Pt+TJTHj4$|O#~--n;+X;RF9+RxjhR5i z@D*v6fe9%Zs{0tGoD%d^5l}kIvym(GNH>{?4(?@QSpMnrXOl!kgSz?}q$?Q9fHV6_ zZboD8lHC*P*OZ08rea-3EXf|C>2 z1yPV4iKVQqtzQC7CIynC>K)kukT6X6tGgTL8#z4#`-h~)i#txMn_F{{VRJwh!UE-1 zYJZ6^m|mlJwDvj8v%+lmU?E${YQ-CemlC22WPzz8kMMxFf=Axd5fH3?)d)c1XTJOV zc`Tt3=Yn(sfI*E zC!I~q0>U3@;;)!q%hby43MHXpy6guIl=;5q258*9tR#~2K<%Hi$4Z~|E8U*4RujP4Z0-ZT z`1oPoEy6TUe(x9S+dR!YwPLq*k>%P4uYVdI5sKWW|07zPIo#KV)E97iGS8iyZj z4BW~s^VH3vB6)gft@10uE_ zTr57WvUL=>E0su5<{;&?2M>0loXgm@rJ(j23i(k3yX0;jJMqfz>4{?}kN+k8R3$;K zswg!?H#;k8-~6+KSG7fq_Q$8-phD;rFGmOtKPudze=si%i+SeQJ?+JYW_-<6poib*Y7p>#^!SV4u?^^}%*8u+Vt*{{cs$+ut zb$~ngyso}MWk8l<#AepV_uK376P;vY5T_8J%8)aY!rR>>#ezLSE3{)yLZ_5!`V zm`(c7uhec;Ba!^B%b+S^Z9h3?Dz+cF?YUi%flEjq6~}9vYtWTtcMf-6S)=HmOwKcr z!9gO@vZ@PjmV1}z#<4|PAR|6+R(hAQI}s7TZFe9dzGgViqWde4pO)77>37TXdwajG z*L<9q#bBx_5PM&Z;o;t73-eX;OMSqexUNr!tlpsbETk|0*DL^oW7P^jJ{ecD+gW#) zUMf1bUD3bH!PbUls&u)ZAFu1+CpJ8|yY={qSLIE+3bO5Gn)U>w>Fd|bFi$gM`;TD- zx5n(4tBsrbf*@`qV}itUc;KU_jiMN)ApFx%KvkJsgfMHGU45dan&z(Cb{O?@>`}w$2Vf# zQrUzad%HY3C@7Ej_OxatvO7A*#5c0paA3oKIIgc*Rj zIUlk5%Vl*L#NYo zGKwLSZ8P`vJYMWT-v(zdH7AHPMY1)8SJmv5O?9(f=f7U@o2i*S$G>Oy9}MFIq)4R3 zWt$mslurf&E`H=nv={KxXv@RtXU~KLR2fi`R3p#Kcid z1$K|mzAv(tDcrZVarW&Nj`t_aYAxU@*#y`66{S65GIAA_eS#*A(UhjSJcsL??Cd50 z<|~pX$1+_WA#3K|gVZ|V@*V}e z?GQ1D14Xe^X>E{JuZ);{31U@IP+VNH_ER6b`mx@DJ70^$HLzj&I;?P_y1G7-VQrA6 z*nSzmQ|wwdHL@3c8fC|OtR*vqJ}MO2NjP{_i>`KG?Pz{qk6E|yZWN){bi=(u;mJ;Q z@g0fX?P}TKWN&2TJDuQLp0XuAj=qp!EM)tE13uK!O7W{X$qboq8pIkk>S{8Xe{YV+ zLZ(RU35<@SB$bZ#S~#HyP(U1(H%D-@L?&6LM8`!RYJX1|;ry6M)eb)(Ux#2K$9ODb zXGZ#oeosY*GfJP*A1ua_`$$^SO^uo?58dBKAD*rQnB_%pmlLb)t6?XZ;OY!~IxBS` zb#Q)$DZJ6y-{||>Op&u&V$3|uH@KXP-07*G*;U~YtEba5C$GY@v1T zvZv=(?Z)^$;{s(mz59-~dsXaKo0Ffgpo(|RwhE+JN~pK0SCqS&TZMhQqtvc{rcP(z zUsu&xUecN@Oo%rDol1&rjG-hXls8_Ws=2EnynKR6{)^*vw!aO$R1LCnt+?`qn4?t>Fu8eo}^HzspH}u z`5O~-+CK&Sl>gFJ5Jm#=6Dla2Ju3NPBms4pPn{0n1MVh&`u7!;SB7V}JZ~Q;L3#=z3dA1n z-dEbI8!%;e_T_pbHrOg63uyP=K)25C%l#gA(iP$CuX_xz2s{V`qO^}YvUvad3KM}V zUz(2TtPK9>h9hQscIHw?Q{vB`E43SECxlV!-sHLMnzDWP_lwlLjUjRhr6Eq1?+vnV zmhE_)%dCyE5%>}aXqzrTJ>+tNB%$E%K69^-_D(pq=1CpBA^mh^?g_5>q}25xW2J#5 zhL!*RS(Q#M)}`Li=%?b^Q)WCsmhz?8bTgQzz8WbNAH9Z2ospk?u&wIKpQksgcPw5i z)R(WPlD`mqqJ7&xW+JU*J>7#PJCQZQ>L;+MuDO=po0_!~-5uu$R`--=0Z#Ug8mLSj zXrAaT+E6q_Zvk27+5H|AtCyAXs=nX#Ki;kZgfSIy{V~RX!hVy$>v86ZHJ0U;{}>FY z_*duPY2GE_hLzFdTkc29YzS-w|0dk7i~fPW8bZ@+s_z*7ifxH>&enfg;1A>w>Z_S% zL_^kp$P`Qt3`F0CH--9s>Z>C~URJUC`$gNXC+v=X=tCLlEMzdeW)n}`5K&yV;VjGe(T|KuH3CkuDqH3WkIzb1|bC(e@f z4jiC=pkB3U-#U`jSi1Y4LpJu34_?zQ_8}*S6ZxEu9*8ZnVD+l(pF2r*7yR72d2Y~~ z7X{zMk5IW`Pq=Zxc%=N2MH*jl z3Z5|GR5Z*0`+@=TZZ%ZNl=hrJaYb$O(+ZwkuOR;t>jK$1c6Qh_jV(H=KX&0Vdp%wl zQv8Qww!ogwiCnVCSjbt2sQkKZ>O^As2m_^lVTF z>MVgFDi^oRFXc2D|8P|Q@Q)XcAm*+M+xL(VOzs)d-rnEe+lw^1wlX*UqeU({I8;<` z{FKqr!>;vcor$D~T!oj%@Md01@r0jEK@T4ZDhlp}$Jz@suK{+>f9hNAb&m66-?>KH ze*{hR9e*P{6HaGpX<1}f>Q~=B!U~0sjjERvBxPKK4I=`uVUGEVL(^-R#|M^x8!>QY z)WF$29Y5cpQ-kIbI{&ABfE^5a+WP}!Oi;@>J+Ev=n~5YXgQEA zrd4wP2ZYrd{g{V3xFH-ax;_RHFdmOzjyPvD6-84JlL{pdJ#Ggm=7Els70E zZUZ1Zere~ zba)*oBmHU6^Q%lfpSOdK1F01aSA&g#8;=>u+m21@smz3rZXZA$r!9rH0rbsz(Q?a7 z)5pK_sy5N-UWPkzFPg*TonthhfnS@CPv7vdaRWUd0fK6#M7ARJRFRmVaO(RV(CtY8 zGeOeKY3NVwPtA8hjv@~kY_PUD8L^}E4nyI^%^=mG?mZ_6=Y=tYmnP5_BE`vx=<(^a z6Rd!U1eOX0A;?R=Kj;u2-}|Hb*O5KoTO9K_nv6kOlgXn~&KB+~h~wJb-4QICLC{=7 z^lwlX@UPfR2D9yAaRd+25b&{UGfYRDj-R=g+Fspq zQU50T_+zi%@DPrJW;l63Kb|^WINSAVWJsMfrP$aheL(}ygwzBKTl#GTlKqvF4Aan= zu_n;%!B`Xqszh+9s(cfaUoozwkpR(C5eLJ>v-Y6`4NRZ}~_Uo0)h z^M3+;cE|*Q_>MpMsM?0rK9#y^#%+>|cM~i7SM>G?;Ae@qUy)`h1c&tWbTmDQ?1gSE zE}-9wyWF4;ke5Oe$=~>|N5DQ11r!C8U?p_LLn_>|<-X4`jY{s`@Tw7AGW3BVk5R0| z)x@{%Vq*CFHaGL?P*#TJv_>9$?20`!r|+4rOYn-R|M|0i3p)kLSUsy1`SrsMYlT}9H{;>tLb6C%4m3A)0?;GL zI4r((@fN7LP{Uyw+JZ`Z9Z6hly8&vKr$)*L4#;`OJWw3x-0JtZPg$li=?TSak){uN zmQX+n&~YS!nkKXZ@=mrDBx)d$^gvUqwIHp~i)YBMXMon^hJH91x-#^)Yy0~3>)*un zeDPXhMs(!~5+MbuQ}?RnOKGAV(K*qz98l*Czg}WYejy$DR;T{S$XJ&y5qji0f(@$2 z+qZ8OC1aJ&1wq0PYRiSJhnmzJUiNiJ8i=6>&(*G9kguATTafaa`&2FN*}W6(q6tL6 zjlAPaI74{U;@-}c{Ksd2%wqyObDt#VA&WHV$2*sXn^UUyH%h~3dP3=(iFwl zcLlnjlw~W|{TaiHTZm#PPsS7o=qT|so1g^^>+0$0shou?p!B_h%nlfkYJ^@x)Jzar zChmRg>%!3hrR`t>eP%p~{H8dfqCCpX3@yMfA!&qi0{Ke*afey+NdM^iS0fG`%1}m# z*~qWr*ovNB0os`6`f-6n&!Cgg8r^^faZRGY(59z&z0uky=}m?^(Eo>gg3Lc>Z(rUB zO%&rSlYQaZ04Hdo^_a(u+818+Hw`=kpt>ufC5)*T2+Ms)woHtT(T7|}@v|34*)qAY zH8!Sy+k!hYp^m}ma+Q8Nfx(xdXL0BkL)J(lHi4jymhc!}WYQ)HVZKB-4@wYJl0}%3 zPC#MUeTN&e8L3q5}C`7ty!R3gk+S0=8BMmk+ZMlanJ zq9dtE*l;r9Kz+kHKTPCj;aLA(O9eU(VmdEz8>XQ@0 zq56x#qqm18FcBc832e)?%RY(%KodjUFvtM4i#`DHq?yh4s$H9Ous8jCBo(GPKbn00 z{5gtDid1h7sQ}`U*Pw|{svyfIPF7?c9p7p7j3dNZ0zeM99YO-$)-i;!bM2f()C6qX zc(vhZd=K$~RtJWj6%frERnG^TAc{7GbLQ1trQafO7{Y1TCk!`Uw|Pe%vO3so`ekV;EPscm^LFh z%|ZlF@mCM6GCO~UwH|P9Woz4KxOLk$D06)Km>8HsDzIwLQ9Xy`0X_MboSq-mhuibR zAE4?2#|@7FYEWNLEe5g$*Hk!?>I&pk6Ocvd>|$dSHKGjy*tQKQ0`2JXz9n8`n1NbA z06JPD4C6Pi@#3+(44C8~Vl}T}I`43BFRfZN#~`C{y9G03(&1q;-qyiL&W6A;=}73l08X-U`X^)9jbhn*<1ZaEv!^1;n*7U5Nbv$t2;3kJ@> z$52QKV1S!pv;aeSH0;5eke`^ZQw5h;0|6J@GY?RRtfS%NUC80p-`*Trk9at$*6{A# zVMvmxsVgBr^AaLOevV3noN-J#_T!@AUj*@Q^hzTF!N|xk2?haaRRE)lvTeB#kSk1M zcu`2T5yL1oc@cm*aZOn$tJVEu(DG2=U_lHq!6LoVWE4=C5xOy5TgLnyOh!h;Vt8ru zbzq*zX8dv|=-TWR#;DVnw-``Q)eStBD(=(yUL9RVb{O@H(w|BZuX z5@rNR52X+jW6fK+GJK#h-*B1QRNySJ-u6LHttigZEtLJQwT;|@6lT|k<1}3Q4Lnwu z(HjBdYAQh11ha25MjP-BXHfuEcl5ar4ln-d7%hal2$?RU8AoN$1y1()VJVH>>T5RW zX$dINgiacf@Cn%iZV!HhSzwyN4;i1vupmsI#o}lKJirrFzi(!2D_U(?v{586yg-93 zP#id`7m`0+0%uz7L(hy}X+#$$iR5XKj8eQmo)^+K86EgP@uZAWlJ@rYDf#))WQ+o= zAMR00o=#Huu@j;`CQ?yPCcxYp40e|0WToA|z3*vz`LeeAu43q8lPQvV&l1`(HR76; zcmN$6aU;Ac^$K)jkAnN=`qWOBHRRCZ;ETieR{IBiXkao$@@);eORuy@LcwZs0L%+T z_NQ3WKDLg5><(F$Hh9Al_|ffCq94jJkOB;ZPB0*YqtG}!!OFq2z%Fj$rbcU)&mdK} z1Gza#20!npHDCaNEDdC8k~Wlx9HkWs7z!XYNss#TXFwU-BmoBSH-;kssXF-mt=qXW zBybc~CJJp{(X;2zG1lonv@i6?B1oMQEZ=5~{?R@K`M>@Z57nVZcs^m&&%o{Jv8s?+ zWo-99Zt$gLkwD)@Of5mB7N?DTPEAc(IG>4BH*b@KtZx_qvV^ta_=xW?Gz$t_s|e?i zj9Ej*0fCaYdu;Ga`dA7169L*P6B8PsH#R-dy9{lRiL|K>MQ9qOv3qf{hj>p0-cEc` z!DUS9ejyKz>*|)wylZZruz=jH-h@%e-FFlT$~vp2HiAVHTyGTL!p8PzB8?!u!sszj zPFNEWOXmwPadjvP8hu&~V;IpID_SlRdX`Zhs8TWQtzwAtW$&*n*;WPxlwDrpD((Eq z!l_sFKL(&MCP*(OfG1#bLBk?xM`a1_eT-iu%i@HQ9~{Z^k@vtlxU>KVgI;M{{HEO* z)ME16W6AiWxjx3;5Gp97$J88Ua6gDR(e?int}ODHB`e4{KIMFfG zR2U{0(6yv>Hq_A!>Sev;?i3cDDlw@U!f|(WrOVN&dFptiLyuvK%KC;W?*o<3zm@d% z1tnY#`)yWUcHYVR+0+7i{kYdGBPHkbLfE6 z3YXPacL|smJ)2SpDR$q~nB@0q_T~0>g$r&!JkPIObE0Eh>15}RglG=A!+6V%M_+!{ z_wMUDY%Opz#QE4G`ETc@tEDn84H=1c4Mr~PA+N%U;(8apZ>eMdQ1ZjYJ?K@~X|~6s zNwy-C8S_2VvY%Q6|U4{ugm? z0*~d|{g0~MZd55Ml_-@dMVaT_DDzA-NTSS{3K`lJp=6hkxd|a8Nfe5rGG)pX%FvUk z$C#P(z3xYQzwi5d&-wh%IsfxHeb6)9&vjqJTHp0u>$;w`EZLg8^h(xuG;63kv_3UY z6WA7JYMoznLf=TXX!Jqg+r)Rvb*hf&Z0)G3wvqEImr(o>=Byg9hWkx0pFp*0DPKxx zaCgz|DE&w|y${2hJ+-Rp+g7J%TdHZ?V}rb&*a@REnQyaPweL;sV#7zx6Mk!>M~yaJ ztv|1@vw+oj+sQOHIW0!*+!AdP1+b zwt8<`m-)zC@y<;G_S=S=HA?!v$2=F*Uq1Qg>)*<=zx+B2aNn!-$!)p51@ndEj7ShO z?KT?;M*2on0u1Z1so>eih5+qk3_aBhVQ~_-!Y(qiH&MyfxLqa zmYkeM0LzQ&>xuW0!wsSeom^k*r_)PH%F=Aw9OMm+)rS2~gk*nP-up#JM*h8fjKz#V z=I7x?+392jbH_X3D#Lqh|9U3m9#vNE#X*g|zmSi(C@fbS!ul{3wMW812=)6>TBYuUq( zW5ZU)j-Pk*lfX5xSR7Vp_40c*e{3{9uVhKqZt(?)?_YGJw3z3j6On;p5`E~?g#3V_ zOG9p-Gw0OwoS##rdtGwVQbS2k$Bs>P&Rn9F;JF)PnS7kB*{;8wUv%JW%?e4WWqPri z+TxeA^bQo*Bpos~yeyg5wKS=Ja+FsJx9b1wP-{0B)-uhMrlD|wwtm9RVj{mb;aKL) z!tu=h(ah=F76=A-YEUkQnqwv!nS$UxZq6X)K+THZ)*6d z`Km4Hn>S;7a=lSb zJdP!M+1of*cDQYg>n4eJ-~JGzM6vY)jt4-fmxM=pSFxV4Wac?#;!eR#eM&5Mj? z`u&lBcktFPI+|MZtcveEXPQ>{`9)#h51G8d$?hpVm5`1!xu11yhqTx_CZ?j#y;NRkOrUN}vGNG!Gg2Ph>YLjl9IuZEoisG|J&xWMD>iM-hs{%tlJ7gU$ zFKT;V^niCnDX{m(vYu7)KGSYa`y-~lZ_7(eE1T&nA97UK(B)`6xwNS?&qylur`>dJ zVQzm$D&JU>LbaV&N8s;FOc$2h9bjUTJ<|7N0K4uY&mk$b?192eu}+b%yVb_KD^>+Bn|_xb zJ``Z*sfh9`b(|t|&ln`@tKjDx3Olq%Ry9e|E=S$1u|$^iPL!zdk95plPm2^j+LE(l zDn3cO|7d4K?E@NTsOO|bXL`9x-Y9Ej(8L3w$?i3xGv0gZnmj!^M~1wnuH;q3Oux>n zuIo`)G~8%BW;!+e-Cv%SQ@1l_s)7F977wfMu2G0(^m=&Nj)mw}qbX*# zXRck#U%5ZGciN>W)2$D_7OC{|&>T;Tf3Q}=W!|I7irajn_DDUU* zM<)kw$d9~j`B+Dv`JrHN&h??fsKRs(c`JCeyq7LD!x}S#2E(T=wN%cGznD1^Gtp}I zUD0?LNj2s$2Txr#EGj}RwXdwPU zm&QSbpSSva$FPK*o{uJlcr)tLvSO+qw8#%{8}HT0yO&medBHI0U4%!QmGKHRCI52m z9Hz$wpB*Z_CPRkkJ5)4!g0FMlJm#i9po+Jd&ORjXUwS!qeW>Qhfa-X@N@bwjR`Sk^ zSJ$v$n+~+xn9iKp;_<_GsEX>`s~x+Dlw7bo7Bua$rDi5==)MLiw)1L->5t#W@7~WF zh;AOgUZtL4m+EA?SEeC1r!rt^@1cpG$`ayF@5_x`>&&Oi#RXPY7`tlNc@$a1yIH3W zHT#@>N{iV!^`hmxDp#=aXz<9;w{wwa6Fo%KC7LBXZXFAsic9fqV|D9ZAM^2SokW{c zo5!zPyeg{9T^qli9`Wn)-jn4X+S!j^8eC z?OZ&-zqog-j0eJI(ToQd_y?g6VJZJlvjfv^pK$n%BC61#tvoU>spOl)DkY-?fUT5_C%khSYxlG4-2Zr_* zq9`vRW?<@4KjHPl@ zqeRO5WT!q>1(tuuD|67ZmhtJOIepdg0p#tJV~s3K)<2W!EgzR?^j6i)UibCu#HSIv z@80o07cpIkI(Cxe&?8&H+d4ITddjHn&qG)J%TP>bU1)Rg%3q*hZ>oqTj z^5^t6nU0SKTg^S@)wUsLvUN@X{;;m|oJ!o`MU(4gJ3n$;eq=yoys9?uen5n}%-e3e zm-j=BWj8_rxE;AZE+CT@Q3dDk ztPT9KBKu=J^e0B#u*&ga70aWvrfwT9tGK=5LZjPHKZa7Bu`8F~d4KA>+?*G0(=|#S4)w5} zhuxB27tQqf)1Mya=P}iV|2FaS`zv{kSGM-YTR4NGU5L7jo_3jgMsdMU=#X_Oxvoci z!OvcR*RMCoWBhX&{hu26WbK^i$<%_p`t%a(H|IsE&{WAFw2^CrBNq$xIVR!#{~Of0 z?@!6=X6Cy@!on&=YYyGq;(za8AErpHY;x7-MOKYR5P z!K#82=6F5m<`yls{n^I$9NVs&e!XwN=8b#thy+nr3i$6CK|&{QlZTBvMc&#!Qc}9f z=g-}giiY>!0LoqJzpQxd<`(I5KO!R?9m@F29mUoyjkQR$@NGNPd-iadloYK!Qs+gJ zK1Wf5|Hg$*U-N%gGdg-yk7Zti?QWKLQoJ;L4&kDz&z~cin7mT;lio94b0|yDPWXSH8?R%R3^G zwnQg9&W&X^%fl9Wu~a-HgU?@Axk?v#deGl8DP(?$lJ_u*6;-S09&V4sYY-|X;q6zi zUWM?n&HHnFDmT*6Qal2hh?NkPkciL75R;-oqp;>tg4?$vCl=PXsSL79UAwqI)1D&< z0_K(zO|$_i5iA6iR-zIIZr9rbnr%+aOJ-QDkIn zTnlXwaDH(#!)Uu&qJEN*p`n(Av$I}NAXn{!L0UN${q!UJy1E*g@~TH_c7D9OS75uK z;6r41a_+3$8h}nwa8Z3)l=LZBUteE0sfOH+jIbV72>e$-ftcTD6eN2x0o7Z+zo z9k{=V@gdtxu@JMciyJj_ju~{ezYkis>w4wi7mOp=3v zcLa>m)6>a{V`!j@f_h;8| zwz7(f3W1g=1+QbJ<~pY2Hz_HJT990NQoVH-a(?6&;9?33b=dZYKYjf8PUYm}%LDgs zC=+33nU|<5Ah3PMj;>=Np`kUWMV}gm$3f81@z~hdt&rg09Y>zuF-nFu=tMMOf^dP&4MwcCOfJ)RA^hd zBf+TMET^qKJdPH8)g({{>HmQ=JrC=x1(a5*5pjxQ+kaO{@j6FE9fowj;xC{|b@%Y) zD?;Ut#2i4=F1`L^5QYfJhO1 z!feiAy6|G~vSM^t0^edaGM`xJ91d9*%|?r}XZ2m9lkhSo!Zq3oPh*v1xye`|%|PZL zxP6ceh-J04ct#j~qRUB|zz~ej{7Zj6t3nwPCnR6AlHrhcI{3F$!WAPP=#(&X2k9~q z5nNLls}eeosp{SXEZleJsugy;?vx6Qe?}6;}VqP)uXgw>^evL+ZZe$mb{H* ze>k>8<`B~MwJrWwDufcYqHLwWk$I2k|j$3EHH<$ zFe<0 z0Tn=s#Z4kWw#wtenouX$GkjzHJ?X93C(8`{N6Zx3Me9VMMMmcQa)R6c|8s&xzcO4^ z_@jGVibPz|;8KNu0xUHa_&2XQ^YD^cJI)^2iD~g3U;eE*XWi9`HeHL--fqp z|IKqlcP<28Ma+hiUr07XgZ}wBKVD)Ql?+?K^yS7t535K+UM&@aaE~lm$kcaG>akrQ zx#CM(AuFzMgx^JG;#HB~-+>Kt66-i#46H4@$F~wwgD4$dd29vz21BtpmWkoD-*?}M zy7P}o9hrb}a%2C8^GeYG;=zP{Gcmb8C7(ql&;(I6v9mvW451=6=1`TeFoshBsca0JM3lx}`MRu-c` zJSQb^vr}b}S|Mf(aM5Bzx5JQ8_a-sAVPQ`Mb*L8#{qGUY2We1-DI>)A9v|*C>j_oq zZWRGx+9d*1&?f&Ak9HLX^*92n*dq-qLwu1!*oAL2niv=jFdKvKbRwt_Ld(Ldpzkd6 zV5r~;On89y27t+$r}NVy0c?pii9Ep14^r`O-|hzwvh0CdMo6vxqeqX3cLG=LKfD6i zhhwQQw*W%8q9JD45e)N$dlOs>IItNs3U|U10r=9;t`yBl2sDSH<(PXcFF>&pxC!)x zu>z3-%C<`C!_Zg7+5FTg_!PRZHW@~0gyMi;1FV6X;8d|NZ)RbI zgoR@E>a8h5pbbOqzX$rjs}ZdWlMD|O)0b9XZy1aVDO#(k#Rdlh?C>m}GOP>e9&nYo zPq+_kajZ_fdM9Q>U_1COT($Oz-0;#ke4{++1=3i8_|5u^|J^B=A|#+L%aMkoKMx4{ zC+k;z_~4IWU1-W@WjbEl?_rGlAjkl6EPb};HqX&4hy7bA7VngoawO~CM1{4ubARjp z#ixPSb*h6tbAr^}Bpw)qn9u)d6Q=aa4J1dW`usVZtOw^Y0Im>(58wB3QB{0Z@Z z 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 DfaFK& literal 0 HcmV?d00001 diff --git "a/zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199351155.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\345\206\205\346\240\270\346\236\266\346\236\204\345\233\276.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199351155.png diff --git "a/zh-cn/device-dev/kernel/figure/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199352039.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\351\235\231\346\200\201\345\206\205\345\255\230\347\244\272\346\204\217\345\233\276.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199352039.png diff --git a/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199352445.png b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001199352445.png new file mode 100644 index 0000000000000000000000000000000000000000..bd73700c41d62b47005ad0612c74f2823a1921a9 GIT binary patch literal 43346 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 W2#1-OL>A};K}uXstn|5_@BaZY?dvQ6 literal 0 HcmV?d00001 diff --git "a/zh-cn/device-dev/kernel/figure/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001219007317.png old mode 100755 new mode 100644 similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\350\277\233\347\250\213\347\212\266\346\200\201\350\277\201\347\247\273\347\244\272\346\204\217\345\233\276.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001219007317.png diff --git "a/zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245051881.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\344\277\241\345\217\267\351\207\217\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245051881.png diff --git "a/zh-cn/device-dev/kernel/figure/\345\257\274\345\207\272\347\232\204\347\254\246\345\217\267\350\241\250\344\277\241\346\201\257.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245171875.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\345\257\274\345\207\272\347\232\204\347\254\246\345\217\267\350\241\250\344\277\241\346\201\257.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245171875.png diff --git "a/zh-cn/device-dev/kernel/figure/ELF\346\226\207\344\273\266\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245251887.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/ELF\346\226\207\344\273\266\347\232\204\345\212\240\350\275\275\350\277\207\347\250\213.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245251887.png diff --git "a/zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" b/zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245411845.png similarity index 100% rename from "zh-cn/device-dev/kernel/figure/\344\272\222\346\226\245\351\224\201\350\277\220\344\275\234\347\244\272\346\204\217\345\233\276.png" rename to zh-cn/device-dev/kernel/figures/zh-cn_image_0000001245411845.png diff --git a/zh-cn/device-dev/kernel/kernel-basic-mini-time.md b/zh-cn/device-dev/kernel/kernel-basic-mini-time.md index a3b59d055e..43d0f544fc 100644 --- a/zh-cn/device-dev/kernel/kernel-basic-mini-time.md +++ b/zh-cn/device-dev/kernel/kernel-basic-mini-time.md @@ -1,7 +1,135 @@ -# 时间管理 +# 时间管理 -- **[基本概念](kernel-mini-basic-time-basic.md)** +## 基本概念 -- **[开发指导](kernel-mini-basic-time-guide.md)** +时间管理以系统时钟为基础,给应用程序提供所有和时间有关的服务。 +系统时钟是由定时器/计数器产生的输出脉冲触发中断产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。 +用户以秒、毫秒为单位计时,而操作系统以Tick为单位计时,当用户需要对系统进行操作时,例如任务挂起、延时等,此时需要时间管理模块对Tick和秒/毫秒进行转换。 + +OpenHarmony LiteOS-M内核时间管理模块提供时间转换、统计功能。 + + +## 时间单位: + +- Cycle + 系统最小的计时单位。Cycle的时长由系统主时钟频率决定,系统主时钟频率就是每秒钟的Cycle数。 + +- Tick + Tick是操作系统的基本时间单位,由用户配置的每秒Tick数决定。 + + +## 接口说明 + +OpenHarmony LiteOS-M内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 + +**表1** 时间管理接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 时间转换 | LOS_MS2Tick | 毫秒转换成Tick | +| LOS_Tick2MS | Tick转化为毫秒 | +| OsCpuTick2MS | Cycle数目转化为毫秒,使用2个UINT32类型的数值分别表示结果数值的高、低32位。 | +| OsCpuTick2US | Cycle数目转化为微秒,使用2个UINT32类型的数值分别表示结果数值的高、低32位。 | +| 时间统计 | LOS_SysClockGet | 获取系统时钟 | +| LOS_TickCountGet | 获取自系统启动以来的Tick数 | +| LOS_CyclePerTickGet | 获取每个Tick多少Cycle数 | + + +## 开发流程 + +时间管理的典型开发流程: + +1. 根据实际需求,完成板级配置适配,并配置系统主时钟频率OS_SYS_CLOCK(单位Hz)和LOSCFG_BASE_CORE_TICK_PER_SECOND。OS_SYS_CLOCK的默认值基于硬件平台配置。 + +2. 调用时钟转换/统计接口。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 时间管理不是单独的功能模块,依赖于OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。 +> +> - 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。 +> +> - 配置选项维护在开发板工程的文件target_config.h。 + + +## 编程实例 + + +### 实例描述 + +在下面的例子中,介绍了时间管理的基本方法,包括: + +1. 时间转换:将毫秒数转换为Tick数,或将Tick数转换为毫秒数。 + +2. 时间统计:每Tick的Cycle数、自系统启动以来的Tick数和延迟后的Tick数。 + + +### 示例代码 + +前提条件: + +- 使用每秒的Tick数LOSCFG_BASE_CORE_TICK_PER_SECOND的默认值100。 + +- 配好OS_SYS_CLOCK系统主时钟频率。 + +时间转换: + +``` +VOID Example_TransformTime(VOID) +{ + UINT32 ms; + UINT32 tick; + + tick = LOS_MS2Tick(10000); // 10000ms转换为tick + dprintf("tick = %d \n", tick); + ms = LOS_Tick2MS(100); // 100tick转换为ms + dprintf("ms = %d \n", ms); +} +``` + +时间统计和时间延迟: + +``` +VOID Example_GetTime(VOID) +{ + UINT32 cyclePerTick; + UINT64 tickCount; + + cyclePerTick = LOS_CyclePerTickGet(); + if(0 != cyclePerTick) { + dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); + } + + tickCount = LOS_TickCountGet(); + if(0 != tickCount) { + dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); + } + + LOS_TaskDelay(200); + tickCount = LOS_TickCountGet(); + if(0 != tickCount) { + dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); + } +} +``` + + +### 结果验证 + +编译运行得到的结果为: + +时间转换: + +``` +tick = 1000 +ms = 1000 +``` + +时间统计和时间延迟: + +``` +LOS_CyclePerTickGet = 495000 +LOS_TickCountGet = 1 +LOS_TickCountGet after delay = 201 +``` diff --git a/zh-cn/device-dev/kernel/kernel-memory-inner.md b/zh-cn/device-dev/kernel/kernel-memory-inner.md deleted file mode 100644 index 932e1b17c8..0000000000 --- a/zh-cn/device-dev/kernel/kernel-memory-inner.md +++ /dev/null @@ -1,9 +0,0 @@ -# 内核调测 - -- **[内存调测](kernel-mini-memory-debug.md)** - -- **[异常调测](kernel-mini-memory-exception.md)** - -- **[Trace调测](kernel-mini-memory-trace.md)** - - diff --git a/zh-cn/device-dev/kernel/kernel-mini-app.md b/zh-cn/device-dev/kernel/kernel-mini-app.md index 26cb843856..3c005673f4 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-app.md +++ b/zh-cn/device-dev/kernel/kernel-mini-app.md @@ -1,9 +1,8 @@ -# 附录 +# 附录 -- **[内核编码规范](kernel-mini-appx-code.md)** -- **[基本数据结构](kernel-mini-appx-data.md)** - -- **[标准库支持](kernel-mini-appx-lib.md)** +- **[内核编码规范](kernel-mini-appx-code.md)** +- **[基本数据结构](kernel-mini-appx-data.md)** +- **[标准库支持](kernel-mini-appx-lib.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-appx-code.md b/zh-cn/device-dev/kernel/kernel-mini-appx-code.md index 6dbadca4da..13245e58b3 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-appx-code.md +++ b/zh-cn/device-dev/kernel/kernel-mini-appx-code.md @@ -1,98 +1,56 @@ -# 内核编码规范 - -- [总体原则](#section9512812145915) -- [目录结构](#section1355317267017) -- [命名](#section1375364815017) -- [注释](#section1692516179119) -- [格式](#section10888536113) -- [宏](#section12276501124) -- [头文件](#section158507231319) -- [数据类型](#section91351731446) -- [变量](#section575493915417) -- [断言](#section13864440410) -- [函数](#section671919481745) +# 内核编码规范 + +- [总体原则](#总体原则) +- [目录结构](#目录结构) +- [命名](#命名) +- [注释](#注释) +- [格式](#格式) +- [宏](#宏) +- [头文件](#头文件) +- [数据类型](#数据类型) +- [变量](#变量) +- [断言](#断言) +- [函数](#函数) 此规范基于业界通用的编程规范整理而成,请内核的开发人员遵守这样的编程风格。 -## 总体原则 + +## 总体原则 总体原则: -- 清晰:代码应当易于理解、易于维护、易于重构,避免晦涩语法 -- 简洁:命名简短,函数紧凑 -- 高效:通过使用算法、编译器优化选项或硬件资源提高程序效率 -- 美观:代码风格合理、一致 +- 清晰:代码应当易于理解、易于维护、易于重构,避免晦涩语法 + +- 简洁:命名简短,函数紧凑 + +- 高效:通过使用算法、编译器优化选项或硬件资源提高程序效率 + +- 美观:代码风格合理、一致 在大部分情况下,开发人员应当遵从以下规范,但也有一些例外场景。如修改第三方开源代码或大量使用开源代码接口下,应当与开源代码保持一致。请依据总体原则,灵活处理。 -## 目录结构 + +## 目录结构 建议按照功能模块划分子目录,子目录再定义头文件和源文件目录。 -目录名和文件名如果没有特殊的需要,采用全小写的形式,可以使用下划线(“\_”)分割。 +目录名和文件名如果没有特殊的需要,采用全小写的形式,可以使用下划线(“_”)分割。 + -## 命名 +## 命名 推荐使用驼峰风格,具体规则如下: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

类型

-

命名风格

-

形式

-

函数、结构体类型、枚举类型、联合体类型、typedef的类型

-

大驼峰,或带有模块前缀的大驼峰

-

AaaBbb

-

XXX_AaaBbb

-

局部变量,函数参数,宏参数,结构体中字段,联合体中成员

-

小驼峰

-

aaaBBB

-

全局变量

-

带“g_”前缀的小驼峰

-

g_aaaBBB

-

宏(不含函数式宏),枚举值,goto标签

-

全大写,下划线分割

-

AAA_BBB

-

函数式宏

-

全大写下划线分割,或大驼峰,或带有模块前缀的大驼峰

-

AAA_BBB

-

AaaBbb

-

XXX_AaaBbb

-

头文件防止重复的符号

-

以下划线“_”开头以H结尾,中间为文件名的全大写并以下划线分割

-

_AAA_H

-
- -内核对外API建议采用LOS\_ModuleFunc的形式,如果有宾语则建议采用前置的方式,比如: +| 类型 | 命名风格 | 形式 | +| -------- | -------- | -------- | +| 函数、结构体类型、枚举类型、联合体类型、typedef的类型 | 大驼峰,或带有模块前缀的大驼峰 | AaaBbb
XXX_AaaBbb | +| 局部变量,函数参数,宏参数,结构体中字段,联合体中成员 | 小驼峰 | aaaBBB | +| 全局变量 | 带“g_”前缀的小驼峰 | g_aaaBBB | +| 宏(不含函数式宏),枚举值,goto标签 | 全大写,下划线分割 | AAA_BBB | +| 函数式宏 | 全大写下划线分割,或大驼峰,或带有模块前缀的大驼峰 | AAA_BBB
AaaBbb
XXX_AaaBbb | +| 头文件防止重复的符号 | 以下划线“_”开头以H结尾,中间为文件名的全大写并以下划线分割 | _AAA_H | + +内核对外API建议采用LOS_ModuleFunc的形式,如果有宾语则建议采用前置的方式,比如: ``` LOS_TaskCreate @@ -106,7 +64,8 @@ OsTaskScan OsMuxInit ``` -## 注释 + +## 注释 一般的,尽量通过清晰的软件架构,良好的符号命名来提高代码可读性;然后在需要的时候,才辅以注释说明。 @@ -142,9 +101,10 @@ OsMuxInit #define CONST_B 2000 /* Const B */ ``` -## 格式 -程序采用缩进风格编写,使用空格而不是制表符(’\\t’)进行缩进,每级缩进为4个空格。 +## 格式 + +程序采用缩进风格编写,使用空格而不是制表符(’\t’)进行缩进,每级缩进为4个空格。 换行时,函数左大括号另起一行放行首,并独占一行;其他左大括号跟随语句放行末。右大括号独占一行,除非后面跟着同一语句的剩余部分,如 do 语句中的 while,或者 if 语句的else/else if,或者逗号、分号。 @@ -156,8 +116,7 @@ OsMuxInit struct MyType { // 跟随语句放行末,前置1空格 ... }; // 右大括号后面紧跟分号 -int Foo(int a) -{ // 函数左大括号独占一行,放行首 +int Foo(int a) { // 函数左大括号独占一行,放行首 if (a > 0) { Foo(); // 一行只有一条语句 Bar(); @@ -234,7 +193,8 @@ int Foo(const char * restrict p); // OK: 当有 restrict 修饰符时,"*"两 sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 ``` -## 宏 + +## 宏 定义函数式宏前,应考虑能否用函数替代。对于可替代场景,建议用函数替代宏。对于有性能需求的场景,可以使用内联函数。 @@ -249,10 +209,13 @@ sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 以下情况需要注意: -- 宏参数参与 '\#', '\#\#' 操作时,不要加括号; -- 宏参数参与字符串拼接时,不要加括号; -- 宏参数作为独立部分,在赋值(包括+=, -=等)操作的某一边时,可以不加括号; -- 宏参数作为独立部分,在逗号表达式,函数或宏调用列表中,可以不加括号。 +- 宏参数参与 '\#', '\#\#' 操作时,不要加括号; + +- 宏参数参与字符串拼接时,不要加括号; + +- 宏参数作为独立部分,在赋值(包括+=, -=等)操作的某一边时,可以不加括号; + +- 宏参数作为独立部分,在逗号表达式,函数或宏调用列表中,可以不加括号。 ``` // x 不要加括号 @@ -268,9 +231,9 @@ sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 #define FOO(a, b) Bar((a) + 1, b) ``` -包含多条语句的函数式宏的实现语句必须放在 do-while\(0\)中。 +包含多条语句的函数式宏的实现语句必须放在 do-while(0)中。 -禁止把带副作用的表达式作为参数传递给函数式宏,比如自加操作\(“a++”\)。 +禁止把带副作用的表达式作为参数传递给函数式宏,比如自加操作(“a++”)。 函数式宏定义中慎用 return、goto、continue、break 等改变程序流程的语句。 @@ -278,7 +241,8 @@ sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 宏定义不以分号结尾。 -## 头文件 + +## 头文件 头文件应当职责单一。 @@ -294,11 +258,13 @@ sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 建议按稳定度包含头文件,依次顺序为: 源码对应的头文件,C标准库,操作系统库,平台库,项目公共库,自己其他的依赖。 -## 数据类型 -基础数据类型建议使用los\_compiler.h中定义的类型,比如无符号32位整数位定义为UINT32。 +## 数据类型 -## 变量 +基础数据类型建议使用los_compiler.h中定义的类型,比如无符号32位整数位定义为UINT32。 + + +## 变量 避免大量栈分配,如较大的局部数组。 @@ -310,7 +276,8 @@ sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 指向资源句柄或描述符的变量,在资源释放后立即赋予新值(如果变量的作用域马上结束可以不赋予新值)。指向资源句柄或描述符的变量包括指针、文件描述符、socket描述符以及其它指向资源的变量。 -## 断言 + +## 断言 断言必须使用宏定义,且只能在调试版本中生效。 @@ -320,14 +287,17 @@ sz = sizeof(int*); // OK:右侧没有变量,"*"跟随类型 一个断言只用于检查一个错误。 -## 函数 + +## 函数 由一个进程向另一个进程发送的数据、由应用向内核发送的数据等应当进行合法性校验,校验包括但不限于: -- 校验数据长度 -- 校验数据范围 -- 校验数据类型和格式 -- 校验输入只包含可接受的字符(“白名单”形式) +- 校验数据长度 -函数应避免使用全局变量、静态局部变量和直接的I/O操作,不可避免时,应当对读写操作进行封装。 +- 校验数据范围 + +- 校验数据类型和格式 +- 校验输入只包含可接受的字符(“白名单”形式) + +函数应避免使用全局变量、静态局部变量和直接的I/O操作,不可避免时,应当对读写操作进行封装。 diff --git a/zh-cn/device-dev/kernel/kernel-mini-appx-data-list.md b/zh-cn/device-dev/kernel/kernel-mini-appx-data-list.md index d219cc86b0..ae167adf29 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-appx-data-list.md +++ b/zh-cn/device-dev/kernel/kernel-mini-appx-data-list.md @@ -1,142 +1,84 @@ -# 双向链表 +# 双向链表 -- [基本概念](#section1990715203418) -- [功能说明](#section848334511411) -- [开发流程](#section01781261552) -- [编程实例](#section67569495514) - - [实例描述](#section48761994551) - - [示例代码](#section1280202685519) - - [结果验证](#section5811249105512) +- [基本概念](#基本概念) +- [功能说明](#功能说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) - -## 基本概念 +## 基本概念 双向链表是指含有往前和往后两个方向的链表,即每个结点中除存放下一个节点指针外,还增加一个指向前一个节点的指针。其头指针head是唯一确定的。 从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点,这种数据结构形式使得双向链表在查找时更加方便,特别是大量数据的遍历。由于双向链表具有对称性,能方便地完成各种插入、删除等操作,但需要注意前后方向的操作。 -## 功能说明 + +## 功能说明 双向链表模块为用户提供下面几种功能,接口详细信息可以查看API参考。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化链表

-

LOS_ListInit

-

将指定双向链表节点初始化为双向链表

-

LOS_DL_LIST_HEAD

-

定义一个双向链表节点并以该节点初始化为双向链表

-

增加节点

-

LOS_ListAdd

-

将指定节点插入到双向链表头端

-

LOS_ListTailInsert

-

将指定节点插入到双向链表尾端

-

删除节点

-

LOS_ListDelete

-

将指定节点从链表中删除

-

LOS_ListDelInit

-

将指定节点从链表中删除,并使用该节点初始化链表

-

判断双向链表是否为空

-

LOS_ListEmpty

-

判断链表是否为空

-

获取结构体信息

-

LOS_DL_LIST_ENTRY

-

获取包含链表的结构体地址,接口的第一个入参表示的是链表中的某个节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称

-

LOS_OFF_SET_OF

-

获取指定结构体内的成员相对于结构体起始地址的偏移量

-

遍历双向链表

-

LOS_DL_LIST_FOR_EACH

-

遍历双向链表

-

LOS_DL_LIST_FOR_EACH_SAFE

-

遍历双向链表,并存储当前节点的后继节点用于安全校验

-

遍历包含双向链表的结构体

-

LOS_DL_LIST_FOR_EACH_ENTRY

-

遍历指定双向链表,获取包含该链表节点的结构体地址

-

LOS_DL_LIST_FOR_EACH_ENTRY_SAFE

-

遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址

-
- -## 开发流程 + +| **功能分类** | **接口名** | **描述** | +| -------- | -------- | -------- | +| 初始化链表 | LOS_ListInit | 将指定双向链表节点初始化为双向链表 | +| LOS_DL_LIST_HEAD | 定义一个双向链表节点并以该节点初始化为双向链表 | +| 增加节点 | LOS_ListAdd | 将指定节点插入到双向链表头端 | +| LOS_ListTailInsert | 将指定节点插入到双向链表尾端 | +| 删除节点 | LOS_ListDelete | 将指定节点从链表中删除 | +| LOS_ListDelInit | 将指定节点从链表中删除,并使用该节点初始化链表 | +| 判断双向链表是否为空 | LOS_ListEmpty | 判断链表是否为空 | +| 获取结构体信息 | LOS_DL_LIST_ENTRY | 获取包含链表的结构体地址,接口的第一个入参表示的是链表中的某个节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称 | +| LOS_OFF_SET_OF | 获取指定结构体内的成员相对于结构体起始地址的偏移量 | +| 遍历双向链表 | LOS_DL_LIST_FOR_EACH | 遍历双向链表 | +| LOS_DL_LIST_FOR_EACH_SAFE | 遍历双向链表,并存储当前节点的后继节点用于安全校验 | +| 遍历包含双向链表的结构体 | LOS_DL_LIST_FOR_EACH_ENTRY | 遍历指定双向链表,获取包含该链表节点的结构体地址 | +| LOS_DL_LIST_FOR_EACH_ENTRY_SAFE | 遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址 | + + +## 开发流程 双向链表的典型开发流程: -1. 调用LOS\_ListInit/LOS\_DL\_LIST\_HEAD初始双向链表。 -2. 调用LOS\_ListAdd向链表插入节点。 -3. 调用LOS\_ListTailInsert向链表尾部插入节点。 -4. 调用LOS\_ListDelete删除指定节点。 -5. 调用LOS\_ListEmpty判断链表是否为空。 -6. 调用LOS\_ListDelInit删除指定节点并以此节点初始化链表。 +1. 调用LOS_ListInit/LOS_DL_LIST_HEAD初始双向链表。 + +2. 调用LOS_ListAdd向链表插入节点。 + +3. 调用LOS_ListTailInsert向链表尾部插入节点。 + +4. 调用LOS_ListDelete删除指定节点。 + +5. 调用LOS_ListEmpty判断链表是否为空。 + +6. 调用LOS_ListDelInit删除指定节点并以此节点初始化链表。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 需要注意节点指针前后方向的操作。 ->- 链表操作接口,为底层接口,不对入参进行判空,需要使用者确保传参合法。 ->- 如果链表节点的内存是动态申请的,删除节点时,要注意释放内存。 -## 编程实例 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 需要注意节点指针前后方向的操作。 +> +> - 链表操作接口,为底层接口,不对入参进行判空,需要使用者确保传参合法。 +> +> - 如果链表节点的内存是动态申请的,删除节点时,要注意释放内存。 -### 实例描述 + +## 编程实例 + + +### 实例描述 本实例实现如下功能: -1. 初始化双向链表。 -2. 增加节点。 -3. 删除节点。 -4. 测试操作是否成功。 +1. 初始化双向链表。 + +2. 增加节点。 + +3. 删除节点。 -### 示例代码 +4. 测试操作是否成功。 + + +### 示例代码 示例代码如下: @@ -178,14 +120,13 @@ static UINT32 ListSample(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: ``` -Initial head -Add listNode1 success +Initial head Add listNode1 success Tail insert listNode2 success Delete success ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-appx-data.md b/zh-cn/device-dev/kernel/kernel-mini-appx-data.md index cfb577f516..577813651c 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-appx-data.md +++ b/zh-cn/device-dev/kernel/kernel-mini-appx-data.md @@ -1,5 +1,4 @@ -# 基本数据结构 - -- **[双向链表](kernel-mini-appx-data-list.md)** +# 基本数据结构 +- **[双向链表](kernel-mini-appx-data-list.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-appx-lib-cmsis.md b/zh-cn/device-dev/kernel/kernel-mini-appx-lib-cmsis.md index fb77b08629..1d3ff6c62f 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-appx-lib-cmsis.md +++ b/zh-cn/device-dev/kernel/kernel-mini-appx-lib-cmsis.md @@ -1,465 +1,119 @@ -# CMSIS支持 +# CMSIS支持 -- [基本概念](#section131091144111615) -- [开发指导](#section57653573161) - - [接口说明](#section1795910417173) - - [开发流程](#section48301225131720) - - [编程实例](#section524434761713) +- [基本概念](#基本概念) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 [CMSIS](https://developer.arm.com/tools-and-software/embedded/cmsis)是Cortex Microcontroller Software Interface Standard(Cortex微控制器软件接口标准)的缩写,是对于那些基于ARM Cortex处理器的微控制器独立于供应商的硬件抽象层。它包含多个组件层,其中之一是RTOS层,该层定义了一套通用及标准化的RTOS API接口,减少了应用开发者对特定RTOS的依赖,方便用户软件的移植重用。该套API有2个版本,分别为版本1(CMSIS-RTOS v1)和版本2(CMSIS-RTOS v2),OpenHarmony LiteOS-M仅提供其版本2的实现。 -## 开发指导 - -### 接口说明 - -CMSIS-RTOS v2提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** CMSIS-RTOS v2接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

内核信息与控制

-

osKernelGetInfo

-

获取RTOS内核信息。

-

osKernelGetState

-

获取当前的RTOS内核状态。

-

osKernelGetSysTimerCount

-

获取RTOS内核系统计时器计数。

-

osKernelGetSysTimerFreq

-

获取RTOS内核系统计时器频率。

-

osKernelInitialize

-

初始化RTOS内核。

-

osKernelLock

-

锁定RTOS内核调度程序。

-

osKernelUnlock

-

解锁RTOS内核调度程序。

-

osKernelRestoreLock

-

恢复RTOS内核调度程序锁定状态。

-

osKernelResume

-

恢复RTOS内核调度程序。(暂未实现)

-

osKernelStart

-

启动RTOS内核调度程序。

-

osKernelSuspend

-

挂起RTOS内核调度程序。(暂未实现)

-

osKernelGetTickCount

-

获取RTOS内核滴答计数。

-

osKernelGetTickFreq

-

获取RTOS内核滴答频率。

-

线程管理

-

osThreadDetach

-

分离线程(线程终止时可以回收线程存储)。(暂未实现)

-

osThreadEnumerate

-

枚举活动线程。(暂未实现)

-

osThreadExit

-

终止当前正在运行的线程的执行。

-

osThreadGetCount

-

获取活动线程的数量。

-

osThreadGetId

-

返回当前正在运行的线程的线程ID。

-

osThreadGetName

-

获取线程的名称。

-

osThreadGetPriority

-

获取线程的当前优先级。

-

osThreadGetStackSize

-

获取线程的堆栈大小。

-

osThreadGetStackSpace

-

根据执行期间的堆栈水印记录获取线程的可用堆栈空间。

-

osThreadGetState

-

获取线程的当前线程状态。

-

osThreadJoin

-

等待指定线程终止。(暂未实现)

-

osThreadNew

-

创建一个线程并将其添加到活动线程中。

-

osThreadResume

-

恢复线程的执行。

-

osThreadSetPriority

-

更改线程的优先级。

-

osThreadSuspend

-

暂停执行线程。

-

osThreadTerminate

-

终止线程的执行。

-

osThreadYield

-

将控制权传递给处于就绪状态的下一个线程。

-

线程标志

-

osThreadFlagsSet

-

设置线程的指定线程标志。(暂未实现)

-

osThreadFlagsClear

-

清除当前正在运行的线程的指定线程标志。(暂未实现)

-

osThreadFlagsGet

-

获取当前正在运行的线程的当前线程标志。(暂未实现)

-

osThreadFlagsWait

-

等待当前正在运行的线程的一个或多个线程标志发出信号。(暂未实现)

-

事件标志

-

osEventFlagsGetName

-

获取事件标志对象的名称。(暂未实现)

-

osEventFlagsNew

-

创建并初始化事件标志对象。

-

osEventFlagsDelete

-

删除事件标志对象。

-

osEventFlagsSet

-

设置指定的事件标志。

-

osEventFlagsClear

-

清除指定的事件标志。

-

osEventFlagsGet

-

获取当前事件标志。

-

osEventFlagsWait

-

等待一个或多个事件标志被发出信号。

-

通用等待函数

-

osDelay

-

等待超时(时间延迟)。

-

osDelayUntil

-

等到指定时间。

-

计时器管理

-

osTimerDelete

-

删除计时器。

-

osTimerGetName

-

获取计时器的名称。(暂未实现)

-

osTimerIsRunning

-

检查计时器是否正在运行。

-

osTimerNew

-

创建和初始化计时器。

-

osTimerStart

-

启动或重新启动计时器。

-

osTimerStop

-

停止计时器。

-

互斥管理

-

osMutexAcquire

-

获取互斥或超时(如果已锁定)。

-

osMutexDelete

-

删除互斥对象。

-

osMutexGetName

-

获取互斥对象的名称。(暂未实现)

-

osMutexGetOwner

-

获取拥有互斥对象的线程。

-

osMutexNew

-

创建并初始化Mutex对象。

-

osMutexRelease

-

释放由osMutexAcquire获取的Mutex。

-

信号量

-

osSemaphoreAcquire

-

获取信号量令牌或超时(如果没有可用的令牌)。

-

osSemaphoreDelete

-

删除一个信号量对象。

-

osSemaphoreGetCount

-

获取当前信号量令牌计数。

-

osSemaphoreGetName

-

获取信号量对象的名称。(暂未实现)

-

osSemaphoreNew

-

创建并初始化一个信号量对象。

-

osSemaphoreRelease

-

释放信号量令牌,直到初始最大计数。

-

内存池

-

osMemoryPoolAlloc

-

从内存池分配一个内存块。

-

osMemoryPoolDelete

-

删除内存池对象。

-

osMemoryPoolFree

-

将分配的内存块返回到内存池。

-

osMemoryPoolGetBlockSize

-

获取内存池中的内存块大小。

-

osMemoryPoolGetCapacity

-

获取内存池中最大的内存块数。

-

osMemoryPoolGetCount

-

获取内存池中使用的内存块数。

-

osMemoryPoolGetName

-

获取内存池对象的名称。

-

osMemoryPoolGetSpace

-

获取内存池中可用的内存块数。

-

osMemoryPoolNew

-

创建并初始化一个内存池对象。

-

消息队列

-

osMessageQueueDelete

-

删除消息队列对象。

-

osMessageQueueGet

-

从队列获取消息,或者如果队列为空,则从超时获取消息。

-

osMessageQueueGetCapacity

-

获取消息队列中的最大消息数。

-

osMessageQueueGetCount

-

获取消息队列中排队的消息数。

-

osMessageQueueGetMsgSize

-

获取内存池中的最大消息大小。

-

osMessageQueueGetName

-

获取消息队列对象的名称。(暂未实现)

-

osMessageQueueGetSpace

-

获取消息队列中消息的可用插槽数。

-

osMessageQueueNew

-

创建和初始化消息队列对象。

-

osMessageQueuePut

-

如果队列已满,则将消息放入队列或超时。

-

osMessageQueueReset

-

将消息队列重置为初始空状态。(暂未实现)

-
-### 开发流程 +## 开发指导 -CMSIS-RTOS2组件可以作为库或源代码提供(下图显示了库)。通过添加CMSIS-RTOS2组件(通常是一些配置文件),可以将基于CMSIS的应用程序扩展为具有RTOS功能。只需包含cmsis\_os2.h头文件就可以访问RTOS API函数,这使用户应用程序能够处理RTOS内核相关事件,而在更换内核时无需重新编译源代码。 -静态对象分配需要访问RTOS对象控制块定义。特定于实现的头文件(下图中的os\_xx .h)提供对此类控制块定义的访问。对于OpenHarmony LiteOS-M内核,由文件名以los\_开头的头文件提供,这些文件包含OpenHarmony LiteOS-M内核的这些定义。 +### 接口说明 -![](figure/zh-cn_image_0000001132778524.png) +CMSIS-RTOS v2提供下面几种功能,接口详细信息可以查看API参考。 -### 编程实例 +**表1** CMSIS-RTOS v2接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 内核信息与控制 | osKernelGetInfo | 获取RTOS内核信息。 | +| osKernelGetState | 获取当前的RTOS内核状态。 | +| osKernelGetSysTimerCount | 获取RTOS内核系统计时器计数。 | +| osKernelGetSysTimerFreq | 获取RTOS内核系统计时器频率。 | +| osKernelInitialize | 初始化RTOS内核。 | +| osKernelLock | 锁定RTOS内核调度程序。 | +| osKernelUnlock | 解锁RTOS内核调度程序。 | +| osKernelRestoreLock | 恢复RTOS内核调度程序锁定状态。 | +| osKernelResume | 恢复RTOS内核调度程序。(暂未实现) | +| osKernelStart | 启动RTOS内核调度程序。 | +| osKernelSuspend | 挂起RTOS内核调度程序。(暂未实现) | +| osKernelGetTickCount | 获取RTOS内核滴答计数。 | +| osKernelGetTickFreq | 获取RTOS内核滴答频率。 | +| 线程管理 | osThreadDetach | 分离线程(线程终止时可以回收线程存储)。(暂未实现) | +| osThreadEnumerate | 枚举活动线程。(暂未实现) | +| osThreadExit | 终止当前正在运行的线程的执行。 | +| osThreadGetCount | 获取活动线程的数量。 | +| osThreadGetId | 返回当前正在运行的线程的线程ID。 | +| osThreadGetName | 获取线程的名称。 | +| osThreadGetPriority | 获取线程的当前优先级。 | +| osThreadGetStackSize | 获取线程的堆栈大小。 | +| osThreadGetStackSpace | 根据执行期间的堆栈水印记录获取线程的可用堆栈空间。 | +| osThreadGetState | 获取线程的当前线程状态。 | +| osThreadJoin | 等待指定线程终止。(暂未实现) | +| osThreadNew | 创建一个线程并将其添加到活动线程中。 | +| osThreadResume | 恢复线程的执行。 | +| osThreadSetPriority | 更改线程的优先级。 | +| osThreadSuspend | 暂停执行线程。 | +| osThreadTerminate | 终止线程的执行。 | +| osThreadYield | 将控制权传递给处于就绪状态的下一个线程。 | +| 线程标志 | osThreadFlagsSet | 设置线程的指定线程标志。(暂未实现) | +| osThreadFlagsClear | 清除当前正在运行的线程的指定线程标志。(暂未实现) | +| osThreadFlagsGet | 获取当前正在运行的线程的当前线程标志。(暂未实现) | +| osThreadFlagsWait | 等待当前正在运行的线程的一个或多个线程标志发出信号。(暂未实现) | +| 事件标志 | osEventFlagsGetName | 获取事件标志对象的名称。(暂未实现) | +| osEventFlagsNew | 创建并初始化事件标志对象。 | +| osEventFlagsDelete | 删除事件标志对象。 | +| osEventFlagsSet | 设置指定的事件标志。 | +| osEventFlagsClear | 清除指定的事件标志。 | +| osEventFlagsGet | 获取当前事件标志。 | +| osEventFlagsWait | 等待一个或多个事件标志被发出信号。 | +| 通用等待函数 | osDelay | 等待超时(时间延迟)。 | +| osDelayUntil | 等到指定时间。 | +| 计时器管理 | osTimerDelete | 删除计时器。 | +| osTimerGetName | 获取计时器的名称。(暂未实现) | +| osTimerIsRunning | 检查计时器是否正在运行。 | +| osTimerNew | 创建和初始化计时器。 | +| osTimerStart | 启动或重新启动计时器。 | +| osTimerStop | 停止计时器。 | +| 互斥管理 | osMutexAcquire | 获取互斥或超时(如果已锁定)。 | +| osMutexDelete | 删除互斥对象。 | +| osMutexGetName | 获取互斥对象的名称。(暂未实现) | +| osMutexGetOwner | 获取拥有互斥对象的线程。 | +| osMutexNew | 创建并初始化Mutex对象。 | +| osMutexRelease | 释放由osMutexAcquire获取的Mutex。 | +| 信号量 | osSemaphoreAcquire | 获取信号量令牌或超时(如果没有可用的令牌)。 | +| osSemaphoreDelete | 删除一个信号量对象。 | +| osSemaphoreGetCount | 获取当前信号量令牌计数。 | +| osSemaphoreGetName | 获取信号量对象的名称。(暂未实现) | +| osSemaphoreNew | 创建并初始化一个信号量对象。 | +| osSemaphoreRelease | 释放信号量令牌,直到初始最大计数。 | +| 内存池 | osMemoryPoolAlloc | 从内存池分配一个内存块。 | +| osMemoryPoolDelete | 删除内存池对象。 | +| osMemoryPoolFree | 将分配的内存块返回到内存池。 | +| osMemoryPoolGetBlockSize | 获取内存池中的内存块大小。 | +| osMemoryPoolGetCapacity | 获取内存池中最大的内存块数。 | +| osMemoryPoolGetCount | 获取内存池中使用的内存块数。 | +| osMemoryPoolGetName | 获取内存池对象的名称。 | +| osMemoryPoolGetSpace | 获取内存池中可用的内存块数。 | +| osMemoryPoolNew | 创建并初始化一个内存池对象。 | +| 消息队列 | osMessageQueueDelete | 删除消息队列对象。 | +| osMessageQueueGet | 从队列获取消息,或者如果队列为空,则从超时获取消息。 | +| osMessageQueueGetCapacity | 获取消息队列中的最大消息数。 | +| osMessageQueueGetCount | 获取消息队列中排队的消息数。 | +| osMessageQueueGetMsgSize | 获取内存池中的最大消息大小。 | +| osMessageQueueGetName | 获取消息队列对象的名称。(暂未实现) | +| osMessageQueueGetSpace | 获取消息队列中消息的可用插槽数。 | +| osMessageQueueNew | 创建和初始化消息队列对象。 | +| osMessageQueuePut | 如果队列已满,则将消息放入队列或超时。 | +| osMessageQueueReset | 将消息队列重置为初始空状态。(暂未实现) | + + +### 开发流程 + +CMSIS-RTOS2组件可以作为库或源代码提供(下图显示了库)。通过添加CMSIS-RTOS2组件(通常是一些配置文件),可以将基于CMSIS的应用程序扩展为具有RTOS功能。只需包含cmsis_os2.h头文件就可以访问RTOS API函数,这使用户应用程序能够处理RTOS内核相关事件,而在更换内核时无需重新编译源代码。 + +静态对象分配需要访问RTOS对象控制块定义。特定于实现的头文件(下图中的os_xx .h)提供对此类控制块定义的访问。对于OpenHarmony LiteOS-M内核,由文件名以los_开头的头文件提供,这些文件包含OpenHarmony LiteOS-M内核的这些定义。 + +![zh-cn_image_0000001153834574](figures/zh-cn_image_0000001153834574.png) + + +### 编程实例 ``` #include ... @@ -484,4 +138,3 @@ int main (void) { for (;;) {} } ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-appx-lib-posix.md b/zh-cn/device-dev/kernel/kernel-mini-appx-lib-posix.md index 43b959bb94..ada544979e 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-appx-lib-posix.md +++ b/zh-cn/device-dev/kernel/kernel-mini-appx-lib-posix.md @@ -1,1598 +1,239 @@ -# POSIX支持 +# POSIX支持 -- [基本概念](#section1757915134139) -- [开发指导](#section1573664211318) - - [接口说明](#section10429150121317) - - [注意事项](#section109174418147) - - [编程实例](#section206149278155) +- [基本概念](#基本概念) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [注意事项](#注意事项) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 OpenHarmony内核使用**musl libc**库以及自研接口,支持部分标准POSIX接口,开发者可基于POSIX标准接口开发内核之上的组件及应用。 -## 开发指导 -### 接口说明 +## 开发指导 + + +### 接口说明 -**表 1** POSIX接口说明 +**表1** POSIX接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

类别

-

需要包含的头文件

-

接口名

-

描述

-

process

-

#include <stdlib.h>

-

void abort(void);

-

中止线程执行

-

#include <assert.h>

-

void assert(scalar expression);

-

断言为假终止线程

-

#include <pthread.h>

-

int pthread_cond_destroy(pthread_cond_t *cond);

-

销毁条件变量

-

#include <pthread.h>

-

int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

-

初始化条件变量

-

#include <pthread.h>

-

int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

-

等待条件

-

#include <pthread.h>

-

int pthread_condattr_init(pthread_condattr_t *attr);

-

初始化条件变量属性对象

-

#include <pthread.h>

-

int pthread_mutex_unlock(pthread_mutex_t *mutex);

-

解锁互斥锁

-

#include <pthread.h>

-

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

-

创建一个新的线程

-

#include <pthread.h>

-

int pthread_join(pthread_t thread, void **retval);

-

等待指定的线程结束

-

#include <pthread.h>

-

pthread_t pthread_self(void);

-

获取当前线程的ID

-

#include <pthread.h>

-

int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);

-

获取线程的调度策略和参数

-

#include <pthread.h>

-

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);

-

设置线程的调度策略和参数

-

#include <pthread.h>

-

int pthread_mutex_init(pthread_mutex_t *__restrict m, const pthread_mutexattr_t *__restrict a);

-

初始化互斥锁

-

#include <pthread.h>

-

int pthread_mutex_lock(pthread_mutex_t *m);

-

互斥锁加锁操作

-

#include <pthread.h>

-

int pthread_mutex_trylock(pthread_mutex_t *m);

-

互斥锁尝试加锁操作

-

#include <pthread.h>

-

int pthread_mutex_destroy(pthread_mutex_t *m);

-

销毁互斥锁

-

#include <pthread.h>

-

int pthread_attr_init(pthread_attr_t *attr);

-

初始化线程属性对象

-

#include <pthread.h>

-

int pthread_attr_destroy(pthread_attr_t *attr);

-

销毁线程属性对象

-

#include <pthread.h>

-

int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);

-

获取线程属性对象的堆栈大小

-

#include <pthread.h>

-

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

-

设置线程属性对象的堆栈大小

-

#include <pthread.h>

-

int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);

-

获取线程属性对象的调度参数属性

-

#include <pthread.h>

-

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);

-

设置线程属性对象的调度参数属性

-

#include <pthread.h>

-

int pthread_getname_np(pthread_t pthread, char *name, size_t len);

-

获取线程名称

-

#include <pthread.h>

-

int pthread_setname_np(pthread_t pthread, const char *name);

-

设置线程名称

-

#include <pthread.h>

-

int pthread_cond_broadcast(pthread_cond_t *c);

-

解除若干已被等待条件阻塞的线程

-

#include <pthread.h>

-

int pthread_cond_signal(pthread_cond_t *c);

-

解除被阻塞的线程

-

#include <pthread.h>

-

int pthread_cond_wait(pthread_cond_t *__restrict c, pthread_mutex_t *__restrict m);

-

等待条件

-

fs

-

-

#include <libgen.h>

-

char *dirname(char *path);

-

获取目录名

-

#include <dirent.h>

-

struct dirent *readdir(DIR *dirp);

-

读目录

-

#include <sys/stat.h>

-

int stat(const char *restrict path, struct stat *restrict buf);

-

获取文件信息

-

#include <unistd.h>

-

int unlink(const char *pathname);

-

删除文件

-

#include <fcntl.h>

-

int open(const char *path, int oflags, ...);

-

用于打开文件,如文件不存在,创建文件并打开

-

#include <nistd.h>

-

int close(int fd);

-

关闭文件

-

#include <stdio.h>

-

int rename(const char *oldpath, const char *newpath);

-

重命名指定的文件

-

#include <dirent.h>

-

DIR *opendir(const char *dirname);

-

打开指定目录

-

#include <dirent.h>

-

int closedir(DIR *dir);

-

关闭指定目录

-

#include <sys/mount.h>

-

int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data);

-

挂载文件系统

-

#include <sys/mount.h>

-

int umount(const char *target);

-

卸载文件系统

-

#include <sys/mount.h>

-

int umount2(const char *target, int flag);

-

卸载文件系统

-

#include <sys/stat.h>

-

int fsync(int fd);

-

将与指定文件描述符关联的文件同步到存储设备

-

#include <sys/stat.h>

-

int mkdir(const char *pathname, mode_t mode);

-

创建目录

-

#include <unistd.h>

-

int rmdir(const char *path);

-

删除目录

-

#include <sys/stat.h>

-

int fstat(int fd, struct stat *buf);

-

获取文件状态信息

-

#include <sys/statfs.h>

-

int statfs(const char *path, struct statfs *buf);

-

获取指定路径下文件的文件系统信息

-

time

-

#include <sys/time.h>

-

int gettimeofday(struct timeval *tv, struct timezone *tz);

-

获取时间。当前暂无时区概念,tz返回为空

-

#include <time.h>

-

struct tm *gmtime(const time_t *timep);

-

将日期和时间转换为细分时间或ASCII

-

#include <time.h>

-

struct tm *localtime(const time_t *timep);

-

获取时间

-

#include <time.h>

-

struct tm *localtime_r(const time_t *timep, struct tm *result);

-

获取时间

-

#include <time.h>

-

time_t mktime(struct tm *tm);

-

将日期和时间转换为细分时间或ASCII

-

#include <time.h>

-

size_t strftime(char *s, size_t max, const char *format,const struct tm *tm);

-

格式化日期和时间字符串

-

#include <time.h>

-

time_t time(time_t *tloc);

-

获得日历时间

-

#include <sys/times.h>

-

clock_t times(struct tms *buf);

-

获取线程时间

-

#include <unistd.h>

-

int usleep(useconds_t usec);

-

休眠(微秒单位)

-

#include <time.h>

-

int nanosleep(const struct timespec *tspec1, struct timespec *tspec2);

-

暂停当前线程直到指定的时间到达

-

#include <time.h>

-

int clock_gettime(clockid_t id, struct timespec *tspec);

-

获取时钟的时间

-

#include <time.h>

-

int timer_create(clockid_t id, struct sigevent *__restrict evp, timer_t *__restrict t);

-

为线程创建计时器

-

#include <time.h>

-

int timer_delete(timer_t t);

-

为线程删除计时器

-

#include <time.h>

-

int timer_settime(timer_t t, int flags, const struct itimerspec *__restrict val, struct itimerspec *__restrict old);

-

为线程设置计时器

-

#include <time.h>

-

time_t time (time_t *t);

-

获取时间

-

#include <time.h>

-

char *strptime(const char *s, const char *format, struct tm *tm);

-

将时间的字符串表示形式转换为时间tm结构

-

util

-

#include <stdlib.h>

-

int atoi(const char *nptr);

-

字符串转换整型(int)

-

#include <stdlib.h>

-

long atol(const char *nptr);

-

字符串转换整型(long)

-

#include <stdlib.h>

-

long long atoll(const char *nptr);

-

字符串转换整型(long long)

-

#include <ctype.h>

-

int isalnum(int c);

-

检查字母数字字符

-

#include <ctype.h>

-

int isascii(int c);

-

检查ASCII

-

#include <ctype.h>

-

int isdigit(int c);

-

检查数字字符

-

#include <ctype.h>

-

int islower(int c);

-

检查小写字符

-

#include <ctype.h>

-

int isprint(int c);

-

检查任何可打印字符,包括空格

-

#include <ctype.h>

-

int isspace(int c);

-

检查空格字符

-

#include <ctype.h>

-

int isupper(int c);

-

检查所传的字符是否是大写字母

-

#include <ctype.h>

-

int isxdigit(int c);

-

判断字符是否为十六进制数

-

#include <stdlib.h>

-

long int random (void);

-

生成伪随机数

-

#include <stdlib.h>

-

void srandom(unsigned int seed);

-

初始化随机数生成器

-

#include <ctype.h>

-

int tolower(int c);

-

字母转换成小写

-

#include <ctype.h>

-

int toupper(int c);

-

字母转换成大写

-

#include <stdarg.h>

-

type va_arg(va_list ap, type);

-

获取可变参数的当前参数,返回指定类型并将指针指向下一参数

-

#include <stdarg.h>

-

void va_copy(va_list dest, va_list src);

-

复制参数

-

#include <stdarg.h>

-

void va_end(va_list ap);

-

清空va_list可变参数列表

-

#include <stdarg.h>

-

void va_start(va_list ap, last);

-

定义变长参数列表的起始位置

-

#include <string.h>

-

char *strchr(const char *s, int c);

-

在字符串中定位字符

-

#include <string.h>

-

int strcmp(const char *s1, const char *s2);

-

比较字符串

-

#include <string.h>

-

size_t strcspn(const char *s, const char *reject);

-

获取前缀子串的长度

-

#include <string.h>

-

char *strdup(const char *s);

-

字符串拷贝到新建的位置处

-

#include <string.h>

-

size_t strlen(const char *s);

-

计算字符串长度

-

#include <strings.h>

-

int strncasecmp(const char *s1, const char *s2, size_t n);

-

比较固定长度字符串(忽略大小写)

-

#include <strings.h>

-

int strcasecmp(const char *s1, const char *s2);

-

比较字符串(忽略大小写)

-

#include <string.h>

-

int strncmp(const char *s1, const char *s2, size_t n);

-

比较字符串(指定长度)

-

#include <string.h>

-

char *strrchr(const char *s, int c);

-

在字符串中定位字符

-

#include <string.h>

-

char *strstr(const char *haystack, const char *needle);

-

寻找指定的子串

-

#include <stdlib.h>

-

long int strtol(const char *nptr, char **endptr, int base);

-

将字符串转换为long型整数

-

#include <stdlib.h>

-

unsigned long int strtoul(const char *nptr, char **endptr, int base);

-

将字符串转换为unsigned long型整数

-

#include <stdlib.h>

-

unsigned long long int strtoull(const char *nptr, char **endptr,int base);

-

将字符串转换为unsigned long long型整数

-

#include <regex.h>

-

int regcomp(regex_t *preg, const char *regex, int cflags);

-

编译正则表达式

-

#include <regex.h>

-

int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);

-

匹配正则表达式

-

#include <regex.h>

-

void regfree(regex_t *preg);

-

释放正则表达式

-

#include <string.h>

-

char *strerror(int errnum);

-

返回描述错误号的字符串

-

math

-

#include <stdlib.h>

-

int abs(int i);

-

取绝对值

-

#include <math.h>

-

double log(double x);

-

自然对数函数

-

#include <math.h>

-

double pow(double x, double y);

-

求x的指数y次幂

-

#include <math.h>

-

double round(double x);

-

从零开始,舍入到最接近的整数

-

#include <math.h>

-

double sqrt(double x);

-

平方根

-

IO

-

#include <stdio.h>

-

void clearerr(FILE *stream);

-

清除流的文件结尾和错误指示

-

#include <stdio.h>

-

int fclose(FILE *stream);

-

关闭文件流

-

#include <stdio.h>

-

FILE *fdopen(int fd, const char *mode);

-

通过文件描述符打开文件流

-

#include <stdio.h>

-

int feof(FILE *stream);

-

检测返回文件末尾指示位

-

#include <stdio.h>

-

int fflush(FILE *stream);

-

刷新流

-

#include <stdio.h>

-

char *fgets(char *s, int size, FILE *stream);

-

读取流的下一行

-

#include <stdio.h>

-

int fileno(FILE *stream);

-

返回流的文件描述符

-

#include <stdio.h>

-

FILE *fopen(const char *path, const char *mode);

-

打开流

-

#include <stdio.h>

-

int fputs(const char *s, FILE *stream);

-

向指定流写入一行

-

#include <stdio.h>

-

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

-

读一个流

-

#include <stdio.h>

-

int fseek(FILE *stream, long offset, int whence);

-

设置流指针的位置

-

#include <stdio.h>

-

long ftell(FILE *stream);

-

获取流指针的位置

-

#include <stdio.h>

-

size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

-

向流写入

-

#include <stdio.h>

-

void perror(const char *s);

-

打印系统错误信息

-

#include <stdio.h>

-

void rewind(FILE *stream);

-

重新定位流

-

#include <unistd.h>

-

ssize_t write(int fd, const void *buf, size_t size);

-

写文件内容

-

#include <unistd.h>

-

ssize_t read(int fd, void *buf, size_t size);

-

读文件内容

-

net

-

#include <sys/socket.h>

-

void freeaddrinfo(struct addrinfo *res);

-

释放调用getaddrinfo所分配的动态内存

-

#include <sys/socket.h>

-

int getaddrinfo(const char *restrict nodename,const char *restrict servname,const struct addrinfo *restrict hints,struct addrinfo **restrict res);

-

网络地址和服务转换

-

#include <sys/socket.h>

-

int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,char *restrict node, socklen_t nodelen, char *restrict service,socklen_t servicelen, int flags);

-

以协议无关的方式进行地址到名称的转换

-

#include <net/if.h>

-

unsigned int if_nametoindex(const char *ifname);

-

通过网络接口名得到索引

-

#include <arpa/inet.h>

-

in_addr_t inet_addr(const char *cp);

-

网络主机地址点分十进制形式转换位二进制形式

-

#include <arpa/inet.h>

-

char *inet_ntoa(struct in_addr in);

-

网络主机地址二进制形式转换位点分十进制形式

-

#include <arpa/inet.h>

-

const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);

-

网络地址转换

-

#include <arpa/inet.h>

-

int inet_pton(int af, const char *src, void *dst);

-

网络地址转换

-

#include <sys/socket.h>

-

int listen(int sockfd, int backlog);

-

监听套接字

-

#include <sys/socket.h>

-

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

-

从套接字接收消息.只支持iov大小为1的场景,且不支持ancillary消息

-

#include <sys/socket.h>

-

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

-

从socket发送消息

-

#include <sys/socket.h>

-

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

-

从socket发送消息。不支持ancillary消息

-

#include <sys/socket.h>

-

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

-

从socket发送消息

-

#include <sys/socket.h>

-

int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);

-

设置与套接字关联的选项

-

mem

-

#include <string.h>

-

int memcmp(const void *s1, const void *s2, size_t n);

-

内存比较

-

#include <string.h>

-

void *memcpy(void *dest, const void *src, size_t n);

-

内存拷贝

-

#include <string.h>

-

void *memset(void *s, int c, size_t n);

-

内存初始化

-

#include <stdlib.h>

-

void *realloc(void *ptr, size_t size);

-

重分配内存

-

#include <stdlib.h>

-

void *malloc(size_t size);

-

动态分配内存块大小

-

#include <stdlib.h>

-

void free(void *ptr);

-

释放ptr所指向的内存空间

-

IPC

-

#include <semaphore.h>

-

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

-

计时锁定信号量

-

#include <semaphore.h>

-

int sem_destroy(sem_t *sem);

-

销毁指定的无名信号量

-

#include <semaphore.h>

-

int sem_init(sem_t *sem, int pshared, unsigned int value);

-

创建并初始化一个无名信号量

-

#include <semaphore.h>

-

int sem_post(sem_t *sem);

-

增加信号量计数

-

#include <semaphore.h>

-

int sem_wait(sem_t *sem);

-

获取信号量

-

#include <mqueue.h>

-

mqd_t mq_open(const char *mqName, int openFlag, ...);

-

此API用于打开一个具有指定名称的已有消息队列或创建一个新的消息队列

-

#include <mqueue.h>

-

int mq_close(mqd_t personal);

-

此API用于关闭具有指定描述符的消息队列

-

#include <mqueue.h>

-

int mq_unlink(const char *mqName);

-

此API用于删除具有指定名称的消息队列

-

#include <mqueue.h>

-

int mq_send(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio);

-

此API用于将具有指定内容和长度的消息放入具有指定描述符的消息队列中

-

#include <mqueue.h>

-

ssize_t mq_receive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio);

-

此API用于从具有指定描述符的消息队列中删除最老的消息,并将其放入msg_ptr所指向的缓冲区中

-

#include <mqueue.h>

-

int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio, const struct timespec *absTimeout)

-

此API用于在预定时间将具有指定内容和长度的消息放入具有描述符的消息队列中

-

#include <mqueue.h>

-

ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio, const struct timespec *absTimeout);

-

此API用于从具有指定描述符的消息队列消息中获取具有指定消息内容和长度的消息

-

#include <mqueue.h>

-

int mq_setattr(mqd_t mqdes, const struct mq_attr *__restrict newattr, struct mq_attr *__restrict oldattr);

-

设置描述符指定的消息队列属性

-

version

-

#include <libc.h>

-

const char *libc_get_version_string(void);

-

获取libc版本字符串

-

#include <libc.h>

-

int libc_get_version(void);

-

获取libc版本号

-
+| 类别 | 需要包含的头文件 | 接口名 | 描述 | +| -------- | -------- | -------- | -------- | +| process | \#include <stdlib.h> | void abort(void); | 中止线程执行 | +| \#include <assert.h> | void assert(scalar expression); | 断言为假终止线程 | +| \#include <pthread.h> | int pthread_cond_destroy(pthread_cond_t \*cond); | 销毁条件变量 | +| \#include <pthread.h> | int pthread_cond_init(pthread_cond_t \*restrict cond, const pthread_condattr_t \*restrict attr); | 初始化条件变量 | +| \#include <pthread.h> | int pthread_cond_timedwait(pthread_cond_t \*restrict cond, pthread_mutex_t \*restrict mutex, const struct timespec \*restrict abstime); | 等待条件 | +| \#include <pthread.h> | int pthread_condattr_init(pthread_condattr_t \*attr); | 初始化条件变量属性对象 | +| \#include <pthread.h> | int pthread_mutex_unlock(pthread_mutex_t \*mutex); | 解锁互斥锁 | +| \#include <pthread.h> | int pthread_create(pthread_t \*thread, const pthread_attr_t \*attr, void \*(\*start_routine)(void \*), void \*arg); | 创建一个新的线程 | +| \#include <pthread.h> | int pthread_join(pthread_t thread, void \*\*retval); | 等待指定的线程结束 | +| \#include <pthread.h> | pthread_t pthread_self(void); | 获取当前线程的ID | +| \#include <pthread.h> | int pthread_getschedparam(pthread_t thread, int \*policy, struct sched_param \*param); | 获取线程的调度策略和参数 | +| \#include <pthread.h> | int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param \*param); | 设置线程的调度策略和参数 | +| \#include <pthread.h> | int pthread_mutex_init(pthread_mutex_t \*__restrict m, const pthread_mutexattr_t \*__restrict a); | 初始化互斥锁 | +| \#include <pthread.h> | int pthread_mutex_lock(pthread_mutex_t \*m); | 互斥锁加锁操作 | +| \#include <pthread.h> | int pthread_mutex_trylock(pthread_mutex_t \*m); | 互斥锁尝试加锁操作 | +| \#include <pthread.h> | int pthread_mutex_destroy(pthread_mutex_t \*m); | 销毁互斥锁 | +| \#include <pthread.h> | int pthread_attr_init(pthread_attr_t \*attr); | 初始化线程属性对象 | +| \#include <pthread.h> | int pthread_attr_destroy(pthread_attr_t \*attr); | 销毁线程属性对象 | +| \#include <pthread.h> | int pthread_attr_getstacksize(const pthread_attr_t \*attr, size_t \*stacksize); | 获取线程属性对象的堆栈大小 | +| \#include <pthread.h> | int pthread_attr_setstacksize(pthread_attr_t \*attr, size_t stacksize); | 设置线程属性对象的堆栈大小 | +| \#include <pthread.h> | int pthread_attr_getschedparam(const pthread_attr_t \*attr, struct sched_param \*param); | 获取线程属性对象的调度参数属性 | +| \#include <pthread.h> | int pthread_attr_setschedparam(pthread_attr_t \*attr, const struct sched_param \*param); | 设置线程属性对象的调度参数属性 | +| \#include <pthread.h> | int pthread_getname_np(pthread_t pthread, char \*name, size_t len); | 获取线程名称 | +| \#include <pthread.h> | int pthread_setname_np(pthread_t pthread, const char \*name); | 设置线程名称 | +| \#include <pthread.h> | int pthread_cond_broadcast(pthread_cond_t \*c); | 解除若干已被等待条件阻塞的线程 | +| \#include <pthread.h> | int pthread_cond_signal(pthread_cond_t \*c); | 解除被阻塞的线程 | +| \#include <pthread.h> | int pthread_cond_wait(pthread_cond_t \*__restrict c, pthread_mutex_t \*__restrict m); | 等待条件 | +| fs | \#include <libgen.h> | char \*dirname(char \*path); | 获取目录名 | +| \#include <dirent.h> | struct dirent \*readdir(DIR \*dirp); | 读目录 | +| \#include <sys/stat.h> | int stat(const char \*restrict path, struct stat \*restrict buf); | 获取文件信息 | +| \#include <unistd.h> | int unlink(const char \*pathname); | 删除文件 | +| \#include <fcntl.h | int open(const char \*path, int oflags, ...); | 用于打开文件,如文件不存在,创建文件并打开 | +| \#include <nistd.h> | int close(int fd); | 关闭文件 | +| \#include <stdio.h> | int rename(const char \*oldpath, const char \*newpath); | 重命名指定的文件 | +| \#include <dirent.h> | DIR  \*opendir(const char \*dirname); | 打开指定目录 | +| \#include <dirent.h> | int closedir(DIR \*dir); | 关闭指定目录 | +| \#include <sys/mount.h> | int mount(const char \*source, const char \*target, const char \*filesystemtype, unsigned long mountflags, const void \*data); | 挂载文件系统 | +| \#include <sys/mount.h> | int umount(const char \*target); | 卸载文件系统 | +| \#include <sys/mount.h> | int umount2(const char \*target, int flag); | 卸载文件系统 | +| \#include <sys/stat.h> | int fsync(int fd); | 将与指定文件描述符关联的文件同步到存储设备 | +| \#include <sys/stat.h> | int mkdir(const char \*pathname, mode_t mode); | 创建目录 | +| \#include <unistd.h> | int rmdir(const char \*path); | 删除目录 | +| \#include <sys/stat.h> | int fstat(int fd, struct stat \*buf); | 获取文件状态信息 | +| \#include <sys/statfs.h> | int statfs(const char \*path, struct statfs \*buf); | 获取指定路径下文件的文件系统信息 | +| time | \#include <sys/time.h> | int gettimeofday(struct timeval \*tv, struct timezone \*tz); | 获取时间。当前暂无时区概念,tz返回为空 | +| \#include <time.h> | struct tm \*gmtime(const time_t \*timep); | 将日期和时间转换为细分时间或ASCII | +| \#include <time.h> | struct tm \*localtime(const time_t \*timep); | 获取时间 | +| \#include <time.h> | struct tm \*localtime_r(const time_t \*timep, struct tm \*result); | 获取时间 | +| \#include <time.h> | time_t mktime(struct tm \*tm); | 将日期和时间转换为细分时间或ASCII | +| \#include <time.h> | size_t strftime(char \*s, size_t max, const char \*format,const struct tm \*tm); | 格式化日期和时间字符串 | +| \#include <time.h> | time_t time(time_t \*tloc); | 获得日历时间 | +| \#include <sys/times.h> | clock_t times(struct tms \*buf); | 获取线程时间 | +| \#include <unistd.h> | int usleep(useconds_t usec); | 休眠(微秒单位) | +| \#include <time.h> | int nanosleep(const struct timespec \*tspec1, struct timespec \*tspec2); | 暂停当前线程直到指定的时间到达 | +| \#include <time.h> | int clock_gettime(clockid_t id, struct timespec \*tspec); | 获取时钟的时间 | +| \#include <time.h> | int timer_create(clockid_t id, struct sigevent \*__restrict evp, timer_t \*__restrict t); | 为线程创建计时器 | +| \#include <time.h> | int timer_delete(timer_t t); | 为线程删除计时器 | +| \#include <time.h> | int timer_settime(timer_t t, int flags, const struct itimerspec \*__restrict val, struct itimerspec \*__restrict old); | 为线程设置计时器 | +| \#include <time.h> | time_t time (time_t \*t); | 获取时间 | +| \#include <time.h> | char \*strptime(const char \*s, const char \*format, struct tm \*tm); | 将时间的字符串表示形式转换为时间tm结构 | +| util | \#include <stdlib.h> | int atoi(const char \*nptr); | 字符串转换整型(int) | +| \#include <stdlib.h> | long atol(const char \*nptr); | 字符串转换整型(long) | +| \#include <stdlib.h> | long long atoll(const char \*nptr); | 字符串转换整型(long long) | +| \#include <ctype.h> | int isalnum(int c); | 检查字母数字字符 | +| \#include <ctype.h> | int isascii(int c); | 检查ASCII | +| \#include <ctype.h> | int isdigit(int c); | 检查数字字符 | +| \#include <ctype.h> | int islower(int c); | 检查小写字符 | +| \#include <ctype.h> | int isprint(int c); | 检查任何可打印字符,包括空格 | +| \#include <ctype.h> | int isspace(int c); | 检查空格字符 | +| \#include <ctype.h> | int isupper(int c); | 检查所传的字符是否是大写字母 | +| \#include <ctype.h> | int isxdigit(int c); | 判断字符是否为十六进制数 | +| \#include <stdlib.h> | long int random (void); | 生成伪随机数 | +| \#include <stdlib.h> | void srandom(unsigned int seed); | 初始化随机数生成器 | +| \#include <ctype.h> | int tolower(int c); | 字母转换成小写 | +| \#include <ctype.h> | int toupper(int c); | 字母转换成大写 | +| \#include <stdarg.h> | type va_arg(va_list ap, type); | 获取可变参数的当前参数,返回指定类型并将指针指向下一参数 | +| \#include <stdarg.h> | void va_copy(va_list dest, va_list src); | 复制参数 | +| \#include <stdarg.h> | void va_end(va_list ap); | 清空va_list可变参数列表 | +| \#include <stdarg.h> | void va_start(va_list ap, last); | 定义变长参数列表的起始位置 | +| \#include <string.h> | char \*strchr(const char \*s, int c); | 在字符串中定位字符 | +| \#include <string.h> | int strcmp(const char \*s1, const char \*s2); | 比较字符串 | +| \#include <string.h> | size_t strcspn(const char \*s, const char \*reject); | 获取前缀子串的长度 | +| \#include <string.h> | char \*strdup(const char \*s); | 字符串拷贝到新建的位置处 | +| \#include <string.h> | size_t strlen(const char \*s); | 计算字符串长度 | +| \#include <strings.h> | int strncasecmp(const char \*s1, const char \*s2, size_t n); | 比较固定长度字符串(忽略大小写) | +| \#include <strings.h> | int strcasecmp(const char \*s1, const char \*s2); | 比较字符串(忽略大小写) | +| \#include <string.h> | int strncmp(const char \*s1, const char \*s2, size_t n); | 比较字符串(指定长度) | +| \#include <string.h> | char \*strrchr(const char \*s, int c); | 在字符串中定位字符 | +| \#include <string.h> | char \*strstr(const char \*haystack, const char \*needle); | 寻找指定的子串 | +| \#include <stdlib.h> | long int strtol(const char \*nptr, char \*\*endptr, int base); | 将字符串转换为long型整数 | +| \#include <stdlib.h> | unsigned long int strtoul(const char \*nptr, char \*\*endptr, int base); | 将字符串转换为unsigned long型整数 | +| \#include <stdlib.h> | unsigned long long int strtoull(const char \*nptr, char \*\*endptr,int base); | 将字符串转换为unsigned long long型整数 | +| \#include <regex.h> | int regcomp(regex_t \*preg, const char \*regex, int cflags); | 编译正则表达式 | +| \#include <regex.h> | int regexec(const regex_t \*preg, const char \*string, size_t nmatch,regmatch_t pmatch[], int eflags); | 匹配正则表达式 | +| \#include <regex.h> | void regfree(regex_t \*preg); | 释放正则表达式 | +| \#include <string.h> | char \*strerror(int errnum); | 返回描述错误号的字符串 | +| math | \#include <stdlib.h> | int abs(int i); | 取绝对值 | +| \#include <math.h> | double log(double x); | 自然对数函数 | +| \#include <math.h> | double pow(double x, double y); | 求x的指数y次幂 | +| \#include <math.h> | double round(double x); | 从零开始,舍入到最接近的整数 | +| \#include <math.h> | double sqrt(double x); | 平方根 | +| IO | \#include <stdio.h> | void clearerr(FILE \*stream); | 清除流的文件结尾和错误指示 | +| \#include <stdio.h> | int fclose(FILE \*stream); | 关闭文件流 | +| \#include <stdio.h> | FILE \*fdopen(int fd, const char \*mode); | 通过文件描述符打开文件流 | +| \#include <stdio.h> | int feof(FILE \*stream); | 检测返回文件末尾指示位 | +| \#include <stdio.h> | int fflush(FILE \*stream); | 刷新流 | +| \#include <stdio.h> | char \*fgets(char \*s, int size, FILE \*stream); | 读取流的下一行 | +| \#include <stdio.h> | int fileno(FILE \*stream); | 返回流的文件描述符 | +| \#include <stdio.h> | FILE \*fopen(const char \*path, const char \*mode); | 打开流 | +| \#include <stdio.h> | int fputs(const char \*s, FILE \*stream); | 向指定流写入一行 | +| \#include <stdio.h> | size_t fread(void \*ptr, size_t size, size_t nmemb, FILE \*stream); | 读一个流 | +| \#include <stdio.h> | int fseek(FILE \*stream, long offset, int whence); | 设置流指针的位置 | +| \#include <stdio.h> | long ftell(FILE \*stream); | 获取流指针的位置 | +| \#include <stdio.h> | size_t fwrite(const void \*ptr, size_t size, size_t nmemb,FILE \*stream); | 向流写入 | +| \#include <stdio.h> | void perror(const char \*s); | 打印系统错误信息 | +| \#include <stdio.h> | void rewind(FILE \*stream); | 重新定位流 | +| \#include <unistd.h> | ssize_t write(int fd, const void \*buf, size_t size); | 写文件内容 | +| \#include <unistd.h> | ssize_t read(int fd, void \*buf, size_t size); | 读文件内容 | +| net | \#include <sys/socket.h> | void freeaddrinfo(struct addrinfo \*res); | 释放调用getaddrinfo所分配的动态内存 | +| \#include <sys/socket.h> | int getaddrinfo(const char \*restrict nodename,const char \*restrict servname,const struct addrinfo \*restrict hints,struct addrinfo \*\*restrict res); | 网络地址和服务转换 | +| \#include <sys/socket.h> | int getnameinfo(const struct sockaddr \*restrict sa, socklen_t salen,char \*restrict node, socklen_t nodelen, char \*restrict service,socklen_t servicelen, int flags); | 以协议无关的方式进行地址到名称的转换 | +| \#include <net/if.h> | unsigned int if_nametoindex(const char \*ifname); | 通过网络接口名得到索引 | +| \#include <arpa/inet.h> | in_addr_t inet_addr(const char \*cp); | 网络主机地址点分十进制形式转换位二进制形式 | +| \#include <arpa/inet.h> | char \*inet_ntoa(struct in_addr in); | 网络主机地址二进制形式转换位点分十进制形式 | +| \#include <arpa/inet.h> | const char \*inet_ntop(int af, const void \*src,char \*dst, socklen_t size); | 网络地址转换 | +| \#include <arpa/inet.h> | int inet_pton(int af, const char \*src, void \*dst); | 网络地址转换 | +| \#include <sys/socket.h> | int listen(int sockfd, int backlog); | 监听套接字 | +| \#include <sys/socket.h> | ssize_t recvmsg(int sockfd, struct msghdr \*msg, int flags); | 从套接字接收消息.只支持iov大小为1的场景,且不支持ancillary消息 | +| \#include <sys/socket.h> | ssize_t send(int sockfd, const void \*buf, size_t len, int flags); | 从socket发送消息 | +| \#include <sys/socket.h> | ssize_t sendmsg(int sockfd, const struct msghdr \*msg, int flags); | 从socket发送消息。不支持ancillary消息 | +| \#include <sys/socket.h> | ssize_t sendto(int sockfd, const void \*buf, size_t len, int flags,const struct sockaddr \*dest_addr, socklen_t addrlen); | 从socket发送消息 | +| \#include <sys/socket.h> | int setsockopt(int sockfd, int level, int optname,const void \*optval, socklen_t optlen); | 设置与套接字关联的选项 | +| mem | \#include <string.h> | int memcmp(const void \*s1, const void \*s2, size_t n); | 内存比较 | +| \#include <string.h> | void \*memcpy(void \*dest, const void \*src, size_t n); | 内存拷贝 | +| \#include <string.h> | void \*memset(void \*s, int c, size_t n); | 内存初始化 | +| \#include <stdlib.h> | void \*realloc(void \*ptr, size_t size); | 重分配内存 | +| \#include <stdlib.h> | void \*malloc(size_t size); | 动态分配内存块大小 | +| \#include <stdlib.h> | void free(void \*ptr); | 释放ptr所指向的内存空间 | +| IPC | \#include <semaphore.h> | int sem_timedwait(sem_t \*sem, const struct timespec \*abs_timeout); | 计时锁定信号量 | +| \#include <semaphore.h> | int sem_destroy(sem_t \*sem); | 销毁指定的无名信号量 | +| \#include <semaphore.h> | int sem_init(sem_t \*sem, int pshared, unsigned int value); | 创建并初始化一个无名信号量 | +| \#include <semaphore.h> | int sem_post(sem_t \*sem); | 增加信号量计数 | +| \#include <semaphore.h> | int sem_wait(sem_t \*sem); | 获取信号量 | +| \#include <mqueue.h> | mqd_t mq_open(const char \*mqName, int openFlag, ...); | 此API用于打开一个具有指定名称的已有消息队列或创建一个新的消息队列 | +| \#include <mqueue.h> | int mq_close(mqd_t personal); | 此API用于关闭具有指定描述符的消息队列 | +| \#include <mqueue.h> | int mq_unlink(const char \*mqName); | 此API用于删除具有指定名称的消息队列 | +| \#include <mqueue.h> | int mq_send(mqd_t personal, const char \*msg, size_t msgLen, unsigned int msgPrio); | 此API用于将具有指定内容和长度的消息放入具有指定描述符的消息队列中 | +| \#include <mqueue.h> | ssize_t mq_receive(mqd_t personal, char \*msg, size_t msgLen, unsigned int \*msgPrio); | 此API用于从具有指定描述符的消息队列中删除最老的消息,并将其放入msg_ptr所指向的缓冲区中 | +| \#include <mqueue.h> | int mq_timedsend(mqd_t personal, const char \*msg, size_t msgLen, unsigned int msgPrio, const struct timespec \*absTimeout) | 此API用于在预定时间将具有指定内容和长度的消息放入具有描述符的消息队列中 | +| \#include <mqueue.h> | ssize_t mq_timedreceive(mqd_t personal, char \*msg, size_t msgLen, unsigned int \*msgPrio, const struct timespec \*absTimeout); | 此API用于从具有指定描述符的消息队列消息中获取具有指定消息内容和长度的消息 | +| \#include <mqueue.h> | int mq_setattr(mqd_t mqdes, const struct mq_attr \*__restrict newattr, struct mq_attr \*__restrict oldattr); | 设置描述符指定的消息队列属性 | +| version | \#include <libc.h> | const char \*libc_get_version_string(void); | 获取libc版本字符串 | +| \#include <libc.h> | int libc_get_version(void); | 获取libc版本号 | -### 注意事项 + +### 注意事项 常用错误码对照表: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

C Name

-

Value

-

Description

-

含义

-

ENOERR

-

0

-

Success

-

成功

-

EPERM

-

1

-

Operation not permitted

-

操作不允许

-

ENOENT

-

2

-

No such file or directory

-

没有这样的文件或目录

-

ESRCH

-

3

-

No such process

-

没有这样的进程(暂不支持)

-

EINTR

-

4

-

Interrupted system call

-

系统调用被中断

-

EIO

-

5

-

I/O error

-

I/O错误

-

ENXIO

-

6

-

No such device or address

-

没有这样的设备或地址

-

E2BIG

-

7

-

Arg list too long

-

参数列表太长

-

ENOEXEC

-

8

-

Exec format error

-

执行格式错误

-

EBADF

-

9

-

Bad file number

-

坏的文件描述符

-

ECHILD

-

10

-

No child processes

-

没有子进程(暂不支持)

-

EAGAIN

-

11

-

Try again

-

资源暂时不可用

-

ENOMEM

-

12

-

Out of memory

-

内存溢出

-

EACCES

-

13

-

Permission denied

-

拒绝许可

-

EFAULT

-

14

-

Bad address

-

错误的地址

-

ENOTBLK

-

15

-

Block device required

-

块设备请求

-

EBUSY

-

16

-

Device or resource busy

-

设备或资源忙

-

EEXIST

-

17

-

File exists

-

文件存在

-

EXDEV

-

18

-

Cross-device link

-

无效的交叉链接

-

ENODEV

-

19

-

No such device

-

设备不存在

-

ENOTDIR

-

20

-

Not a directory

-

不是一个目录

-

EISDIR

-

21

-

Is a directory

-

是一个目录

-

EINVAL

-

22

-

Invalid argument

-

无效的参数

-

ENFILE*

-

23

-

File table overflow

-

打开太多的文件系统

-

EMFILE

-

24

-

Too many open files

-

打开的文件过多

-

EFBIG

-

27

-

File too large

-

文件太大

-

ENOSPC

-

28

-

No space left on device

-

设备上没有空间

-

ESPIPE

-

29

-

Illegal seek

-

非法移位

-

EROFS

-

30

-

Read-only file system

-

只读文件系统

-

EMLINK

-

31

-

Too many links

-

太多的链接

-

EDOM

-

33

-

Math argument out of domain

-

数值结果超出范围

-

ERANGE

-

34

-

Math result not representable

-

数值结果不具代表性

-

EDEADLK

-

35

-

Resource deadlock would occur

-

资源死锁错误

-

ENAMETOOLONG

-

36

-

Filename too long

-

文件名太长

-

ENOLCK

-

37

-

No record locks available

-

没有可用锁

-

ENOSYS

-

38

-

Function not implemented

-

功能没有实现

-

ENOTEMPTY

-

39

-

Directory not empty

-

目录不空

-

ELOOP

-

40

-

Too many symbolic links encountered

-

符号链接层次太多

-

ENOMSG

-

42

-

No message of desired type

-

没有期望类型的消息

-

EIDRM

-

43

-

Identifier removed

-

标识符删除

-

ELNRNG

-

48

-

Link number out of range

-

链接数超出范围

-

EBADR

-

53

-

Invalid request descriptor

-

请求描述符无效

-

EBADRQC

-

56

-

Invalid request code

-

无效的请求代码

-

ENOSTR

-

60

-

Device not a stream

-

设备不是字符流

-

ENODATA

-

61

-

No data available

-

无可用数据

-

ETIME

-

62

-

Timer expired

-

计时器过期

-

EPROTO

-

71

-

Protocol error

-

协议错误

-

EBADMSG

-

74

-

Not a data message

-

非数据消息

-

EOVERFLOW

-

75

-

Value too large for defined data type

-

值太大,对于定义数据类型

-

EMSGSIZE

-

90

-

Message too long

-

消息太长

-
+| C Name | Value | Description | 含义 | +| -------- | -------- | -------- | -------- | +| ENOERR | 0 | Success | 成功 | +| EPERM | 1 | Operation not permitted | 操作不允许 | +| ENOENT | 2 | No such file or directory | 没有这样的文件或目录 | +| ESRCH | 3 | No such process | 没有这样的进程(暂不支持) | +| EINTR | 4 | Interrupted system call | 系统调用被中断 | +| EIO | 5 | I/O error | I/O错误 | +| ENXIO | 6 | No such device or address | 没有这样的设备或地址 | +| E2BIG | 7 | Arg list too long | 参数列表太长 | +| ENOEXEC | 8 | Exec format error | 执行格式错误 | +| EBADF | 9 | Bad file number | 坏的文件描述符 | +| ECHILD | 10 | No child processes | 没有子进程(暂不支持) | +| EAGAIN | 11 | Try again | 资源暂时不可用 | +| ENOMEM | 12 | Out of memory | 内存溢出 | +| EACCES | 13 | Permission denied | 拒绝许可 | +| EFAULT | 14 | Bad address | 错误的地址 | +| ENOTBLK | 15 | Block device required | 块设备请求 | +| EBUSY | 16 | Device or resource busy | 设备或资源忙 | +| EEXIST | 17 | File exists | 文件存在 | +| EXDEV | 18 | Cross-device link | 无效的交叉链接 | +| ENODEV | 19 | No such device | 设备不存在 | +| ENOTDIR | 20 | Not a directory | 不是一个目录 | +| EISDIR | 21 | Is a directory | 是一个目录 | +| EINVAL | 22 | Invalid argument | 无效的参数 | +| ENFILE\* | 23 | File table overflow | 打开太多的文件系统 | +| EMFILE | 24 | Too many open files | 打开的文件过多 | +| EFBIG | 27 | File too large | 文件太大 | +| ENOSPC | 28 | No space left on device | 设备上没有空间 | +| ESPIPE | 29 | Illegal seek | 非法移位 | +| EROFS | 30 | Read-only file system | 只读文件系统 | +| EMLINK | 31 | Too many links | 太多的链接 | +| EDOM | 33 | Math argument out of domain | 数值结果超出范围 | +| ERANGE | 34 | Math result not representable | 数值结果不具代表性 | +| EDEADLK | 35 | Resource deadlock would occur | 资源死锁错误 | +| ENAMETOOLONG | 36 | Filename too long | 文件名太长 | +| ENOLCK | 37 | No record locks available | 没有可用锁 | +| ENOSYS | 38 | Function not implemented | 功能没有实现 | +| ENOTEMPTY | 39 | Directory not empty | 目录不空 | +| ELOOP | 40 | Too many symbolic links encountered | 符号链接层次太多 | +| ENOMSG | 42 | No message of desired type | 没有期望类型的消息 | +| EIDRM | 43 | Identifier removed | 标识符删除 | +| ELNRNG | 48 | Link number out of range | 链接数超出范围 | +| EBADR | 53 | Invalid request descriptor | 请求描述符无效 | +| EBADRQC | 56 | Invalid request code | 无效的请求代码 | +| ENOSTR | 60 | Device not a stream | 设备不是字符流 | +| ENODATA | 61 | No data available | 无可用数据 | +| ETIME | 62 | Timer expired | 计时器过期 | +| EPROTO | 71 | Protocol error | 协议错误 | +| EBADMSG | 74 | Not a data message | 非数据消息 | +| EOVERFLOW | 75 | Value too large for defined data type | 值太大,对于定义数据类型 | +| EMSGSIZE | 90 | Message too long | 消息太长 | + -### 编程实例 +### 编程实例 demo功能: @@ -1635,4 +276,3 @@ void DemoForTest() ++++++++++++++ Hello world ThreadFn tid = 48 ++++++++++++++ ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-appx-lib.md b/zh-cn/device-dev/kernel/kernel-mini-appx-lib.md index 260d8ef24f..ee74f5b789 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-appx-lib.md +++ b/zh-cn/device-dev/kernel/kernel-mini-appx-lib.md @@ -1,7 +1,6 @@ -# 标准库支持 +# 标准库支持 -- **[CMSIS支持](kernel-mini-appx-lib-cmsis.md)** - -- **[POSIX支持](kernel-mini-appx-lib-posix.md)** +- **[CMSIS支持](kernel-mini-appx-lib-cmsis.md)** +- **[POSIX支持](kernel-mini-appx-lib-posix.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-concept.md b/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-concept.md deleted file mode 100644 index 8582b7742a..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-concept.md +++ /dev/null @@ -1,37 +0,0 @@ -# 基本概念 - -在程序运行过程中,出现需要由CPU立即处理的事务时,CPU暂时中止当前程序的执行转而处理这个事务,这个过程叫做中断。当硬件产生中断时,通过中断号查找到其对应的中断处理程序,执行中断处理程序完成中断处理。 - -通过中断机制,在外设不需要CPU介入时,CPU可以执行其它任务;当外设需要CPU时,CPU会中断当前任务来响应中断请求。这样可以使CPU避免把大量时间耗费在等待、查询外设状态的操作上,有效提高系统实时性及执行效率。 - -下面介绍下中断的相关概念: - -- 中断号 - - 中断请求信号特定的标志,计算机能够根据中断号判断是哪个设备提出的中断请求。 - -- 中断请求 - - “紧急事件”向CPU提出申请(发一个电脉冲信号),请求中断,需要CPU暂停当前执行的任务处理该“紧急事件”,这一过程称为中断请求。 - -- 中断优先级 - - 为使系统能够及时响应并处理所有中断,系统根据中断事件的重要性和紧迫程度,将中断源分为若干个级别,称作中断优先级。 - -- 中断处理程序 - - 当外设发出中断请求后,CPU暂停当前的任务,转而响应中断请求,即执行中断处理程序。产生中断的每个设备都有相应的中断处理程序。 - -- 中断触发 - - 中断源向中断控制器发送中断信号,中断控制器对中断进行仲裁,确定优先级,将中断信号发送给CPU。中断源产生中断信号的时候,会将中断触发器置“1”,表明该中断源产生了中断,要求CPU去响应该中断。 - -- 中断向量 - - 中断服务程序的入口地址。 - -- 中断向量表 - - 存储中断向量的存储区,中断向量与中断号对应,中断向量在中断向量表中按照中断号顺序存储。 - - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-guide.md deleted file mode 100644 index 83841bb53c..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt-guide.md +++ /dev/null @@ -1,130 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section11841123033618) -- [编程实例](#section460018317164) - - [结果验证](#section1048572415182) - - -当产生中断请求时,CPU暂停当前的任务,转而去响应外设请求。用户可以根据需要注册对应的中断处理程序,指定CPU响应中断请求时所执行的具体操作。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的中断模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 中断模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建、删除中断

-

HalHwiCreate

-

中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,会调用该中断处理程序。

-

HalHwiDelete

-

根据指定的中断号,删除中断。

-

打开、关闭中断

-

LOS_IntUnLock

-

开中断,使能当前处理器所有中断响应。

-

LOS_IntLock

-

关中断,关闭当前处理器所有中断响应。

-

LOS_IntRestore

-

恢复到使用LOS_IntLock、LOS_IntUnLock操作之前的中断状态。

-
- -## 开发流程 - -1. 调用中断创建接口HalHwiCreate创建中断。 -2. 调用TestHwiTrigger接口触发指定中断(该接口在测试套中定义,通过写中断控制器的相关寄存器模拟外部中断,一般的外设设备,不需要执行这一步)。 -3. 调用HalHwiDelete接口删除指定中断,此接口根据实际情况使用,判断是否需要删除中断。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 根据具体硬件,配置支持的最大中断数及可设置的中断优先级个数。 ->- 中断处理程序耗时不能过长,否则会影响CPU对中断的及时响应。 ->- 中断响应过程中不能直接、间接执行引起调度的LOS\_Schedule等函数。 ->- 中断恢复LOS\_IntRestore\(\)的入参必须是与之对应的LOS\_IntLock\(\)的返回值(即关中断之前的CPSR值)。Cortex-M系列处理器中0-15中断为内部使用,因此不建议用户去申请和创建。 - -## 编程实例 - -本实例实现如下功能: - -1. 创建中断。 -2. 触发中断。 -3. 删除中断。 - -代码实现如下,演示如何创建中断和删除中断,当指定的中断号HWI\_NUM\_TEST产生中断时,会调用中断处理函数: - -``` -#include "los_interrupt.h" - -/*创建中断*/ -#define HWI_NUM_TEST 7 - -STATIC VOID HwiUsrIrq(VOID) -{ - printf("in the func HwiUsrIrq \n"); -} - -static UINT32 Example_Interrupt(VOID) -{ - UINT32 ret; - HWI_PRIOR_T hwiPrio = 3; - HWI_MODE_T mode = 0; - HWI_ARG_T arg = 0; - - /*创建中断*/ - ret = HalHwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, arg); - if(ret == LOS_OK){ - printf("Hwi create success!\n"); - } else { - printf("Hwi create failed!\n"); - return LOS_NOK; - } - - /* 延时50个Ticks, 当有硬件中断发生时,会调用函数HwiUsrIrq*/ - LOS_TaskDelay(50); - - /*删除中断*/ - ret = HalHwiDelete(HWI_NUM_TEST); - if(ret == LOS_OK){ - printf("Hwi delete success!\n"); - } else { - printf("Hwi delete failed!\n"); - return LOS_NOK; - } - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Hwi create success! -Hwi delete success! -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt.md b/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt.md index 71593c41c4..df70260e95 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-interrupt.md @@ -1,7 +1,136 @@ -# 中断管理 +# 中断管理 -- **[基本概念](kernel-mini-basic-interrupt-concept.md)** +- [基本概念](#基本概念) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) +- [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-interrupt-guide.md)** +## 基本概念 +在程序运行过程中,出现需要由CPU立即处理的事务时,CPU暂时中止当前程序的执行转而处理这个事务,这个过程叫做中断。当硬件产生中断时,通过中断号查找到其对应的中断处理程序,执行中断处理程序完成中断处理。 +通过中断机制,在外设不需要CPU介入时,CPU可以执行其它任务;当外设需要CPU时,CPU会中断当前任务来响应中断请求。这样可以使CPU避免把大量时间耗费在等待、查询外设状态的操作上,有效提高系统实时性及执行效率。 + +下面介绍下中断的相关概念: + +- 中断号 + 中断请求信号特定的标志,计算机能够根据中断号判断是哪个设备提出的中断请求。 + +- 中断请求 + “紧急事件”向CPU提出申请(发一个电脉冲信号),请求中断,需要CPU暂停当前执行的任务处理该“紧急事件”,这一过程称为中断请求。 + +- 中断优先级 + 为使系统能够及时响应并处理所有中断,系统根据中断事件的重要性和紧迫程度,将中断源分为若干个级别,称作中断优先级。 + +- 中断处理程序 + 当外设发出中断请求后,CPU暂停当前的任务,转而响应中断请求,即执行中断处理程序。产生中断的每个设备都有相应的中断处理程序。 + +- 中断触发 + 中断源向中断控制器发送中断信号,中断控制器对中断进行仲裁,确定优先级,将中断信号发送给CPU。中断源产生中断信号的时候,会将中断触发器置“1”,表明该中断源产生了中断,要求CPU去响应该中断。 + +- 中断向量 + 中断服务程序的入口地址。 + +- 中断向量表 + 存储中断向量的存储区,中断向量与中断号对应,中断向量在中断向量表中按照中断号顺序存储。 + + +## 接口说明 + +OpenHarmony LiteOS-M内核的中断模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表1** 中断模块接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 创建、删除中断 | HalHwiCreate | 中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,会调用该中断处理程序。 | +| HalHwiDelete | 根据指定的中断号,删除中断。 | +| 打开、关闭中断 | LOS_IntUnLock | 开中断,使能当前处理器所有中断响应。 | +| LOS_IntLock | 关中断,关闭当前处理器所有中断响应。 | +| LOS_IntRestore | 恢复到使用LOS_IntLock、LOS_IntUnLock操作之前的中断状态。 | + + +## 开发流程 + +1. 调用中断创建接口HalHwiCreate创建中断。 + +2. 调用TestHwiTrigger接口触发指定中断(该接口在测试套中定义,通过写中断控制器的相关寄存器模拟外部中断,一般的外设设备,不需要执行这一步)。 + +3. 调用HalHwiDelete接口删除指定中断,此接口根据实际情况使用,判断是否需要删除中断。 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 根据具体硬件,配置支持的最大中断数及可设置的中断优先级个数。 +> +> - 中断处理程序耗时不能过长,否则会影响CPU对中断的及时响应。 +> +> - 中断响应过程中不能直接、间接执行引起调度的LOS_Schedule等函数。 +> +> - 中断恢复LOS_IntRestore()的入参必须是与之对应的LOS_IntLock()的返回值(即关中断之前的CPSR值)。Cortex-M系列处理器中0-15中断为内部使用,因此不建议用户去申请和创建。 + + +## 编程实例 + +本实例实现如下功能: + +1. 创建中断。 + +2. 触发中断。 + +3. 删除中断。 + +代码实现如下,演示如何创建中断和删除中断,当指定的中断号HWI_NUM_TEST产生中断时,会调用中断处理函数: + +``` +#include "los_interrupt.h" + +/*创建中断*/ +#define HWI_NUM_TEST 7 + +STATIC VOID HwiUsrIrq(VOID) +{ + printf("in the func HwiUsrIrq \n"); +} + +static UINT32 Example_Interrupt(VOID) +{ + UINT32 ret; + HWI_PRIOR_T hwiPrio = 3; + HWI_MODE_T mode = 0; + HWI_ARG_T arg = 0; + + /*创建中断*/ + ret = HalHwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, arg); + if(ret == LOS_OK){ + printf("Hwi create success!\n"); + } else { + printf("Hwi create failed!\n"); + return LOS_NOK; + } + + /* 延时50个Ticks, 当有硬件中断发生时,会调用函数HwiUsrIrq*/ + LOS_TaskDelay(50); + + /*删除中断*/ + ret = HalHwiDelete(HWI_NUM_TEST); + if(ret == LOS_OK){ + printf("Hwi delete success!\n"); + } else { + printf("Hwi delete failed!\n"); + return LOS_NOK; + } + return LOS_OK; +} +``` + + +## 结果验证 + +编译运行得到的结果为: + + +``` +Hwi create success! +Hwi delete success! +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md deleted file mode 100644 index 9977d38c76..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-basic.md +++ /dev/null @@ -1,50 +0,0 @@ -# 基本概念 - -- [运行机制](#section1735611583011) - - [事件控制块](#section1161415384467) - - [事件运作原理](#section187761153144617) - - -事件(Event)是一种任务间的通信机制,可用于任务间的同步操作。事件的特点是: - -- 任务间的事件同步,可以一对多,也可以多对多。一对多表示一个任务可以等待多个事件,多对多表示多个任务可以等待多个事件。但是一次写事件最多触发一个任务从阻塞中醒来。 -- 事件读超时机制。 -- 只做任务间同步,不传输具体数据。 - -提供了事件初始化、事件读写、事件清零、事件销毁等接口。 - -## 运行机制 - -### 事件控制块 - -``` -/** - * 事件控制块数据结构 - */ -typedef struct tagEvent { - UINT32 uwEventID; /* 事件集合,表示已经处理(写入和清零)的事件集合 */ - LOS_DL_LIST stEventList; /* 等待特定事件的任务链表 */ -} EVENT_CB_S, *PEVENT_CB_S; -``` - -### 事件运作原理 - -**事件初始化**:会创建一个事件控制块,该控制块维护一个已处理的事件集合,以及等待特定事件的任务链表。 - -**写事件**:会向事件控制块写入指定的事件,事件控制块更新事件集合,并遍历任务链表,根据任务等待具体条件满足情况决定是否唤醒相关任务。 - -**读事件**:如果读取的事件已存在时,会直接同步返回。其他情况会根据超时时间以及事件触发情况,来决定返回时机:等待的事件条件在超时时间耗尽之前到达,阻塞任务会被直接唤醒,否则超时时间耗尽该任务才会被唤醒。 - -读事件条件满足与否取决于入参eventMask和mode,eventMask即需要关注的事件类型掩码。mode是具体处理方式,分以下三种情况: - -- LOS\_WAITMODE\_AND:逻辑与,基于接口传入的事件类型掩码eventMask,只有这些事件都已经发生才能读取成功,否则该任务将阻塞等待或者返回错误码。。 -- LOS\_WAITMODE\_OR:逻辑或,基于接口传入的事件类型掩码eventMask,只要这些事件中有任一种事件发生就可以读取成功,否则该任务将阻塞等待或者返回错误码。 -- LOS\_WAITMODE\_CLR:这是一种附加读取模式,需要与所有事件模式或任一事件模式结合使用(LOS\_WAITMODE\_AND | LOS\_WAITMODE\_CLR或 LOS\_WAITMODE\_OR | LOS\_WAITMODE\_CLR)。在这种模式下,当设置的所有事件模式或任一事件模式读取成功后,会自动清除事件控制块中对应的事件类型位。 - -**事件清零**:根据指定掩码,去对事件控制块的事件集合进行清零操作。当掩码为0时,表示将事件集合全部清零。当掩码为0xffff时,表示不清除任何事件,保持事件集合原状。 - -**事件销毁**:销毁指定的事件控制块。 - -**图 1** 事件运作原理图 -![](figure/事件运作原理图.png "事件运作原理图") - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md deleted file mode 100644 index 91a6c20c0e..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event-guide.md +++ /dev/null @@ -1,194 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section896412438910) - - [示例代码](#section149077554912) - - [结果验证](#section4461439172017) - - -## 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

事件检测

-

LOS_EventPoll

-

根据eventID,eventMask(事件掩码),mode(事件读取模式),检查用户期待的事件是否发生。

-
须知:

当mode含LOS_WAITMODE_CLR,且用户期待的事件发生时,此时eventID中满足要求的事件会被清零,这种情况下eventID既是入参也是出参。其他情况eventID只作为入参。

-
-

初始化

-

LOS_EventInit

-

事件控制块初始化。

-

事件读

-

LOS_EventRead

-

读事件(等待事件),任务会根据timeOut(单位:tick)进行阻塞等待;

-

未读取到事件时,返回值为0;

-

正常读取到事件时,返回正值(事件发生的集合);

-

其他情况返回特定错误码。

-

事件写

-

LOS_EventWrite

-

写一个特定的事件到事件控制块。

-

事件清除

-

LOS_EventClear

-

根据events掩码,清除事件控制块中的事件。

-

事件销毁

-

LOS_EventDestroy

-

事件控制块销毁。

-
- -## 开发流程 - -事件的典型开发流程: - -1. 初始化事件控制块 -2. 阻塞读事件控制块 -3. 写入相关事件 -4. 阻塞任务被唤醒,读取事件并检查是否满足要求 -5. 处理事件控制块 -6. 事件控制块销毁 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 进行事件读写操作时,事件的第25位为保留位,不可以进行位设置。 ->- 对同一事件反复写入,算作一次写入。 - -## 编程实例 - -### 实例描述 - -示例中,任务Example\_TaskEntry创建一个任务Example\_Event,Example\_Event读事件阻塞,Example\_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。 - -1. 在任务Example\_TaskEntry创建任务Example\_Event,其中任务Example\_Event优先级高于Example\_TaskEntry。 -2. 在任务Example\_Event中读事件0x00000001,阻塞,发生任务切换,执行任务Example\_TaskEntry。 -3. 在任务Example\_TaskEntry向任务Example\_Event写事件0x00000001,发生任务切换,执行任务Example\_Event。 -4. Example\_Event得以执行,直到任务结束。 -5. Example\_TaskEntry得以执行,直到任务结束。 - -### 示例代码 - -示例代码如下: - -``` -#include "los_event.h" -#include "los_task.h" -#include "securec.h" - -/* 任务ID */ -UINT32 g_testTaskId; - -/* 事件控制结构体 */ -EVENT_CB_S g_exampleEvent; - -/* 等待的事件类型 */ -#define EVENT_WAIT 0x00000001 - -/* 用例任务入口函数 */ -VOID Example_Event(VOID) -{ - UINT32 ret; - UINT32 event; - - /* 超时等待方式读事件,超时时间为100 ticks, 若100 ticks后未读取到指定事件,读事件超时,任务直接唤醒 */ - printf("Example_Event wait event 0x%x \n", EVENT_WAIT); - - event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); - if (event == EVENT_WAIT) { - printf("Example_Event,read event :0x%x\n", event); - } else { - printf("Example_Event,read event timeout\n"); - } -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - - /* 事件初始化 */ - ret = LOS_EventInit(&g_exampleEvent); - if (ret != LOS_OK) { - printf("init event failed .\n"); - return -1; - } - - /* 创建任务 */ - (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; - task1.pcName = "EventTsk1"; - task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId, &task1); - if (ret != LOS_OK) { - printf("task create failed.\n"); - return LOS_NOK; - } - - /* 写g_testTaskId 等待事件 */ - printf("Example_TaskEntry write event.\n"); - - ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); - if (ret != LOS_OK) { - printf("event write failed.\n"); - return LOS_NOK; - } - - /* 清标志位 */ - printf("EventMask:%d\n", g_exampleEvent.uwEventID); - LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); - printf("EventMask:%d\n", g_exampleEvent.uwEventID); - - /* 删除任务 */ - ret = LOS_TaskDelete(g_testTaskId); - if (ret != LOS_OK) { - printf("task delete failed.\n"); - return LOS_NOK; - } - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Example_Event wait event 0x1 -Example_TaskEntry write event. -Example_Event,read event :0x1 -EventMask:1 -EventMask:0 -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event.md index 9b774e1193..0cf23cf329 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-event.md @@ -1,7 +1,216 @@ -# 事件 +# 事件 -- **[基本概念](kernel-mini-basic-ipc-event-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [事件控制块](#事件控制块) + - [事件运作原理](#事件运作原理) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-ipc-event-guide.md)** +## 基本概念 +事件(Event)是一种任务间的通信机制,可用于任务间的同步操作。事件的特点是: +- 任务间的事件同步,可以一对多,也可以多对多。一对多表示一个任务可以等待多个事件,多对多表示多个任务可以等待多个事件。但是一次写事件最多触发一个任务从阻塞中醒来。 + +- 事件读超时机制。 + +- 只做任务间同步,不传输具体数据。 + +提供了事件初始化、事件读写、事件清零、事件销毁等接口。 + + +## 运行机制 + + +### 事件控制块 + +``` +/** + * 事件控制块数据结构 + */ +typedef struct tagEvent { + UINT32 uwEventID; /* 事件集合,表示已经处理(写入和清零)的事件集合 */ + LOS_DL_LIST stEventList; /* 等待特定事件的任务链表 */ +} EVENT_CB_S, *PEVENT_CB_S; +``` + + +### 事件运作原理 + +**事件初始化**:会创建一个事件控制块,该控制块维护一个已处理的事件集合,以及等待特定事件的任务链表。 + +**写事件**:会向事件控制块写入指定的事件,事件控制块更新事件集合,并遍历任务链表,根据任务等待具体条件满足情况决定是否唤醒相关任务。 + +**读事件**:如果读取的事件已存在时,会直接同步返回。其他情况会根据超时时间以及事件触发情况,来决定返回时机:等待的事件条件在超时时间耗尽之前到达,阻塞任务会被直接唤醒,否则超时时间耗尽该任务才会被唤醒。 + +读事件条件满足与否取决于入参eventMask和mode,eventMask即需要关注的事件类型掩码。mode是具体处理方式,分以下三种情况: + +- LOS_WAITMODE_AND:逻辑与,基于接口传入的事件类型掩码eventMask,只有这些事件都已经发生才能读取成功,否则该任务将阻塞等待或者返回错误码。 + +- LOS_WAITMODE_OR:逻辑或,基于接口传入的事件类型掩码eventMask,只要这些事件中有任一种事件发生就可以读取成功,否则该任务将阻塞等待或者返回错误码。 + +- LOS_WAITMODE_CLR:这是一种附加读取模式,需要与所有事件模式或任一事件模式结合使用(LOS_WAITMODE_AND | LOS_WAITMODE_CLR或 LOS_WAITMODE_OR | LOS_WAITMODE_CLR)。在这种模式下,当设置的所有事件模式或任一事件模式读取成功后,会自动清除事件控制块中对应的事件类型位。 + +**事件清零**:根据指定掩码,去对事件控制块的事件集合进行清零操作。当掩码为0时,表示将事件集合全部清零。当掩码为0xffff时,表示不清除任何事件,保持事件集合原状。 + +**事件销毁**:销毁指定的事件控制块。 + +**图1** 轻量系统事件运作原理图 +![zh-cn_image_0000001200771972](figures/zh-cn_image_0000001200771972.png) + + +## 接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 事件检测 | LOS_EventPoll | 根据eventID,eventMask(事件掩码),mode(事件读取模式),检查用户期待的事件是否发生。
> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:**
> 当mode含LOS_WAITMODE_CLR,且用户期待的事件发生时,此时eventID中满足要求的事件会被清零,这种情况下eventID既是入参也是出参。其他情况eventID只作为入参。 | +| 初始化 | LOS_EventInit | 事件控制块初始化。 | +| 事件读 | LOS_EventRead | 读事件(等待事件),任务会根据timeOut(单位:tick)进行阻塞等待;
未读取到事件时,返回值为0;
正常读取到事件时,返回正值(事件发生的集合);
其他情况返回特定错误码。 | +| 事件写 | LOS_EventWrite | 写一个特定的事件到事件控制块。 | +| 事件清除 | LOS_EventClear | 根据events掩码,清除事件控制块中的事件。 | +| 事件销毁 | LOS_EventDestroy | 事件控制块销毁。 | + + +## 开发流程 + +事件的典型开发流程: + +1. 初始化事件控制块 + +2. 阻塞读事件控制块 + +3. 写入相关事件 + +4. 阻塞任务被唤醒,读取事件并检查是否满足要求 + +5. 处理事件控制块 + +6. 事件控制块销毁 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 进行事件读写操作时,事件的第25位为保留位,不可以进行位设置。 +> +> - 对同一事件反复写入,算作一次写入。 + + +## 编程实例 + + +### 实例描述 + +示例中,任务Example_TaskEntry创建一个任务Example_Event,Example_Event读事件阻塞,Example_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。 + +1. 在任务Example_TaskEntry创建任务Example_Event,其中任务Example_Event优先级高于Example_TaskEntry。 + +2. 在任务Example_Event中读事件0x00000001,阻塞,发生任务切换,执行任务Example_TaskEntry。 + +3. 在任务Example_TaskEntry向任务Example_Event写事件0x00000001,发生任务切换,执行任务Example_Event。 + +4. Example_Event得以执行,直到任务结束。 + +5. Example_TaskEntry得以执行,直到任务结束。 + + +### 示例代码 + +示例代码如下: + +``` +#include "los_event.h" +#include "los_task.h" +#include "securec.h" + +/* 任务ID */ +UINT32 g_testTaskId; + +/* 事件控制结构体 */ +EVENT_CB_S g_exampleEvent; + +/* 等待的事件类型 */ +#define EVENT_WAIT 0x00000001 + +/* 用例任务入口函数 */ +VOID Example_Event(VOID) +{ + UINT32 ret; + UINT32 event; + + /* 超时等待方式读事件,超时时间为100 ticks, 若100 ticks后未读取到指定事件,读事件超时,任务直接唤醒 */ + printf("Example_Event wait event 0x%x \n", EVENT_WAIT); + + event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, 100); + if (event == EVENT_WAIT) { + printf("Example_Event,read event :0x%x\n", event); + } else { + printf("Example_Event,read event timeout\n"); + } +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + + /* 事件初始化 */ + ret = LOS_EventInit(&g_exampleEvent); + if (ret != LOS_OK) { + printf("init event failed .\n"); + return -1; + } + + /* 创建任务 */ + (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Event; + task1.pcName = "EventTsk1"; + task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId, &task1); + if (ret != LOS_OK) { + printf("task create failed.\n"); + return LOS_NOK; + } + + /* 写g_testTaskId 等待事件 */ + printf("Example_TaskEntry write event.\n"); + + ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); + if (ret != LOS_OK) { + printf("event write failed.\n"); + return LOS_NOK; + } + + /* 清标志位 */ + printf("EventMask:%d\n", g_exampleEvent.uwEventID); + LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); + printf("EventMask:%d\n", g_exampleEvent.uwEventID); + + /* 删除任务 */ + ret = LOS_TaskDelete(g_testTaskId); + if (ret != LOS_OK) { + printf("task delete failed.\n"); + return LOS_NOK; + } + + return LOS_OK; +} +``` + + +### 结果验证 + +编译运行得到的结果为: + + +``` +Example_Event wait event 0x1 +Example_TaskEntry write event. +Example_Event,read event :0x1 +EventMask:1 +EventMask:0 +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md deleted file mode 100644 index 1d29734624..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-basic.md +++ /dev/null @@ -1,19 +0,0 @@ -# 基本概念 - -- [运行机制](#section115161649726) - -互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。 - -任意时刻互斥锁的状态只有两种,开锁或闭锁。当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。当该任务释放它时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。 - -多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。另外互斥锁可以解决信号量存在的优先级翻转问题。 - -## 运行机制 - -多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? - -用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 - -**图 1** 互斥锁运作示意图 -![](figure/互斥锁运作示意图.png "互斥锁运作示意图") - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md deleted file mode 100644 index 053174daa3..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex-guide.md +++ /dev/null @@ -1,205 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section1426719434114) - - [实例描述](#section896412438910) - - [示例代码](#section149077554912) - - [结果验证](#section2059413981311) - - -## 接口说明 - -**表 1** 互斥锁模块接口 - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

互斥锁的创建和删除

-

LOS_MuxCreate

-

创建互斥锁

-

LOS_MuxDelete

-

删除指定的互斥锁

-

互斥锁的申请和释放

-

LOS_MuxPend

-

申请指定的互斥锁

-

LOS_MuxPost

-

释放指定的互斥锁

-
- -## 开发流程 - -互斥锁典型场景的开发流程: - -1. 创建互斥锁LOS\_MuxCreate。 -2. 申请互斥锁LOS\_MuxPend。 - - 申请模式有三种:无阻塞模式、永久阻塞模式、定时阻塞模式。 - - - 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功。 - - 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行。 - - 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用户指定时间超时后,阻塞任务才会重新得以执行。 - -3. 释放互斥锁LOS\_MuxPost。 - - 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; - - 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。 - -4. 删除互斥锁LOS\_MuxDelete。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 ->- 互斥锁不能在中断服务程序中使用。 ->- LiteOS-M内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 ->- 持有互斥锁的过程中,不得再调用LOS\_TaskPriSet等接口更改持有互斥锁任务的优先级。 - -## 编程实例 - -### 实例描述 - -本实例实现如下流程。 - -1. 任务Example\_TaskEntry创建一个互斥锁,锁任务调度,创建两个任务Example\_MutexTask1、Example\_MutexTask2。Example\_MutexTask2优先级高于Example\_MutexTask1,解锁任务调度。 -2. Example\_MutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,Example\_MutexTask2挂起,Example\_MutexTask1被唤醒。 -3. Example\_MutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。10Tick超时时间到达后,Example\_MutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。 -4. 100Tick休眠时间到达后,Example\_MutexTask2被唤醒, 释放互斥锁,唤醒Example\_MutexTask1。Example\_MutexTask1成功获取到互斥锁后,释放,删除互斥锁。 - -### 示例代码 - -示例代码如下: - -``` -#include -#include "los_mux.h" - -/* 互斥锁句柄id */ -UINT32 g_testMux; -/* 任务ID */ -UINT32 g_testTaskId01; -UINT32 g_testTaskId02; - -VOID Example_MutexTask1(VOID) -{ - UINT32 ret; - - printf("task1 try to get mutex, wait 10 ticks.\n"); - /* 申请互斥锁 */ - ret = LOS_MuxPend(g_testMux, 10); - - if (ret == LOS_OK) { - printf("task1 get mutex g_testMux.\n"); - /* 释放互斥锁 */ - LOS_MuxPost(g_testMux); - return; - } - if (ret == LOS_ERRNO_MUX_TIMEOUT ) { - printf("task1 timeout and try to get mutex, wait forever.\n"); - /* 申请互斥锁 */ - ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); - if (ret == LOS_OK) { - printf("task1 wait forever, get mutex g_testMux.\n"); - /* 释放互斥锁 */ - LOS_MuxPost(g_testMux); - /* 删除互斥锁 */ - LOS_MuxDelete(g_testMux); - printf("task1 post and delete mutex g_testMux.\n"); - return; - } - } - return; -} - -VOID Example_MutexTask2(VOID) -{ - printf("task2 try to get mutex, wait forever.\n"); - /* 申请互斥锁 */ - (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); - - printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); - - /* 任务休眠100Ticks */ - LOS_TaskDelay(100); - - printf("task2 resumed and post the g_testMux\n"); - /* 释放互斥锁 */ - LOS_MuxPost(g_testMux); - return; -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - TSK_INIT_PARAM_S task2; - - /* 创建互斥锁 */ - LOS_MuxCreate(&g_testMux); - - /* 锁任务调度 */ - LOS_TaskLock(); - - /* 创建任务1 */ - memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; - task1.pcName = "MutexTsk1"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("task1 create failed.\n"); - return LOS_NOK; - } - - /* 创建任务2 */ - memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); - task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; - task2.pcName = "MutexTsk2"; - task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task2.usTaskPrio = 4; - ret = LOS_TaskCreate(&g_testTaskId02, &task2); - if (ret != LOS_OK) { - printf("task2 create failed.\n"); - return LOS_NOK; - } - - /* 解锁任务调度 */ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -task2 try to get mutex, wait forever. -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. -task2 resumed and post the g_testMux -task1 wait forever, get mutex g_testMux. -task1 post and delete mutex g_testMux. -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex.md index e76ed0a791..bf14d0c579 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-mutex.md @@ -1,7 +1,205 @@ -# 互斥锁 +# 互斥锁 -- **[基本概念](kernel-mini-basic-ipc-mutex-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-ipc-mutex-guide.md)** +## 基本概念 +互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。 +任意时刻互斥锁的状态只有两种,开锁或闭锁。当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。当该任务释放它时,该互斥锁被开锁,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。 + +多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。另外互斥锁可以解决信号量存在的优先级翻转问题。 + + +## 运行机制 + +多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? + +用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 + +**图1** 轻量系统互斥锁运作示意图 +![zh-cn_image_0000001245411845](figures/zh-cn_image_0000001245411845.png) + + +## 接口说明 + +**表1** 互斥锁模块接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 互斥锁的创建和删除 | LOS_MuxCreate | 创建互斥锁 | +| LOS_MuxDelete | 删除指定的互斥锁 | +| 互斥锁的申请和释放 | LOS_MuxPend | 申请指定的互斥锁 | +| LOS_MuxPost | 释放指定的互斥锁 | + + +## 开发流程 + +互斥锁典型场景的开发流程: + +1. 创建互斥锁LOS_MuxCreate。 + +2. 申请互斥锁LOS_MuxPend。 + 申请模式有三种:无阻塞模式、永久阻塞模式、定时阻塞模式。 + + - 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功。 + - 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行。 + - 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用户指定时间超时后,阻塞任务才会重新得以执行。 + +3. 释放互斥锁LOS_MuxPost。 + - 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; + - 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。 + +4. 删除互斥锁LOS_MuxDelete。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 +> +> - 互斥锁不能在中断服务程序中使用。 +> +> - LiteOS-M内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 +> +> - 持有互斥锁的过程中,不得再调用LOS_TaskPriSet等接口更改持有互斥锁任务的优先级。 + + +## 编程实例 + + +### 实例描述 + +本实例实现如下流程。 + +1. 任务Example_TaskEntry创建一个互斥锁,锁任务调度,创建两个任务Example_MutexTask1、Example_MutexTask2。Example_MutexTask2优先级高于Example_MutexTask1,解锁任务调度。 + +2. Example_MutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,Example_MutexTask2挂起,Example_MutexTask1被唤醒。 + +3. Example_MutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被Example_MutexTask2持有,Example_MutexTask1挂起。10Tick超时时间到达后,Example_MutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被Example_MutexTask2持有,Example_MutexTask1挂起。 + +4. 100Tick休眠时间到达后,Example_MutexTask2被唤醒, 释放互斥锁,唤醒Example_MutexTask1。Example_MutexTask1成功获取到互斥锁后,释放,删除互斥锁。 + + +### 示例代码 + +示例代码如下: + +``` +#include +#include "los_mux.h" + +/* 互斥锁句柄id */ +UINT32 g_testMux; +/* 任务ID */ +UINT32 g_testTaskId01; +UINT32 g_testTaskId02; + +VOID Example_MutexTask1(VOID) +{ + UINT32 ret; + + printf("task1 try to get mutex, wait 10 ticks.\n"); + /* 申请互斥锁 */ + ret = LOS_MuxPend(g_testMux, 10); + + if (ret == LOS_OK) { + printf("task1 get mutex g_testMux.\n"); + /* 释放互斥锁 */ + LOS_MuxPost(g_testMux); + return; + } + if (ret == LOS_ERRNO_MUX_TIMEOUT ) { + printf("task1 timeout and try to get mutex, wait forever.\n"); + /* 申请互斥锁 */ + ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); + if (ret == LOS_OK) { + printf("task1 wait forever, get mutex g_testMux.\n"); + /* 释放互斥锁 */ + LOS_MuxPost(g_testMux); + /* 删除互斥锁 */ + LOS_MuxDelete(g_testMux); + printf("task1 post and delete mutex g_testMux.\n"); + return; + } + } + return; +} + +VOID Example_MutexTask2(VOID) +{ + printf("task2 try to get mutex, wait forever.\n"); + /* 申请互斥锁 */ + (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER); + + printf("task2 get mutex g_testMux and suspend 100 ticks.\n"); + + /* 任务休眠100Ticks */ + LOS_TaskDelay(100); + + printf("task2 resumed and post the g_testMux\n"); + /* 释放互斥锁 */ + LOS_MuxPost(g_testMux); + return; +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + TSK_INIT_PARAM_S task2; + + /* 创建互斥锁 */ + LOS_MuxCreate(&g_testMux); + + /* 锁任务调度 */ + LOS_TaskLock(); + + /* 创建任务1 */ + memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1; + task1.pcName = "MutexTsk1"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("task1 create failed.\n"); + return LOS_NOK; + } + + /* 创建任务2 */ + memset(&task2, 0, sizeof(TSK_INIT_PARAM_S)); + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2; + task2.pcName = "MutexTsk2"; + task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task2.usTaskPrio = 4; + ret = LOS_TaskCreate(&g_testTaskId02, &task2); + if (ret != LOS_OK) { + printf("task2 create failed.\n"); + return LOS_NOK; + } + + /* 解锁任务调度 */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + + +### 结果验证 + +编译运行得到的结果为: +``` +task2 try to get mutex, wait forever. +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. +task2 resumed and post the g_testMux +task1 wait forever, get mutex g_testMux. +task1 post and delete mutex g_testMux. +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md deleted file mode 100644 index 06f38749de..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-basic.md +++ /dev/null @@ -1,67 +0,0 @@ -# 基本概念 - -- [运行机制](#section1582619446311) - - [队列控制块](#section1648304614720) - - [队列运作原理](#section15384012164811) - - -队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 - -任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时,挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。 - -可以通过调整读队列和写队列的超时时间来调整读写接口的阻塞模式,如果将读队列和写队列的超时时间设置为0,就不会挂起任务,接口会直接返回,这就是非阻塞模式。反之,如果将都队列和写队列的超时时间设置为大于0的时间,就会以阻塞模式运行。 - -消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用,可以使用队列实现任务异步通信,队列具有如下特性: - -- 消息以先进先出的方式排队,支持异步读写。 -- 读队列和写队列都支持超时机制。 -- 每读取一条消息,就会将该消息节点设置为空闲。 -- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列的消息节点大小)的消息。 -- 一个任务能够从任意一个消息队列接收和发送消息。 -- 多个任务能够从同一个消息队列接收和发送消息。 -- 创建队列时所需的队列空间,接口内系统自行动态申请内存。 - -## 运行机制 - -### 队列控制块 - -``` -/** - * 队列控制块数据结构 - */ -typedef struct -{ - UINT8 *queue; /* 队列消息内存空间的指针 */ - UINT16 queueState; /* 队列状态 */ - UINT16 queueLen; /* 队列中消息节点个数,即队列长度 */ - UINT16 queueSize; /* 消息节点大小 */ - UINT16 queueID; /* 队列ID */ - UINT16 queueHead; /* 消息头节点位置(数组下标)*/ - UINT16 queueTail; /* 消息尾节点位置(数组下标)*/ - UINT16 readWriteableCnt[OS_READWRITE_LEN]; /* 数组下标0的元素表示队列中可读消息数, - 数组下标1的元素表示队列中可写消息数 */ - LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /* 读取或写入消息的任务等待链表, - 下标0:读取链表,下标1:写入链表 */ - LOS_DL_LIST memList; /* 内存块链表 */ -} LosQueueCB; -``` - -每个队列控制块中都含有队列状态,表示该队列的使用情况: - -- OS\_QUEUE\_UNUSED:队列未被使用。 -- OS\_QUEUE\_INUSED:队列被使用中。 - -### 队列运作原理 - -- 创建队列时,创建队列成功会返回队列ID。 -- 在队列控制块中维护着一个消息头节点位置Head和一个消息尾节点位置Tail,用于表示当前队列中消息的存储情况。Head表示队列中被占用的消息节点的起始位置。Tail表示被占用的消息节点的结束位置,也是空闲消息节点的起始位置。队列刚创建时,Head和Tail均指向队列起始位置。 -- 写队列时,根据readWriteableCnt\[1\]判断队列是否可以写入,不能对已满(readWriteableCnt\[1\]为0)队列进行写操作。写队列支持两种写入方式:向队列尾节点写入,也可以向队列头节点写入。尾节点写入时,根据Tail找到起始空闲消息节点作为数据写入对象,如果Tail已经指向队列尾部则采用回卷方式。头节点写入时,将Head的前一个节点作为数据写入对象,如果Head指向队列起始位置则采用回卷方式。 -- 读队列时,根据readWriteableCnt\[0\]判断队列是否有消息需要读取,对全部空闲(readWriteableCnt\[0\]为0)队列进行读操作会引起任务挂起。如果队列可以读取消息,则根据Head找到最先写入队列的消息节点进行读取。如果Head已经指向队列尾部则采用回卷方式。 -- 删除队列时,根据队列ID找到对应队列,把队列状态置为未使用,把队列控制块置为初始状态,并释放队列所占内存。 - -图 1 队列读写数据操作示意图 - -![](figure/zh-cn_image_0000001132935054.png) - -上图对读写队列做了示意,图中只画了尾节点写入方式,没有画头节点写入,但是两者是类似的。 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md deleted file mode 100644 index b1b9570e18..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue-guide.md +++ /dev/null @@ -1,198 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section2148236125814) - - [示例代码](#section121451047155716) - - [结果验证](#section2742182082117) - - -## 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建/删除消息队列

-

LOS_QueueCreate

-

创建一个消息队列,由系统动态申请队列空间。

-

LOS_QueueDelete

-

根据队列ID删除一个指定队列。

-

读/写队列(不带拷贝)

-

LOS_QueueRead

-

读取指定队列头节点中的数据(队列节点中的数据实际上是一个地址)。

-

LOS_QueueWrite

-

向指定队列尾节点中写入入参bufferAddr的值(即buffer的地址)。

-

LOS_QueueWriteHead

-

向指定队列头节点中写入入参bufferAddr的值(即buffer的地址)。

-

读/写队列(带拷贝)

-

LOS_QueueReadCopy

-

读取指定队列头节点中的数据。

-

LOS_QueueWriteCopy

-

向指定队列尾节点中写入入参bufferAddr中保存的数据。

-

LOS_QueueWriteHeadCopy

-

向指定队列头节点中写入入参bufferAddr中保存的数据。

-

获取队列信息

-

LOS_QueueInfoGet

-

获取指定队列的信息,包括队列ID、队列长度、消息节点大小、头节点、尾节点、可读节点数量、可写节点数量、等待读操作的任务、等待写操作的任务。

-
- -## 开发流程 - -1. 用LOS\_QueueCreate创建队列。创建成功后,可以得到队列ID。 -2. 通过LOS\_QueueWrite或者LOS\_QueueWriteCopy写队列。 -3. 通过LOS\_QueueRead或者LOS\_QueueReadCopy读队列。 -4. 通过LOS\_QueueInfoGet获取队列信息。 -5. 通过LOS\_QueueDelete删除队列。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 系统支持的最大队列数是指:整个系统的队列资源总个数,而非用户能使用的个数。例如:系统软件定时器多占用一个队列资源,那么用户能使用的队列资源就会减少一个。 ->- 创建队列时传入的队列名和flags暂时未使用,作为以后的预留参数。 ->- 队列接口函数中的入参timeOut是相对时间。 ->- LOS\_QueueReadCopy和LOS\_QueueWriteCopy及LOS\_QueueWriteHeadCopy是一组接口,LOS\_QueueRead和LOS\_QueueWrite及LOS\_QueueWriteHead是一组接口,每组接口需要配套使用。 ->- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,用户必须保证调用LOS\_QueueRead获取到的指针所指向的内存区域在读队列期间没有被异常修改或释放,否则可能导致不可预知的后果。 ->- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,也就意味着实际写和读的消息长度仅仅是一个指针数据,因此用户使用这组接口之前,需确保创建队列时的消息节点大小,为一个指针的长度,避免不必要的浪费和读取失败。 - -## 编程实例 - -### 实例描述 - -创建一个队列,两个任务。任务1调用写队列接口发送消息,任务2通过读队列接口接收消息。 - -1. 通过LOS\_TaskCreate创建任务1和任务2。 -2. 通过LOS\_QueueCreate创建一个消息队列。 -3. 在任务1 SendEntry中发送消息。 -4. 在任务2 RecvEntry中接收消息。 -5. 通过LOS\_QueueDelete删除队列。 - -### 示例代码 - -示例代码如下: - -``` -#include "los_task.h" -#include "los_queue.h" -static UINT32 g_queue; -#define BUFFER_LEN 50 - -VOID SendEntry(VOID) -{ - UINT32 ret = 0; - CHAR abuf[] = "test message"; - UINT32 len = sizeof(abuf); - - ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); - if(ret != LOS_OK) { - printf("Failed to send the message. Error: %x\n", ret); - } -} - -VOID RecvEntry(VOID) -{ - UINT32 ret = 0; - CHAR readBuf[BUFFER_LEN] = {0}; - UINT32 readLen = BUFFER_LEN; - - ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); - if(ret != LOS_OK) { - printf("Failed to receive the message. Error: %x\n", ret); - } - - printf("Message received: %s\n", readBuf); - - ret = LOS_QueueDelete(g_queue); - if(ret != LOS_OK) { - printf("Failed to delete the queue. Error: %x\n", ret); - } - - printf("Queue deleted.\n"); -} - -UINT32 ExampleQueue(VOID) -{ - printf("Start queue example.\n"); - UINT32 ret = 0; - UINT32 task1, task2; - TSK_INIT_PARAM_S initParam = {0}; - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; - initParam.usTaskPrio = 9; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - initParam.pcName = "SendQueue"; - - LOS_TaskLock(); - ret = LOS_TaskCreate(&task1, &initParam); - if(ret != LOS_OK) { - printf("Failed to create task1. Error: %x\n", ret); - return ret; - } - - initParam.pcName = "RecvQueue"; - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; - initParam.usTaskPrio = 10; - ret = LOS_TaskCreate(&task2, &initParam); - if(ret != LOS_OK) { - printf("Failed to create task2. Error: %x\n", ret); - return ret; - } - - ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); - if(ret != LOS_OK) { - printf("Failed to create the queue. Error: %x\n", ret); - } - - printf("Queue created.\n"); - LOS_TaskUnlock(); - return ret; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -Start queue example. -Queue created. -Message received: test message. -Queue deleted. -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue.md index fa56e6878a..7af723e817 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-queue.md @@ -1,7 +1,245 @@ -# 消息队列 +# 消息队列 -- **[基本概念](kernel-mini-basic-ipc-queue-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [队列控制块](#队列控制块) + - [队列运作原理](#队列运作原理) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-ipc-queue-guide.md)** +## 基本概念 +队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 +任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时,挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。 + +可以通过调整读队列和写队列的超时时间来调整读写接口的阻塞模式,如果将读队列和写队列的超时时间设置为0,就不会挂起任务,接口会直接返回,这就是非阻塞模式。反之,如果将都队列和写队列的超时时间设置为大于0的时间,就会以阻塞模式运行。 + +消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用,可以使用队列实现任务异步通信,队列具有如下特性: + +- 消息以先进先出的方式排队,支持异步读写。 + +- 读队列和写队列都支持超时机制。 + +- 每读取一条消息,就会将该消息节点设置为空闲。 + +- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列的消息节点大小)的消息。 + +- 一个任务能够从任意一个消息队列接收和发送消息。 + +- 多个任务能够从同一个消息队列接收和发送消息。 + +- 创建队列时所需的队列空间,接口内系统自行动态申请内存。 + + +## 运行机制 + + +### 队列控制块 + +``` +/** + * 队列控制块数据结构 + */ +typedef struct +{ + UINT8 *queue; /* 队列消息内存空间的指针 */ + UINT16 queueState; /* 队列状态 */ + UINT16 queueLen; /* 队列中消息节点个数,即队列长度 */ + UINT16 queueSize; /* 消息节点大小 */ + UINT16 queueID; /* 队列ID */ + UINT16 queueHead; /* 消息头节点位置(数组下标)*/ + UINT16 queueTail; /* 消息尾节点位置(数组下标)*/ + UINT16 readWriteableCnt[OS_READWRITE_LEN]; /* 数组下标0的元素表示队列中可读消息数, + 数组下标1的元素表示队列中可写消息数 */ + LOS_DL_LIST readWriteList[OS_READWRITE_LEN]; /* 读取或写入消息的任务等待链表, + 下标0:读取链表,下标1:写入链表 */ + LOS_DL_LIST memList; /* 内存块链表 */ +} LosQueueCB; +``` + +每个队列控制块中都含有队列状态,表示该队列的使用情况: + +- OS_QUEUE_UNUSED:队列未被使用。 + +- OS_QUEUE_INUSED:队列被使用中。 + + +### 队列运作原理 + +- 创建队列时,创建队列成功会返回队列ID。 + +- 在队列控制块中维护着一个消息头节点位置Head和一个消息尾节点位置Tail,用于表示当前队列中消息的存储情况。Head表示队列中被占用的消息节点的起始位置。Tail表示被占用的消息节点的结束位置,也是空闲消息节点的起始位置。队列刚创建时,Head和Tail均指向队列起始位置。 + +- 写队列时,根据readWriteableCnt[1]判断队列是否可以写入,不能对已满(readWriteableCnt[1]为0)队列进行写操作。写队列支持两种写入方式:向队列尾节点写入,也可以向队列头节点写入。尾节点写入时,根据Tail找到起始空闲消息节点作为数据写入对象,如果Tail已经指向队列尾部则采用回卷方式。头节点写入时,将Head的前一个节点作为数据写入对象,如果Head指向队列起始位置则采用回卷方式。 + +- 读队列时,根据readWriteableCnt[0]判断队列是否有消息需要读取,对全部空闲(readWriteableCnt[0]为0)队列进行读操作会引起任务挂起。如果队列可以读取消息,则根据Head找到最先写入队列的消息节点进行读取。如果Head已经指向队列尾部则采用回卷方式。 + +- 删除队列时,根据队列ID找到对应队列,把队列状态置为未使用,把队列控制块置为初始状态,并释放队列所占内存。 + +**图1** 队列读写数据操作示意图 +![zh-cn_image_0000001200452026](figures/zh-cn_image_0000001200452026.png) + +上图对读写队列做了示意,图中只画了尾节点写入方式,没有画头节点写入,但是两者是类似的。 + + +## 接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 创建/删除消息队列 | LOS_QueueCreate | 创建一个消息队列,由系统动态申请队列空间。 | +| LOS_QueueDelete | 根据队列ID删除一个指定队列。 | +| 读/写队列(不带拷贝) | LOS_QueueRead | 读取指定队列头节点中的数据(队列节点中的数据实际上是一个地址)。 | +| LOS_QueueWrite | 向指定队列尾节点中写入入参bufferAddr的值(即buffer的地址)。 | +| LOS_QueueWriteHead | 向指定队列头节点中写入入参bufferAddr的值(即buffer的地址)。 | +| 读/写队列(带拷贝) | LOS_QueueReadCopy | 读取指定队列头节点中的数据。 | +| LOS_QueueWriteCopy | 向指定队列尾节点中写入入参bufferAddr中保存的数据。 | +| LOS_QueueWriteHeadCopy | 向指定队列头节点中写入入参bufferAddr中保存的数据。 | +| 获取队列信息 | LOS_QueueInfoGet | 获取指定队列的信息,包括队列ID、队列长度、消息节点大小、头节点、尾节点、可读节点数量、可写节点数量、等待读操作的任务、等待写操作的任务。 | + + +## 开发流程 + +1. 用LOS_QueueCreate创建队列。创建成功后,可以得到队列ID。 + +2. 通过LOS_QueueWrite或者LOS_QueueWriteCopy写队列。 + +3. 通过LOS_QueueRead或者LOS_QueueReadCopy读队列。 + +4. 通过LOS_QueueInfoGet获取队列信息。 + +5. 通过LOS_QueueDelete删除队列。 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 系统支持的最大队列数是指:整个系统的队列资源总个数,而非用户能使用的个数。例如:系统软件定时器多占用一个队列资源,那么用户能使用的队列资源就会减少一个。 +> +> - 创建队列时传入的队列名和flags暂时未使用,作为以后的预留参数。 +> +> - 队列接口函数中的入参timeOut是相对时间。 +> +> - LOS_QueueReadCopy和LOS_QueueWriteCopy及LOS_QueueWriteHeadCopy是一组接口,LOS_QueueRead和LOS_QueueWrite及LOS_QueueWriteHead是一组接口,每组接口需要配套使用。 +> +> - 鉴于LOS_QueueWrite和LOS_QueueWriteHead和LOS_QueueRead这组接口实际操作的是数据地址,用户必须保证调用LOS_QueueRead获取到的指针所指向的内存区域在读队列期间没有被异常修改或释放,否则可能导致不可预知的后果。 +> +> - 鉴于LOS_QueueWrite和LOS_QueueWriteHead和LOS_QueueRead这组接口实际操作的是数据地址,也就意味着实际写和读的消息长度仅仅是一个指针数据,因此用户使用这组接口之前,需确保创建队列时的消息节点大小,为一个指针的长度,避免不必要的浪费和读取失败。 + + +## 编程实例 + + +### 实例描述 + +创建一个队列,两个任务。任务1调用写队列接口发送消息,任务2通过读队列接口接收消息。 + +1. 通过LOS_TaskCreate创建任务1和任务2。 + +2. 通过LOS_QueueCreate创建一个消息队列。 + +3. 在任务1 SendEntry中发送消息。 + +4. 在任务2 RecvEntry中接收消息。 + +5. 通过LOS_QueueDelete删除队列。 + + +### 示例代码 + +示例代码如下: + +``` +#include "los_task.h" +#include "los_queue.h" +static UINT32 g_queue; +#define BUFFER_LEN 50 + +VOID SendEntry(VOID) +{ + UINT32 ret = 0; + CHAR abuf[] = "test message"; + UINT32 len = sizeof(abuf); + + ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); + if(ret != LOS_OK) { + printf("send message failure, error: %x\n", ret); + } +} + +VOID RecvEntry(VOID) +{ + UINT32 ret = 0; + CHAR readBuf[BUFFER_LEN] = {0}; + UINT32 readLen = BUFFER_LEN; + + //休眠1s + usleep(1000000); + ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); + if(ret != LOS_OK) { + printf("recv message failure, error: %x\n", ret); + } + + printf("recv message: %s\n", readBuf); + + ret = LOS_QueueDelete(g_queue); + if(ret != LOS_OK) { + printf("delete the queue failure, error: %x\n", ret); + } + + printf("delete the queue success.\n"); +} + +UINT32 ExampleQueue(VOID) +{ + printf("start queue example.\n"); + UINT32 ret = 0; + UINT32 task1, task2; + TSK_INIT_PARAM_S initParam = {0}; + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; + initParam.usTaskPrio = 9; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + initParam.pcName = "SendQueue"; + + LOS_TaskLock(); + ret = LOS_TaskCreate(&task1, &initParam); + if(ret != LOS_OK) { + printf("create task1 failed, error: %x\n", ret); + return ret; + } + + initParam.pcName = "RecvQueue"; + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; + initParam.usTaskPrio = 10; + ret = LOS_TaskCreate(&task2, &initParam); + if(ret != LOS_OK) { + printf("create task2 failed, error: %x\n", 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 succes.\n"); + LOS_TaskUnlock(); + return ret; +} +``` + + +### 结果验证 + +编译运行得到的结果为: + + +``` +start queue example. +create the queue success. +recv message: test message. +delete the queue success. +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md deleted file mode 100644 index 79c4d7e6f5..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-basic.md +++ /dev/null @@ -1,53 +0,0 @@ -# 基本概念 - -- [运行机制](#section1794010261861) - - [信号量控制块](#section11372149164815) - - [信号量运作原理](#section139726510491) - - -信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 - -一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数,其值的含义分两种情况: - -- 0,表示该信号量当前不可获取,因此可能存在正在等待该信号量的任务。 -- 正值,表示该信号量当前可被获取。 - -以同步为目的的信号量和以互斥为目的的信号量在使用上有如下不同: - -- 用作互斥时,初始信号量计数值不为0,表示可用的共享资源个数。在需要使用共享资源前,先获取信号量,然后使用一个共享资源,使用完毕后释放信号量。这样在共享资源被取完,即信号量计数减至0时,其他需要获取信号量的任务将被阻塞,从而保证了共享资源的互斥访问。另外,当共享资源数为1时,建议使用二值信号量,一种类似于互斥锁的机制。 -- 用作同步时,初始信号量计数值为0。任务1获取信号量而阻塞,直到任务2或者某中断释放信号量,任务1才得以进入Ready或Running态,从而达到了任务间的同步。 - -## 运行机制 - -### 信号量控制块 - -``` -/** - * 信号量控制块数据结构 - */ -typedef struct { - UINT16 semStat; /* 信号量状态 */ - UINT16 semType; /* 信号量类型 */ - UINT16 semCount; /* 信号量计数 */ - UINT16 semId; /* 信号量索引号 */ - LOS_DL_LIST semList; /* 挂接阻塞于该信号量的任务 */ -} LosSemCB; -``` - -### 信号量运作原理 - -信号量初始化,为配置的N个信号量申请内存(N值可以由用户自行配置,通过LOSCFG\_BASE\_IPC\_SEM\_LIMIT宏实现),并把所有信号量初始化成未使用,加入到未使用链表中供系统使用。 - -信号量创建,从未使用的信号量链表中获取一个信号量,并设定初值。 - -信号量申请,若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 - -信号量释放,若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 - -信号量删除,将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 - -信号量允许多个任务在同一时刻访问共享资源,但会限制同一时刻访问此资源的最大任务数目。当访问资源的任务数达到该资源允许的最大数量时,会阻塞其他试图获取该资源的任务,直到有任务释放该信号量。 - -**图 1** 信号量运作示意图 -![](figure/信号量运作示意图.png "信号量运作示意图") - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md deleted file mode 100644 index cb3d295cc3..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem-guide.md +++ /dev/null @@ -1,206 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section22061718111412) - - [示例代码](#section1775922321416) - - [结果验证](#section160404016213) - - -## 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建/删除信号量

-

LOS_SemCreate

-

创建信号量,返回信号量ID

-

LOS_BinarySemCreate

-

创建二值信号量,其计数值最大为1

-

LOS_SemDelete

-

删除指定的信号量

-

申请/释放信号量

-

LOS_SemPend

-

申请指定的信号量,并设置超时时间

-

LOS_SemPost

-

释放指定的信号量

-
- -## 开发流程 - -1. 创建信号量LOS\_SemCreate,若要创建二值信号量则调用LOS\_BinarySemCreate。 -2. 申请信号量LOS\_SemPend。 -3. 释放信号量LOS\_SemPost。 -4. 删除信号量LOS\_SemDelete。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->由于中断不能被阻塞,因此不能在中断中使用阻塞模式申请信号量。 - -## 编程实例 - -### 实例描述 - -本实例实现如下功能: - -1. 测试任务ExampleSem创建一个信号量,锁任务调度,创建两个任务ExampleSemTask1、ExampleSemTask2, ExampleSemTask2优先级高于ExampleSemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务ExampleSem释放信号量。 -2. ExampleSemTask2得到信号量,被调度,然后任务休眠20Tick,ExampleSemTask2延迟,ExampleSemTask1被唤醒。 -3. ExampleSemTask1定时阻塞模式申请信号量,等待时间为10Tick,因信号量仍被ExampleSemTask2持有,ExampleSemTask1挂起,10Tick后仍未得到信号量,ExampleSemTask1被唤醒,试图以永久阻塞模式申请信号量,ExampleSemTask1挂起。 -4. 20Tick后ExampleSemTask2唤醒, 释放信号量后,ExampleSemTask1得到信号量被调度运行,最后释放信号量。 -5. ExampleSemTask1执行完,400Tick后任务ExampleSem被唤醒,执行删除信号量。 - -### 示例代码 - -示例代码如下: - -``` -#include "los_sem.h" -#include "securec.h" - -/* 任务ID */ -static UINT32 g_testTaskId01; -static UINT32 g_testTaskId02; - -/* 测试任务优先级 */ -#define TASK_PRIO_TEST 5 - -/* 信号量结构体id */ -static UINT32 g_semId; - -VOID ExampleSemTask1(VOID) -{ - UINT32 ret; - - printf("ExampleSemTask1 try get sem g_semId, timeout 10 ticks.\n"); - - /* 定时阻塞模式申请信号量,定时时间为10ticks */ - ret = LOS_SemPend(g_semId, 10); - - /* 申请到信号量 */ - if (ret == LOS_OK) { - LOS_SemPost(g_semId); - return; - } - /* 定时时间到,未申请到信号量 */ - if (ret == LOS_ERRNO_SEM_TIMEOUT) { - printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); - - /*永久阻塞模式申请信号量*/ - ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); - printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); - if (ret == LOS_OK) { - LOS_SemPost(g_semId); - return; - } - } -} - -VOID ExampleSemTask2(VOID) -{ - UINT32 ret; - printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); - - /* 永久阻塞模式申请信号量 */ - ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); - - if (ret == LOS_OK) { - printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); - } - - /* 任务休眠20 ticks */ - LOS_TaskDelay(20); - - printf("ExampleSemTask2 post sem g_semId.\n"); - /* 释放信号量 */ - LOS_SemPost(g_semId); - return; -} - -UINT32 ExampleSem(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - TSK_INIT_PARAM_S task2; - - /* 创建信号量 */ - LOS_SemCreate(0, &g_semId); - - /* 锁任务调度 */ - LOS_TaskLock(); - - /* 创建任务1 */ - (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; - task1.pcName = "TestTask1"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = TASK_PRIO_TEST; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("task1 create failed.\n"); - return LOS_NOK; - } - - /* 创建任务2 */ - (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); - task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; - task2.pcName = "TestTask2"; - task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task2.usTaskPrio = (TASK_PRIO_TEST - 1); - ret = LOS_TaskCreate(&g_testTaskId02, &task2); - if (ret != LOS_OK) { - printf("task2 create failed.\n"); - return LOS_NOK; - } - - /* 解锁任务调度 */ - LOS_TaskUnlock(); - - ret = LOS_SemPost(g_semId); - - /* 任务休眠400 ticks */ - LOS_TaskDelay(400); - - /* 删除信号量 */ - LOS_SemDelete(g_semId); - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -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 timeout and try get sem g_semId wait forever. -ExampleSemTask2 post sem g_semId. -ExampleSemTask1 wait_forever and get sem g_semId. -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem.md index cc9f53c413..205e987c9b 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc-sem.md @@ -1,7 +1,234 @@ -# 信号量 +# 信号量 -- **[基本概念](kernel-mini-basic-ipc-sem-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [信号量控制块](#信号量控制块) + - [信号量运作原理](#信号量运作原理) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-ipc-sem-guide.md)** +## 基本概念 +信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 +一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数,其值的含义分两种情况: + +- 0,表示该信号量当前不可获取,因此可能存在正在等待该信号量的任务。 + +- 正值,表示该信号量当前可被获取。 + +以同步为目的的信号量和以互斥为目的的信号量在使用上有如下不同: + +- 用作互斥时,初始信号量计数值不为0,表示可用的共享资源个数。在需要使用共享资源前,先获取信号量,然后使用一个共享资源,使用完毕后释放信号量。这样在共享资源被取完,即信号量计数减至0时,其他需要获取信号量的任务将被阻塞,从而保证了共享资源的互斥访问。另外,当共享资源数为1时,建议使用二值信号量,一种类似于互斥锁的机制。 + +- 用作同步时,初始信号量计数值为0。任务1因获取不到信号量而阻塞,直到任务2或者某中断释放信号量,任务1才得以进入Ready或Running态,从而达到了任务间的同步。 + + +## 运行机制 + + +### 信号量控制块 + +``` +/** * 信号量控制块数据结构*/typedefstruct { UINT16 semStat; /*信号量状态 */ UINT16 semType; /*信号量类型 */ UINT16 semCount; /*信号量计数 */ UINT16 semId; /*信号量索引号 */ LOS_DL_LIST semList; /*用于插入阻塞于信号量的任务 */} LosSemCB; +``` + + +### 信号量运作原理 + +信号量初始化,为配置的N个信号量申请内存(N值可以由用户自行配置,通过LOSCFG_BASE_IPC_SEM_LIMIT宏实现),并把所有信号量初始化成未使用,加入到未使用链表中供系统使用。 + +信号量创建,从未使用的信号量链表中获取一个信号量,并设定初值。 + +信号量申请,若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 + +信号量释放,若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 + +信号量删除,将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 + +信号量允许多个任务在同一时刻访问共享资源,但会限制同一时刻访问此资源的最大任务数目。当访问资源的任务数达到该资源允许的最大数量时,会阻塞其他试图获取该资源的任务,直到有任务释放该信号量。 + +**图1** 轻量系统信号量运作示意图 +![zh-cn_image_0000001245051881](figures/zh-cn_image_0000001245051881.png) + + +## 接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 创建/删除信号量 | LOS_SemCreate | 创建信号量,返回信号量ID | +| LOS_BinarySemCreate | 创建二值信号量,其计数值最大为1 | +| LOS_SemDelete | 删除指定的信号量 | +| 申请/释放信号量 | LOS_SemPend | 申请指定的信号量,并设置超时时间 | +| LOS_SemPost | 释放指定的信号量 | + + +## 开发流程 + +1. 创建信号量LOS_SemCreate,若要创建二值信号量则调用LOS_BinarySemCreate。 + +2. 申请信号量LOS_SemPend。 + +3. 释放信号量LOS_SemPost。 + +4. 删除信号量LOS_SemDelete。 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 由于中断不能被阻塞,因此不能在中断中使用阻塞模式申请信号量。 + + +## 编程实例 + + +### 实例描述 + +本实例实现如下功能: + +1. 测试任务ExampleSem创建一个信号量,锁任务调度,创建两个任务ExampleSemTask1、ExampleSemTask2, ExampleSemTask2优先级高于ExampleSemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务ExampleSem释放信号量。 + +2. ExampleSemTask2得到信号量,被调度,然后任务休眠20Tick,ExampleSemTask2延迟,ExampleSemTask1被唤醒。 + +3. ExampleSemTask1定时阻塞模式申请信号量,等待时间为10Tick,因信号量仍被ExampleSemTask2持有,ExampleSemTask1挂起,10Tick后仍未得到信号量,ExampleSemTask1被唤醒,试图以永久阻塞模式申请信号量,ExampleSemTask1挂起。 + +4. 20Tick后ExampleSemTask2唤醒, 释放信号量后,ExampleSemTask1得到信号量被调度运行,最后释放信号量。 + +5. ExampleSemTask1执行完,400Tick后任务ExampleSem被唤醒,执行删除信号量。 + + +### 示例代码 + +示例代码如下: + +``` +#include "los_sem.h" +#include "securec.h" + +/* 任务ID */ +static UINT32 g_testTaskId01; +static UINT32 g_testTaskId02; + +/* 测试任务优先级 */ +#define TASK_PRIO_TEST 5 + +/* 信号量结构体id */ +static UINT32 g_semId; + +VOID ExampleSemTask1(VOID) +{ + UINT32 ret; + + printf("ExampleSemTask1 try get sem g_semId, timeout 10 ticks.\n"); + + /* 定时阻塞模式申请信号量,定时时间为10ticks */ + ret = LOS_SemPend(g_semId, 10); + + /* 申请到信号量 */ + if (ret == LOS_OK) { + LOS_SemPost(g_semId); + return; + } + /* 定时时间到,未申请到信号量 */ + if (ret == LOS_ERRNO_SEM_TIMEOUT) { + printf("ExampleSemTask1 timeout and try get sem g_semId wait forever.\n"); + + /*永久阻塞模式申请信号量*/ + ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); + printf("ExampleSemTask1 wait_forever and get sem g_semId.\n"); + if (ret == LOS_OK) { + LOS_SemPost(g_semId); + return; + } + } +} + +VOID ExampleSemTask2(VOID) +{ + UINT32 ret; + printf("ExampleSemTask2 try get sem g_semId wait forever.\n"); + + /* 永久阻塞模式申请信号量 */ + ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); + + if (ret == LOS_OK) { + printf("ExampleSemTask2 get sem g_semId and then delay 20 ticks.\n"); + } + + /* 任务休眠20 ticks */ + LOS_TaskDelay(20); + + printf("ExampleSemTask2 post sem g_semId.\n"); + /* 释放信号量 */ + LOS_SemPost(g_semId); + return; +} + +UINT32 ExampleSem(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + TSK_INIT_PARAM_S task2; + + /* 创建信号量 */ + LOS_SemCreate(0, &g_semId); + + /* 锁任务调度 */ + LOS_TaskLock(); + + /* 创建任务1 */ + (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1; + task1.pcName = "TestTask1"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = TASK_PRIO_TEST; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("task1 create failed.\n"); + return LOS_NOK; + } + + /* 创建任务2 */ + (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); + task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2; + task2.pcName = "TestTask2"; + task2.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task2.usTaskPrio = (TASK_PRIO_TEST - 1); + ret = LOS_TaskCreate(&g_testTaskId02, &task2); + if (ret != LOS_OK) { + printf("task2 create failed.\n"); + return LOS_NOK; + } + + /* 解锁任务调度 */ + LOS_TaskUnlock(); + + ret = LOS_SemPost(g_semId); + + /* 任务休眠400 ticks */ + LOS_TaskDelay(400); + + /* 删除信号量 */ + LOS_SemDelete(g_semId); + return LOS_OK; +} +``` + + +### 结果验证 + +编译运行得到的结果为: + + +``` +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 timeout and try get sem g_semId wait forever. +ExampleSemTask2 post sem g_semId. +ExampleSemTask1 wait_forever and get sem g_semId. +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc.md b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc.md index 9caa565d34..e733e292f6 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-ipc.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-ipc.md @@ -1,11 +1,10 @@ -# 内核通信机制 +# 内核通信机制 -- **[事件](kernel-mini-basic-ipc-event.md)** -- **[互斥锁](kernel-mini-basic-ipc-mutex.md)** +- **[事件](kernel-mini-basic-ipc-event.md)** -- **[消息队列](kernel-mini-basic-ipc-queue.md)** - -- **[信号量](kernel-mini-basic-ipc-sem.md)** +- **[互斥锁](kernel-mini-basic-ipc-mutex.md)** +- **[消息队列](kernel-mini-basic-ipc-queue.md)** +- **[信号量](kernel-mini-basic-ipc-sem.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-memory-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-memory-basic.md index 50b4c21033..23abc39d28 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-memory-basic.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-memory-basic.md @@ -1,17 +1,18 @@ -# 基本概念 +# 基本概念 内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包括内存的初始化、分配以及释放。 + 在系统运行过程中,内存管理模块通过对内存的申请/释放来管理用户和OS对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统的内存碎片问题。 -OpenHarmony LiteOS-M的内存管理分为静态内存管理和动态内存管理,提供内存初始化、分配、释放等功能。 -- 动态内存:在动态内存池中分配用户指定大小的内存块。 - - 优点:按需分配。 - - 缺点:内存池中可能出现碎片。 +OpenHarmony LiteOS-M的内存管理分为静态内存管理和动态内存管理,提供内存初始化、分配、释放等功能。 -- 静态内存:在静态内存池中分配用户初始化时预设(固定)大小的内存块。 - - 优点:分配和释放效率高,静态内存池中无碎片。 - - 缺点:只能申请到初始化预设大小的内存块,不能按需申请。 +- 动态内存:在动态内存池中分配用户指定大小的内存块。 + - 优点:按需分配。 + - 缺点:内存池中可能出现碎片。 +- 静态内存:在静态内存池中分配用户初始化时预设(固定)大小的内存块。 + - 优点:分配和释放效率高,静态内存池中无碎片。 + - 缺点:只能申请到初始化预设大小的内存块,不能按需申请。 diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-memory-dynamic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-memory-dynamic.md index 5dfdb5bab6..6abee7f094 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-memory-dynamic.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-memory-dynamic.md @@ -1,205 +1,132 @@ -# 动态内存 +# 动态内存 -- [运行机制](#section328282013571) -- [开发指导](#section7921151015814) - - [使用场景](#section326917198583) - - [接口说明](#section1032331584) - - [开发流程](#section07271773592) - - [编程实例](#section84931234145913) - - [结果验证](#section165233233917) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [使用场景](#使用场景) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [结果验证](#结果验证) - -## 运行机制 +## 运行机制 动态内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存(内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。与静态内存相比,动态内存管理的优点是按需分配,缺点是内存池中容易出现碎片。 OpenHarmony LiteOS-M动态内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。动态内存核心算法框图如下: -**图 1** 动态内存核心算法 -![](figure/轻量系统动态内存核心算法.png "动态内存核心算法") - -根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:\[4, 127\]和\[27, 231\],如上图size class所示: +**图1** 轻量系统动态内存核心算法 +![zh-cn_image_0000001199352445](figures/zh-cn_image_0000001199352445.png) -1. 对\[4,127\]区间的内存进行等分,如上图下半部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。\[4,127\]区间的31个小区间内存对应31个比特位进行标记链表是否为空。 -2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见上图上半部分的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24\*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。 +$$根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:[4, 127]和[2^{7}$, 2^{31}$],如上图size class所示: -例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间\[40,43\],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间\[2^9,2^9+2^6\],第31+2\*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。 +1. 对[4,127]区间的内存进行等分,如上图下半部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。[4,127]区间的31个小区间内存对应31个比特位进行标记链表是否为空。 -内存管理结构如下图所示: +2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见上图上半部分的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24\*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。 -**图 2** 动态内存管理结构图 -![](figure/动态内存管理结构图.png "动态内存管理结构图") +例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间[40,43],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间[2^9,2^9+2^6],第31+2\*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。 -- 内存池池头部分 +内存管理结构如下图所示: - 内存池池头部分包含内存池信息、位图标记数组和空闲链表数组。内存池信息包含内存池起始地址及堆区域总大小,内存池属性。位图标记数组有7个32位无符号整数组成,每个比特位标记对应的空闲链表是否挂载空闲内存块节点。空闲内存链表包含223个空闲内存头节点信息,每个空闲内存头节点信息维护内存节点头和空闲链表中的前驱、后继空闲内存节点。 +**图2** 轻量系统动态内存管理结构图 +![zh-cn_image_0000001153313284](figures/zh-cn_image_0000001153313284.png) -- 内存池节点部分 +- 内存池池头部分 + 内存池池头部分包含内存池信息、位图标记数组和空闲链表数组。内存池信息包含内存池起始地址及堆区域总大小,内存池属性。位图标记数组有7个32位无符号整数组成,每个比特位标记对应的空闲链表是否挂载空闲内存块节点。空闲内存链表包含223个空闲内存头节点信息,每个空闲内存头节点信息维护内存节点头和空闲链表中的前驱、后继空闲内存节点。 - 包含3种类型节点:未使用空闲内存节点,已使用内存节点和尾节点。每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。空闲内存节点和已使用内存节点后面的内存区域是数据域,尾节点没有数据域。 +- 内存池节点部分 + 包含3种类型节点:未使用空闲内存节点,已使用内存节点和尾节点。每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。空闲内存节点和已使用内存节点后面的内存区域是数据域,尾节点没有数据域。 -一些芯片片内RAM大小无法满足要求,需要使用片外物理内存进行扩充。对于这样的多段非连续性内存,OpenHarmony LiteOS-M内核支持把多个非连续性内存逻辑上合一,用户不感知底层的多段非连续性内存区域。OpenHarmony LiteOS-M内核内存模块把不连续的内存区域作为空闲内存结点插入到空闲内存节点链表,把不同内存区域间的不连续部分标记为虚拟的已使用内存节点,从逻辑上把多个非连续性内存区域实现为一个统一的内存池。下面通过示意图说明下多段非连续性内存的运行机制: +一些芯片片内RAM大小无法满足要求,需要使用片外物理内存进行扩充。对于这样的多段非连续性内存, LiteOS-M内核支持把多个非连续性内存逻辑上合一,用户不感知底层的多段非连续性内存区域。 LiteOS-M内核内存模块把不连续的内存区域作为空闲内存结点插入到空闲内存节点链表,把不同内存区域间的不连续部分标记为虚拟的已使用内存节点,从逻辑上把多个非连续性内存区域实现为一个统一的内存池。下面通过示意图说明下多段非连续性内存的运行机制: -**图 3** 非连续性内存合一示意图 -![](figure/非连续性内存合一示意图.png "非连续性内存合一示意图") +**图3** 非连续性内存合一示意图 +![zh-cn_image_0000001198253551](figures/zh-cn_image_0000001198253551.png) 结合上述示意图,非连续性内存合并为一个统一的内存池的步骤如下: + 1. 把多段非连续性内存区域的第一块内存区域通过调用LOS_MemInit接口进行初始化。 + 2. 获取下一个内存区域的开始地址和长度,计算该内存区域和上一块内存区域的间隔大小gapSize。 + 3. 把内存区域间隔部分视为虚拟的已使用节点,使用上一个内存区域的尾节点,设置其大小为gapSize+ OS_MEM_NODE_HEAD_SIZE。 + 4. 把当前内存区域划分为一个空闲内存节点和一个尾节点,把空闲内存节点插入到空闲链表,并设置各个节点的前后链接关系。 + 5. 如果有更多的非连续内存区域,重复上述步骤2-4。 -## 开发指导 +## 开发指导 -### 使用场景 + +### 使用场景 动态内存管理的主要工作是动态分配并管理用户申请到的内存区间。动态内存管理主要用于用户需要使用大小不等的内存块的场景,当用户需要使用内存时,可以通过操作系统的动态内存申请函数索取指定大小的内存块,一旦使用完毕,通过动态内存释放函数归还所占用内存,使之可以重复使用。 -### 接口说明 + +### 接口说明 OpenHarmony LiteOS-M的动态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 -**表 1** 动态内存模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化和删除内存池

-

LOS_MemInit

-

初始化一块指定的动态内存池,大小为size。

-

LOS_MemDeInit

-

删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效。

-

申请、释放动态内存

-

LOS_MemAlloc

-

从指定动态内存池中申请size长度的内存。

-

LOS_MemFree

-

释放从指定动态内存中申请的内存。

-

LOS_MemRealloc

-

按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块。

-

LOS_MemAllocAlign

-

从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存。

-

获取内存池信息

-

LOS_MemPoolSizeGet

-

获取指定动态内存池的总大小。

-

LOS_MemTotalUsedGet

-

获取指定动态内存池的总使用量大小。

-

LOS_MemInfoGet

-

获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小。

-

LOS_MemPoolList

-

打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效。

-

获取内存块信息

-

LOS_MemFreeNodeShow

-

打印指定内存池的空闲内存块的大小及数量。

-

LOS_MemUsedNodeShow

-

打印指定内存池的已使用内存块的大小及数量。

-

检查指定内存池的完整性

-

LOS_MemIntegrityCheck

-

对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效。

-

增加非连续性内存区域

-

LOS_MemRegionsAdd

-

支持多段非连续性内存区域,把非连续性内存区域逻辑上整合为一个统一的内存池。仅打开LOSCFG_MEM_MUL_REGIONS时有效。如果内存池指针参数pool为空,则使用多段内存的第一个初始化为内存池,其他内存区域,作为空闲节点插入;如果内存池指针参数pool不为空,则把多段内存作为空闲节点,插入到指定的内存池。

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项OS\_SYS\_MEM\_SIZE的大小。 ->- 对齐分配内存接口LOS\_MemAllocAlign/LOS\_MemMallocAlign因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。 ->- 非连续性内存区域接口LOS\_MemRegionsAdd的LosMemRegion数组参数传入的非连续性内存区域需要按各个内存区域的内存开始地址升序,且内存区域不能重叠。 - -### 开发流程 +**表1** 动态内存模块接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 初始化和删除内存池 | LOS_MemInit | 初始化一块指定的动态内存池,大小为size。 | +| LOS_MemDeInit | 删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效。 | +| 申请、释放动态内存 | LOS_MemAlloc | 从指定动态内存池中申请size长度的内存。 | +| LOS_MemFree | 释放从指定动态内存中申请的内存。 | +| LOS_MemRealloc | 按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块。 | +| LOS_MemAllocAlign | 从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存。 | +| 获取内存池信息 | LOS_MemPoolSizeGet | 获取指定动态内存池的总大小。 | +| LOS_MemTotalUsedGet | 获取指定动态内存池的总使用量大小。 | +| LOS_MemInfoGet | 获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小。 | +| LOS_MemPoolList | 打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效。 | +| 获取内存块信息 | LOS_MemFreeNodeShow | 打印指定内存池的空闲内存块的大小及数量。 | +| LOS_MemUsedNodeShow | 打印指定内存池的已使用内存块的大小及数量。 | +| 检查指定内存池的完整性 | LOS_MemIntegrityCheck | 对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效。 | +| 增加非连续性内存区域 | LOS_MemRegionsAdd | 支持多段非连续性内存区域,把非连续性内存区域逻辑上整合为一个统一的内存池。仅打开LOSCFG_MEM_MUL_REGIONS时有效。如果内存池指针参数pool为空,则使用多段内存的第一个初始化为内存池,其他内存区域,作为空闲节点插入;如果内存池指针参数pool不为空,则把多段内存作为空闲节点,插入到指定的内存池。 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项OS_SYS_MEM_SIZE的大小。 +> +> - 对齐分配内存接口LOS_MemAllocAlign/LOS_MemMallocAlign因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。 +> +> - 非连续性内存区域接口LOS_MemRegionsAdd的LosMemRegion数组参数传入的非连续性内存区域需要按各个内存区域的内存开始地址升序,且内存区域不能重叠。 + + +### 开发流程 本节介绍使用动态内存的典型场景开发流程。 -1. 初始化LOS\_MemInit。 - - 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。注:EndNode作为内存池末尾的节点,size为0。 +1. 初始化LOS_MemInit。 + 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。注:EndNode作为内存池末尾的节点,size为0。 +1. 申请任意大小的动态内存LOS_MemAlloc。 + 判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存块挂载到空闲内存链表上。 -1. 申请任意大小的动态内存LOS\_MemAlloc。 +1. 释放动态内存LOS_MemFree。 + 回收内存块,供下一次使用。调用LOS_MemFree释放内存块,则会回收内存块,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。 - 判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存块挂载到空闲内存链表上。 +### 编程实例 -1. 释放动态内存LOS\_MemFree。 +本实例执行以下步骤: - 回收内存块,供下一次使用。调用LOS\_MemFree释放内存块,则会回收内存块,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。 +1. 初始化一个动态内存池。 +2. 从动态内存池中申请一个内存块。 -### 编程实例 +3. 在内存块中存放一个数据。 -本实例执行以下步骤: +4. 打印出内存块中的数据。 -1. 初始化一个动态内存池。 -2. 从动态内存池中申请一个内存块。 -3. 在内存块中存放一个数据。 -4. 打印出内存块中的数据。 -5. 释放该内存块。 +5. 释放该内存块。 示例代码如下: ``` #include "los_memory.h" - #define TEST_POOL_SIZE (2*1024) __attribute__((aligned(4))) UINT8 g_testPool[TEST_POOL_SIZE]; - VOID Example_DynMem(VOID) { UINT32 *mem = NULL; @@ -208,19 +135,19 @@ VOID Example_DynMem(VOID) /*初始化内存池*/ ret = LOS_MemInit(g_testPool, TEST_POOL_SIZE); if (LOS_OK == ret) { - printf("Memory pool initialized.\n"); + printf("Mem init success!\n"); } else { - printf("Memory pool initialization failed.\n"); + printf("Mem init failed!\n"); return; } /*分配内存*/ mem = (UINT32 *)LOS_MemAlloc(g_testPool, 4); if (NULL == mem) { - printf("Memory allocation failed.\n"); + printf("Mem alloc failed!\n"); return; } - printf("Memory allocated.\n"); + printf("Mem alloc success!\n"); /*赋值*/ *mem = 828; @@ -229,23 +156,23 @@ VOID Example_DynMem(VOID) /*释放内存*/ ret = LOS_MemFree(g_testPool, mem); if (LOS_OK == ret) { - printf("Memory released.\n"); + printf("Mem free success!\n"); } else { - printf("Memory release failed.\n"); + printf("Mem free failed!\n"); } return; } ``` -### 结果验证 + +### 结果验证 输出结果如下: ``` -Memory pool initialized. -Memory allocated. +Mem init success! +Mem alloc success! *mem = 828 -Memory released. +Mem free success! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-memory-static.md b/zh-cn/device-dev/kernel/kernel-mini-basic-memory-static.md index b52510e80b..ace4ad566e 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-memory-static.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-memory-static.md @@ -1,123 +1,85 @@ -# 静态内存 +# 静态内存 -- [运行机制](#section165473517522) -- [开发指导](#section57511620165218) - - [使用场景](#section215474911529) - - [接口说明](#section79231214539) - - [开发流程](#section1388511316548) - - [编程实例](#section17801515105519) - - [结果验证](#section11818154112319) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [使用场景](#使用场景) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [结果验证](#结果验证) - -## 运行机制 +## 运行机制 静态内存实质上是一个静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更。 -静态内存池由一个控制块LOS\_MEMBOX\_INFO和若干相同大小的内存块LOS\_MEMBOX\_NODE构成。控制块位于内存池头部,用于内存块管理,包含内存块大小uwBlkSize,内存块数量uwBlkNum,已分配使用的内存块数量uwBlkCnt和空闲内存块链表stFreeList。内存块的申请和释放以块大小为粒度,每个内存块包含指向下一个内存块的指针pstNext。 +静态内存池由一个控制块LOS_MEMBOX_INFO和若干相同大小的内存块LOS_MEMBOX_NODE构成。控制块位于内存池头部,用于内存块管理,包含内存块大小uwBlkSize,内存块数量uwBlkNum,已分配使用的内存块数量uwBlkCnt和空闲内存块链表stFreeList。内存块的申请和释放以块大小为粒度,每个内存块包含指向下一个内存块的指针pstNext。 + +**图1** 静态内存示意图 +![zh-cn_image_0000001199352039](figures/zh-cn_image_0000001199352039.png) + -**图 1** 静态内存示意图 -![](figure/静态内存示意图.png "静态内存示意图") +## 开发指导 -## 开发指导 -### 使用场景 +### 使用场景 当用户需要使用固定长度的内存时,可以通过静态内存分配的方式获取内存,一旦使用完毕,通过静态内存释放函数归还所占用内存,使之可以重复使用。 -### 接口说明 + +### 接口说明 OpenHarmony LiteOS-M的静态内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 -**表 1** 静态内存模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化静态内存池

-

LOS_MemboxInit

-

初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小。

-

清除静态内存块内容

-

LOS_MemboxClr

-

清零从静态内存池中申请的静态内存块的内容。

-

申请、释放静态内存

-

LOS_MemboxAlloc

-

从指定的静态内存池中申请一块静态内存块。

-

LOS_MemboxFree

-

释放从静态内存池中申请的一块静态内存块。

-

获取、打印静态内存池信息

-

LOS_MemboxStatisticsGet

-

获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小。

-

LOS_ShowBox

-

打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址。

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->初始化后的内存池的内存块数量,不等于总大小除于内存块大小,因为内存池的控制块和每个内存块的控制头,都存在内存开销,设置总大小时,需要将这些因素考虑进去。 - -### 开发流程 +**表1** 静态内存模块接口 -本节介绍使用静态内存的典型场景开发流程。 +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 初始化静态内存池 | LOS_MemboxInit | 初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小。 | +| 清除静态内存块内容 | LOS_MemboxClr | 清零从静态内存池中申请的静态内存块的内容。 | +| 申请、释放静态内存 | LOS_MemboxAlloc | 从指定的静态内存池中申请一块静态内存块。 | +| LOS_MemboxFree | 释放从静态内存池中申请的一块静态内存块。 | +| 获取、打印静态内存池信息 | LOS_MemboxStatisticsGet | 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小。 | +| LOS_ShowBox | 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址。 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 初始化后的内存池的内存块数量,不等于总大小除于内存块大小,因为内存池的控制块和每个内存块的控制头,都存在内存开销,设置总大小时,需要将这些因素考虑进去。 -1. 规划一片内存区域作为静态内存池。 -2. 调用LOS\_MemboxInit初始化静态内存池。 - 初始化会将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。 +### 开发流程 -3. 调用LOS\_MemboxAlloc接口分配静态内存。 +本节介绍使用静态内存的典型场景开发流程。 - 系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。 +1. 规划一片内存区域作为静态内存池。 -4. 调用LOS\_MemboxClr接口。 +2. 调用LOS_MemboxInit初始化静态内存池。 + 初始化会将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。 - 将入参地址对应的内存块清零。 +3. 调用LOS_MemboxAlloc接口分配静态内存。 + 系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。 -5. 调用LOS\_MemboxFree接口。 +4. 调用LOS_MemboxClr接口。 + 将入参地址对应的内存块清零。 - 将该内存块加入空闲链表。 +5. 调用LOS_MemboxFree接口。 + 将该内存块加入空闲链表。 -### 编程实例 +### 编程实例 本实例执行以下步骤: -1. 初始化一个静态内存池。 -2. 从静态内存池中申请一块静态内存。 -3. 在内存块存放一个数据。 -4. 打印出内存块中的数据。 -5. 清除内存块中的数据。 -6. 释放该内存块。 +1. 初始化一个静态内存池。 + +2. 从静态内存池中申请一块静态内存。 + +3. 在内存块存放一个数据。 - 示例代码如下: +4. 打印出内存块中的数据。 +5. 清除内存块中的数据。 + +6. 释放该内存块。 + 示例代码如下: ``` #include "los_membox.h" @@ -167,7 +129,8 @@ VOID Example_StaticMem(VOID) } ``` -### 结果验证 + +### 结果验证 输出结果如下: @@ -179,4 +142,3 @@ Mem clear success *mem = 0 Mem free success! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-memory.md b/zh-cn/device-dev/kernel/kernel-mini-basic-memory.md index 1aa6736664..39ee73a31e 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-memory.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-memory.md @@ -1,9 +1,8 @@ -# 内存管理 +# 内存管理 -- **[基本概念](kernel-mini-basic-memory-basic.md)** -- **[静态内存](kernel-mini-basic-memory-static.md)** - -- **[动态内存](kernel-mini-basic-memory-dynamic.md)** +- **[基本概念](kernel-mini-basic-memory-basic.md)** +- **[静态内存](kernel-mini-basic-memory-static.md)** +- **[动态内存](kernel-mini-basic-memory-dynamic.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-soft-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-soft-basic.md deleted file mode 100644 index 2c64cf5b52..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-soft-basic.md +++ /dev/null @@ -1,54 +0,0 @@ -# 基本概念 - -- [运行机制](#section070665816719) - - [定时器状态](#section115453813506) - - [定时器模式](#section137521353175010) - - -软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。 - -硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,OpenHarmony LiteOS-M内核提供软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。 - -软件定时器功能上支持: - -- 静态裁剪:能通过宏关闭软件定时器功能。 -- 软件定时器创建。 -- 软件定时器启动。 -- 软件定时器停止。 -- 软件定时器删除。 -- 软件定时器剩余Tick数获取。 - -## 运行机制 - -软件定时器是系统资源,在模块初始化的时候已经分配了一块连续的内存,系统支持的最大定时器个数由los\_config.h中的LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT宏配置。 - -软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。 - -软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,OpenHarmony LiteOS-M内核会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 - -当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。 - -Tick中断处理函数结束后,软件定时器任务(优先级为最高)被唤醒,在该任务中调用之前记录下来的定时器的超时回调函数。 - -### 定时器状态 - -- OS\_SWTMR\_STATUS\_UNUSED(未使用) - -系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态。 - -- OS\_SWTMR\_STATUS\_CREATED(创建未启动/停止) - -在未使用状态下调用LOS\_SwtmrCreate接口或者启动后调用LOS\_SwtmrStop接口后,定时器将变成该状态。 - -- OS\_SWTMR\_STATUS\_TICKING(计数) - -在定时器创建后调用LOS\_SwtmrStart接口,定时器将变成该状态,表示定时器运行时的状态。 - -### 定时器模式 - -OpenHarmony LiteOS-M内核的软件定时器提供三类定时器机制: - -- 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 -- 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动地停止定时器,否则将永远持续执行下去。 -- 第三类也是单次触发定时器,但与第一类不同之处在于这类定时器超时后不会自动删除,需要调用定时器删除接口删除定时器。 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-soft-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-soft-guide.md deleted file mode 100644 index 455c8ae06d..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-soft-guide.md +++ /dev/null @@ -1,219 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section3741753191918) - - [示例代码](#section20760101182016) - - [结果验证](#section11244112818172) - - -## 接口说明 - -OpenHarmony LiteOS-M内核的软件定时器模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 软件定时器接口 - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建、删除定时器

-

LOS_SwtmrCreate

-

创建定时器

-

LOS_SwtmrDelete

-

删除定时器

-

启动、停止定时器

-

LOS_SwtmrStart

-

启动定时器

-

LOS_SwtmrStop

-

停止定时器

-

获得软件定时器剩余Tick数

-

LOS_SwtmrTimeGet

-

获得软件定时器剩余Tick数

-
- -## 开发流程 - -软件定时器的典型开发流程: - -1. 配置软件定时器。 - - 确认配置项LOSCFG\_BASE\_CORE\_SWTMR和LOSCFG\_BASE\_IPC\_QUEUE为1打开状态; - - 配置LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数; - - 配置OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度; - -2. 创建定时器LOS\_SwtmrCreate。 - - 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器; - - 返回函数运行结果,成功或失败; - -3. 启动定时器LOS\_SwtmrStart。 -4. 获得软件定时器剩余Tick数LOS\_SwtmrTimeGet。 -5. 停止定时器LOS\_SwtmrStop。 -6. 删除定时器LOS\_SwtmrDelete。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。 ->- 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。 ->- 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。 ->- 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。 ->- 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 - -## 编程实例 - -### 实例描述 - -在下面的例子中,演示如下功能: - -1. 软件定时器创建、启动、删除、暂停、重启操作。 -2. 单次软件定时器,周期软件定时器使用方法。 - -### 示例代码 - -前提条件: - -- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR配置项打开。 -- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR\_ALIGN配置项关闭,示例代码中演示代码不涉及定时器对齐。 -- 配置好LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数。 -- 配置好OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 - -代码实现如下: - -``` -#include "los_swtmr.h" - -/* Timer count */ -UINT32 g_timerCount1 = 0; -UINT32 g_timerCount2 = 0; - -/* 任务ID */ -UINT32 g_testTaskId01; - -void Timer1_Callback(UINT32 arg) // 回调函数1 -{ - UINT32 tick_last1; - g_timerCount1++; - tick_last1 = (UINT32)LOS_TickCountGet(); // 获取当前Tick数 - printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); -} - -void Timer2_Callback(UINT32 arg) // 回调函数2 -{ - UINT32 tick_last2; - tick_last2 = (UINT32)LOS_TickCountGet(); - g_timerCount2++; - printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); -} - -void Timer_example(void) -{ - UINT32 ret; - UINT32 id1; // timer id1 - UINT32 id2; // timer id2 - UINT32 tickCount; - - /*创建单次软件定时器,Tick数为1000,启动到1000Tick数时执行回调函数1 */ - LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); - - /*创建周期性软件定时器,每100Tick数执行回调函数2 */ - LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); - printf("Timer 1 created.\n"); - - LOS_SwtmrStart(id1); //启动单次软件定时器 - printf("Timer 1 started.\n"); - - LOS_TaskDelay(200); //延时200Tick数 - LOS_SwtmrTimeGet(id1, &tickCount); // 获得单次软件定时器剩余Tick数 - printf("tickCount=%d\n", tickCount); - - LOS_SwtmrStop(id1); // 停止软件定时器 - printf("Timer 1 stopped.\n"); - - LOS_SwtmrStart(id1); - LOS_TaskDelay(1000); - - LOS_SwtmrStart(id2); // 启动周期性软件定时器 - printf("Timer 2 started.\n"); - - LOS_TaskDelay(1000); - LOS_SwtmrStop(id2); - ret = LOS_SwtmrDelete(id2); // 删除软件定时器 - if (ret == LOS_OK) { - printf("Timer 2 deleted.\n"); - } -} - -UINT32 Example_TaskEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S task1; - - /* 锁任务调度 */ - LOS_TaskLock(); - - /* 创建任务1 */ - (VOID)memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); - task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; - task1.pcName = "TimerTsk"; - task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - task1.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_testTaskId01, &task1); - if (ret != LOS_OK) { - printf("Failed to create the timer task.\n"); - return LOS_NOK; - } - - /* 解锁任务调度 */ - LOS_TaskUnlock(); - - return LOS_OK; -} -``` - -### 结果验证 - -编译烧录运行,输出结果如下: - -``` -Timer 1 created. -Timer 1 started. -tickCount=798 -Timer 1 stopped. -g_timerCount1=1, tick_last1=1208 -Timer 2 started. -g_timerCount2=1 tick_last2=1313 -g_timerCount2=2 tick_last2=1413 -g_timerCount2=3 tick_last2=1513 -g_timerCount2=4 tick_last2=1613 -g_timerCount2=5 tick_last2=1713 -g_timerCount2=6 tick_last2=1813 -g_timerCount2=7 tick_last2=1913 -g_timerCount2=8 tick_last2=2013 -g_timerCount2=9 tick_last2=2113 -g_timerCount2=10 tick_last2=2213 -Timer 2 deleted. -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-soft.md b/zh-cn/device-dev/kernel/kernel-mini-basic-soft.md index a557f1b061..5e466442b3 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-soft.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-soft.md @@ -1,7 +1,260 @@ -# 软件定时器 +# 软件定时器 -- **[基本概念](kernel-mini-basic-soft-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [定时器状态](#定时器状态) + - [定时器模式](#定时器模式) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-soft-guide.md)** +## 基本概念 +软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。 +硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,OpenHarmony LiteOS-M内核提供软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。 + +软件定时器功能上支持: + +- 静态裁剪:能通过宏关闭软件定时器功能。 + +- 软件定时器创建。 + +- 软件定时器启动。 + +- 软件定时器停止。 + +- 软件定时器删除。 + +- 软件定时器剩余Tick数获取。 + + +## 运行机制 + +软件定时器是系统资源,在模块初始化的时候已经分配了一块连续的内存,系统支持的最大定时器个数由los_config.h中的LOSCFG_BASE_CORE_SWTMR_LIMIT宏配置。 + +软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。 + +软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,OpenHarmony LiteOS-M内核会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 + +当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。 + +Tick中断处理函数结束后,软件定时器任务(优先级为最高)被唤醒,在该任务中调用之前记录下来的定时器的超时回调函数。 + + +### 定时器状态 + +- OS_SWTMR_STATUS_UNUSED(未使用) + 系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态。 + +- OS_SWTMR_STATUS_CREATED(创建未启动/停止) + 在未使用状态下调用LOS_SwtmrCreate接口或者启动后调用LOS_SwtmrStop接口后,定时器将变成该状态。 + +- OS_SWTMR_STATUS_TICKING(计数) + 在定时器创建后调用LOS_SwtmrStart接口,定时器将变成该状态,表示定时器运行时的状态。 + + +### 定时器模式 + +OpenHarmony LiteOS-M内核的软件定时器提供三类定时器机制: + +- 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 + +- 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动地停止定时器,否则将永远持续执行下去。 + +- 第三类也是单次触发定时器,但与第一类不同之处在于这类定时器超时后不会自动删除,需要调用定时器删除接口删除定时器。 + + +## 接口说明 + +OpenHarmony LiteOS-M内核的软件定时器模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表1** 软件定时器接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 创建、删除定时器 | LOS_SwtmrCreate | 创建定时器 | +| LOS_SwtmrDelete | 删除定时器 | +| 启动、停止定时器 | LOS_SwtmrStart | 启动定时器 | +| LOS_SwtmrStop | 停止定时器 | +| 获得软件定时器剩余Tick数 | LOS_SwtmrTimeGet | 获得软件定时器剩余Tick数 | + + +## 开发流程 + +软件定时器的典型开发流程: + +1. 配置软件定时器。 + - 确认配置项LOSCFG_BASE_CORE_SWTMR和LOSCFG_BASE_IPC_QUEUE为1打开状态; + - 配置LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数; + - 配置OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度; + +2. 创建定时器LOS_SwtmrCreate。 + - 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器; + - 返回函数运行结果,成功或失败; + +3. 启动定时器LOS_SwtmrStart。 + +4. 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。 + +5. 停止定时器LOS_SwtmrStop。 + +6. 删除定时器LOS_SwtmrDelete。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。 +> +> - 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。 +> +> - 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。 +> +> - 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。 +> +> - 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 + + +## 编程实例 + + +### 实例描述 + +在下面的例子中,演示如下功能: + +1. 软件定时器创建、启动、删除、暂停、重启操作。 + +2. 单次软件定时器,周期软件定时器使用方法。 + + +### 示例代码 + +前提条件: + +- 在los_config.h中,将LOSCFG_BASE_CORE_SWTMR配置项打开。 + +- 在los_config.h中,将LOSCFG_BASE_CORE_SWTMR_ALIGN配置项关闭,示例代码中演示代码不涉及定时器对齐。 + +- 配置好LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数。 + +- 配置好OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度。 + +代码实现如下: + +``` +#include "los_swtmr.h" + +/* Timer count */ +UINT32 g_timerCount1 = 0; +UINT32 g_timerCount2 = 0; + +/* 任务ID */ +UINT32 g_testTaskId01; + +void Timer1_Callback(UINT32 arg) // 回调函数1 +{ + UINT32 tick_last1; + g_timerCount1++; + tick_last1 = (UINT32)LOS_TickCountGet(); // 获取当前Tick数 + printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); +} + +void Timer2_Callback(UINT32 arg) // 回调函数2 +{ + UINT32 tick_last2; + tick_last2 = (UINT32)LOS_TickCountGet(); + g_timerCount2++; + printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); +} + +void Timer_example(void) +{ + UINT32 ret; + UINT32 id1; // timer id1 + UINT32 id2; // timer id2 + UINT32 tickCount; + + /*创建单次软件定时器,Tick数为1000,启动到1000Tick数时执行回调函数1 */ + LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); + + /*创建周期性软件定时器,每100Tick数执行回调函数2 */ + LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); + printf("create Timer1 success\n"); + + LOS_SwtmrStart(id1); //启动单次软件定时器 + printf("start Timer1 success\n"); + + LOS_TaskDelay(200); //延时200Tick数 + LOS_SwtmrTimeGet(id1, &tickCount); // 获得单次软件定时器剩余Tick数 + printf("tickCount=%d\n", tickCount); + + LOS_SwtmrStop(id1); // 停止软件定时器 + printf("stop Timer1 success\n"); + + LOS_SwtmrStart(id1); + LOS_TaskDelay(1000); + + LOS_SwtmrStart(id2); // 启动周期性软件定时器 + printf("start Timer2\n"); + + LOS_TaskDelay(1000); + LOS_SwtmrStop(id2); + ret = LOS_SwtmrDelete(id2); // 删除软件定时器 + if (ret == LOS_OK) { + printf("delete Timer2 success\n"); + } +} + +UINT32 Example_TaskEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S task1; + + /* 锁任务调度 */ + LOS_TaskLock(); + + /* 创建任务1 */ + (VOID)memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); + task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; + task1.pcName = "TimerTsk"; + task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + task1.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_testTaskId01, &task1); + if (ret != LOS_OK) { + printf("TimerTsk create failed.\n"); + return LOS_NOK; + } + + /* 解锁任务调度 */ + LOS_TaskUnlock(); + + return LOS_OK; +} +``` + + +### 结果验证 + +编译烧录运行,输出结果如下: + +``` +create Timer1 success +start Timer1 success +tickCount=798 +stop Timer1 success +g_timerCount1=1, tick_last1=1208 +delete Timer1 sucess +start Timer2 +g_timerCount2=1 tick_last2=1313 +g_timerCount2=2 tick_last2=1413 +g_timerCount2=3 tick_last2=1513 +g_timerCount2=4 tick_last2=1613 +g_timerCount2=5 tick_last2=1713 +g_timerCount2=6 tick_last2=1813 +g_timerCount2=7 tick_last2=1913 +g_timerCount2=8 tick_last2=2013 +g_timerCount2=9 tick_last2=2113 +g_timerCount2=10 tick_last2=2213 +delete Timer2 success +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-task-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-task-basic.md deleted file mode 100644 index a9a5a554cf..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-task-basic.md +++ /dev/null @@ -1,96 +0,0 @@ -# 基本概念 - -- [任务相关概念](#section673132352511) -- [任务运行机制](#section176294469251) - -从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。 - -OpenHarmony LiteOS-M的任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。任务模块具有如下特性: - -- 支持多任务。 -- 一个任务表示一个线程。 -- 抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 -- 相同优先级任务支持时间片轮转调度方式。 -- 共有32个优先级\[0-31\],最高优先级为0,最低优先级为31。 - -## 任务相关概念 - -**任务状态** - -任务有多种运行状态。系统初始化完成后,创建的任务就可以在系统中竞争一定的资源,由内核进行调度。 - -任务状态通常分为以下四种: - -- 就绪(Ready):该任务在就绪队列中,只等待CPU。 -- 运行(Running):该任务正在执行。 -- 阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、任务正在等待信号量、读写队列或者等待事件等。 -- 退出态(Dead):该任务运行结束,等待系统回收资源。 - -**任务状态迁移** - -**图 1** 任务状态示意图 -![](figure/任务状态示意图.png "任务状态示意图") - -**任务状态迁移说明:** - -- 就绪态→运行态 - - 任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,从而进入运行态,同时该任务从就绪队列中移出。 - -- 运行态→阻塞态 - - 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,将该任务插入到对应的阻塞队列中,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。 - -- 阻塞态→就绪态(阻塞态→运行态) - - 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。 - -- 就绪态→阻塞态 - - 任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务从就绪队列中删除,不会参与任务调度,直到该任务被恢复。 - -- 运行态→就绪态 - - 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。 - -- 运行态→退出态 - - 运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。 - -- 阻塞态→退出态 - - 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。 - - -**任务ID** - -任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。 - -**任务优先级** - -优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,就绪队列中最高优先级的任务将得到执行。 - -**任务入口函数** - -新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。 - -**任务栈** - -每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。 - -**任务上下文** - -任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行,可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。因此在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。 - -**任务控制块TCB** - -每个任务都含有一个任务控制块\(TCB\)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。 - -**任务切换** - -任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。 - -## 任务运行机制 - -用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-task-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-task-guide.md deleted file mode 100644 index 29b1538d8b..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-task-guide.md +++ /dev/null @@ -1,324 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [结果验证](#section189023104457) - - -任务创建后,内核可以执行锁任务调度,解锁任务调度,挂起,恢复,延时等操作,同时也可以设置任务优先级,获取任务优先级。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的任务管理模块提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 任务管理模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

创建和删除任务

-

LOS_TaskCreateOnly

-

创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态。

-

LOS_TaskCreate

-

创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务。

-

LOS_TaskDelete

-

删除指定的任务。

-

控制任务状态

-

LOS_TaskResume

-

恢复挂起的任务,使该任务进入ready状态。

-

LOS_TaskSuspend

-

挂起指定的任务,然后切换任务。

-

LOS_TaskJoin

-

挂起当前任务,等待指定任务运行结束并回收其任务控制块资源。

-

LOS_TaskDetach

-

修改任务的joinable属性为detach属性,detach属性的任务运行结束会自动回收任务控制块资源。

-

LOS_TaskDelay

-

任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态。传入参数为Tick数目。

-

LOS_Msleep

-

传入参数为毫秒数,转换为Tick数目,调用LOS_TaskDelay。

-

LOS_TaskYield

-

当前任务时间片设置为0,释放CPU,触发调度运行就绪任务队列中优先级最高的任务。

-

控制任务调度

-

LOS_TaskLock

-

锁任务调度,但任务仍可被中断打断。

-

LOS_TaskUnlock

-

解锁任务调度。

-

LOS_Schedule

-

触发任务调度。

-

控制任务优先级

-

LOS_CurTaskPriSet

-

设置当前任务的优先级。

-

LOS_TaskPriSet

-

设置指定任务的优先级。

-

LOS_TaskPriGet

-

获取指定任务的优先级。

-

获取任务信息

-

LOS_CurTaskIDGet

-

获取当前任务的ID。

-

LOS_NextTaskIDGet

-

获取任务就绪队列中优先级最高的任务的ID。

-

LOS_NewTaskIDGet

-

等同LOS_NextTaskIDGet。

-

LOS_CurTaskNameGet

-

获取当前任务的名称。

-

LOS_TaskNameGet

-

获取指定任务的名称。

-

LOS_TaskStatusGet

-

获取指定任务的状态。

-

LOS_TaskInfoGet

-

获取指定任务的信息,包括任务状态、优先级、任务栈大小、栈顶指针SP、任务入口函数、已使用的任务栈大小等。

-

LOS_TaskIsRunning

-

获取任务模块是否已经开始调度运行。

-

任务信息维测

-

LOS_TaskSwitchInfoGet

-

获取任务切换信息,需要开启宏LOSCFG_BASE_CORE_EXC_TSK_SWITCH。

-
- -## 开发流程 - -本节介绍任务模块的典型场景开发流程: - -1. 锁任务调度LOS\_TaskLock,防止高优先级任务调度。 -2. 创建任务LOS\_TaskCreate。 -3. 解锁任务LOS\_TaskUnlock,让任务按照优先级进行调度。 -4. 延时任务LOS\_TaskDelay,任务延时等待。 -5. 挂起指定的任务LOS\_TaskSuspend,任务挂起等待恢复操作。 -6. 恢复挂起的任务LOS\_TaskResume。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 执行Idle任务时,会对待回收链表中的任务控制块和任务栈进行回收。 ->- 任务名是指针,并没有分配空间,在设置任务名时,禁止将局部变量的地址赋值给任务名指针。 ->- 任务栈的大小按8字节大小对齐。确定任务栈大小的原则是,够用就行,多了浪费,少了任务栈溢出。 ->- 挂起当前任务时,如果已经锁任务调度,则无法挂起。 ->- Idle任务及软件定时器任务不能被挂起或者删除。 ->- 在中断处理函数中或者在锁任务的情况下,执行LOS\_TaskDelay会失败。 ->- 锁任务调度,并不关中断,因此任务仍可被中断打断。 ->- 锁任务调度必须和解锁任务调度配合使用。 ->- 设置任务优先级时可能会发生任务调度。 ->- 可配置的系统最大任务数是指:整个系统的任务总个数,而非用户能使用的任务个数。例如:系统软件定时器多占用一个任务资源,那么用户能使用的任务资源就会减少一个。 ->- LOS\_CurTaskPriSet和LOS\_TaskPriSet接口不能在中断中使用,也不能用于修改软件定时器任务的优先级。 ->- LOS\_TaskPriGet接口传入的task ID对应的任务未创建或者超过最大任务数,统一返回-1。 ->- 在删除任务时要保证任务申请的资源(如互斥锁、信号量等)已被释放。 - -## 编程实例 - -本实例介绍基本的任务操作方法,包含2个不同优先级任务的创建、任务延时、任务锁与解锁调度、挂起和恢复等操作,阐述任务优先级调度的机制以及各接口的应用。示例代码如下: - -``` -UINT32 g_taskHiId; -UINT32 g_taskLoId; -#define TSK_PRIOR_HI 4 -#define TSK_PRIOR_LO 5 - -UINT32 Example_TaskHi(VOID) -{ - UINT32 ret; - - printf("Enter TaskHi Handler.\n"); - - /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务(TaskLo任务) */ - ret = LOS_TaskDelay(100); - if (ret != LOS_OK) { - printf("Delay TaskHi Failed.\n"); - return LOS_NOK; - } - - /* 100个Ticks时间到了后,该任务恢复,继续执行 */ - printf("TaskHi LOS_TaskDelay Done.\n"); - - /* 挂起自身任务 */ - ret = LOS_TaskSuspend(g_taskHiId); - if (ret != LOS_OK) { - printf("Suspend TaskHi Failed.\n"); - return LOS_NOK; - } - printf("TaskHi LOS_TaskResume Success.\n"); - return ret; -} - -/* 低优先级任务入口函数 */ -UINT32 Example_TaskLo(VOID) -{ - UINT32 ret; - - printf("Enter TaskLo Handler.\n"); - - /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务 */ - ret = LOS_TaskDelay(100); - if (ret != LOS_OK) { - printf("Delay TaskLo Failed.\n"); - return LOS_NOK; - } - - printf("TaskHi LOS_TaskSuspend Success.\n"); - - /* 恢复被挂起的任务g_taskHiId */ - ret = LOS_TaskResume(g_taskHiId); - if (ret != LOS_OK) { - printf("Resume TaskHi Failed.\n"); - return LOS_NOK; - } - return ret; -} - -/* 任务测试入口函数,创建两个不同优先级的任务 */ -UINT32 Example_TskCaseEntry(VOID) -{ - UINT32 ret; - TSK_INIT_PARAM_S initParam = { 0 }; - - /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ - LOS_TaskLock(); - - printf("LOS_TaskLock() Success!\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; - initParam.usTaskPrio = TSK_PRIOR_HI; - initParam.pcName = "TaskHi"; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - initParam.uwResved = LOS_TASK_ATTR_JOINABLE; - /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ - ret = LOS_TaskCreate(&g_taskHiId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - - printf("Example_TaskHi create Failed!\n"); - return LOS_NOK; - } - - printf("Example_TaskHi create Success!\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; - initParam.usTaskPrio = TSK_PRIOR_LO; - initParam.pcName = "TaskLo"; - initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; - initParam.uwResved = 0; /* detach 属性 */ - - /* 创建低优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ - ret = LOS_TaskCreate(&g_taskLoId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - printf("Example_TaskLo create Failed!\n"); - return LOS_NOK; - } - - printf("Example_TaskLo create Success!\n"); - - /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ - LOS_TaskUnlock(); - - ret = LOS_TaskJoin(g_taskHiId, NULL); - if (ret != LOS_OK) { - printf("Join Example_TaskHi Failed!\n"); - } else { - printf("Join Example_TaskHi Success!\n"); - } - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -LOS_TaskLock() Success! -Example_TaskHi create Success! -Example_TaskLo create Success! -Enter TaskHi Handler. -Enter TaskLo Handler. -TaskHi LOS_TaskDelay Done. -TaskHi LOS_TaskSuspend Success. -TaskHi LOS_TaskResume Success. -Join Example_TaskHi Success! -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-task.md b/zh-cn/device-dev/kernel/kernel-mini-basic-task.md index 89a03fb58f..e7d56d101a 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-task.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic-task.md @@ -1,7 +1,315 @@ -# 任务管理 +# 任务管理 -- **[基本概念](kernel-mini-basic-task-basic.md)** +- [基本概念](#基本概念) + - [任务相关概念](#任务相关概念) + - [任务运行机制](#任务运行机制) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-basic-task-guide.md)** +## 基本概念 +从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。 +OpenHarmony LiteOS-M的任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。任务模块具有如下特性: + +- 支持多任务。 + +- 一个任务表示一个线程。 + +- 抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 + +- 相同优先级任务支持时间片轮转调度方式。 + +- 共有32个优先级[0-31],最高优先级为0,最低优先级为31。 + + +### 任务相关概念 + +**任务状态** + +任务有多种运行状态。系统初始化完成后,创建的任务就可以在系统中竞争一定的资源,由内核进行调度。 + +任务状态通常分为以下四种: + +- 就绪(Ready):该任务在就绪队列中,只等待CPU。 + +- 运行(Running):该任务正在执行。 + +- 阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、任务正在等待信号量、读写队列或者等待事件等。 + +- 退出态(Dead):该任务运行结束,等待系统回收资源。 + +**任务状态迁移** + +**图1** 任务状态示意图 +![zh-cn_image_0000001200612002](figures/zh-cn_image_0000001200612002.png) + +**任务状态迁移说明:** + +- 就绪态→运行态 + 任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,从而进入运行态,同时该任务从就绪队列中移出。 + +- 运行态→阻塞态 + 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,将该任务插入到对应的阻塞队列中,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。 + +- 阻塞态→就绪态(阻塞态→运行态) + 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。 + +- 就绪态→阻塞态 + 任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务从就绪队列中删除,不会参与任务调度,直到该任务被恢复。 + +- 运行态→就绪态 + 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。 + +- 运行态→退出态 + 运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。 + +- 阻塞态→退出态 + 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。 + +**任务ID** + +任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。 + +**任务优先级** + +优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,就绪队列中最高优先级的任务将得到执行。 + +**任务入口函数** + +新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。 + +**任务栈** + +每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。 + +**任务上下文** + +任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行,可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。因此在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。 + +**任务控制块TCB** + +每个任务都含有一个任务控制块(TCB)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。 + +**任务切换** + +任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。 + + +### 任务运行机制 + +用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。 + + +## 接口说明 + +OpenHarmony LiteOS-M内核的任务管理模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表1** 任务管理模块接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 创建和删除任务 | LOS_TaskCreateOnly | 创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态。 | +| LOS_TaskCreate | 创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务。 | +| LOS_TaskDelete | 删除指定的任务。 | +| 控制任务状态 | LOS_TaskResume | 恢复挂起的任务,使该任务进入ready状态。 | +| LOS_TaskSuspend | 挂起指定的任务,然后切换任务。 | +| LOS_TaskJoin | 挂起当前任务,等待指定任务运行结束并回收其任务控制块资源 | +| LOS_TaskDelay | 任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态。传入参数为Tick数目。 | +| LOS_Msleep | 传入参数为毫秒数,转换为Tick数目,调用LOS_TaskDelay。 | +| LOS_TaskYield | 当前任务时间片设置为0,释放CPU,触发调度运行就绪任务队列中优先级最高的任务。 | +| 控制任务调度 | LOS_TaskLock | 锁任务调度,但任务仍可被中断打断。 | +| LOS_TaskUnlock | 解锁任务调度。 | +| LOS_Schedule | 触发任务调度。 | +| 控制任务优先级 | LOS_CurTaskPriSet | 设置当前任务的优先级。 | +| LOS_TaskPriSet | 设置指定任务的优先级。 | +| LOS_TaskPriGet | 获取指定任务的优先级。 | +| 获取任务信息 | LOS_CurTaskIDGet | 获取当前任务的ID。 | +| LOS_NextTaskIDGet | 获取任务就绪队列中优先级最高的任务的ID。 | +| LOS_NewTaskIDGet | 等同LOS_NextTaskIDGet。 | +| LOS_CurTaskNameGet | 获取当前任务的名称。 | +| LOS_TaskNameGet | 获取指定任务的名称。 | +| LOS_TaskStatusGet | 获取指定任务的状态。 | +| LOS_TaskInfoGet | 获取指定任务的信息,包括任务状态、优先级、任务栈大小、栈顶指针SP、任务入口函数、已使用的任务栈大小等。 | +| LOS_TaskIsRunning | 获取任务模块是否已经开始调度运行。 | +| 任务信息维测 | LOS_TaskSwitchInfoGet | 获取任务切换信息,需要开启宏LOSCFG_BASE_CORE_EXC_TSK_SWITCH。 | + + +## 开发流程 + +本节介绍任务模块的典型场景开发流程: + +1. 锁任务调度LOS_TaskLock,防止高优先级任务调度。 + +2. 创建任务LOS_TaskCreate。 + +3. 解锁任务LOS_TaskUnlock,让任务按照优先级进行调度。 + +4. 延时任务LOS_TaskDelay,任务延时等待。 + +5. 挂起指定的任务LOS_TaskSuspend,任务挂起等待恢复操作。 + +6. 恢复挂起的任务LOS_TaskResume。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 执行Idle任务时,会对待回收链表中的任务控制块和任务栈进行回收。 +> +> - 任务名是指针,并没有分配空间,在设置任务名时,禁止将局部变量的地址赋值给任务名指针。 +> +> - 任务栈的大小按8字节大小对齐。确定任务栈大小的原则是,够用就行,多了浪费,少了任务栈溢出。 +> +> - 挂起当前任务时,如果已经锁任务调度,则无法挂起。 +> +> - Idle任务及软件定时器任务不能被挂起或者删除。 +> +> - 在中断处理函数中或者在锁任务的情况下,执行LOS_TaskDelay会失败。 +> +> - 锁任务调度,并不关中断,因此任务仍可被中断打断。 +> +> - 锁任务调度必须和解锁任务调度配合使用。 +> +> - 设置任务优先级时可能会发生任务调度。 +> +> - 可配置的系统最大任务数是指:整个系统的任务总个数,而非用户能使用的任务个数。例如:系统软件定时器多占用一个任务资源,那么用户能使用的任务资源就会减少一个。 +> +> - LOS_CurTaskPriSet和LOS_TaskPriSet接口不能在中断中使用,也不能用于修改软件定时器任务的优先级。 +> +> - LOS_TaskPriGet接口传入的task ID对应的任务未创建或者超过最大任务数,统一返回-1。 +> +> - 在删除任务时要保证任务申请的资源(如互斥锁、信号量等)已被释放。 + + +## 编程实例 + +本实例介绍基本的任务操作方法,包含2个不同优先级任务的创建、任务延时、任务锁与解锁调度、挂起和恢复等操作,阐述任务优先级调度的机制以及各接口的应用。示例代码如下: + +``` +UINT32 g_taskHiId; +UINT32 g_taskLoId; +#define TSK_PRIOR_HI 4 +#define TSK_PRIOR_LO 5 + +UINT32 Example_TaskHi(VOID) +{ + UINT32 ret; + + printf("Enter TaskHi Handler.\n"); + + /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务(TaskLo任务) */ + ret = LOS_TaskDelay(100); + if (ret != LOS_OK) { + printf("Delay TaskHi Failed.\n"); + return LOS_NOK; + } + + /* 100个Ticks时间到了后,该任务恢复,继续执行 */ + printf("TaskHi LOS_TaskDelay Done.\n"); + + /* 挂起自身任务 */ + ret = LOS_TaskSuspend(g_taskHiId); + if (ret != LOS_OK) { + printf("Suspend TaskHi Failed.\n"); + return LOS_NOK; + } + printf("TaskHi LOS_TaskResume Success.\n"); + return ret; +} + +/* 低优先级任务入口函数 */ +UINT32 Example_TaskLo(VOID) +{ + UINT32 ret; + + printf("Enter TaskLo Handler.\n"); + + /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务 */ + ret = LOS_TaskDelay(100); + if (ret != LOS_OK) { + printf("Delay TaskLo Failed.\n"); + return LOS_NOK; + } + + printf("TaskHi LOS_TaskSuspend Success.\n"); + + /* 恢复被挂起的任务g_taskHiId */ + ret = LOS_TaskResume(g_taskHiId); + if (ret != LOS_OK) { + printf("Resume TaskHi Failed.\n"); + return LOS_NOK; + } + return ret; +} + +/* 任务测试入口函数,创建两个不同优先级的任务 */ +UINT32 Example_TskCaseEntry(VOID) +{ + UINT32 ret; + TSK_INIT_PARAM_S initParam; + + /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success!\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi; + initParam.usTaskPrio = TSK_PRIOR_HI; + initParam.pcName = "TaskHi"; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + initParam.uwResved = 0; /* detach 属性 */ + + /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ + ret = LOS_TaskCreate(&g_taskHiId, &initParam); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + + printf("Example_TaskHi create Failed!\n"); + return LOS_NOK; + } + + printf("Example_TaskHi create Success!\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo; + initParam.usTaskPrio = TSK_PRIOR_LO; + initParam.pcName = "TaskLo"; + initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; + + /* 创建低优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ + ret = LOS_TaskCreate(&g_taskLoId, &initParam); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + printf("Example_TaskLo create Failed!\n"); + return LOS_NOK; + } + + printf("Example_TaskLo create Success!\n"); + + /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ + LOS_TaskUnlock(); + ret = LOS_TaskJoin(g_taskHiId, NULL); + if (ret != LOS_OK) { + printf("Join Example_TaskHi Failed!\n"); + } else { + printf("Join Example_TaskHi Success!\n"); + } + return LOS_OK; +} +``` + + +### 结果验证 + +编译运行得到的结果为: + +``` +LOS_TaskLock() Success! +Example_TaskHi create Success! +Example_TaskLo create Success! +Enter TaskHi Handler. +Enter TaskLo Handler. +TaskHi LOS_TaskDelay Done. +TaskHi LOS_TaskSuspend Success. +TaskHi LOS_TaskResume Success. +Join Example_TaskHi Success! +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-time-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic-time-basic.md deleted file mode 100644 index afdc202def..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-time-basic.md +++ /dev/null @@ -1,23 +0,0 @@ -# 基本概念 - -- [时间单位:](#section97172532397) - -时间管理以系统时钟为基础,给应用程序提供所有和时间有关的服务。 - -系统时钟是由定时器/计数器产生的输出脉冲触发中断产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。 - -用户以秒、毫秒为单位计时,而操作系统以Tick为单位计时,当用户需要对系统进行操作时,例如任务挂起、延时等,此时需要时间管理模块对Tick和秒/毫秒进行转换。 - -OpenHarmony LiteOS-M内核时间管理模块提供时间转换、统计功能。 - -## 时间单位: - -- Cycle - - 系统最小的计时单位。Cycle的时长由系统主时钟频率决定,系统主时钟频率就是每秒钟的Cycle数。 - -- Tick - - Tick是操作系统的基本时间单位,由用户配置的每秒Tick数决定。 - - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic-time-guide.md b/zh-cn/device-dev/kernel/kernel-mini-basic-time-guide.md deleted file mode 100644 index f987de0780..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-basic-time-guide.md +++ /dev/null @@ -1,157 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section127752801718) - - [示例代码](#section321653551711) - - [结果验证](#section4366193318167) - - -用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系时,需要使用到时间管理模块的接口。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 - -**表 1** 时间管理接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

时间转换

-

LOS_MS2Tick

-

毫秒转换成Tick

-

LOS_Tick2MS

-

Tick转化为毫秒

-

OsCpuTick2MS

-

Cycle数目转化为毫秒,使用2个UINT32类型的数值分别表示结果数值的高、低32位。

-

OsCpuTick2US

-

Cycle数目转化为微秒,使用2个UINT32类型的数值分别表示结果数值的高、低32位。

-

时间统计

-

LOS_SysClockGet

-

获取系统时钟

-

LOS_TickCountGet

-

获取自系统启动以来的Tick数

-

LOS_CyclePerTickGet

-

获取每个Tick多少Cycle数

-
- -## 开发流程 - -时间管理的典型开发流程: - -1. 根据实际需求,完成板级配置适配,并配置系统主时钟频率OS\_SYS\_CLOCK(单位Hz)和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND。OS\_SYS\_CLOCK的默认值基于硬件平台配置。 -2. 调用时钟转换/统计接口。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 时间管理不是单独的功能模块,依赖于OS\_SYS\_CLOCK和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND两个配置选项。 ->- 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间使用。 ->- 配置选项维护在开发板工程的文件target\_config.h。 - -## 编程实例 - -### 实例描述 - -在下面的例子中,介绍了时间管理的基本方法,包括: - -1. 时间转换:将毫秒数转换为Tick数,或将Tick数转换为毫秒数。 -2. 时间统计:每Tick的Cycle数、自系统启动以来的Tick数和延迟后的Tick数。 - -### 示例代码 - -前提条件: - -- 使用每秒的Tick数LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND的默认值100。 -- 配好OS\_SYS\_CLOCK系统主时钟频率。 - -时间转换: - -``` -VOID Example_TransformTime(VOID) -{ - UINT32 ms; - UINT32 tick; - - tick = LOS_MS2Tick(10000); // 10000ms转换为tick - dprintf("tick = %d \n", tick); - ms = LOS_Tick2MS(100); // 100tick转换为ms - dprintf("ms = %d \n", ms); -} -``` - -时间统计和时间延迟: - -``` -VOID Example_GetTime(VOID) -{ - UINT32 cyclePerTick; - UINT64 tickCount; - - cyclePerTick = LOS_CyclePerTickGet(); - if(0 != cyclePerTick) { - dprintf("LOS_CyclePerTickGet = %d \n", cyclePerTick); - } - - tickCount = LOS_TickCountGet(); - if(0 != tickCount) { - dprintf("LOS_TickCountGet = %d \n", (UINT32)tickCount); - } - - LOS_TaskDelay(200); - tickCount = LOS_TickCountGet(); - if(0 != tickCount) { - dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)tickCount); - } -} -``` - -### 结果验证 - -编译运行得到的结果为: - -时间转换: - -``` -tick = 1000 -ms = 1000 -``` - -时间统计和时间延迟: - -``` -LOS_CyclePerTickGet = 495000 -LOS_TickCountGet = 1 -LOS_TickCountGet after delay = 201 -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-basic.md b/zh-cn/device-dev/kernel/kernel-mini-basic.md index 82230d2f4a..0d44f0cb00 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-basic.md +++ b/zh-cn/device-dev/kernel/kernel-mini-basic.md @@ -1,15 +1,14 @@ -# 基础内核 +# 基础内核 -- **[中断管理](kernel-mini-basic-interrupt.md)** -- **[任务管理](kernel-mini-basic-task.md)** +- **[中断管理](kernel-mini-basic-interrupt.md)** -- **[内存管理](kernel-mini-basic-memory.md)** +- **[任务管理](kernel-mini-basic-task.md)** -- **[内核通信机制](kernel-mini-basic-ipc.md)** +- **[内存管理](kernel-mini-basic-memory.md)** -- **[时间管理](kernel-basic-mini-time.md)** - -- **[软件定时器](kernel-mini-basic-soft.md)** +- **[内核通信机制](kernel-mini-basic-ipc.md)** +- **[时间管理](kernel-basic-mini-time.md)** +- **[软件定时器](kernel-mini-basic-soft.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-debug-lms.md b/zh-cn/device-dev/kernel/kernel-mini-debug-lms.md deleted file mode 100644 index faf8e495fd..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-debug-lms.md +++ /dev/null @@ -1,293 +0,0 @@ -# LMS调测 - -- [基本概念](#section1) - -- [运行机制](#section2) - -- [接口说明](#section3) - -- [开发指导](#section4) - - - [开发流程](#section4.1.1) - - - [编程实例](#section4.1.2) - - - [实例代码](#section4.1.3) - - - [结果验证](#section4.1.4) - - -## 基本概念 -LMS全称为Lite Memory Sanitizer,是一种实时检测内存操作合法性的调测工具。LMS能够实时检测缓冲区溢出(buffer overflow),释放后使用(use after free) 和重复释放(double Free), 在异常发生的第一时间通知操作系统,结合backtrace等定位手段,能准确定位到产生内存问题的代码行,极大提升内存问题定位效率。 - -## 运行机制 -LMS使用影子内存映射标记系统内存的状态,一共可标记为三个状态:可读写,不可读写,已释放。影子内存存放在内存池的尾部。 - -- 内存从堆上申请后,会将数据区的影子内存设置为“可读写”状态,并将头结点区的影子内存设置为“不可读写”状态。 - -- 内存在堆上被释放时,会将被释放内存的影子内存设置为“已释放”状态。 - -- 编译代码时,会在代码中的读写指令前插入检测函数,对地址的合法性进行检验。主要是检测访问内存的影子内存的状态值,若检测到影子内存为不可读写,则会报溢出错误;若检测到影子内存为已释放,则会报释放后使用错误。 - -- 在内存释放时,会检测被释放地址的影子内存状态值,若检测到影子内存非可读写,则会报重复释放错误。 - -## 接口说明 - -OpenHarmony LiteOS-M内核的LMS模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_m/blob/master/components/lms/los_lms.h)参考。 - - -1. 支持多内存池检测; - -2. 支持LOS_MemAlloc、LOS_MemAllocAlign、LOS_MemRealloc申请出的内存检测; - -3. 支持安全函数的访问检测(默认开启); - -4. 支持libc 高频函数的访问检测,包括:memset、memcpy、memmove、strcat、strcpy、strncat、strncpy。 - -5. 可动态设置的功能如下: - -**表 1** LMS模块接口说明 - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

添加指定内存池被检测

-

LOS_LmsCheckPoolAdd

-

将指定内存池的地址范围添加到LMS的内存检测链表上,当访问的地址在链表范围内时,LMS才进行合法性校验;且LOS_MemInit接口会调用该接口,默认将初始化的内存池挂入到检测链表中。

-

删除指定内存池不被检测

-

LOS_LmsCheckPoolDel

-

不检测指定内存池地址范围内的合法性校验。

-

使能指定内存段锁保护

-

LOS_LmsAddrProtect

-

为某段内存地址上锁,设置为不可读写,一旦访问则报错。

-

去能指定内存段锁保护

-

LOS_LmsAddrDisableProtect

-

为某段内存地址解锁,设置为可读写。

-
- - -## 开发指导 - -### 开发流程 - -开启LMS调测的典型流程如下: - -1. 配置LMS模块相关宏。 - - 配置LMS控制宏LOSCFG_KERNEL_LMS,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Lite Memory Sanitizer"中打开: - - | 配置项 | menuconfig选项 | 含义 | 设置值 | - | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | - | LOSCFG_KERNEL_LMS | Enable Lms Feature | Lms模块的裁剪开关 | YES/NO | - | LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms check pool max num | LMS支持的检测内存池最大个数 | INT | - | LOSCFG_LMS_LOAD_CHECK | Enable lms read check | LMS内存读检测的裁剪开关 | YES/NO | - | LOSCFG_LMS_STORE_CHECK | Enable lms write check | LMS内存写检测的裁剪开关 | YES/NO | - | LOSCFG_LMS_CHECK_STRICT | Enable lms strict check, byte-by-byte | LMS内存逐字节严格检测的裁剪开关 | YES/NO | - -2. 在被检测模块的编译脚本中,增加LMS检测编译选项-fsanitize=kernel-address。 - -3. 为避免编译器优化,增加-O0编译选项。 - -4. gcc与clang编译选项存在差异,参照如下示例: - - ``` - if ("$ohos_build_compiler_specified" == "gcc") { - cflags_c = [ - "-O0", - "-fsanitize=kernel-address", - ] - } else { - cflags_c = [ - "-O0", - "-fsanitize=kernel-address", - "-mllvm", - "-asan-instrumentation-with-call-threshold=0", - "-mllvm", - "-asan-stack=0", - "-mllvm", - "-asan-globals=0", - ] - } - ``` - -5. 重新编译,查看串口输出。如果检测到内存问题,会输出检测结果。 - -### 编程实例 - - 本实例实现如下功能: - - 1. 创建一个用于Lms测试的任务。 - - 2. 构造内存溢出错误和释放后使用错误。 - - 3. 添加-fsanitize=kernel-address后编译执行,观察输出结果 - -### 示例代码 - -实例代码如下: - -```C -#define PAGE_SIZE (0x1000U) -#define INDEX_MAX 20 - -UINT32 g_lmsTestTaskId; -char g_testLmsPool[2 * PAGE_SIZE]; - -STATIC VOID testPoolInit(void) -{ - UINT32 ret = LOS_MemInit(g_testLmsPool, 2 * PAGE_SIZE); - if (ret != 0) { - PRINT_ERR("%s failed, ret = 0x%x\n", __FUNCTION__, ret); - return; - } -} - -static VOID LmsTestOsmallocOverflow(VOID) -{ - PRINTK("\n######%s start ######\n", __FUNCTION__); - UINT32 i; - CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); - PRINTK("str[%2d]=0x%2x ", INDEX_MAX, str[INDEX_MAX]); /* trigger heap overflow at str[INDEX_MAX] */ - PRINTK("\n######%s stop ######\n", __FUNCTION__); -} - -static VOID LmsTestUseAfterFree(VOID) -{ - PRINTK("\n######%s start ######\n", __FUNCTION__); - UINT32 i; - CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); - LOS_MemFree(g_testLmsPool, str); - PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */ - PRINTK("\n######%s stop ######\n", __FUNCTION__); -} - -VOID LmsTestCaseTask(VOID) -{ - testPoolInit(); - LmsTestOsmallocOverflow(); - LmsTestUseAfterFree(); -} - -UINT32 Example_Lms_test(VOID){ - UINT32 ret; - TSK_INIT_PARAM_S lmsTestTask; - /* 创建用于lms测试的任务 */ - memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S)); - lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask; - lmsTestTask.pcName = "TestLmsTsk"; /* 测试任务名称 */ - lmsTestTask.uwStackSize = 0x800; - lmsTestTask.usTaskPrio = 5; - lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED; - ret = LOS_TaskCreate(&g_lmsTestTaskId, &lmsTestTask); - if(ret != LOS_OK){ - PRINT_ERR("LmsTestTask create failed .\n"); - return LOS_NOK; - } - return LOS_OK; -} -``` - -### 结果验证 - -输出结果如下: - -```c -######LmsTestOsmallocOverflow start ###### -[ERR]***** Kernel Address Sanitizer Error Detected Start ***** -[ERR]Heap buffer overflow error detected -[ERR]Illegal READ address at: [0x4157a3c8] -[ERR]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2] -OsBackTrace fp = 0x402c0f88 -runTask->taskName = LmsTestCaseTask -runTask->taskID = 2 -*******backtrace begin******* -traceback fp fixed, trace using fp = 0x402c0fd0 -traceback 0 -- lr = 0x400655a4 fp = 0x402c0ff8 -traceback 1 -- lr = 0x40065754 fp = 0x402c1010 -traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 -traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca - -[LMS] Dump info around address [0x4157a3c8]: - - [0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1 - [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 - [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 - [0x4157a3c8]: [ba] dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: [2] 2 - [0x4157a3d0]: 2c 1a 00 00 00 00 00 00 | [0x4157be3d | 0]: 2 3 - [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 - [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 - [0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3 - [0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3 -[ERR]***** Kernel Address Sanitizer Error Detected End ***** -str[20]=0xffffffba -######LmsTestOsmallocOverflow stop ###### - -###### LmsTestUseAfterFree start ###### -[ERR]***** Kernel Address Sanitizer Error Detected Start ***** -[ERR]Use after free error detected -[ERR]Illegal READ address at: [0x4157a3d4] -[ERR]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3] -OsBackTrace fp = 0x402c0f90 -runTask->taskName = LmsTestCaseTask -runTask->taskID = 2 -*******backtrace begin******* -traceback fp fixed, trace using fp = 0x402c0fd8 -traceback 0 -- lr = 0x40065680 fp = 0x402c0ff8 -traceback 1 -- lr = 0x40065758 fp = 0x402c1010 -traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 -traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca - -[LMS] Dump info around address [0x4157a3d4]: - - [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 - [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 - [0x4157a3c8]: ba dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: 2 2 - [0x4157a3d0]: 2c 1a 00 00 [00] 00 00 00 | [0x4157be3d | 0]: 2 [3] - [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 - [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 - [0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2 - [0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3 - [0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3 -[ERR]***** Kernel Address Sanitizer Error Detected End ***** -str[ 0]=0x 0 -######LmsTestUseAfterFree stop ###### -``` -输出的关键信息包括: -- 错误类型: - - Heap buffer overflow堆内存越界 - - Use after free 释放后使用 -- 错误操作: - - Illegal Read非法读 - - Illegal Write非法写 - - Illegal Double free重复释放 -- 上下文: - - 当前任务信息(taskName, taskId) - - 回溯栈(backtrace) -- 出错地址的内存信息: - - 内存的值、及对应影子内存的值 - - 内存地址:内存值| [影子内存地址 | 影子内存字节内偏移]:影子内存值 - - 影子内存值:0(可读可写)、3(已释放)、2(红区)、1(填充值)。 diff --git a/zh-cn/device-dev/kernel/kernel-mini-debug.md b/zh-cn/device-dev/kernel/kernel-mini-debug.md new file mode 100644 index 0000000000..5a847c2509 --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-mini-debug.md @@ -0,0 +1,10 @@ +# 内核调测 + + +- **[内存调测](kernel-mini-memory-debug.md)** + +- **[异常调测](kernel-mini-memory-exception.md)** + +- **[Trace调测](kernel-mini-memory-trace.md)** + +- **[LMS调测](kernel-mini-memory-lms.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-cpup-basic.md b/zh-cn/device-dev/kernel/kernel-mini-extend-cpup-basic.md deleted file mode 100644 index 6d21b260ce..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-cpup-basic.md +++ /dev/null @@ -1,31 +0,0 @@ -# 基本概念 - -- [运行机制](#section96644177124) - -CPU(中央处理器,Central Processing Unit)占用率分为系统CPU占用率和任务CPU占用率。 - -系统CPU占用率(CPU Percent)是指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示系统满负荷运转。 - -任务CPU占用率指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该任务。 - -用户通过系统级的CPU占用率,判断当前系统负载是否超出设计规格。 - -通过系统中各个任务的CPU占用情况,判断各个任务的CPU占用率是否符合设计的预期。 - -## 运行机制 - -OpenHarmony LiteOS-M的CPUP(CPU Percent,系统CPU占用率)采用任务级记录的方式,在任务切换时,记录任务启动时间,任务切出或者退出时间,每次当任务退出时,系统会累加整个任务的占用时间。 - -可以在target\_config.h的中对该功能进行选配。 - -OpenHarmony LiteOS-M提供以下两种CPU占用率的信息查询: - -- 系统CPU占用率。 -- 任务CPU占用率。 - -**CPU占用率的计算方法:** - -系统CPU占用率=系统中除idle任务外其他任务运行总时间/系统运行总时间 - -任务CPU占用率=任务运行总时间/系统运行总时间 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-cpup-guide.md b/zh-cn/device-dev/kernel/kernel-mini-extend-cpup-guide.md deleted file mode 100644 index f447cb15cb..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-cpup-guide.md +++ /dev/null @@ -1,163 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section783435801510) -- [编程实例](#section460018317164) - - [实例描述](#section51413507517) - - [示例代码](#section17617965523) - - [结果验证](#section1968771515188) - - -## 接口说明 - -**表 1** 功能列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

获取系统CPU占用率

-

LOS_SysCpuUsage

-

获取当前系统CPU占用率

-

LOS_HistorySysCpuUsage

-

获取系统历史CPU占用率

-

获取任务CPU占用率

-

LOS_TaskCpuUsage

-

获取指定任务CPU占用率

-

LOS_HistoryTaskCpuUsage

-

获取指定任务历史CPU占用率

-

LOS_AllCpuUsage

-

获取所有任务CPU占用率

-

输出任务CPU占用率

-

LOS_CpupUsageMonitor

-

输出任务历史CPU占用率

-
- -## 开发流程 - -CPU占用率的典型开发流程: - -1. 调用获取系统CPU使用率函数LOS\_SysCpuUsage。 -2. 调用获取系统历史CPU使用率函数LOS\_HistorySysCpuUsage。 -3. 调用获取指定任务CPU使用率函数LOS\_TaskCpuUsage。 - - 若任务已创建,则关中断,正常获取,恢复中断; - - 若任务未创建,则返回错误码; - -4. 调用获取指定任务历史CPU使用率函数LOS\_HistoryTaskCpuUsage。 - - 若任务已创建,则关中断,根据不同模式正常获取,恢复中断; - - 若任务未创建,则返回错误码; - -5. 调用获取所有任务CPU使用率函数LOS\_AllCpuUsage。 - - 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断; - - 若CPUP未初始化或有非法入参,则返回错误码; - - -## 编程实例 - -### 实例描述 - -本实例实现如下功能: - -1. 创建一个用于CPUP测试的任务。 -2. 获取当前系统CPUP。 -3. 以不同模式获取历史系统CPUP。 -4. 获取创建的测试任务的CPUP。 -5. 以不同模式获取创建的测试任务的CPUP - -### 示例代码 - -前提条件: - -在target\_config.h中将LOSCFG\_BASE\_CORE\_CPUP配置项打开。 - -代码实现如下: - -``` -#include "los_task.h" -#include "los_cpup.h" -#define MODE 4 -UINT32 g_cpuTestTaskID; -VOID ExampleCpup(VOID) -{ - printf("entry cpup test example\n"); - while(1) { - usleep(100); - } -} -UINT32 ItCpupTest(VOID) -{ - UINT32 ret; - UINT32 cpupUse; - TSK_INIT_PARAM_S cpupTestTask = { 0 }; - memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S)); - cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup; - cpupTestTask.pcName = "TestCpupTsk"; - cpupTestTask.uwStackSize = 0x800; - cpupTestTask.usTaskPrio = 5; - ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask); - if(ret != LOS_OK) { - printf("cpupTestTask create failed .\n"); - return LOS_NOK; - } - - usleep(100); - - /* 获取当前系统cpu占用率 */ - cpupUse = LOS_SysCpuUsage(); - printf("the current system cpu usage is: %u.%u\n", - cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); - - cpupUse = LOS_HistorySysCpuUsage(CPU_LESS_THAN_1S); - /* 获取指定任务的cpu占用率,该测试例程中指定的任务为以上创建的cpup测试任务 */ - printf("the history system cpu usage in all time:%u.%u\n", - cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); - cpupUse = LOS_TaskCpuUsage(g_cpuTestTaskID); - /* 获取指定历史任务在系统启动到现在的cpu占用率,该测试例程中指定的任务为以上创建的cpup测试任务 */ - 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); - cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPU_LESS_THAN_1S); - 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); - return LOS_OK; -} -``` - -### 结果验证 - -编译运行得到的结果为: - -``` -entry cpup test example -the current system cpu usage is : 1.5 - the history system cpu usage in all time: 3.0 - cpu usage of the cpupTestTask: TaskID:10 usage: 0.0 - cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0 -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-cpup.md b/zh-cn/device-dev/kernel/kernel-mini-extend-cpup.md index 9691962674..cf7fdd3ee2 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-cpup.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend-cpup.md @@ -1,7 +1,165 @@ -# CPU占用率 +# CPU占用率 -- **[基本概念](kernel-mini-extend-cpup-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) +- [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-extend-cpup-guide.md)** +## 基本概念 +CPU(中央处理器,Central Processing Unit)占用率分为系统CPU占用率和任务CPU占用率。 +系统CPU占用率(CPU Percent)是指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示系统满负荷运转。 + +任务CPU占用率指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该任务。 + +用户通过系统级的CPU占用率,判断当前系统负载是否超出设计规格。 + +通过系统中各个任务的CPU占用情况,判断各个任务的CPU占用率是否符合设计的预期。 + + +## 运行机制 + +OpenHarmony LiteOS-M的CPUP(CPU Percent,系统CPU占用率)采用任务级记录的方式,在任务切换时,记录任务启动时间,任务切出或者退出时间,每次当任务退出时,系统会累加整个任务的占用时间。 + +可以在target_config.h的中对该功能进行选配。 + +OpenHarmony LiteOS-M提供以下两种CPU占用率的信息查询: + +- 系统CPU占用率。 + +- 任务CPU占用率。 + +**CPU占用率的计算方法:** + +系统CPU占用率=系统中除idle任务外其他任务运行总时间/系统运行总时间 + +任务CPU占用率=任务运行总时间/系统运行总时间 + + +## 接口说明 + +**表1** 功能列表 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 获取系统CPU占用率 | LOS_SysCpuUsage | 获取当前系统CPU占用率 | +| LOS_HistorySysCpuUsage | 获取系统历史CPU占用率 | +| 获取任务CPU占用率 | LOS_TaskCpuUsage | 获取指定任务CPU占用率 | +| LOS_HistoryTaskCpuUsage | 获取指定任务历史CPU占用率 | +| LOS_AllCpuUsage | 获取所有任务CPU占用率 | +| 输出任务CPU占用率 | LOS_CpupUsageMonitor | 输出任务历史CPU占用率 | + + +## 开发流程 + +CPU占用率的典型开发流程: + +1. 调用获取系统CPU使用率函数LOS_SysCpuUsage。 + +2. 调用获取系统历史CPU使用率函数LOS_HistorySysCpuUsage。 + +3. 调用获取指定任务CPU使用率函数LOS_TaskCpuUsage。 + - 若任务已创建,则关中断,正常获取,恢复中断; + - 若任务未创建,则返回错误码; + +4. 调用获取指定任务历史CPU使用率函数LOS_HistoryTaskCpuUsage。 + - 若任务已创建,则关中断,根据不同模式正常获取,恢复中断; + - 若任务未创建,则返回错误码; + +5. 调用获取所有任务CPU使用率函数LOS_AllCpuUsage。 + - 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断; + - 若CPUP未初始化或有非法入参,则返回错误码; + + +## 编程实例 + + +### 实例描述 + +本实例实现如下功能: + +1. 创建一个用于CPUP测试的任务。 + +2. 获取当前系统CPUP。 + +3. 以不同模式获取历史系统CPUP。 + +4. 获取创建的测试任务的CPUP。 + +5. 以不同模式获取创建的测试任务的CPUP + + +### 示例代码 + +前提条件: + +在target_config.h中将LOSCFG_BASE_CORE_CPUP配置项打开。 + +代码实现如下: + +``` +#include "los_task.h" +#include "los_cpup.h" +#define MODE 4 +UINT32 g_cpuTestTaskID; +VOID ExampleCpup(VOID) +{ + printf("entry cpup test example\n"); + while(1) { + usleep(100); + } +} +UINT32 ItCpupTest(VOID) +{ + UINT32 ret; + UINT32 cpupUse; + TSK_INIT_PARAM_S cpupTestTask = { 0 }; + memset(&cpupTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + cpupTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleCpup; + cpupTestTask.pcName = "TestCpupTsk"; + cpupTestTask.uwStackSize = 0x800; + cpupTestTask.usTaskPrio = 5; + ret = LOS_TaskCreate(&g_cpuTestTaskID, &cpupTestTask); + if(ret != LOS_OK) { + printf("cpupTestTask create failed .\n"); + return LOS_NOK; + } + + usleep(100); + + /* 获取当前系统cpu占用率 */ + cpupUse = LOS_SysCpuUsage(); + printf("the current system cpu usage is: %u.%u\n", + cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); + + cpupUse = LOS_HistorySysCpuUsage(CPU_LESS_THAN_1S); + /* 获取指定任务的cpu占用率,该测试例程中指定的任务为以上创建的cpup测试任务 */ + printf("the history system cpu usage in all time:%u.%u\n", + cpupUse / LOS_CPUP_PRECISION_MULT, cpupUse % LOS_CPUP_PRECISION_MULT); + cpupUse = LOS_TaskCpuUsage(g_cpuTestTaskID); + /* 获取指定历史任务在系统启动到现在的cpu占用率,该测试例程中指定的任务为以上创建的cpup测试任务 */ + 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); + cpupUse = LOS_HistoryTaskCpuUsage(g_cpuTestTaskID, CPU_LESS_THAN_1S); + 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); + return LOS_OK; +} +``` + + +### 结果验证 + +编译运行得到的结果为: +``` +entry cpup test example +the current system cpu usage is : 1.5 + the history system cpu usage in all time: 3.0 + cpu usage of the cpupTestTask: TaskID:10 usage: 0.0 + cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0 +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md b/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md deleted file mode 100644 index 49d9521d20..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-basic.md +++ /dev/null @@ -1,91 +0,0 @@ -# 基本概念 - -- [运行机制](#section139861939219) - - [符号表导出](#section15414650102716) - - [ELF文件加载](#section5221181562810) - - [ELF文件链接](#section68441639182817) - -- [ELF支持规格](#section187315541916) - - [ELF支持类型](#section1701552268) - - [ELF共享库编译链接选项](#section17292133274) - - -在硬件资源有限的小设备中,需要通过算法的动态部署能力来解决无法同时部署多种算法的问题。以开发者易用为主要考虑因素,同时考虑到多平台的通用性,LiteOS-M选择业界标准的ELF方案,方便拓展算法生态。LiteOS-M提供类似于dlopen、dlsym等接口,APP通过动态加载模块提供的接口可以加载、卸载相应算法库。如图1所示,APP需要通过三方算法库所需接口获取对应信息输出,三方算法库又依赖内核提供的基本接口,如malloc等。APP加载所需接口,并对相关的未定义符号完成重定位后,APP即可调用该接口完成功能调用。目前动态加载组件只支持arm架构。此外,待加载的共享库需要验签或者限制来源,确保系统的安全性。 - -**图 1** LiteOS-M内核动态加载架构图 -![](figure/LiteOS-M内核动态加载架构图.png "LiteOS-M内核动态加载架构图") - -## 运行机制 - -### 符号表导出 - -共享库调用内核接口需要内核主动暴露动态库所需的接口,如图2所示,该机制将符号信息编译到指定段中,调用SYM\_EXPORT宏即可完成对指定符号的信息导出。符号信息通过结构体SymInfo描述,成员包括符号名和符号地址信息,宏SYM\_EXPORT通过\_\_attribute\_\_编译属性将符号信息导入.sym.\*段中。 - -``` -typedef struct { - CHAR *name; - UINTPTR addr; -} SymInfo; - -#define SYM_EXPORT(func) \ -const SymInfo sym_##func __attribute__((section(".sym."#func))) = { \ - .name = #func, \ - .addr = (UINTPTR)func \ -}; -``` - -**图 2** 导出的符号表信息 -![](figure/导出的符号表信息.png "导出的符号表信息") - -### ELF文件加载 - -加载过程中,根据ELF文件的句柄以及程序头表的段偏移可以得到需要加载到内存的LOAD段,一般有两个段,只读段及读写段,如下所示,可以用readelf -l查看ELF文件的LOAD段信息。如图3所示,根据相应的对齐属性申请物理内存,通过每个段的加载基址及偏移将代码段或数据段写入内存中。 - -``` -$ readelf -l lib.so - -Elf file type is DYN (Shared object file) -Entry point 0x5b4 -There are 4 program headers, starting at offset 52 - -Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - EXIDX 0x000760 0x00000760 0x00000760 0x00008 0x00008 R 0x4 - LOAD 0x000000 0x00000000 0x00000000 0x0076c 0x0076c R E 0x10000 - LOAD 0x00076c 0x0001076c 0x0001076c 0x0010c 0x00128 RW 0x10000 - DYNAMIC 0x000774 0x00010774 0x00010774 0x000c8 0x000c8 RW 0x4 - - Section to Segment mapping: - Segment Sections... - 00 .ARM.exidx - 01 .hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .ARM.exidx .eh_frame - 02 .init_array .fini_array .dynamic .got .data .bss - 03 .dynamic -``` - -**图 3** ELF文件的加载过程 -![](figure/ELF文件的加载过程.png "ELF文件的加载过程") - -### ELF文件链接 - -如图4所示,通过ELF文件的.dynamic段获取重定位表,遍历表中每一个需要重定位的条目,再根据需要重定位的符号名在共享库和内核提供的导出符号表中查找相应符号并更新相应的重定位信息。 - -**图 4** ELF文件的链接过程 -![](figure/ELF文件的链接过程.png "ELF文件的链接过程") - -## ELF支持规格 - -### ELF支持类型 - -编译共享库时,添加-fPIC可以编译出位置无关代码(-fPIC为编译选项),此时共享库文件类型为ET\_DYN,其可以加载至任意有效的地址区间。 - -例:arm-none-eabi-gcc -fPIC –shared –o lib.so lib.c - -### ELF共享库编译链接选项 - -1. “-nostdlib”编译链接选项:不依赖编译器中lib库。 -2. “-nostartfiles”编译链接选项:不依赖编译器中启动相关的文件。 -3. “-fPIC”编译选项:可编译位置无关的共享库。 -4. “-z max-page-size=4”链接选项:二进制文件中可加载段的对齐字节数为4,可节约内存,可用于动态库。 -5. “-mcpu=”需要指定对应的cpu架构。 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md b/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md deleted file mode 100644 index 64f8859363..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading-guide.md +++ /dev/null @@ -1,187 +0,0 @@ -# 开发指导 - -- [接口说明](#section158501652121514) -- [开发流程](#section5241132917523) -- [编程实例](#section8708112313531) - -## 接口说明 - -**表 1** 功能列表 - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

动态加载功能接口

-

LOS_DynlinkInit

-

初始化动态链接器链表以及互斥锁

-

LOS_SoLoad

-

加载指定路径的共享库

-

LOS_FindSym

-

根据共享库句柄查找指定符号

-

LOS_SoUnload

-

卸载共享库句柄

-
- -## 开发流程 - -1. 利用arm-none-eabi-gcc交叉编译器编译共享库并制作FAT或LittleFS文件系统格式镜像烧写至flash中; -2. 在target\_config.h文件中定义宏LOSCFG\_DYNLINK为1使能动态加载模块; -3. 调用LOS\_SoLoad接口加载指定路径下的共享库; -4. 调用LOS\_FindSym接口查找指定符号,获取符号地址; -5. 调用LOS\_SoUnload卸载指定共享库句柄。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->1. 利用交叉编译器编译共享库所需要的编译选项参考ELF支持规格一节。 ->2. 制作文件系统镜像之前需要对特定单板适配FAT或LittleFS文件系统。 ->3. 共享库不依赖编译器中的libc库,不支持c++。 ->4. 共享库只能依赖内核提供的接口,不能依赖其他共享库。 - -## 编程实例 - -实例以cortex-m4单板为例。 - -1. 共享库示例代码及编译 - - 示例代码主要测试全局符号间的调用功能以及对内核接口maloc、free、memset接口的调用功能。 - - ``` - #include - #include - - int g_param = 10; - - int callee(int a, int b) - { - char *addr = malloc(g_param); - if (addr == NULL) { - return 0; - } - - memset(addr, '1', g_param); - - free(addr); - return a + b + g_param; - } - - int caller(int a, int b) - { - return callee(a, b); - } - ``` - - ``` - $ arm-none-eabi-gcc -fPIC -shared -mcpu=cortex-m4 -nostdlib -nostartfiles -z max-page-size=4 -o test.so test.c - ``` - -2. 导出共享库中使用到的malloc、free、memset符号,下述代码单独编写成一个.c文件,参与OS编译即可。 - - ``` - #include "stdlib.h" - #include "string.h" - - SYM_EXPORT(malloc); - SYM_EXPORT(free); - SYM_EXPORT(memset); - ``` - -3. 确定内核的编译环境,在对应编译器的编译链接脚本中添加如下语句,保证符号表信息在编译链接的时候输出到指定的段。 - - 在IAR编译器.icf链接脚本中添加如下语句: - - ``` - keep {section .TABLE.START}; - keep {section .sym.*}; - keep {section .table.end}; - define block SYMBOL_TABLE with fixed order - { - section .TABLE.START, - section .sym.*, - section .table.end - }; - place in ROM_region {readonly, block SYMBOL_TABLE}; - ``` - - 在gcc编译器的.ld链接脚本中添加如下语句: - - ``` - __sym_table_start = .; - KEEP(*( SORT (.sym.*))); - __sym_table_end = .; - ``` - -4. 共享库加载链接、执行与卸载 - - 示例代码主要测试LOS\_SoLoad、LOS\_FindSym、LOS\_SoUnload接口的功能是否正常以及通过LOS\_FindSym查找到的符号的调用是否正常。 - - ``` - #include "los_dynlink.h" - - VOID DynlinkTest(VOID) - { - VOID *handle = NULL; - INT32 (*func)(INT32, INT32) = NULL; - CHAR *symbolName = "caller"; - CHAR *dsoName = "/lib/test.so"; - INT32 ret; - - handle = (VOID *)LOS_SoLoad(dsoName, NULL); - if (handle == NULL) { - printf("Failed to load so\n"); - return; - } - - func = (INT32 (*)(INT32, INT32))LOS_FindSym(handle, symbolName); - if (func == NULL) { - printf("Failed to find symbol\n"); - LOS_SoUnload(handle); - return; - } - - ret = func(1, 1); - if (ret != 12) { - printf("Failed to execute function\n"); - LOS_SoUnload(handle); - return; - } - - ret = LOS_SoUnload(handle); - if (ret != 0) { - printf("Failed to unload so\n"); - } - - - printf("Success!\n"); - } - ``` - -5. 结果验证 - - ``` - Success! - ``` - - ->![](../public_sys-resources/icon-note.gif) **说明:** ->用例中文件系统路径为/lib/test.so; ->可以创建一个任务,在任务中调用DynlinkTest接口进行测试; - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading.md b/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading.md index 22214ff3fb..fd952435e7 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend-dynamic-loading.md @@ -1,7 +1,101 @@ -# +# 动态加载 -- **[基本概念](kernel-mini-extend-dynamic-loading-basic.md)** +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [符号表导出](#符号表导出) + - [ELF文件加载](#elf文件加载) + - [ELF文件链接](#elf文件链接) +- [ELF支持规格](#elf支持规格) + - [ELF支持类型](#elf支持类型) + - [ELF共享库编译链接选项](#elf共享库编译链接选项) -- **[开发指导](kernel-mini-extend-dynamic-loading-guide.md)** +## 基本概念 +在硬件资源有限的小设备中,需要通过算法的动态部署能力来解决无法同时部署多种算法的问题。以开发者易用为主要考虑因素,同时考虑到多平台的通用性,LiteOS-M选择业界标准的ELF加载方案,方便拓展算法生态。LiteOS-M提供类似于dlopen、dlsym等接口,APP通过动态加载模块提供的接口可以加载、卸载相应算法库。如图1所示,APP需要通过三方算法库所需接口获取对应信息输出,三方算法库又依赖内核提供的基本接口,如malloc等。APP加载所需接口,并对相关的未定义符号完成重定位后,APP即可调用该接口完成功能调用。目前动态加载组件只支持arm架构。此外,待加载的共享库需要验签或者限制来源,确保系统的安全性。 +**图1** LiteOS-M内核动态加载架构图 +![zh-cn_image_0000001200292052](figures/zh-cn_image_0000001200292052.png) + + +## 运行机制 + + +### 符号表导出 + +共享库调用内核接口需要内核主动暴露动态库所需的接口,如图2所示,该机制将符号信息编译到指定段中,调用SYM_EXPORT宏即可完成对指定符号的信息导出。符号信息通过结构体SymInfo描述,成员包括符号名和符号地址信息,宏SYM_EXPORT通过__attribute__编译属性将符号信息导入.sym.\*段中。 + +``` +typedef struct { + CHAR *name; + UINTPTR addr; +} SymInfo; + +#define SYM_EXPORT(func) \ +const SymInfo sym_##func __attribute__((section(".sym."#func))) = { \ + .name = #func, \ + .addr = (UINTPTR)func \ +}; +``` + +**图2** 导出的符号表信息 +![zh-cn_image_0000001245171875](figures/zh-cn_image_0000001245171875.png) + + +### ELF文件加载 + +加载过程中,根据ELF文件的句柄以及程序头表的段偏移可以得到需要加载到内存的LOAD段,一般有两个段,只读段及读写段,如下所示,可以用readelf -l查看ELF文件的LOAD段信息。如图3所示,根据相应的对齐属性申请物理内存,通过每个段的加载基址及偏移将代码段或数据段写入内存中。 + +``` +$ readelf -l lib.so + +Elf file type is DYN (Shared object file) +Entry point 0x5b4 +There are 4 program headers, starting at offset 52 + +Program Headers: + Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align + EXIDX 0x000760 0x00000760 0x00000760 0x00008 0x00008 R 0x4 + LOAD 0x000000 0x00000000 0x00000000 0x0076c 0x0076c R E 0x10000LOAD 0x00076c 0x0001076c 0x0001076c 0x0010c 0x00128 RW 0x10000 + DYNAMIC 0x000774 0x00010774 0x00010774 0x000c8 0x000c8 RW 0x4 + + Section to Segment mapping: + Segment Sections... + 00 .ARM.exidx + 01 .hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .ARM.exidx .eh_frame + 02 .init_array .fini_array .dynamic .got .data .bss + 03 .dynamic +``` + +**图3** ELF文件的加载过程 +![zh-cn_image_0000001245251887](figures/zh-cn_image_0000001245251887.png) + + +### ELF文件链接 + +如图4所示,通过ELF文件的.dynamic段获取重定位表,遍历表中每一个需要重定位的条目,再根据需要重定位的符号名在共享库和内核提供的导出符号表中查找相应符号并更新相应的重定位信息。 + +**图4** ELF文件的链接过程 +![zh-cn_image_0000001200612006](figures/zh-cn_image_0000001200612006.png) + + +## ELF支持规格 + + +### ELF支持类型 + +编译共享库时,添加-fPIC可以编译出位置无关代码(-fPIC为编译选项),此时共享库文件类型为ET_DYN,其可以加载至任意有效的地址区间。 + +例:arm-none-eabi-gcc -fPIC –shared –o lib.so lib.c + + +### ELF共享库编译链接选项 + +1. “-nostdlib”编译链接选项:不依赖编译器中lib库。 + +2. “-nostartfiles”编译链接选项:不依赖编译器中启动相关的文件。 + +3. “-fPIC”编译选项:可编译位置无关的共享库。 + +4. “-z max-page-size=4”链接选项:二进制文件中可加载段的对齐字节数为4,可节约内存,可用于动态库。 + +5. “-mcpu=”需要指定对应的cpu架构。 diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-file-fat.md b/zh-cn/device-dev/kernel/kernel-mini-extend-file-fat.md index 620dbcf9e1..3a05c20766 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-file-fat.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend-file-fat.md @@ -1,31 +1,31 @@ -# FAT +# FAT -- [基本概念](#section1772629121418) -- [开发指导](#section1149072811148) - - [驱动适配](#section19174939191414) - - [开发流程](#section131211626151513) +- [基本概念](#基本概念) +- [开发指导](#开发指导) + - [驱动适配](#驱动适配) + - [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- [编程实例](#section1133718619459) - - [实例描述](#section45337345313) - - [示例代码](#section119813171539) - - [结果验证](#section7987101232311) +## 基本概念 +FAT文件系统是File Allocation Table(文件配置表)的简称,主要包括DBR区、FAT区、DATA区三个区域。其中,FAT区各个表项记录存储设备中对应簇的信息,包括簇是否被使用、文件下一个簇的编号、是否文件结尾等。FAT文件系统有FAT12、FAT16、FAT32等多种格式,其中,12、16、32表示对应格式中FAT表项的比特数。FAT文件系统支持多种介质,特别在可移动存储介质(U盘、SD卡、移动硬盘等)上广泛使用,使嵌入式设备和Windows、Linux等桌面系统保持很好的兼容性,方便用户管理操作文件。 -## 基本概念 +OpenHarmony内核支持FAT12、FAT16与FAT32三种格式的FAT文件系统,具有代码量小、资源占用小、可裁切、支持多种物理介质等特性,并且与Windows、Linux等系统保持兼容,支持多设备、多分区识别等功能。OpenHarmony内核支持硬盘多分区,可以在主分区以及逻辑分区上创建FAT文件系统。 -FAT文件系统是File Allocation Table(文件配置表)的简称,主要包括DBR区、FAT区、DATA区三个区域。其中,FAT区各个表项记录存储设备中对应簇的信息,包括簇是否被使用、文件下一个簇的编号、是否文件结尾等。FAT文件系统有FAT12、FAT16、FAT32等多种格式,其中,12、16、32表示对应格式中FAT表项的字节数。FAT文件系统支持多种介质,特别在可移动存储介质(U盘、SD卡、移动硬盘等)上广泛使用,使嵌入式设备和Windows、Linux等桌面系统保持很好的兼容性,方便用户管理操作文件。 -OpenHarmony内核支持FAT12、FAT16与FAT32三种格式的FAT文件系统,具有代码量小、资源占用小、可裁切、支持多种物理介质等特性,并且与Windows、Linux等系统保持兼容,支持多设备、多分区识别等功能。OpenHarmony内核支持硬盘多分区,可以在主分区以及逻辑分区上创建FAT文件系统。 +## 开发指导 -## 开发指导 -### 驱动适配 +### 驱动适配 FAT文件系统的使用需要底层MMC相关驱动的支持。在一个带MMC存储设备的板子上运行FATFS,需要: -1、适配板端EMMC驱动,实现disk\_status、disk\_initialize、disk\_read、disk\_write、disk\_ioctl接口; +1、适配板端EMMC驱动,实现disk_status、disk_initialize、disk_read、disk_write、disk_ioctl接口; -2、新增fs\_config.h文件,配置FS\_MAX\_SS(存储设备最大sector大小)、FF\_VOLUME\_STRS(分区名)等信息,例如: +2、新增fs_config.h文件,配置FS_MAX_SS(存储设备最大sector大小)、FF_VOLUME_STRS(分区名)等信息,例如: ``` #define FF_VOLUME_STRS "system", "inner", "update", "user" @@ -33,51 +33,64 @@ FAT文件系统的使用需要底层MMC相关驱动的支持。在一个带MMC #define FAT_MAX_OPEN_FILES 50 ``` -### 开发流程 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- FATFS文件与目录操作: -> - 单个文件大小不超过4G。 -> - 支持同时打开的文件数最大为FAT\_MAX\_OPEN\_FILES,文件夹数最大为FAT\_MAX\_OPEN\_DIRS。 -> - 暂不支持根目录管理,文件/目录名均以分区名开头,例如“user/testfile”就是在“user”分区下名为“testfile”的文件或目录。 -> - 若需要同时多次打开同一文件,必须全部使用只读方式(O\_RDONLY)。以可写方式(O\_RDWR、O\_WRONLY等)只能打开一次。 -> - 读写指针未分离,例如以O\_APPEND(追加写)方式打开文件后,读指针也在文件尾,从头读文件前需要用户手动置位。 -> - 暂不支持文件与目录的权限管理。 -> - stat及fstat接口暂不支持查询修改时间、创建时间和最后访问时间。微软FAT协议不支持1980年以前的时间。 ->- FATFS分区挂载与卸载: -> - 支持以只读属性挂载分区。当mount函数的入参为MS\_RDONLY时,所有的带有写入的接口,如write、mkdir、unlink,以及非O\_RDONLY属性的open,将均被拒绝。 -> - mount支持通过MS\_REMOUNT标记修改已挂载分区的权限。 -> - 在umount操作前,需确保所有目录及文件全部关闭。 -> - umount2支持通过MNT\_FORCE参数强制关闭所有文件与文件夹并umount,但可能造成数据丢失,请谨慎使用。 ->- FATFS支持重新划分存储设备分区、格式化分区,对应接口为fatfs\_fdisk与fatfs\_format: -> - 在fatfs\_format操作之前,若需要格式化的分区已挂载,需确保分区中的所有目录及文件全部关闭,并且分区umount。 -> - 在fatfs\_fdisk操作前,需要该设备中的所有分区均已umount。 -> - fatfs\_fdisk与fatfs\_format会造成设备数据丢失,请谨慎使用。 - -## 编程实例 - -### 实例描述 + +### 开发流程 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - FATFS文件与目录操作: +> - 单个文件大小不超过4G。 +> - 支持同时打开的文件数最大为FAT_MAX_OPEN_FILES,文件夹数最大为FAT_MAX_OPEN_DIRS。 +> - 暂不支持根目录管理,文件/目录名均以分区名开头,例如“user/testfile”就是在“user”分区下名为“testfile”的文件或目录。 +> - 若需要同时多次打开同一文件,必须全部使用只读方式(O_RDONLY)。以可写方式(O_RDWR、O_WRONLY等)只能打开一次。 +> - 读写指针未分离,例如以O_APPEND(追加写)方式打开文件后,读指针也在文件尾,从头读文件前需要用户手动置位。 +> - 暂不支持文件与目录的权限管理。 +> - stat及fstat接口暂不支持查询修改时间、创建时间和最后访问时间。微软FAT协议不支持1980年以前的时间。 +> +> - FATFS分区挂载与卸载: +> - 支持以只读属性挂载分区。当mount函数的入参为MS_RDONLY时,所有的带有写入的接口,如write、mkdir、unlink,以及非O_RDONLY属性的open,将均被拒绝。 +> - mount支持通过MS_REMOUNT标记修改已挂载分区的权限。 +> - 在umount操作前,需确保所有目录及文件全部关闭。 +> - umount2支持通过MNT_FORCE参数强制关闭所有文件与文件夹并umount,但可能造成数据丢失,请谨慎使用。 +> +> - FATFS支持重新划分存储设备分区、格式化分区,对应接口为fatfs_fdisk与fatfs_format: +> - 在fatfs_format操作之前,若需要格式化的分区已挂载,需确保分区中的所有目录及文件全部关闭,并且分区umount。 +> - 在fatfs_fdisk操作前,需要该设备中的所有分区均已umount。 +> - fatfs_fdisk与fatfs_format会造成设备数据丢失,请谨慎使用。 + + +## 编程实例 + + +### 实例描述 本实例实现以下功能: -1. 创建目录“user/test” -2. 在“user/test”目录下创建文件“file.txt” -3. 在文件起始位置写入“Hello OpenHarmony!” -4. 将文件内容刷入设备中 -5. 设置偏移到文件起始位置 -6. 读取文件内容 -7. 关闭文件 -8. 删除文件 -9. 删除目录 +1. 创建目录“user/test” + +2. 在“user/test”目录下创建文件“file.txt” + +3. 在文件起始位置写入“Hello OpenHarmony!” -### 示例代码 +4. 将文件内容刷入设备中 + +5. 设置偏移到文件起始位置 + +6. 读取文件内容 + +7. 关闭文件 + +8. 删除文件 + +9. 删除目录 + + +### 示例代码 前提条件: -- 系统已将MMC设备分区挂载到user目录 +- 系统已将MMC设备分区挂载到user目录 代码实现如下: - ``` #include #include @@ -167,11 +180,11 @@ int FatfsTest(void) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: ``` Hello OpenHarmony! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-file-lit.md b/zh-cn/device-dev/kernel/kernel-mini-extend-file-lit.md index b11f2782f7..f3676d2056 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-file-lit.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend-file-lit.md @@ -1,7 +1,105 @@ -# LittleFS +# LittleFS -- **[基本概念](kernel-mini-extend-file-littlefs-basic.md)** +- [基本概念](#基本概念) +- [开发指导](#开发指导) +- [示例代码](#示例代码) + - [结果验证](#结果验证) -- **[开发指导](kernel-mini-extend-file-littlefs-guide.md)** +## 基本概念 +LittleFS是一个小型的Flash文件系统,它结合日志结构(log-structured)文件系统和COW(copy-on-write)文件系统的思想,以日志结构存储元数据,以COW结构存储数据。这种特殊的存储方式,使LittleFS具有强大的掉电恢复能力(power-loss resilience)。分配COW数据块时LittleFS采用了名为统计损耗均衡的动态损耗均衡算法,使Flash设备的寿命得到有效保障。同时LittleFS针对资源紧缺的小型设备进行设计,具有极其有限的ROM和RAM占用,并且所有RAM的使用都通过一个可配置的固定大小缓冲区进行分配,不会随文件系统的扩大占据更多的系统资源。 +当在一个资源非常紧缺的小型设备上,寻找一个具有掉电恢复能力并支持损耗均衡的Flash文件系统时,LittleFS是一个比较好的选择。 + + +## 开发指导 + +移植LittleFS到新硬件设备上,需要申明lfs_config: + +``` +const struct lfs_config cfg = { + // block device operations + .read = user_provided_block_device_read, + .prog = user_provided_block_device_prog, + .erase = user_provided_block_device_erase, + .sync = user_provided_block_device_sync, + + // block device configuration + .read_size = 16, + .prog_size = 16, + .block_size = 4096, + .block_count = 128, + .cache_size = 16, + .lookahead_size = 16, + .block_cycles = 500, +}; +``` + +其中.read,.prog,.erase,.sync分别对应该硬件平台上的底层的读写\擦除\同步等接口。 + +read_size 每次读取的字节数,可以比物理读单元大以改善性能,这个数值决定了读缓存的大小,但值太大会带来更多的内存消耗。 + +prog_size 每次写入的字节数,可以比物理写单元大以改善性能,这个数值决定了写缓存的大小,必须是read_size的整数倍,但值太大会带来更多的内存消耗。 + +block_size 每个擦除块的字节数,可以比物理擦除单元大,但此数值应尽可能小因为每个文件至少会占用一个块。必须是prog_size的整数倍。 + +block_count 可以被擦除的块数量,这取决于块设备的容量及擦除块的大小。 + + +## 示例代码 + +代码实现如下: +``` +#include "lfs.h" +#include "stdio.h" +lfs_t lfs; +lfs_file_t file; +const struct lfs_config cfg = { + // block device operations + .read = user_provided_block_device_read, + .prog = user_provided_block_device_prog, + .erase = user_provided_block_device_erase, + .sync = user_provided_block_device_sync, + // block device configuration + .read_size = 16, + .prog_size = 16, + .block_size = 4096, + .block_count = 128, + .cache_size = 16, + .lookahead_size = 16, + .block_cycles = 500, +}; +int main(void) { + // mount the filesystem + int err = lfs_mount(&lfs, &cfg); + // reformat if we can't mount the filesystem + // this should only happen on the first boot + if (err) { + lfs_format(&lfs, &cfg); + lfs_mount(&lfs, &cfg); + } + // read current count + uint32_t boot_count = 0; + lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); + // update boot count + boot_count += 1; + 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 + lfs_file_close(&lfs, &file); + // release any resources we were using + lfs_unmount(&lfs); + // print the boot count + printf("boot_count: %d\n", boot_count); +} +``` + + +### 结果验证 + +首次编译运行得到的结果为: + +``` +Say hello 1 times. +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md b/zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md deleted file mode 100644 index 05608b21da..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-basic.md +++ /dev/null @@ -1,6 +0,0 @@ -# 基本概念 - -LittleFS是一个小型的Flash文件系统,它结合日志结构(log-structured)文件系统和COW(copy-on-write)文件系统的思想,以日志结构存储元数据,以COW结构存储数据。这种特殊的存储方式,使LittleFS具有强大的掉电恢复能力(power-loss resilience\)。分配COW数据块时LittleFS采用了名为统计损耗均衡的动态损耗均衡算法,使Flash设备的寿命得到有效保障。同时LittleFS针对资源紧缺的小型设备进行设计,具有极其有限的ROM和RAM占用,并且所有RAM的使用都通过一个可配置的固定大小缓冲区进行分配,不会随文件系统的扩大占据更多的系统资源。 - -当在一个资源非常紧缺的小型设备上,寻找一个具有掉电恢复能力并支持损耗均衡的Flash文件系统时,LittleFS是一个比较好的选择。 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md b/zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md deleted file mode 100644 index 624870c863..0000000000 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-file-littlefs-guide.md +++ /dev/null @@ -1,95 +0,0 @@ -# 开发指导 - -- [示例代码](#section1034515054620) - -移植LittleFS到新硬件设备上,需要申明lfs\_config: - -``` -const struct lfs_config cfg = { - // block device operations - .read = user_provided_block_device_read, - .prog = user_provided_block_device_prog, - .erase = user_provided_block_device_erase, - .sync = user_provided_block_device_sync, - - // block device configuration - .read_size = 16, - .prog_size = 16, - .block_size = 4096, - .block_count = 128, - .cache_size = 16, - .lookahead_size = 16, - .block_cycles = 500, -}; -``` - -其中.read,.prog,.erase,.sync分别对应该硬件平台上的底层的读写\\擦除\\同步等接口。 - -read\_size 每次读取的字节数,可以比物理读单元大以改善性能,这个数值决定了读缓存的大小,但值太大会带来更多的内存消耗。 - -prog\_size 每次写入的字节数,可以比物理写单元大以改善性能,这个数值决定了写缓存的大小,必须是read\_size的整数倍,但值太大会带来更多的内存消耗。 - -block\_size 每个擦除块的字节数,可以比物理擦除单元大,但此数值应尽可能小因为每个文件至少会占用一个块。必须是prog\_size的整数倍。 - -block\_count 可以被擦除的块数量,这取决于块设备的容量及擦除块的大小。 - -## 示例代码 - -代码实现如下: - -``` -#include "lfs.h" -#include "stdio.h" - -lfs_t lfs; -lfs_file_t file; - -const struct lfs_config cfg = { - // block device operations - .read = user_provided_block_device_read, - .prog = user_provided_block_device_prog, - .erase = user_provided_block_device_erase, - .sync = user_provided_block_device_sync, - - // block device configuration - .read_size = 16, - .prog_size = 16, - .block_size = 4096, - .block_count = 128, - .cache_size = 16, - .lookahead_size = 16, - .block_cycles = 500, -}; - -int main(void) { - // mount the filesystem - int err = lfs_mount(&lfs, &cfg); - - // reformat if we can't mount the filesystem - // this should only happen on the first boot - if (err) { - lfs_format(&lfs, &cfg); - lfs_mount(&lfs, &cfg); - } - - // read current count - uint32_t boot_count = 0; - lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); - lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); - - // update boot count - boot_count += 1; - 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 - lfs_file_close(&lfs, &file); - - // release any resources we were using - lfs_unmount(&lfs); - - // print the boot count - printf("boot_count: %d\n", boot_count); -} -``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-file.md b/zh-cn/device-dev/kernel/kernel-mini-extend-file.md index 8b0d2d84c7..a3b9600217 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-file.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend-file.md @@ -1,204 +1,33 @@ -# 文件系统 +# 文件系统 -当前支持的文件系统有FATFS与LittleFS,支持的功能如下表所示: +M核的文件系统子系统当前支持的文件系统有FATFS与LittleFS。同A核一样,通过VFS层提供了POSIX标准的操作,保持了接口的一致性,但是因为M核的资源非常紧张,VFS层非常轻薄,没有提供类似A核的高级功能(如pagecache等),主要是接口的标准化和适配工作,具体的事务由各个文件系统实际承载。M核文件系统支持的功能如下表所示: -**表 1** ****功能列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

FATFS

-

LITTELFS

-

文件操作

-

open

-

打开文件

-

支持

-

支持

-

close

-

关闭文件

-

支持

-

支持

-

read

-

读取文件内容

-

支持

-

支持

-

write

-

往文件写入内容

-

支持

-

支持

-

lseek

-

设置文件偏移位置

-

支持

-

支持

-

unlink

-

删除文件

-

支持

-

支持

-

rename

-

重命名文件

-

支持

-

支持

-

fstat

-

通过文件句柄获取文件信息

-

支持

-

支持

-

stat

-

通过文件路径名获取文件信息

-

支持

-

支持

-

fsync

-

文件内容刷入存储设备

-

支持

-

支持

-

目录操作

-

mkdir

-

创建目录

-

支持

-

支持

-

opendir

-

打开目录

-

支持

-

支持

-

readdir

-

读取目录项内容

-

支持

-

支持

-

closedir

-

关闭目录

-

支持

-

支持

-

rmdir

-

删除目录

-

支持

-

支持

-

分区操作

-

mount

-

分区挂载

-

支持

-

支持

-

umount

-

分区卸载

-

支持

-

支持

-

umount2

-

分区卸载,可通过MNT_FORCE参数进行强制卸载

-

支持

-

不支持

-

statfs

-

获取分区信息

-

支持

-

不支持

-
+**表1** 功能列表 -- **[FAT](kernel-mini-extend-file-fat.md)** +| 功能分类 | 接口名 | 描述 | FATFS | LITTLEFS | +| -------- | -------- | -------- | -------- | -------- | +| 文件操作 | open | 打开文件 | 支持 | 支持 | +| close | 关闭文件 | 支持 | 支持 | +| read | 读取文件内容 | 支持 | 支持 | +| write | 往文件写入内容 | 支持 | 支持 | +| lseek | 设置文件偏移位置 | 支持 | 支持 | +| unlink | 删除文件 | 支持 | 支持 | +| rename | 重命名文件 | 支持 | 支持 | +| fstat | 通过文件句柄获取文件信息 | 支持 | 支持 | +| stat | 通过文件路径名获取文件信息 | 支持 | 支持 | +| fsync | 文件内容刷入存储设备 | 支持 | 支持 | +| 目录操作 | mkdir | 创建目录 | 支持 | 支持 | +| opendir | 打开目录 | 支持 | 支持 | +| readdir | 读取目录项内容 | 支持 | 支持 | +| closedir | 关闭目录 | 支持 | 支持 | +| rmdir | 删除目录 | 支持 | 支持 | +| 分区操作 | mount | 分区挂载 | 支持 | 支持 | +| umount | 分区卸载 | 支持 | 支持 | +| umount2 | 分区卸载,可通过MNT_FORCE参数进行强制卸载 | 支持 | 不支持 | +| statfs | 获取分区信息 | 支持 | 不支持 | -- **[LittleFS](kernel-mini-extend-file-lit.md)** +- **[FAT](kernel-mini-extend-file-fat.md)** +- **[LittleFS](kernel-mini-extend-file-lit.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend-support.md b/zh-cn/device-dev/kernel/kernel-mini-extend-support.md index c20fed127b..8213dc8dca 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend-support.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend-support.md @@ -1,76 +1,50 @@ -# C++支持 +# C++支持 -- [基本概念](#section11374125415814) -- [运行机制](#section189351319134418) -- [开发指导](#section166302407911) - - [接口说明](#section1881825119919) - - [开发流程](#section76371145108) - - [编程实例](#section994427141111) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 C++作为目前使用最广泛的编程语言之一,支持类、封装、重载等特性,是在C语言基础上开发的一种面向对象的编程语言。 -## 运行机制 + +## 运行机制 C++代码的识别主要由编译器支持,系统主要对全局对象进行构造函数调用,进行初始化操作。 -## 开发指导 - -### 接口说明 - -**表 1** C++支持接口 - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

使用C++特性的前置条件

-

LOS_CppSystemInit

-

C++构造函数初始化

-
- -### 开发流程 - -使用C++特性之前,需要调用函数LOS\_CppSystemInit,实现C++构造函数初始化,其中被初始化的构造函数存在init\_array这个段中,段区间通过变量\_\_init\_array\_start\_\_、\_\_init\_array\_end\_\_传递。 - -**表 2** 参数说明 - - - - - - - - - - - - - -

参数

-

参数说明

-

__init_array_start__

-

init_array段起始位置

-

__init_array_end__

-

init_array段结束位置

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->调用该函数时,一定要在c++业务前。另外部分与系统资源强相关的类或接口,如std::thread,std::mutex等,在三方编译器使用的c库非musl c时,存在兼容性问题,不建议使用。 - -### 编程实例 + +## 开发指导 + + +### 接口说明 + +**表1** C++支持接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 使用C++特性的前置条件 | LOS_CppSystemInit | C++构造函数初始化 | + + +### 开发流程 + +使用C++特性之前,需要调用函数LOS_CppSystemInit,实现C++构造函数初始化,其中被初始化的构造函数存在init_array这个段中,段区间通过变量__init_array_start__、__init_array_end__传递。 + +**表2** 参数说明 + +| 参数 | 参数说明 | +| -------- | -------- | +| __init_array_start__ | init_array段起始位置 | +| __init_array_end__ | init_array段结束位置 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 调用该函数时,一定要在c++业务前。另外部分与系统资源强相关的类或接口,如std::thread,std::mutex等,在三方编译器使用的c库非musl c时,存在兼容性问题,不建议使用。 + + +### 编程实例 ``` void app_init(void) @@ -82,4 +56,3 @@ LOS_CppSystemInit((UINTPTR)&__init_array_start__, (UINTPTR)&__init_array_end__); ...... } ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-extend.md b/zh-cn/device-dev/kernel/kernel-mini-extend.md index 2c171e7ce6..b9e0d97ba5 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-extend.md +++ b/zh-cn/device-dev/kernel/kernel-mini-extend.md @@ -1,11 +1,10 @@ -# 扩展组件 +# 扩展组件 -- **[C++支持](kernel-mini-extend-support.md)** -- **[CPU占用率](kernel-mini-extend-cpup.md)** +- **[C++支持](kernel-mini-extend-support.md)** -- **[动态加载](kernel-mini-extend-dynamic-loading.md)** - -- **[文件系统](kernel-mini-extend-file.md)** +- **[CPU占用率](kernel-mini-extend-cpup.md)** +- **[动态加载](kernel-mini-extend-dynamic-loading.md)** +- **[文件系统](kernel-mini-extend-file.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-imemory-debug-det.md b/zh-cn/device-dev/kernel/kernel-mini-imemory-debug-det.md index 7f49df4fc8..09971dd3ba 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-imemory-debug-det.md +++ b/zh-cn/device-dev/kernel/kernel-mini-imemory-debug-det.md @@ -1,37 +1,40 @@ -# 内存泄漏检测 +# 内存泄漏检测 -- [基础概念](#section1026719436293) -- [功能配置](#section13991354162914) -- [开发指导](#section95828159308) - - [开发流程](#section369844416304) - - [编程实例](#section460801313313) - - [示例代码](#section96539275311) - - [结果验证](#section20527343183119) +- [基础概念](#基础概念) +- [功能配置](#功能配置) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [示例代码](#示例代码) + - [结果验证](#结果验证) - -## 基础概念 +## 基础概念 内存泄漏检测机制作为内核的可选功能,用于辅助定位动态内存泄漏问题。开启该功能,动态内存机制会自动记录申请内存时的函数调用关系(下文简称LR)。如果出现泄漏,就可以利用这些记录的信息,找到内存申请的地方,方便进一步确认。 -## 功能配置 -1. LOSCFG\_MEM\_LEAKCHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 -2. LOSCFG\_MEM\_RECORD\_LR\_CNT:记录的LR层数,默认3层;每层LR消耗sizeof\(void \*\)字节数的内存。 -3. LOSCFG\_MEM\_OMIT\_LR\_CNT:忽略的LR层数,默认4层,即从调用LOS\_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下: - - LOS\_MemAlloc接口内部也有函数调用; - - 外部可能对LOS\_MemAlloc接口有封装; - - LOSCFG\_MEM\_RECORD\_LR\_CNT 配置的LR层数有限; +## 功能配置 + +1. LOSCFG_MEM_LEAKCHECK:开关宏,默认关闭;若打开这个功能,在target_config.h中将这个宏定义为1。 +2. LOSCFG_MEM_RECORD_LR_CNT:记录的LR层数,默认3层;每层LR消耗sizeof(void \*)字节数的内存。 + +3. LOSCFG_MEM_OMIT_LR_CNT:忽略的LR层数,默认4层,即从调用LOS_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下: + - LOS_MemAlloc接口内部也有函数调用; + - 外部可能对LOS_MemAlloc接口有封装; + - LOSCFG_MEM_RECORD_LR_CNT 配置的LR层数有限; 正确配置这个宏,将无效的LR层数忽略,就可以记录有效的LR层数,节省内存消耗。 -## 开发指导 -### 开发流程 +## 开发指导 + -该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS\_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。 +### 开发流程 -调用LOS\_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3\~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。 +该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。 + +调用LOS_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。 ``` node size LR[0] LR[1] LR[2] @@ -43,20 +46,26 @@ node size LR[0] LR[1] LR[2] 0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 ``` ->![](../public_sys-resources/icon-caution.gif) **注意:** ->开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。 +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** +> 开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。 + -### 编程实例 +### 编程实例 本实例实现如下功能:构建内存泄漏代码段。 -1. 调用LOS\_MemUsedNodeShow接口,输出全部节点信息打印; -2. 申请内存,但没有释放,模拟内存泄漏; -3. 再次调用LOS\_MemUsedNodeShow接口,输出全部节点信息打印; -4. 将两次log进行对比,得出泄漏的节点信息; -5. 通过LR地址,找出泄漏的代码位置; +1. 调用LOS_MemUsedNodeShow接口,输出全部节点信息打印; + +2. 申请内存,但没有释放,模拟内存泄漏; -### 示例代码 +3. 再次调用LOS_MemUsedNodeShow接口,输出全部节点信息打印; + +4. 将两次log进行对比,得出泄漏的节点信息; + +5. 通过LR地址,找出泄漏的代码位置; + + +### 示例代码 代码实现如下: @@ -75,7 +84,8 @@ void MemLeakTest(void) } ``` -### 结果验证 + +### 结果验证 编译运行输出log如下: @@ -125,4 +135,3 @@ node size LR[0] LR[1] LR[2] ``` 其中,通过查找0x080041ee,就可以发现该内存节点是在MemLeakTest接口里申请的且是没有释放的。 - diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-debug-cet.md b/zh-cn/device-dev/kernel/kernel-mini-memory-debug-cet.md index 20a2b532d3..0e44b1e348 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-memory-debug-cet.md +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-debug-cet.md @@ -1,45 +1,52 @@ -# 踩内存检测 +# 踩内存检测 -- [基础概念](#section17368154517335) -- [功能配置](#section4696190123420) -- [开发指导](#section672362973417) - - [开发流程](#section026014863416) - - [编程实例](#section186311302356) - - [示例代码](#section12709533354) - - [结果验证](#section81214126369) +- [基础概念](#基础概念) +- [功能配置](#功能配置) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [示例代码](#示例代码) + - [结果验证](#结果验证) - -## 基础概念 +## 基础概念 踩内存检测机制作为内核的可选功能,用于检测动态内存池的完整性。通过该机制,可以及时发现内存池是否发生了踩内存问题,并给出错误信息,便于及时发现系统问题,提高问题解决效率,降低问题定位成本。 -## 功能配置 -LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:开关宏,默认关闭;若打开这个功能,在target\_config.h中将这个宏定义为1。 +## 功能配置 + +LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK:开关宏,默认关闭;若打开这个功能,在target_config.h中将这个宏定义为1。 + +1. 开启这个功能,每次申请内存,会实时检测内存池的完整性。 -1. 开启这个功能,每次申请内存,会实时检测内存池的完整性。 -2. 如果不开启该功能,也可以调用LOS\_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 +2. 如果不开启该功能,也可以调用LOS_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 由于该功能只会检测出哪个内存节点被破坏了,并给出前节点信息(因为内存分布是连续的,当前节点最有可能被前节点破坏)。如果要进一步确认前节点在哪里申请的,需开启内存泄漏检测功能,通过LR记录,辅助定位。 ->![](../public_sys-resources/icon-caution.gif) **注意:** ->开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS\_MemIntegrityCheck接口检测。 +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** +> 开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS_MemIntegrityCheck接口检测。 + + +## 开发指导 + -## 开发指导 +### 开发流程 -### 开发流程 +通过调用LOS_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 -通过调用LOS\_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 -### 编程实例 +### 编程实例 本实例实现如下功能: -1. 申请两个物理上连续的内存块; -2. 通过memset构造越界访问,踩到下个节点的头4个字节; -3. 调用LOS\_MemIntegrityCheck检测是否发生踩内存。 +1. 申请两个物理上连续的内存块; -### 示例代码 +2. 通过memset构造越界访问,踩到下个节点的头4个字节; + +3. 调用LOS_MemIntegrityCheck检测是否发生踩内存。 + + +### 示例代码 代码实现如下: @@ -60,7 +67,8 @@ void MemIntegrityTest(void) } ``` -### 结果验证 + +### 结果验证 编译运行输出log如下: @@ -82,4 +90,3 @@ memory used but magic num wrong, magic num = 0x00000000 /* 提示信息,检 LR[2]:0x00000000 [ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* 被破坏节点和其前节点的地址 */ ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-debug-mes.md b/zh-cn/device-dev/kernel/kernel-mini-memory-debug-mes.md index 6f58e1b077..8d6325dc6b 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-memory-debug-mes.md +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-debug-mes.md @@ -1,31 +1,33 @@ -# 内存信息统计 +# 内存信息统计 -- [基础概念](#section52691565235) -- [功能配置](#section470611682411) -- [开发指导](#section9368374243) - - [开发流程](#section679912407257) - - [编程实例](#section1025453412611) - - [示例代码](#section165277971315) - - [结果验证](#section3460102414271) +- [基础概念](#基础概念) +- [功能配置](#功能配置) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [示例代码](#示例代码) + - [结果验证](#结果验证) - -## 基础概念 +## 基础概念 内存信息包括内存池大小、内存使用量、剩余内存大小、最大空闲内存、内存水线、内存节点数统计、碎片率等。 -- 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小; +- 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小; + +- 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)来度量; + +- 其他参数:通过调用接口(详见[内存管理](../kernel/kernel-mini-basic-memory-basic.md)章节接口说明),扫描内存池的节点信息,统计出相关信息。 -- 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)来度量; -- 其他参数:通过调用接口(详见[内存管理](kernel-mini-basic-memory-basic.md)章节接口说明),扫描内存池的节点信息,统计出相关信息。 +## 功能配置 -## 功能配置 +LOSCFG_MEM_WATERLINE:开关宏,默认打开;若关闭这个功能,在target_config.h中将这个宏定义为0。如需获取内存水线,需要打开该配置。 -LOSCFG\_MEM\_WATERLINE:开关宏,默认打开;若关闭这个功能,在target\_config.h中将这个宏定义为0。如需获取内存水线,需要打开该配置。 -## 开发指导 +## 开发指导 -### 开发流程 + +### 开发流程 关键结构体介绍: @@ -42,24 +44,25 @@ typedef struct { } LOS_MEM_POOL_STATUS; ``` -- 内存水线获取:调用LOS\_MemInfoGet接口,第1个参数是内存池首地址,第2个参数是LOS\_MEM\_POOL\_STATUS类型的句柄,其中字段usageWaterLine即水线值。 +- 内存水线获取:调用LOS_MemInfoGet接口,第1个参数是内存池首地址,第2个参数是LOS_MEM_POOL_STATUS类型的句柄,其中字段usageWaterLine即水线值。 + +- 内存碎片率计算:同样调用LOS_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 -- 内存碎片率计算:同样调用LOS\_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 -### 编程实例 +### 编程实例 本实例实现如下功能: 1.创建一个监控任务,用于获取内存池的信息; -2.调用LOS\_MemInfoGet接口,获取内存池的基础信息; +2.调用LOS_MemInfoGet接口,获取内存池的基础信息; 3.利用公式算出使用率及碎片率。 -### 示例代码 -代码实现如下: +### 示例代码 +代码实现如下: ``` #include #include @@ -67,11 +70,12 @@ typedef struct { #include "los_memory.h" #include "los_config.h" + void MemInfoTaskFunc(void) { LOS_MEM_POOL_STATUS poolStatus = {0}; - /* pool为要统计信息的内存地址,此处以OS_SYS_MEM_ADDR为例 */ + /* pool为要统计信息的内存地址,此处以OS_SYS_MEM_ADDR为例 */ void *pool = OS_SYS_MEM_ADDR; LOS_MemInfoGet(pool, &poolStatus); /* 算出内存池当前的碎片率百分比 */ @@ -100,11 +104,11 @@ int MemTest(void) } ``` -### 结果验证 + +### 结果验证 编译运行输出的结果如下: ``` usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-debug.md b/zh-cn/device-dev/kernel/kernel-mini-memory-debug.md index e4906c53bd..d3e4753307 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-memory-debug.md +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-debug.md @@ -1,11 +1,10 @@ -# 内存调测 +# 内存调测 内存调测方法旨在辅助定位动态内存相关问题,提供了基础的动态内存池信息统计手段,向用户呈现内存池水线、碎片率等信息;提供了内存泄漏检测手段,方便用户准确定位存在内存泄漏的代码行,也可以辅助分析系统各个模块内存的使用情况;提供了踩内存检测手段,可以辅助定位越界踩内存的场景。 -- **[内存信息统计](kernel-mini-memory-debug-mes.md)** -- **[内存泄漏检测](kernel-mini-imemory-debug-det.md)** - -- **[踩内存检测](kernel-mini-memory-debug-cet.md)** +- **[内存信息统计](kernel-mini-memory-debug-mes.md)** +- **[内存泄漏检测](kernel-mini-imemory-debug-det.md)** +- **[踩内存检测](kernel-mini-memory-debug-cet.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-exception.md b/zh-cn/device-dev/kernel/kernel-mini-memory-exception.md index 5828d645f1..dc76f32d54 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-memory-exception.md +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-exception.md @@ -1,18 +1,18 @@ -# 异常调测 +# 异常调测 -- [基本概念](#section2741911123412) -- [运行机制](#section16618124317346) -- [接口说明](#section16111931351) -- [使用指导](#section16317163520350) - - [开发流程](#section13457839133618) - - [定位流程](#section197332323815) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) +- [使用指导](#使用指导) + - [开发流程](#开发流程) + - [定位流程](#定位流程) - -## 基本概念 +## 基本概念 OpenHarmony LiteOS-M提供异常接管调测手段,帮助开发者定位分析问题。异常接管是操作系统对运行期间发生的异常情况进行处理的一系列动作,例如打印异常发生时异常类型、发生异常时的系统状态、当前函数的调用栈信息、CPU现场信息、任务调用堆栈等信息。 -## 运行机制 + +## 运行机制 栈帧用于保存函数调用过程中的函数参数、变量、返回值等信息。调用函数时,会创建子函数的栈帧,同时将函数入参、局部变量、寄存器入栈。栈帧从高地址向低地址生长。以ARM32 CPU架构为例,每个栈帧中都会保存PC、LR、SP和FP寄存器的历史值。LR链接寄存器(Link Register)指向函数的返回地址,FP帧指针寄存器(Frame Point)指向当前函数的父函数的栈帧起始地址。利用FP寄存器可以得到父函数的栈帧,从栈帧中获取父函数的FP,就可以得到祖父函数的栈帧,以此类推,可以追溯程序调用栈,得到函数间的调用关系。 @@ -20,310 +20,257 @@ OpenHarmony LiteOS-M提供异常接管调测手段,帮助开发者定位分析 堆栈分析原理如下图所示,实际堆栈信息根据不同CPU架构有所差异,此处仅做示意。 -**图 1** 堆栈分析原理示意图 -![](figure/堆栈分析原理示意图.png "堆栈分析原理示意图") +**图1** 堆栈分析原理示意图 +![zh-cn_image_0000001132936268](figures/zh-cn_image_0000001132936268.png) 图中不同颜色的寄存器表示不同的函数。可以看到函数调用过程中,寄存器的保存。通过FP寄存器,栈回溯到异常函数的父函数,继续按照规律对栈进行解析,推出函数调用关系,方便用户定位问题。 -## 接口说明 + +## 接口说明 OpenHarmony LiteOS-M内核的回溯栈模块提供下面几种功能,接口详细信息可以查看API参考。 -**表 1** 回溯栈模块接口 - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

回溯栈接口

-

LOS_BackTrace

-

打印调用处的函数调用栈关系。

-

LOS_RecordLR

-

在无法打印的场景,用该接口获取调用处的函数调用栈关系。

-
- -## 使用指导 - -### 开发流程 +**表1** 回溯栈模块接口 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 回溯栈接口 | LOS_BackTrace | 打印调用处的函数调用栈关系。 | +| LOS_RecordLR | 在无法打印的场景,用该接口获取调用处的函数调用栈关系。 | + + +## 使用指导 + + +### 开发流程 开启异常调测的典型流程如下: -1. 配置异常接管相关宏。 - - 需要在target\_config.h头文件中修改配置: - - - - - - - - - - - - - - - - -

配置项

-

含义

-

设置值

-

LOSCFG_BACKTRACE_DEPTH

-

函数调用栈深度,默认15层

-

15

-

LOSCFG_BACKTRACE_TYPE

-

回溯栈类型:

-

0:表示关闭该功能;

-

1:表示支持Cortex-m系列硬件的函数调用栈解析;

-

2:表示用于Risc-v系列硬件的函数调用栈解析;

-

根据工具链类型设置1或2

-
- - -1. 使用示例中有问题的代码,编译、运行工程,在串口终端中查看异常信息输出。示例代码模拟异常代码,实际产品开发时使用异常调测机制定位异常问题。 - - 本示例演示异常输出,包含1个任务,该任务入口函数模拟若干函数调用,最终调用一个模拟异常的函数。代码实现如下: - - ``` - #include - #include "los_config.h" - #include "los_interrupt.h" - #include "los_task.h" - - UINT32 g_taskExcId; - #define TSK_PRIOR 4 - - /* 模拟异常函数 */ - - UINT32 Get_Result_Exception_0(UINT16 dividend){ - UINT32 divisor = 0; - UINT32 result = dividend / divisor; - return result; - } - - UINT32 Get_Result_Exception_1(UINT16 dividend){ - return Get_Result_Exception_0(dividend); - } - - UINT32 Get_Result_Exception_2(UINT16 dividend){ - return Get_Result_Exception_1(dividend); - } - - UINT32 Example_Exc(VOID) - { - UINT32 ret; - - printf("Enter Example_Exc Handler.\r\n"); - - /* 模拟函数调用 */ - ret = Get_Result_Exception_2(TSK_PRIOR); - printf("Divided result =%u.\r\n", ret); - - printf("Exit Example_Exc Handler.\r\n"); - return ret; - } - - - /* 任务测试入口函数,创建一个会发生异常的任务 */ - UINT32 Example_Exc_Entry(VOID) - { - UINT32 ret; - TSK_INIT_PARAM_S initParam; - - /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ - LOS_TaskLock(); - - printf("LOS_TaskLock() Success!\r\n"); - - initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Exc; - initParam.usTaskPrio = TSK_PRIOR; - initParam.pcName = "Example_Exc"; - initParam.uwStackSize = LOSCFG_SECURE_STACK_DEFAULT_SIZE; - /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ - ret = LOS_TaskCreate(&g_taskExcId, &initParam); - if (ret != LOS_OK) { - LOS_TaskUnlock(); - - printf("Example_Exc create Failed!\r\n"); - return LOS_NOK; - } - - printf("Example_Exc create Success!\r\n"); - - /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ - LOS_TaskUnlock(); - - return LOS_OK; - } - ``` - - -1. 上述代码串口终端输出异常信息如下: - - ``` - entering kernel init... - LOS_TaskLock() Success! - Example_Exc create Success! - Entering scheduler - Enter Example_Exc Handler. - *************Exception Information************** - Type = 10 - ThrdPid = 4 - Phase = exc in task - FaultAddr = 0xabababab - Current task info: - Task name = Example_Exc - Task ID = 4 - Task SP = 0x200051ac - Task ST = 0x20004ff0 - Task SS = 0x200 - Exception reg dump: - PC = 0x80037da - LR = 0x80037fe - SP = 0x20005190 - R0 = 0x4 - R1 = 0x40 - R2 = 0x4 - R3 = 0x0 - R4 = 0x4040404 - R5 = 0x5050505 - R6 = 0x6060606 - R7 = 0x20005190 - R8 = 0x8080808 - R9 = 0x9090909 - R10 = 0x10101010 - R11 = 0x11111111 - R12 = 0x12121212 - PriMask = 0x0 - xPSR = 0x41000000 - ----- backtrace start ----- - backtrace 0 -- lr = 0x800381a - backtrace 1 -- lr = 0x8003836 - backtrace 2 -- lr = 0x8005a4e - backtrace 3 -- lr = 0x8000494 - 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 ----- - - TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID name - --- -------- -------- --------- ---------- ---------- ---------- --------- ----- ---- - 0 0 Pend 0x2d0 0x104 0x200029bc 0x200027f0 0x0 0xffff Swt_Task - 1 31 Ready 0x500 0x44 0x20002f84 0x20002ac8 0x0 0xffff IdleCore000 - 2 6 Ready 0x1000 0x44 0x20003f94 0x20002fd8 0x0 0xffff TaskSampleEntry1 - 3 7 Ready 0x1000 0x44 0x20004f9c 0x20003fe0 0x0 0xffff TaskSampleEntry2 - 4 4 Running 0x200 0xec 0x200051ac 0x20004ff0 0x0 0xffff Example_Exc - - OS exception NVIC dump: - interrupt enable register, base address: 0xe000e100, size: 0x20 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt pending register, base address: 0xe000e200, size: 0x20 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt active register, base address: 0xe000e300, size: 0x20 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt priority register, base address: 0xe000e400, size: 0xf0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 - interrupt exception register, base address: 0xe000ed18, size: 0xc - 0x0 0x0 0xf0f00000 - interrupt shcsr register, base address: 0xe000ed24, size: 0x4 - 0x70008 - interrupt control register, base address: 0xe000ed04, size: 0x4 - 0x400f806 - - memory pools check: - system heap memcheck over, all passed! - memory pool check end! - ``` - - -### 定位流程 +1. 配置异常接管相关宏。 + 需要在target_config.h头文件中修改配置: + | 配置项 | 含义 | 设置值 | + | -------- | -------- | -------- | + | LOSCFG_BACKTRACE_DEPTH | 函数调用栈深度,默认15层 | 15 | + | LOSCFG_BACKTRACE_TYPE | 回溯栈类型:
0:表示关闭该功能;
1:表示支持Cortex-m系列硬件的函数调用栈解析;
2:表示用于Risc-v系列硬件的函数调用栈解析; | 根据工具链类型设置1或2 | + +1. 使用示例中有问题的代码,编译、运行工程,在串口终端中查看异常信息输出。示例代码模拟异常代码,实际产品开发时使用异常调测机制定位异常问题。 + 本示例演示异常输出,包含1个任务,该任务入口函数模拟若干函数调用,最终调用一个模拟异常的函数。代码实现如下: + ``` + #include + #include "los_config.h" + #include "los_interrupt.h" + #include "los_task.h" + + UINT32 g_taskExcId; + #define TSK_PRIOR 4 + + /* 模拟异常函数 */ + + UINT32 Get_Result_Exception_0(UINT16 dividend){ + UINT32 divisor = 0; + UINT32 result = dividend / divisor; + return result; + } + + UINT32 Get_Result_Exception_1(UINT16 dividend){ + return Get_Result_Exception_0(dividend); + } + + UINT32 Get_Result_Exception_2(UINT16 dividend){ + return Get_Result_Exception_1(dividend); + } + + UINT32 Example_Exc(VOID) + { + UINT32 ret; + + printf("Enter Example_Exc Handler.\r\n"); + + /* 模拟函数调用 */ + ret = Get_Result_Exception_2(TSK_PRIOR); + printf("Divided result =%u.\r\n", ret); + + printf("Exit Example_Exc Handler.\r\n"); + return ret; + } + + + /* 任务测试入口函数,创建一个会发生异常的任务 */ + UINT32 Example_Exc_Entry(VOID) + { + UINT32 ret; + TSK_INIT_PARAM_S initParam; + + /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */ + LOS_TaskLock(); + + printf("LOS_TaskLock() Success!\r\n"); + + initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_Exc; + initParam.usTaskPrio = TSK_PRIOR; + initParam.pcName = "Example_Exc"; + initParam.uwStackSize = LOSCFG_SECURE_STACK_DEFAULT_SIZE; + /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ + ret = LOS_TaskCreate(&g_taskExcId, &initParam); + if (ret != LOS_OK) { + LOS_TaskUnlock(); + + printf("Example_Exc create Failed!\r\n"); + return LOS_NOK; + } + + printf("Example_Exc create Success!\r\n"); + + /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */ + LOS_TaskUnlock(); + + return LOS_OK; + } + ``` + +1. 上述代码串口终端输出异常信息如下: + ``` + entering kernel init... + LOS_TaskLock() Success! + Example_Exc create Success! + Entering scheduler + Enter Example_Exc Handler. + *Exception Information** + Type = 10 + ThrdPid = 4 + Phase = exc in task + FaultAddr = 0xabababab + Current task info: + Task name = Example_Exc + Task ID = 4 + Task SP = 0x200051ac + Task ST = 0x20004ff0 + Task SS = 0x200 + Exception reg dump: + PC = 0x80037da + LR = 0x80037fe + SP = 0x20005190 + R0 = 0x4 + R1 = 0x40 + R2 = 0x4 + R3 = 0x0 + R4 = 0x4040404 + R5 = 0x5050505 + R6 = 0x6060606 + R7 = 0x20005190 + R8 = 0x8080808 + R9 = 0x9090909 + R10 = 0x10101010 + R11 = 0x11111111 + R12 = 0x12121212 + PriMask = 0x0 + xPSR = 0x41000000 + ----- backtrace start ----- + backtrace 0 -- lr = 0x800381a + backtrace 1 -- lr = 0x8003836 + backtrace 2 -- lr = 0x8005a4e + backtrace 3 -- lr = 0x8000494 + 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 ----- + + TID Priority Status StackSize WaterLine StackPoint TopOfStack EventMask SemID name + --- -------- -------- --------- ---------- ---------- ---------- --------- ----- ---- + 0 0 Pend 0x2d0 0x104 0x200029bc 0x200027f0 0x0 0xffff Swt_Task + 1 31 Ready 0x500 0x44 0x20002f84 0x20002ac8 0x0 0xffff IdleCore000 + 2 6 Ready 0x1000 0x44 0x20003f94 0x20002fd8 0x0 0xffff TaskSampleEntry1 + 3 7 Ready 0x1000 0x44 0x20004f9c 0x20003fe0 0x0 0xffff TaskSampleEntry2 + 4 4 Running 0x200 0xec 0x200051ac 0x20004ff0 0x0 0xffff Example_Exc + + OS exception NVIC dump: + interrupt enable register, base address: 0xe000e100, size: 0x20 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt pending register, base address: 0xe000e200, size: 0x20 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt active register, base address: 0xe000e300, size: 0x20 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt priority register, base address: 0xe000e400, size: 0xf0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 + interrupt exception register, base address: 0xe000ed18, size: 0xc + 0x0 0x0 0xf0f00000 + interrupt shcsr register, base address: 0xe000ed24, size: 0x4 + 0x70008 + interrupt control register, base address: 0xe000ed04, size: 0x4 + 0x400f806 + + memory pools check: + system heap memcheck over, all passed! + memory pool check end! + ``` + + +### 定位流程 异常接管一般的定位步骤如下: -1. 打开编译后生成的镜像反汇编(asm)文件。如果默认没有生成,可以使用objdump工具生成,命令为: - - ``` - arm-none-eabi-objdump -S -l XXX.elf - ``` - - -1. 搜索PC指针(指向当前正在执行的指令)在asm中的位置,找到发生异常的函数。 - - PC地址指向发生异常时程序正在执行的指令。在当前执行的二进制文件对应的asm文件中,查找PC值0x80037da,找到当前CPU正在执行的指令行,反汇编如下所示: - - ``` - UINT32 Get_Result_Exception_0(UINT16 dividend){ - 80037c8: b480 push {r7} - 80037ca: b085 sub sp, #20 - 80037cc: af00 add r7, sp, #0 - 80037ce: 4603 mov r3, r0 - 80037d0: 80fb strh r3, [r7, #6] - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:10 - UINT32 divisor = 0; - 80037d2: 2300 movs r3, #0 - 80037d4: 60fb str r3, [r7, #12] - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:11 - UINT32 result = dividend / divisor; - 80037d6: 88fa ldrh r2, [r7, #6] - 80037d8: 68fb ldr r3, [r7, #12] - 80037da: fbb2 f3f3 udiv r3, r2, r3 - 80037de: 60bb str r3, [r7, #8] - ``` - - -1. 可以看到: - 1. 异常时CPU正在执行的指令是udiv r3, r2, r3,其中r3取值为0,导致发生除零异常。 - 2. 异常发生在函数Get\_Result\_Exception\_0中。 - -2. 根据LR值查找异常函数的父函数。 - - 包含LR值0x80037fe的反汇编如下所示: - - ``` - 080037ec : - Get_Result_Exception_1(): - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:15 - UINT32 Get_Result_Exception_1(UINT16 dividend){ - 80037ec: b580 push {r7, lr} - 80037ee: b082 sub sp, #8 - 80037f0: af00 add r7, sp, #0 - 80037f2: 4603 mov r3, r0 - 80037f4: 80fb strh r3, [r7, #6] - kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:16 - return Get_Result_Exception_0(dividend); - 80037f6: 88fb ldrh r3, [r7, #6] - 80037f8: 4618 mov r0, r3 - 80037fa: f7ff ffe5 bl 80037c8 - 80037fe: 4603 mov r3, r0 - ``` - - -1. LR值80037fe上一行是bl 80037c8 ,此处调用了异常函数,调用异常函数的父函数为Get\_Result\_Exception\_1\(\)。 -2. 重复步骤3,解析异常信息中backtrace start至backtrace end之间的LR值,得到调用产生异常的函数调用栈关系,找到异常原因。 - +1. 打开编译后生成的镜像反汇编(asm)文件。如果默认没有生成,可以使用objdump工具生成,命令为: + ``` + arm-none-eabi-objdump -S -l XXX.elf + ``` + +1. 搜索PC指针(指向当前正在执行的指令)在asm中的位置,找到发生异常的函数。 + PC地址指向发生异常时程序正在执行的指令。在当前执行的二进制文件对应的asm文件中,查找PC值0x80037da,找到当前CPU正在执行的指令行,反汇编如下所示: + + ``` + UINT32 Get_Result_Exception_0(UINT16 dividend){ + 80037c8: b480 push {r7} + 80037ca: b085 sub sp, #20 + 80037cc: af00 add r7, sp, #0 + 80037ce: 4603 mov r3, r0 + 80037d0: 80fb strh r3, [r7, #6] + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:10 + UINT32 divisor = 0; + 80037d2: 2300 movs r3, #0 + 80037d4: 60fb str r3, [r7, #12] + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:11 + UINT32 result = dividend / divisor; + 80037d6: 88fa ldrh r2, [r7, #6] + 80037d8: 68fb ldr r3, [r7, #12] + 80037da: fbb2 f3f3 udiv r3, r2, r3 + 80037de: 60bb str r3, [r7, #8] + ``` + +1. 可以看到: + 1. 异常时CPU正在执行的指令是udiv r3, r2, r3,其中r3取值为0,导致发生除零异常。 + 2. 异常发生在函数Get_Result_Exception_0中。 + +2. 根据LR值查找异常函数的父函数。 + 包含LR值0x80037fe的反汇编如下所示: + + ``` + 080037ec : + Get_Result_Exception_1(): + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:15 + UINT32 Get_Result_Exception_1(UINT16 dividend){ + 80037ec: b580 push {r7, lr} + 80037ee: b082 sub sp, #8 + 80037f0: af00 add r7, sp, #0 + 80037f2: 4603 mov r3, r0 + 80037f4: 80fb strh r3, [r7, #6] + kernel_liteos_m\targets\cortex-m7_nucleo_f767zi_gcc/Core/Src/exc_example.c:16 + return Get_Result_Exception_0(dividend); + 80037f6: 88fb ldrh r3, [r7, #6] + 80037f8: 4618 mov r0, r3 + 80037fa: f7ff ffe5 bl 80037c8 + 80037fe: 4603 mov r3, r0 + ``` + +1. LR值80037fe上一行是bl 80037c8 <Get_Result_Exception_0>,此处调用了异常函数,调用异常函数的父函数为Get_Result_Exception_1()。 + +2. 重复步骤3,解析异常信息中backtrace start至backtrace end之间的LR值,得到调用产生异常的函数调用栈关系,找到异常原因。 diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-lms.md b/zh-cn/device-dev/kernel/kernel-mini-memory-lms.md new file mode 100644 index 0000000000..15c7df576a --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-lms.md @@ -0,0 +1,251 @@ +# LMS调测 + +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [示例代码](#示例代码) + - [结果验证](#结果验证) + +## 基本概念 + +LMS全称为Lite Memory Sanitizer,是一种实时检测内存操作合法性的调测工具。LMS能够实时检测缓冲区溢出(buffer overflow),释放后使用(use after free) 和重复释放(double Free), 在异常发生的第一时间通知操作系统,结合backtrace等定位手段,能准确定位到产生内存问题的代码行,极大提升内存问题定位效率。 + +OpenHarmony LiteOS-M内核的LMS模块提供下面几种功能: + +- 支持多内存池检测。 + +- 支持LOS_MemAlloc、LOS_MemAllocAlign、LOS_MemRealloc申请出的内存检测。 + +- 支持安全函数的访问检测(默认开启)。 + +- 支持libc 高频函数的访问检测,包括:memset、memcpy、memmove、strcat、strcpy、strncat、strncpy。 + + +## 运行机制 + +LMS使用影子内存映射标记系统内存的状态,一共可标记为三个状态:可读写,不可读写,已释放。影子内存存放在内存池的尾部。 + +- 内存从堆上申请后,会将数据区的影子内存设置为“可读写”状态,并将头结点区的影子内存设置为“不可读写”状态。 + +- 内存在堆上被释放时,会将被释放内存的影子内存设置为“已释放”状态。 + +- 编译代码时,会在代码中的读写指令前插入检测函数,对地址的合法性进行检验。主要是检测访问内存的影子内存的状态值,若检测到影子内存为不可读写,则会报溢出错误;若检测到影子内存为已释放,则会报释放后使用错误。 + +- 在内存释放时,会检测被释放地址的影子内存状态值,若检测到影子内存非可读写,则会报重复释放错误。 + + +## 接口说明 + +OpenHarmony LiteOS-M内核的LMS模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_m/blob/master/components/lms/los_lms.h)参考。 + +**表1** LMS模块接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 添加指定内存池被检测 | LOS_LmsCheckPoolAdd | 将指定内存池的地址范围添加到LMS的内存检测链表上,当访问的地址在链表范围内时,LMS才进行合法性校验;且LOS_MemInit接口会调用该接口,默认将初始化的内存池挂入到检测链表中。 | +| 删除指定内存池不被检测 | LOS_LmsCheckPoolDel | 不检测指定内存池地址范围内的合法性校验。 | +| 使能指定内存段锁保护 | LOS_LmsAddrProtect | 为某段内存地址上锁,设置为不可读写,一旦访问则报错。 | +| 去能指定内存段锁保护 | LOS_LmsAddrDisableProtect | 为某段内存地址解锁,设置为可读写。 | + + +## 开发指导 + + +### 开发流程 + +开启LMS调测的典型流程如下: + +1. 配置LMS模块相关宏。 + 配置LMS控制宏LOSCFG_KERNEL_LMS,默认关,在kernel/liteos_m目录下执行 make update_config命令配置"Kernel->Enable Lite Memory Sanitizer"中打开YES: + + | 宏 | menuconfig选项 | 含义 | 取值 | + | -------- | -------- | -------- | -------- | + | LOSCFG_KERNEL_LMS | Enable Lms Feature | Lms模块的裁剪开关 | YES/NO | + | LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms check pool max num | LMS支持的检测内存池最大个数 | INT | + | LOSCFG_LMS_LOAD_CHECK | Enable lms read check | LMS内存读检测的裁剪开关 | YES/NO | + | LOSCFG_LMS_STORE_CHECK | Enable lms write check | LMS内存写检测的裁剪开关 | YES/NO | + | LOSCFG_LMS_CHECK_STRICT | Enable lms strict check, byte-by-byte | LMS内存逐字节严格检测的裁剪开关 | YES/NO | + +2. 在被检测模块的编译脚本中,修改编译选项。 + 增加LMS检测编译选项-fsanitize=kernel-address。为避免编译器优化,增加-O0编译选项。 + + gcc与clang编译选项存在差异,参照如下示例: + ``` + if ("$ohos_build_compiler_specified" == "gcc") { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + ] + } else { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + ] + } + ``` + +3. 重新编译,查看串口输出。如果检测到内存问题,会输出检测结果。 + + +### 编程实例 + +本实例实现如下功能: + +1. 创建一个用于Lms测试的任务。 + +2. 构造内存溢出错误和释放后使用错误。 + +3. 添加-fsanitize=kernel-address后编译执行,观察输出结果 + + +### 示例代码 + +实例代码如下: +``` +#define PAGE_SIZE (0x1000U) +#define INDEX_MAX 20 +UINT32 g_lmsTestTaskId; +char g_testLmsPool[2 * PAGE_SIZE]; +STATIC VOID testPoolInit(void) +{ + UINT32 ret = LOS_MemInit(g_testLmsPool, 2 * PAGE_SIZE); + if (ret != 0) { + PRINT_ERR("%s failed, ret = 0x%x\n", __FUNCTION__, ret); + return; + } +} +static VOID LmsTestOsmallocOverflow(VOID) +{ + PRINTK("\n######%s start ######\n", __FUNCTION__); + UINT32 i; + CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); + PRINTK("str[%2d]=0x%2x ", INDEX_MAX, str[INDEX_MAX]); /* trigger heap overflow at str[INDEX_MAX] */ + PRINTK("\n######%s stop ######\n", __FUNCTION__); +} +static VOID LmsTestUseAfterFree(VOID) +{ + PRINTK("\n######%s start ######\n", __FUNCTION__); + UINT32 i; + CHAR *str = (CHAR *)LOS_MemAlloc(g_testLmsPool, INDEX_MAX); + LOS_MemFree(g_testLmsPool, str); + PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */ + PRINTK("\n######%s stop ######\n", __FUNCTION__); +} +VOID LmsTestCaseTask(VOID) +{ + testPoolInit(); + LmsTestOsmallocOverflow(); + LmsTestUseAfterFree(); +} +UINT32 Example_Lms_test(VOID){ + UINT32 ret; + TSK_INIT_PARAM_S lmsTestTask; + /* 创建用于lms测试的任务 */ + memset(&lmsTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + lmsTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LmsTestCaseTask; + lmsTestTask.pcName = "TestLmsTsk"; /* 测试任务名称 */ + lmsTestTask.uwStackSize = 0x800; + lmsTestTask.usTaskPrio = 5; + lmsTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_lmsTestTaskId, &lmsTestTask); + if(ret != LOS_OK){ + PRINT_ERR("LmsTestTask create failed .\n"); + return LOS_NOK; + } + return LOS_OK; +} +``` + + +### 结果验证 + +输出结果如下: +``` +######LmsTestOsmallocOverflow start ###### +[ERR]* Kernel Address Sanitizer Error Detected Start * +[ERR]Heap buffer overflow error detected +[ERR]Illegal READ address at: [0x4157a3c8] +[ERR]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2] +OsBackTrace fp = 0x402c0f88 +runTask->taskName = LmsTestCaseTask +runTask->taskID = 2 +***backtrace begin*** +traceback fp fixed, trace using fp = 0x402c0fd0 +traceback 0 -- lr = 0x400655a4 fp = 0x402c0ff8 +traceback 1 -- lr = 0x40065754 fp = 0x402c1010 +traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 +traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca +[LMS] Dump info around address [0x4157a3c8]: + [0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1 + [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 + [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 + [0x4157a3c8]: [ba] dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: [2] 2 + [0x4157a3d0]: 2c 1a 00 00 00 00 00 00 | [0x4157be3d | 0]: 2 3 + [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 + [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 + [0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3 + [0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3 +[ERR]* Kernel Address Sanitizer Error Detected End * +str[20]=0xffffffba +######LmsTestOsmallocOverflow stop ###### +###### LmsTestUseAfterFree start ###### +[ERR]* Kernel Address Sanitizer Error Detected Start * +[ERR]Use after free error detected +[ERR]Illegal READ address at: [0x4157a3d4] +[ERR]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3] +OsBackTrace fp = 0x402c0f90 +runTask->taskName = LmsTestCaseTask +runTask->taskID = 2 +***backtrace begin*** +traceback fp fixed, trace using fp = 0x402c0fd8 +traceback 0 -- lr = 0x40065680 fp = 0x402c0ff8 +traceback 1 -- lr = 0x40065758 fp = 0x402c1010 +traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 +traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca +[LMS] Dump info around address [0x4157a3d4]: + [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 + [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 + [0x4157a3c8]: ba dc cd ab a8 a3 57 41 | [0x4157be3c | 4]: 2 2 + [0x4157a3d0]: 2c 1a 00 00 [00] 00 00 00 | [0x4157be3d | 0]: 2 [3] + [0x4157a3d8]: 00 00 00 00 00 00 00 00 | [0x4157be3d | 4]: 3 3 + [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 + [0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2 + [0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3 + [0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3 +[ERR]* Kernel Address Sanitizer Error Detected End * +str[ 0]=0x 0 +######LmsTestUseAfterFree stop ###### +``` + +输出的关键信息包括: + +- 错误类型: + - Heap buffer overflow堆内存越界 + - Use after free 释放后使用 + +- 错误操作: + - Illegal Read非法读 + - Illegal Write非法写 + - Illegal Double free重复释放 + +- 上下文: + - 当前任务信息(taskName, taskId) + - 回溯栈(backtrace) + +- 出错地址的内存信息: + - 内存的值、及对应影子内存的值 + - 内存地址:内存值| [影子内存地址 | 影子内存字节内偏移]:影子内存值 + - 影子内存值:0(可读可写)、3(已释放)、2(红区)、1(填充值) diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-perf.md b/zh-cn/device-dev/kernel/kernel-mini-memory-perf.md new file mode 100644 index 0000000000..c04e40cbac --- /dev/null +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-perf.md @@ -0,0 +1,439 @@ +# Perf调测 + +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) + - [内核态](#内核态) + - [用户态](#用户态) +- [开发指导](#开发指导) + - [内核态开发流程](#内核态开发流程) +- [内核态编程实例](#内核态编程实例) +- [内核态示例代码](#内核态示例代码) + - [内核态结果验证](#内核态结果验证) + - [用户态开发流程](#用户态开发流程) + - [用户态编程实例](#用户态编程实例) + - [用户态示例代码](#用户态示例代码) + - [用户态结果验证](#用户态结果验证) + +## 基本概念 + +Perf为性能分析工具,依赖PMU(Performance Monitoring Unit)对采样事件进行计数和上下文采集,统计出热点分布(hot spot)和热路径(hot path)。 + + +## 运行机制 + +基于事件采样原理,以性能事件为基础,当事件发生时,相应的事件计数器溢出发生中断,在中断处理函数中记录事件信息,包括当前的pc、当前运行的任务ID以及调用栈等信息。 + +Perf提供2种工作模式,计数模式和采样模式。 + +计数模式仅统计事件发生的次数和耗时,采样模式会收集上下文数据到环形buffer中,需要IDE进行数据解析生成热点函数与热点路径 + + +## 接口说明 + + +### 内核态 + +OpenHarmony LiteOS-A内核的Perf模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_perf.h)参考。 + +**表1** Perf模块接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 开启/停止Perf采样 | LOS_PerfStart | 开启采样 | +| LOS_PerfStop | 停止采样 | +| 配置Perf采样事件 | LOS_PerfConfig | 配置采样事件的类型、周期等 | +| 读取采样数据 | LOS_PerfDataRead | 读取采样数据到指定地址 | +| 注册采样数据缓冲区的钩子函数 | LOS_PerfNotifyHookReg | 注册缓冲区水线到达的处理钩子 | +| LOS_PerfFlushHookReg | 注册缓冲区刷cache的钩子 | + + +1. Perf采样事件的结构体为PerfConfigAttr,详细字段含义及取值详见kernel\include\los_perf.h。 + +2. 采样数据缓冲区为环形buffer,buffer中读过的区域可以覆盖写,未被读过的区域不能被覆盖写。 + +3. 缓冲区有限,用户可通过注册水线到达的钩子进行buffer溢出提醒或buffer读操作。默认水线值为buffer总大小的1/2。 示例如下: + ``` + 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); + ``` + +4. 若perf采样的buffer涉及到cpu 跨cache,则用户可通过注册刷cache的钩子,进行cache同步。 示例如下: + ``` + VOID Example_PerfFlushHook(VOID *addr, UINT32 size) + { + OsCacheFlush(addr, size); /* platform interface */ + } + LOS_PerfNotifyHookReg(Example_PerfFlushHook); + ``` + + 刷cache接口视具体的平台自行配置。 + + +### 用户态 + + +新增perf字符设备,位于"/dev/perf",通过对设备节点的read\write\ioctl,实现用户态perf的读写和控制: + + +- read: 用户态读取perf记录数据 + +- write: 用户态采样事件配置 + +- ioctl: 用户态Perf控制操作,包括 + ``` + #define PERF_IOC_MAGIC 'T' + #define PERF_START _IO(PERF_IOC_MAGIC, 1) + #define PERF_STOP _IO(PERF_IOC_MAGIC, 2) + ``` + + 分别对应Perf启动(LOS_PerfStart)、停止(LOS_PerfStop) + + +具体的使用方法参见[用户态编程实例](#用户态编程实例)。 + + +## 开发指导 + + +### 内核态开发流程 + +开启Perf调测的典型流程如下: + +1. 配置Perf模块相关宏。 + 配置Perf控制宏LOSCFG_KERNEL_PERF,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Perf Feature"中打开: + + | 配置项 | menuconfig选项 | 含义 | 设置值 | + | -------- | -------- | -------- | -------- | + | LOSCFG_KERNEL_PERF | Enable Perf Feature | Perf模块的裁剪开关 | YES/NO | + | LOSCFG_PERF_CALC_TIME_BY_TICK | Time-consuming Calc Methods->By Tick | Perf计时单位为tick | YES/NO | + | LOSCFG_PERF_CALC_TIME_BY_CYCLE | Time-consuming Calc Methods->By Cpu Cycle | Perf计时单位为cycle | YES/NO | + | LOSCFG_PERF_BUFFER_SIZE | Perf Sampling Buffer Size | Perf采样buffer的大小 | INT | + | LOSCFG_PERF_HW_PMU | Enable Hardware Pmu Events for Sampling | 使能硬件PMU事件,需要目标平台支持硬件PMU | YES/NO | + | LOSCFG_PERF_TIMED_PMU | Enable Hrtimer Period Events for Sampling | 使能高精度周期事件,需要目标平台支持高精度定时器 | YES/NO | + | LOSCFG_PERF_SW_PMU | Enable Software Events for Sampling | 使能软件事件,需要开启LOSCFG_KERNEL_HOOK | YES/NO | + +2. 调用LOS_PerfConfig配置需要采样的事件。 + Perf提供2种模式的配置,及3大类型的事件配置: + + 2种模式:计数模式(仅统计事件发生次数)、采样模式(收集上下文如任务ID、pc、backtrace等)。 + + 3种事件类型:CPU硬件事件(cycle、branch、icache、dcache等)、高精度周期事件(cpu clock)、OS软件事件(task switch、mux pend、irq等)。 + +3. 在需要采样的代码起始点调用LOS_PerfStart(UINT32 sectionId), 入参sectionId标记不同的采样回话id。 + +4. 在需要采样的代码结束点调用LOS_PerfStop。 + +5. 调用输出缓冲区数据的接口LOS_PerfDataRead读取采样数据,并使用IDE工具进行解析。 + + +## 内核态编程实例 + +本实例实现如下功能: + +1. 创建perf测试任务。 + +2. 配置采样事件。 + +3. 启动perf。 + +4. 执行需要统计的算法。 + +5. 停止perf。 + +6. 输出统计结果。 + + +## 内核态示例代码 + +前提条件:在menuconfig菜单中完成perf模块的配置。 + +实例代码如下: +``` +#include "los_perf.h" +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; + PerfConfigAttr attr = { + .eventsCfg = { + .type = PERF_EVENT_TYPE_HW, + .events = { + [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, + [1] = {PERF_COUNT_HW_BRANCH_INSTRUCTIONS, 0xFFFFFF00}, + }, + .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); + 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; + /* 创建用于perf测试的任务 */ + memset(&perfTestTask, 0, sizeof(TSK_INIT_PARAM_S)); + perfTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)perfTestHwEvent; + perfTestTask.pcName = "TestPerfTsk"; /* 测试任务名称 */ + perfTestTask.uwStackSize = 0x800; + perfTestTask.usTaskPrio = 5; + perfTestTask.uwResved = LOS_TASK_STATUS_DETACHED; + ret = LOS_TaskCreate(&g_perfTestTaskId, &perfTestTask); + if(ret != LOS_OK){ + PRINT_ERR("PerfTestTask create failed.\n"); + return LOS_NOK; + } + return LOS_OK; +} +LOS_MODULE_INIT(perfTestHwEvent, LOS_INIT_LEVEL_KMOD_EXTENDED); +``` + + +### 内核态结果验证 + +输出结果如下: +``` +--------count mode---------- +[EMG] [cycles] eventType: 0xff: 5466989440 +[EMG] [branches] eventType: 0xc: 602166445 +------- sample mode---------- +[EMG] dump section data, addr: 0x8000000 length: 0x800000 +num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ... +hex: 00 ef ef ef 00 00 00 00 14 00 00 00 60 00 00 00 00 00 00 00 70 88 36 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 01 00 00 00 cc 55 30 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 +``` + +- 针对计数模式,系统在perf stop后会打印: + 事件名称(cycles)、事件类型(0xff)、事件发生的次数(5466989440)。 + + 当采样事件为硬件PMU事件时,打印的事件类型为实际的硬件事件id,非enum PmuHWId中定义的抽象类型。 + +- 针对采样模式,系统在perf stop后会打印采样数据的地址和长度: + dump section data, addr: (0x8000000) length: (0x5000) + + 用户可以通过JTAG口导出该片内存,再使用IDE线下工具解析。 + + 或者通过LOS_PerfDataRead将数据读到指定地址,进行查看或进一步处理。示例中OsPrintBuff为测试接口,其按字节打印Read到的采样数据,num表示第几个字节,hex表示该字节中的数值。 + + +### 用户态开发流程 + +通过在menuconfig配置"Driver->Enable PERF DRIVER",开启Perf驱动。该配置仅在内核Enable Perf Feature后,才可在Driver的选项中可见。 + +1. 打开“/dev/perf”字符文件,进行读写和IOCTL操作; + +2. 系统提供用户态的perf命令,该命令位于/bin目录下,cd bin 后可执行如下命令: + - ./perf start [id] 启动perf采样, id 为可选项,默认值为0 + - ./perf stop 停止perf采样 + - ./perf read <nBytes> 从采样缓冲区中读取nBytes数据并打印内容 + - ./perf list 罗列-e支持的具体事件 + - ./perf stat/record [option] <command> 计数/采样模式命令 + - option可选如下: + - -e,配置采样事件。可使用./perf list 中罗列的同类型事件。 + - -p,配置事件采样周期。 + - -o, 指定perf采样数据结果保存的文件路径。 + - -t,任务Id过滤(白名单),只采取指定任务中的上下文。如果不指定改参数,则默认采集所有的任务。 + - -s, 配置采样的具体上下文类型,可查阅los_perf.h中定义的PerfSampleType。 + - -P, 进程Id过滤(白名单),只采取指定进程中的上下文。如果不指定改参数,则默认采集所有进程。 + - -d, 是否进行分频(事件每发生64次累计+1),该选项仅在硬件cycle事件上生效。 + - command 为待统计的子程序。 + +用户态命令行的典型使用方法如下: + +./perf list 查看可使用的事件列表, 输出如下: + +``` +cycles [Hardware event] +instruction [Hardware event] +dcache [Hardware event] +dcache-miss [Hardware event] +icache [Hardware event] +icache-miss [Hardware event] +branch [Hardware event] +branch-miss [Hardware event] +clock [Timed event] +task-switch [Software event] +irq-in [Software event] +mem-alloc [Software event] +mux-pend [Software event] +``` + +./perf stat -e cycles os_dump, 输出如下: + +``` +type: 0 +events[0]: 255, 0xffff +predivided: 0 +sampleType: 0x0 +needSample: 0 +usage os_dump [--help | -l | SERVICE] + --help: shows this help + -l: only list services, do not dump them + SERVICE: dumps only service SERVICE +time used: 0.058000(s) +[cycles] eventType: 0xff [core 0]: 21720647 +[cycles] eventType: 0xff [core 1]: 13583830 +``` + +./perf record -e cycles os_dump, 输出如下: + +``` +type: 0 +events[0]: 255, 0xffff +predivided: 0 +sampleType: 0x60 +needSample: 1 +usage os_dump [--help | -l | SERVICE] + --help: shows this help + -l: only list services, do not dump them + SERVICE: dumps only service SERVICE +dump perf data, addr: 0x408643d8 length: 0x5000 +time used: 0.059000(s) +save perf data success at /storage/data/perf.data +``` + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 在进行./perf stat/record命令后,用户可多次执行./perf start 和 ./perf stop进行采样, 采样的事件配置为最近一次执行./perfstat/record 中设置的参数。 + + +### 用户态编程实例 + +本实例实现如下功能: + +1. 打开perf字符设备。 + +2. 写perf配置事件。 + +3. 启动perf。 + +4. 停止perf。 + +5. 读取perf采样数据。 + + +### 用户态示例代码 + +实例代码如下: +``` +#include "fcntl.h" +#include "user_copy.h" +#include "sys/ioctl.h" +#include "fs/driver.h" +#include "los_dev_perf.h" +#include "los_perf.h" +#include "los_init.h" +/* perf ioctl */ +#define PERF_IOC_MAGIC 'T' +#define PERF_START _IO(PERF_IOC_MAGIC, 1) +#define PERF_STOP _IO(PERF_IOC_MAGIC, 2) +int main(int argc, char **argv) +{ + char *buf = NULL; + ssize_t len; + int fd = open("/dev/perf", O_RDWR); + if (fd == -1) { + printf("Perf open failed.\n"); + exit(EXIT_FAILURE); + } + PerfConfigAttr attr = { + .eventsCfg = { +#ifdef LOSCFG_PERF_HW_PMU + .type = PERF_EVENT_TYPE_HW, + .events = { + [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, + }, +#elif defined LOSCFG_PERF_TIMED_PMU + .type = PERF_EVENT_TYPE_TIMED, + .events = { + [0] = {PERF_COUNT_CPU_CLOCK, 100}, + }, +#elif defined LOSCFG_PERF_SW_PMU + .type = PERF_EVENT_TYPE_SW, + .events = { + [0] = {PERF_COUNT_SW_TASK_SWITCH, 1}, + }, +#endif + .eventsNr = 1, /* 1 event */ + .predivided = 0, + }, + .taskIds = {0}, + .taskIdsNr = 0, + .processIds = {0}, + .processIdsNr = 0, + .needSample = 1, + .sampleType = PERF_RECORD_IP | PERF_RECORD_CALLCHAIN, + }; + (void)write(fd, &attr, sizeof(PerfConfigAttr)); /* perf config */ + ioctl(fd, PERF_START, NULL); /* perf start */ + test(); + ioctl(fd, PERF_STOP, NULL); /* perf stop */ + buf = (char *)malloc(LOSCFG_PERF_BUFFER_SIZE); + if (buf == NULL) { + printf("no memory for read perf 0x%x\n", LOSCFG_PERF_BUFFER_SIZE); + return -1; + } + len = read(fd, buf, LOSCFG_PERF_BUFFER_SIZE); + OsPrintBuff(buf, len); /* print data */ + free(buf); + close(fd); + return 0; +} +``` + + +### 用户态结果验证 + +输输出结果如下:出结果如下: +``` +[EMG] dump section data, addr: 0x8000000 length: 0x800000 +num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ... +hex: 00 ef ef ef 00 00 00 00 14 00 00 00 60 00 00 00 00 00 00 00 70 88 36 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 01 00 00 00 cc 55 30 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 +``` diff --git a/zh-cn/device-dev/kernel/kernel-mini-memory-trace.md b/zh-cn/device-dev/kernel/kernel-mini-memory-trace.md index 22302976d8..d47ca277b3 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-memory-trace.md +++ b/zh-cn/device-dev/kernel/kernel-mini-memory-trace.md @@ -1,25 +1,21 @@ # Trace调测 -- [基本概念](#section1) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [示例代码](#示例代码) + - [结果验证](#结果验证) -- [运行机制](#section2) +## 基本概念 -- [接口说明](#section3) - -- [开发指导](#section4) - - - [开发流程](#section4.1) - - - [编程实例](#section4.2) - - - [实例代码](#section4.3) +Trace调测旨在帮助开发者获取内核的运行流程,各个模块、任务的执行顺序,从而可以辅助开发者定位一些时序问题或者了解内核的代码运行过程。 - - [结果验证](#section4.4) -## 基本概念 -Trace调测旨在帮助开发者获取内核的运行流程,各个模块、任务的执行顺序,从而可以辅助开发者定位一些时序问题或者了解内核的代码运行过程。 +## 运行机制 -## 运行机制 内核提供一套Hook框架,将Hook点预埋在各个模块的主要流程中, 在内核启动初期完成Trace功能的初始化,并注册Trace的处理函数到Hook中。 当系统触发到一个Hook点时,Trace模块会对输入信息进行封装,添加Trace帧头信息,包含事件类型、运行的cpuid、运行的任务id、运行的相对时间戳等信息; @@ -28,181 +24,122 @@ Trace提供2种工作模式,离线模式和在线模式。 离线模式会将trace frame记录到预先申请好的循环buffer中。如果循环buffer记录的frame过多则可能出现翻转,会覆盖之前的记录,故保持记录的信息始终是最新的信息。Trace循环buffer的数据可以通过shell命令导出进行详细分析,导出信息已按照时间戳信息完成排序。 -![](figure/zh-cn_image_0000001127390512.png) +![zh-cn_image_0000001168711762](figures/zh-cn_image_0000001168711762.png) 在线模式需要配合IDE使用,实时将trace frame记录发送给IDE,IDE端进行解析并可视化展示。 -## 接口说明 -OpenHarmony LiteOS-M内核的Trace模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_m/blob/master/components/trace/los_trace.h)参考。 - -**表 1** Trace模块接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

启停控制

-

LOS_TraceStart

-

启动Trace

-

LOS_TraceStop

-

停止Trace

-

操作Trace记录的数据

-

LOS_TraceRecordDump

-

输出Trace缓冲区数据

-

LOS_TraceRecordGet

-

获取Trace缓冲区的首地址

-

LOS_TraceReset

-

清除Trace缓冲区中的事件

-

过滤Trace记录的数据

-

LOS_TraceEventMaskSet

-

设置事件掩码,仅记录某些模块的事件

-

屏蔽某些中断号事件

-

LOS_TraceHwiFilterHookReg

-

注册过滤特定中断号事件的钩子函数

-

插桩函数

-

LOS_TRACE_EASY

-

简易插桩

-

LOS_TRACE

-

标准插桩

-
- - -1. 当用户需要针对自定义事件进行追踪时,可按规则在目标源代码中进行插桩,系统提供如下2种插桩接口: - -+ LOS_TRACE_EASY(TYPE, IDENTITY, params...) 简易插桩。 - - - 一句话插桩,用户在目标源代码中插入该接口即可。 - - - TYPE有效取值范围为[0, 0xF],表示不同的事件类型,不同取值表示的含义由用户自定义。 - - - IDENTITY类型UINTPTR,表示事件操作的主体对象。 - - - Params类型UINTPTR,表示事件的参数。 - - - 示例: - - ``` - 假设需要新增对文件(fd1、fd2)读写操作的简易插桩, - 自定义读操作为type:1, 写操作为type:2,则 - 在读fd1文件的适当位置插入: - LOS_TRACE_EASY(1, fd1, flag, size); - 在读fd2文件的适当位置插入: - LOS_TRACE_EASY(1, fd2, flag, size); - 在写fd1文件的适当位置插入: - LOS_TRACE_EASY(2, fd1, flag, size); - 在写fd2文件的适当位置插入: - LOS_TRACE_EASY(2, fd2,flag, size); - ``` - -+ LOS_TRACE(TYPE, IDENTITY, params...) 标准插桩。 - - - 相比简易插桩,支持动态过滤事件和参数裁剪,但使用上需要用户按规则来扩展。 - - - TYPE用于设置具体的事件类型,可以在头文件los_trace.h中的enum LOS_TRACE_TYPE中自定义事件类型。定义方法和规则可以参考其他事件类型。 - - - IDENTITY和Params的类型及含义同简易插桩。 - - - 示例: -``` - 1.在enum LOS_TRACE_MASK中定义事件掩码,即模块级别的事件类型。 - 定义规范为TRACE_#MOD#_FLAG,#MOD#表示模块名,例如: - TRACE_FS_FLAG = 0x4000 - 2.在enum LOS_TRACE_TYPE中定义具体事件类型。定义规范为#TYPE# = TRACE_#MOD#_FLAG | NUMBER,例如: - FS_READ = TRACE_FS_FLAG | 0; // 读文件 - FS_WRITE = TRACE_FS_FLAG | 1; // 写文件 - 3.定义事件参数。定义规范为#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ... - 其中的#TYPE#就是上面2中的#TYPE#,例如: - #define FS_READ_PARAMS(fp, fd, flag, size) fp, fd, flag, size - 宏定义的参数对应于Trace缓冲区中记录的事件参数,用户可对任意参数字段进行裁剪: - 当定义为空时,表示不追踪该类型事件: - #define FS_READ_PARAMS(fp, fd, flag, size) // 不追踪文件读事件 - 4.在适当位置插入代码桩。定义规范为LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...)) - LOS_TRACE(FS_READ, fp, fd, flag, size); // 读文件的代码桩, - #TYPE#之后的入参就是上面3中的FS_READ_PARAMS函数的入参 -``` -2. 预置的Trace事件及参数均可以通过上述方式进行裁剪,参数详见kernel\include\los_trace.h。 - -3. Trace Mask事件过滤接口LOS_TraceEventMaskSet(UINT32 mask),其入参mask仅高28位生效(对应LOS_TRACE_MASK中某模块的使能位),仅用于模块的过滤,暂不支持针对某个特定事件的细粒度过滤。例如:LOS_TraceEventMaskSet(0x202),则实际设置生效的mask为0x200(TRACE_QUE_FLAG),QUE模块的所有事件均会被采集。一般建议使用的方法为: - LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG); - -4. 如果仅需要过滤简易插桩事件,通过设置Trace Mask为TRACE_MAX_FLAG即可。 - -5. Trace缓冲区有限,事件写满之后会覆盖写,用户可通过LOS_TraceRecordDump中打印的CurEvtIndex识别最新记录。 - -6. Trace的典型操作流程为:LOS_TraceStart、 LOS_TraceStop、 LOS_TraceRecordDump. -7. 针对中断事件的Trace, 提供中断号过滤,用于解决某些场景下特定中断号频繁触发导致其他事件被覆盖的情况,用户可自定义中断过滤的规则, - - 示例如下: -``` -BOOL Example_HwiNumFilter(UINT32 hwiNum) -{ - if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { - return TRUE; - } - return FALSE; -} -LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); -``` -则当中断号为TIMER_INT 或者DMA_INT时,不记录中断事件。 - -## 开发指导 - -### 开发流程 +## 接口说明 + +OpenHarmony LiteOS-M内核的Trace模块提供下面几种功能,接口详细信息可以查看API参考。 + +**表1** Trace模块接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 启停控制 | LOS_TraceStart | 启动Trace | +| LOS_TraceStop | 停止Trace | +| 操作Trace记录的数据 | LOS_TraceRecordDump | 输出Trace缓冲区数据 | +| LOS_TraceRecordGet | 获取Trace缓冲区的首地址 | +| LOS_TraceReset | 清除Trace缓冲区中的事件 | +| 过滤Trace记录的数据 | LOS_TraceEventMaskSet | 设置事件掩码,仅记录某些模块的事件 | +| 屏蔽某些中断号事件 | LOS_TraceHwiFilterHookReg | 注册过滤特定中断号事件的钩子函数 | +| 插桩函数 | LOS_TRACE_EASY | 简易插桩 | +| LOS_TRACE | 标准插桩 | + +- 当用户需要针对自定义事件进行追踪时,可按规则在目标源代码中进行插桩,系统提供如下2种插桩接口: + - LOS_TRACE_EASY(TYPE, IDENTITY, params...) 简易插桩。 + - 一句话插桩,用户在目标源代码中插入该接口即可。 + - TYPE有效取值范围为[0, 0xF],表示不同的事件类型,不同取值表示的含义由用户自定义。 + - IDENTITY类型UINTPTR,表示事件操作的主体对象。 + - Params类型UINTPTR,表示事件的参数。 + - 示例: + ``` + 假设需要新增对文件(fd1、fd2)读写操作的简易插桩, + 自定义读操作为type:1, 写操作为type:2,则 + 在读fd1文件的适当位置插入: + LOS_TRACE_EASY(1, fd1, flag, size); + 在读fd2文件的适当位置插入: + LOS_TRACE_EASY(1, fd2, flag, size); + 在写fd1文件的适当位置插入: + LOS_TRACE_EASY(2, fd1, flag, size); + 在写fd2文件的适当位置插入: + LOS_TRACE_EASY(2, fd2,flag, size); + ``` + - LOS_TRACE(TYPE, IDENTITY, params...) 标准插桩。 + - 相比简易插桩,支持动态过滤事件和参数裁剪,但使用上需要用户按规则来扩展。 + - TYPE用于设置具体的事件类型,可以在头文件los_trace.h中的enum LOS_TRACE_TYPE中自定义事件类型。定义方法和规则可以参考其他事件类型。 + - IDENTITY和Params的类型及含义同简易插桩。 + - 示例: + ``` + 1.在enum LOS_TRACE_MASK中定义事件掩码,即模块级别的事件类型。 + 定义规范为TRACE_#MOD#_FLAG,#MOD#表示模块名。 + 例如: + TRACE_FS_FLAG = 0x4000 + 2.在enum LOS_TRACE_TYPE中定义具体事件类型。 + 定义规范为#TYPE# = TRACE_#MOD#_FLAG | NUMBER, + 例如: + FS_READ = TRACE_FS_FLAG | 0; // 读文件 + FS_WRITE = TRACE_FS_FLAG | 1; // 写文件 + 3.定义事件参数。定义规范为#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ... + 其中的#TYPE#就是上面2中的#TYPE#, + 例如: + #define FS_READ_PARAMS(fp, fd, flag, size) fp, fd, flag, size + 宏定义的参数对应于Trace缓冲区中记录的事件参数,用户可对任意参数字段进行裁剪: + 当定义为空时,表示不追踪该类型事件: + #define FS_READ_PARAMS(fp, fd, flag, size) // 不追踪文件读事件 + 4.在适当位置插入代码桩。 + 定义规范为LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...)) + LOS_TRACE(FS_READ, fp, fd, flag, size); // 读文件的代码桩, + #TYPE#之后的入参就是上面3中的FS_READ_PARAMS函数的入参 + ``` + + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** + > 预置的Trace事件及参数均可以通过上述方式进行裁剪,参数详见kernel\include\los_trace.h。 + +- Trace Mask事件过滤接口LOS_TraceEventMaskSet(UINT32 mask),其入参mask仅高28位生效(对应LOS_TRACE_MASK中某模块的使能位),仅用于模块的过滤,暂不支持针对某个特定事件的细粒度过滤。例如:LOS_TraceEventMaskSet(0x202),则实际设置生效的mask为0x200(TRACE_QUE_FLAG),QUE模块的所有事件均会被采集。一般建议使用的方法为: LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG); + +- 如果仅需要简易插桩事件,通过设置Trace Mask为TRACE_MAX_FLAG即可。 + +- Trace缓冲区有限,事件写满之后会覆盖写,用户可通过LOS_TraceRecordDump中打印的CurEvtIndex识别最新记录。 + +- Trace的典型操作流程为:LOS_TraceStart、 LOS_TraceStop、 LOS_TraceRecordDump. + +- 针对中断事件的Trace, 提供中断号过滤,用于解决某些场景下特定中断号频繁触发导致其他事件被覆盖的情况,用户可自定义中断过滤的规则, + 示例如下: + ``` + BOOL Example_HwiNumFilter(UINT32 hwiNum) + { + if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { + return TRUE; + } + return FALSE; + } + LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); + ``` + + 则当中断号为TIMER_INT 或者DMA_INT时,不记录中断事件。 + + +## 开发指导 + + +### 开发流程 开启Trace调测的典型流程如下: 1. 配置Trace模块相关宏。 - -需要在target_config.h头文件中修改配置: - -| 配置项 | 含义 | 设置值 | -| ------------------------------ | ------------------------------------------------------------ | ------ | -| LOSCFG_KERNEL_TRACE | Trace模块的裁剪开关 | YES/NO | -| LOSCFG_RECORDER_MODE_OFFLINE | Trace工作模式为离线模式 | YES/NO | -| LOSCFG_RECORDER_MODE_ONLINE | Trace工作模式为在线模式 | YES/NO | -| LOSCFG_TRACE_CLIENT_INTERACT | 使能与Trace IDE (dev tools)的交互,包括数据可视化和流程控制 | YES/NO | -| LOSCFG_TRACE_FRAME_CORE_MSG | 记录CPUID、中断状态、锁任务状态 | YES/NO | -| LOSCFG_TRACE_FRAME_EVENT_COUNT | 记录事件的次序编号 | YES/NO | -| LOSCFG_TRACE_FRAME_MAX_PARAMS | 配置记录事件的最大参数个数 | INT | -| LOSCFG_TRACE_BUFFER_SIZE | 配置Trace的缓冲区大小 | INT | + 需要在target_config.h头文件中修改配置: + | 配置项 | 含义 | 设置值 | + | -------- | -------- | -------- | + | LOSCFG_KERNEL_TRACE | Trace模块的裁剪开关 | YES/NO | + | LOSCFG_RECORDER_MODE_OFFLINE | Trace工作模式为离线模式 | YES/NO | + | LOSCFG_RECORDER_MODE_ONLINE | Trace工作模式为在线模式 | YES/NO | + | LOSCFG_TRACE_CLIENT_INTERACT | 使能与Trace IDE (dev tools)的交互,包括数据可视化和流程控制 | YES/NO | + | LOSCFG_TRACE_FRAME_CORE_MSG | 记录CPUID、中断状态、锁任务状态 | YES/NO | + | LOSCFG_TRACE_FRAME_EVENT_COUNT | 记录事件的次序编号 | YES/NO | + | LOSCFG_TRACE_FRAME_MAX_PARAMS | 配置记录事件的最大参数个数 | INT | + | LOSCFG_TRACE_BUFFER_SIZE | 配置Trace的缓冲区大小 | INT | 2. (可选)预置事件参数和事件桩(或使用系统默认的事件参数配置和事件桩)。 @@ -216,7 +153,6 @@ LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); 7. 调用LOS_TraceRecordDump输出缓冲区数据(函数的入参为布尔型,FALSE表示格式化输出,TRUE表示输出到windows客户端)。 - 上述第3-7步中的接口,均封装有对应的shell命令,对应关系如下 - LOS_TraceReset —— trace_reset @@ -229,25 +165,27 @@ LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); - LOS_TraceRecordDump —— trace_dump -### 编程实例 - 本实例实现如下功能: +### 编程实例 + +本实例实现如下功能: - 1. 创建一个用于Trace测试的任务。 +1. 创建一个用于Trace测试的任务。 - 2. 设置事件掩码。 +2. 设置事件掩码。 - 3. 启动trace。 +3. 启动trace。 - 4. 停止trace。 +4. 停止trace。 - 5. 格式化输出trace数据。 +5. 格式化输出trace数据。 -### 示例代码 -实例代码如下: +### 示例代码 -```C +示例代码如下: + +``` #include "los_trace.h" UINT32 g_traceTestTaskId; VOID Example_Trace(VOID) @@ -268,7 +206,6 @@ VOID Example_Trace(VOID) LOS_TraceStop(); LOS_TraceRecordDump(FALSE); } - UINT32 Example_Trace_test(VOID){ UINT32 ret; TSK_INIT_PARAM_S traceTestTask; @@ -293,12 +230,13 @@ UINT32 Example_Trace_test(VOID){ } ``` -### 结果验证 + +### 结果验证 输出结果如下: -```c -*******TraceInfo begin******* +``` +***TraceInfo begin*** clockFreq = 50000000 CurEvtIndex = 7 Index Time(cycles) EventType CurTask Identity params @@ -310,7 +248,7 @@ Index Time(cycles) EventType CurTask Identity params 5 0x36eec810 0x45 0xc 0x1 0x9 0x8 0x1f 6 0x3706f804 0x45 0x1 0x0 0x1f 0x4 0x0 7 0x37070e59 0x45 0x0 0x1 0x0 0x8 0x1f -*******TraceInfo end******* +***TraceInfo end*** ``` 输出的事件信息包括:发生时间、事件类型、事件发生在哪个任务中、事件操作的主体对象、事件的其他参数。 @@ -319,9 +257,9 @@ Index Time(cycles) EventType CurTask Identity params - CurrentTask:表示当前运行在哪个任务中,值为taskid。 -- Identity:表示事件操作的主体对象,可查阅头文件los_trace.h中的#TYPE#_PARAMS。 +- Identity:表示事件操作的主体对象,可查阅头文件los_trace.h中的\#TYPE\#_PARAMS。 -- params:表示的事件参数可查阅头文件los_trace.h中的#TYPE#_PARAMS。 +- params:表示的事件参数可查阅头文件los_trace.h中的\#TYPE\#_PARAMS。 下面以序号为0的输出项为例,进行说明。 @@ -336,16 +274,13 @@ Index Time(cycles) EventType CurTask Identity params - Identity和params的含义需要查看TASK_SWITCH_PARAMS宏定义: -```c +``` #define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus ``` -因为#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ...,所以Identity为taskId(0x0),第一个参数为oldPriority(0x1f) - -> ![](../public_sys-resources/icon-note.gif)**说明** - - > params的个数由LOSCFG_TRACE_FRAME_MAX_PARAMS配置,默认为3,超出的参数不会被记录,用户应自行合理配置该值。 - - 综上所述,任务由0x1切换到0x0,0x1任务的优先级为0x1f,状态为0x4,0x0任务的优先级为0x0。 +因为\#TYPE\#_PARAMS(IDENTITY, parma1...) IDENTITY, ...,所以Identity为taskId(0x0),第一个参数为oldPriority(0x1f) +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> params的个数由LOSCFG_TRACE_FRAME_MAX_PARAMS配置,默认为3,超出的参数不会被记录,用户应自行合理配置该值。 +综上所述,任务由0x1切换到0x0,0x1任务的优先级为0x1f,状态为0x4,0x0任务的优先级为0x0。 diff --git a/zh-cn/device-dev/kernel/kernel-mini-overview.md b/zh-cn/device-dev/kernel/kernel-mini-overview.md index cb0c2d42c1..1a7369be01 100644 --- a/zh-cn/device-dev/kernel/kernel-mini-overview.md +++ b/zh-cn/device-dev/kernel/kernel-mini-overview.md @@ -1,62 +1,37 @@ -# 内核概述 +# 内核概述 -- [内核简介](#section1429342661510) - - [cpu体系架构支持](#section48891456112819) - - [运行机制](#section4599142312817) +- [内核简介](#内核简介) + - [cpu体系架构支持](#cpu体系架构支持) + - [运行机制](#运行机制) +## 内核简介 -## 内核简介 +OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点。其代码结构简单,主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等。支持驱动框架HDF(Hardware Driver Foundation),统一驱动标准,为设备厂商提供了更统一的接入方式,使驱动更加容易移植,力求做到一次开发,多系统部署。 -OpenHarmony LiteOS-M内核是面向IoT领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点。其代码结构简单,主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等。OpenHarmony LiteOS-M内核架构包含硬件相关层以及硬件无关层,如下图所示,其中硬件相关层按不同编译工具链、芯片架构分类,提供统一的HAL(Hardware Abstraction Layer)接口,提升了硬件易适配性,满足AIoT类型丰富的硬件和编译工具链的拓展;其他模块属于硬件无关层,其中基础内核模块提供基础能力,扩展模块提供网络、文件系统等组件能力,还提供错误处理、调测等能力;KAL(Kernel Abstraction Layer)模块提供统一的标准接口。 +OpenHarmony LiteOS-M内核架构包含硬件相关层以及硬件无关层,如下图所示,其中硬件相关层按不同编译工具链、芯片架构分类,提供统一的HAL(Hardware Abstraction Layer)接口,提升了硬件易适配性,满足AIoT类型丰富的硬件和编译工具链的拓展;其他模块属于硬件无关层,其中基础内核模块提供基础能力,扩展模块提供网络、文件系统等组件能力,还提供错误处理、调测等能力,KAL(Kernel Abstraction Layer)模块提供统一的标准接口。 -**图 1** 内核架构图 -![](figure/内核架构图.png "内核架构图") +**图1** 内核架构图 +![zh-cn_image_0000001199351155](figures/zh-cn_image_0000001199351155.png) -### cpu体系架构支持 + +### cpu体系架构支持 CPU体系架构分为通用架构定义和特定架构定义两层,通用架构定义层为所有体系架构都需要支持和实现的接口,特定架构定义层为特定体系架构所特有的部分。在新增一个体系架构的时候,必须需要实现通用架构定义层,如果该体系架构还有特有的功能,可以在特定架构定义层来实现。 -**表 1** CPU体系架构规则 - - - - - - - - - - - - - - - - - - - - -

规则

-

通用体系架构层

-

特定体系架构层

-

头文件位置

-

arch/include

-

arch/<arch>/<arch>/<toolchain>/

-

头文件命名

-

los_<function>.h

-

los_arch_<function>.h

-

函数命名

-

Halxxxx

-

Halxxxx

-
- -LiteOS-M已经支持ARM Cortex-M3、ARM Cortex-M4、ARM Cortex-M7、ARM Cortex-M33、RISC-V等主流架构,如果需要扩展CPU体系架构,请参考[芯片架构适配点](../porting/porting-chip-kernel-overview.md#section137431650339)。 - -### 运行机制 - -在开发板配置文件target\_config.h配置系统时钟、每秒Tick数,可以对任务、内存、IPC、异常处理模块进行裁剪配置。系统启动时,根据配置进行指定模块的初始化。内核启动流程包含外设初始化、系统时钟配置、内核初始化、操作系统启动等,详见内核启动流程图。 - -**图 2** 内核启动流程 -![](figure/内核启动流程.png "内核启动流程") +**表1** CPU体系架构规则 + +| 规则 | 通用体系架构层 | 特定体系架构层 | +| -------- | -------- | -------- | +| 头文件位置 | arch/include | arch/<arch>/<arch>/<toolchain>/ | +| 头文件命名 | los_<function>.h | los_arch_<function>.h | +| 函数命名 | Halxxxx | Halxxxx | + +LiteOS-M已经支持ARM Cortex-M3、ARM Cortex-M4、ARM Cortex-M7、ARM Cortex-M33、RISC-V等主流架构,如果需要扩展CPU体系架构,请参考[芯片架构适配点](../porting/porting-chip-kernel-overview.md#芯片架构适配点)。 + + +### 运行机制 + +在开发板配置文件target_config.h配置系统时钟、每秒Tick数,可以对任务、内存、IPC、异常处理模块进行裁剪配置。系统启动时,根据配置进行指定模块的初始化。内核启动流程包含外设初始化、系统时钟配置、内核初始化、操作系统启动等,详见内核启动流程。 +**图2** 内核启动流程 +![zh-cn_image_0000001160338832](figures/zh-cn_image_0000001160338832.png) diff --git a/zh-cn/device-dev/kernel/kernel-mini.md b/zh-cn/device-dev/kernel/kernel-mini.md index 11bfc8b151..04e901ddfc 100644 --- a/zh-cn/device-dev/kernel/kernel-mini.md +++ b/zh-cn/device-dev/kernel/kernel-mini.md @@ -1,13 +1,12 @@ -# 轻量系统内核 +# 轻量系统内核 -- **[内核概述](kernel-mini-overview.md)** -- **[基础内核](kernel-mini-basic.md)** +- **[内核概述](kernel-mini-overview.md)** -- **[扩展组件](kernel-mini-extend.md)** +- **[基础内核](kernel-mini-basic.md)** -- **[内核调测](kernel-memory-inner.md)** - -- **[附录](kernel-mini-app.md)** +- **[扩展组件](kernel-mini-extend.md)** +- **[内核调测](kernel-mini-debug.md)** +- **[附录](kernel-mini-app.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-apx-bitwise.md b/zh-cn/device-dev/kernel/kernel-small-apx-bitwise.md index 2cdda3573a..43f68e9887 100644 --- a/zh-cn/device-dev/kernel/kernel-small-apx-bitwise.md +++ b/zh-cn/device-dev/kernel/kernel-small-apx-bitwise.md @@ -1,85 +1,47 @@ -# 位操作 +# 位操作 -- [基本概念](#section1990715203418) -- [功能说明](#section848334511411) -- [编程实例](#section67569495514) - - [实例描述](#section33551554391) - - [结果验证](#section8931859194) +- [基本概念](#基本概念) +- [功能说明](#功能说明) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [结果验证](#结果验证) - -## 基本概念 +## 基本概念 位操作是指对二进制数的bit位进行操作。程序可以设置某一变量为状态字,状态字中的每一bit位(标志位)可以具有自定义的含义。 -## 功能说明 + +## 功能说明 系统提供标志位的置1和清0操作,可以改变标志位的内容,同时还提供获取状态字中标志位为1的最高位和最低位的功能。用户也可以对系统的寄存器进行位操作。位操作模块为用户提供下面几种功能,接口详细信息可以查看API参考。 -**表 1** 位操作模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

置1/清0标志位

-

LOS_BitmapSet

-

对状态字的某一标志位进行置1操作

-

LOS_BitmapClr

-

对状态字的某一标志位进行清0操作

-

获取标志位为1的bit位

-

LOS_HighBitGet

-

获取状态字中为1的最高位

-

LOS_LowBitGet

-

获取状态字中为1的最低位

-

连续bit位操作

-

LOS_BitmapSetNBits

-

对状态字的连续标志位进行置1操作

-

LOS_BitmapClrNBits

-

对状态字的连续标志位进行清0操作

-

LOS_BitmapFfz

-

获取从最低有效位开始的第一个0的bit位

-
- -## 编程实例 - -### 实例描述 +**表1** 位操作模块接口 + +| **功能分类** | **接口名称** | **描述** | +| -------- | -------- | -------- | +| 置1/清0标志位 | LOS_BitmapSet | 对状态字的某一标志位进行置1操作 | +| LOS_BitmapClr | 对状态字的某一标志位进行清0操作 | +| 获取标志位为1的bit位 | LOS_HighBitGet | 获取状态字中为1的最高位 | +| LOS_LowBitGet | 获取状态字中为1的最低位 | +| 连续bit位操作 | LOS_BitmapSetNBits | 对状态字的连续标志位进行置1操作 | +| LOS_BitmapClrNBits | 对状态字的连续标志位进行清0操作 | +| LOS_BitmapFfz | 获取从最低有效位开始的第一个0的bit位 | + + +## 编程实例 + + +### 实例描述 对数据实现位操作,本实例实现如下功能: -1. 某一标志位置1。 -2. 获取标志位为1的最高bit位。 -3. 某一标志位清0。 -4. 获取标志位为1的最低bit位。 +1. 某一标志位置1。 + +2. 获取标志位为1的最高bit位。 + +3. 某一标志位清0。 + +4. 获取标志位为1的最低bit位。 ``` #include "los_bitmap.h" @@ -110,7 +72,8 @@ static UINT32 BitSample(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: @@ -122,4 +85,3 @@ LOS_HighBitGet:The highest one bit is 28, the flag is 0x10101110 LOS_BitmapClr: pos : 28, the flag is 0x00101110 LOS_LowBitGet: The lowest one bit is 4, the flag is 0x00101110 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-apx-dll.md b/zh-cn/device-dev/kernel/kernel-small-apx-dll.md index fe91be48f9..eac1bb16f5 100644 --- a/zh-cn/device-dev/kernel/kernel-small-apx-dll.md +++ b/zh-cn/device-dev/kernel/kernel-small-apx-dll.md @@ -1,182 +1,86 @@ -# 双向链表 +# 双向链表 -- [基本概念](#section1990715203418) -- [功能说明](#section848334511411) -- [开发流程](#section01781261552) - - [编程实例](#section8354175218128) +- [基本概念](#基本概念) +- [功能说明](#功能说明) +- [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 双向链表是指含有往前和往后两个方向的链表,即每个结点中除存放下一个节点指针外,还增加一个指向前一个节点的指针。其头指针head是唯一确定的。从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点,这种数据结构形式使得双向链表在查找时更加方便,特别是大量数据的遍历。由于双向链表具有对称性,能方便地完成各种插入、删除等操作,但需要注意前后方向的操作。 -## 功能说明 + +## 功能说明 双向链表模块为用户提供下面几种功能,接口详细信息可以查看API参考。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

初始化链表

-

LOS_ListInit

-

将指定节点初始化为双向链表节点

-

LOS_DL_LIST_HEAD

-

定义一个节点并初始化为双向链表节点

-

增加节点

-

LOS_ListAdd

-

将指定节点插入到双向链表头端

-

LOS_ListHeadInsert

-

将指定节点插入到双向链表头端,LOS_ListAdd

-

LOS_ListTailInsert

-

将指定节点插入到双向链表尾端

-

增加链表

-

LOS_ListAddList

-

将指定链表的头端插入到双向链表头端

-

LOS_ListHeadInsertList

-

将指定链表的头端插入到双向链表头端,同LOS_ListAddList

-

LOS_ListTailInsertList

-

将指定链表的尾端插入到双向链表头端

-

删除节点

-

LOS_ListDelete

-

将指定节点从链表中删除

-

LOS_ListDelInit

-

将指定节点从链表中删除,并使用该节点初始化链表

-

判断双向链表

-

LOS_ListEmpty

-

判断链表是否为空

-

LOS_DL_LIST_IS_END

-

判断指定链表节点是否为链表尾端

-

LOS_DL_LIST_IS_ON_QUEUE

-

判断链表节点是否在双向链表里

-

获取结构体信息

-

LOS_OFF_SET_OF

-

获取指定结构体内的成员相对于结构体起始地址的偏移量

-

LOS_DL_LIST_ENTRY

-

获取双向链表中第一个链表节点所在的结构体地址,接口的第一个入参表示的是链表中的头节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称

-

LOS_ListPeekHeadType

-

获取双向链表中第一个链表节点所在的结构体地址,接口的第一个入参表示的是链表中的头节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称。如果链表为空,返回NULL。

-

LOS_ListRemoveHeadType

-

获取双向链表中第一个链表节点所在的结构体地址,并把第一个链表节点从链表中删除。接口的第一个入参表示的是链表中的头节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称。如果链表为空,返回NULL。

-

LOS_ListNextType

-

获取双向链表中指定链表节点的下一个节点所在的结构体地址。接口的第一个入参表示的是链表中的头节点,第二个入参是指定的链表节点,第三个入参是要获取的结构体名称,第四个入参是链表在该结构体中的名称。如果链表节点下一个为链表头结点为空,返回NULL。

-

遍历双向链表

-

LOS_DL_LIST_FOR_EACH

-

遍历双向链表

-

LOS_DL_LIST_FOR_EACH_SAFE

-

遍历双向链表,并存储当前节点的后继节点用于安全校验

-

遍历包含双向链表的结构体

-

LOS_DL_LIST_FOR_EACH_ENTRY

-

遍历指定双向链表,获取包含该链表节点的结构体地址

-

LOS_DL_LIST_FOR_EACH_ENTRY_SAFE

-

遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址

-
- -## 开发流程 +| **功能分类** | **接口名** | **描述** | +| -------- | -------- | -------- | +| 初始化链表 | LOS_ListInit | 将指定节点初始化为双向链表节点 | +| LOS_DL_LIST_HEAD | 定义一个节点并初始化为双向链表节点 | +| 增加节点 | LOS_ListAdd | 将指定节点插入到双向链表头端 | +| LOS_ListHeadInsert | 将指定节点插入到双向链表头端,同LOS_ListAdd | +| LOS_ListTailInsert | 将指定节点插入到双向链表尾端 | +| 增加链表 | LOS_ListAddList | 将指定链表的头端插入到双向链表头端 | +| LOS_ListHeadInsertList | 将指定链表的头端插入到双向链表头端,同LOS_ListAddList | +| LOS_ListTailInsertList | 将指定链表的尾端插入到双向链表头端 | +| 删除节点 | LOS_ListDelete | 将指定节点从链表中删除 | +| LOS_ListDelInit | 将指定节点从链表中删除,并使用该节点初始化链表 | +| 判断双向链表 | LOS_ListEmpty | 判断链表是否为空 | +| LOS_DL_LIST_IS_END | 判断指定链表节点是否为链表尾端 | +| LOS_DL_LIST_IS_ON_QUEUE | 判断链表节点是否在双向链表里 | +| 获取结构体信息 | LOS_OFF_SET_OF | 获取指定结构体内的成员相对于结构体起始地址的偏移量 | +| LOS_DL_LIST_ENTRY | 获取双向链表中第一个链表节点所在的结构体地址,接口的第一个入参表示的是链表中的头节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称 | +| LOS_ListPeekHeadType | 获取双向链表中第一个链表节点所在的结构体地址,接口的第一个入参表示的是链表中的头节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称。如果链表为空,返回NULL。 | +| LOS_ListRemoveHeadType | 获取双向链表中第一个链表节点所在的结构体地址,并把第一个链表节点从链表中删除。接口的第一个入参表示的是链表中的头节点,第二个入参是要获取的结构体名称,第三个入参是链表在该结构体中的名称。如果链表为空,返回NULL。 | +| LOS_ListNextType | 获取双向链表中指定链表节点的下一个节点所在的结构体地址。接口的第一个入参表示的是链表中的头节点,第二个入参是指定的链表节点,第三个入参是要获取的结构体名称,第四个入参是链表在该结构体中的名称。如果链表节点下一个为链表头结点为空,返回NULL。 | +| 遍历双向链表 | LOS_DL_LIST_FOR_EACH | 遍历双向链表 | +| LOS_DL_LIST_FOR_EACH_SAFE | 遍历双向链表,并存储当前节点的后继节点用于安全校验 | +| 遍历包含双向链表的结构体 | LOS_DL_LIST_FOR_EACH_ENTRY | 遍历指定双向链表,获取包含该链表节点的结构体地址 | +| LOS_DL_LIST_FOR_EACH_ENTRY_SAFE | 遍历指定双向链表,获取包含该链表节点的结构体地址,并存储包含当前节点的后继节点的结构体地址 | + + +## 开发流程 双向链表的典型开发流程: -1. 调用LOS\_ListInit/LOS\_DL\_LIST\_HEAD初始双向链表。 -2. 调用LOS\_ListAdd向链表插入节点。 -3. 调用LOS\_ListTailInsert向链表尾部插入节点。 -4. 调用LOS\_ListDelete删除指定节点。 -5. 调用LOS\_ListEmpty判断链表是否为空。 -6. 调用LOS\_ListDelInit删除指定节点并以此节点初始化链表。 +1. 调用LOS_ListInit/LOS_DL_LIST_HEAD初始双向链表。 + +2. 调用LOS_ListAdd向链表插入节点。 + +3. 调用LOS_ListTailInsert向链表尾部插入节点。 + +4. 调用LOS_ListDelete删除指定节点。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 需要注意节点指针前后方向的操作。 ->- 链表操作接口,为底层接口,不对入参进行判空,需要使用者确保传参合法。 ->- 如果链表节点的内存是动态申请的,删除节点时,要注意释放内存。 +5. 调用LOS_ListEmpty判断链表是否为空。 -### 编程实例 +6. 调用LOS_ListDelInit删除指定节点并以此节点初始化链表。 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 需要注意节点指针前后方向的操作。 +> +> - 链表操作接口,为底层接口,不对入参进行判空,需要使用者确保传参合法。 +> +> - 如果链表节点的内存是动态申请的,删除节点时,要注意释放内存。 + + +### 编程实例 **实例描述** + 本实例实现如下功能: -1. 初始化双向链表。 -2. 增加节点。 -3. 删除节点。 -4. 测试操作是否成功。 + +1. 初始化双向链表。 + +2. 增加节点。 + +3. 删除节点。 + +4. 测试操作是否成功。 + ``` #include "stdio.h" @@ -216,14 +120,15 @@ static UINT32 ListSample(VOID) } ``` + **结果验证** + 编译运行得到的结果为: + ``` -Initial head -Add listNode1 success +Initial head Add listNode1 success Tail insert listNode2 success Delete success ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-apx-library.md b/zh-cn/device-dev/kernel/kernel-small-apx-library.md index 732a187a26..4b4b3ad62d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-apx-library.md +++ b/zh-cn/device-dev/kernel/kernel-small-apx-library.md @@ -1,29 +1,30 @@ -# 标准库 - -- [标准库接口框架](#section149319478561) -- [操作实例](#section20874620185915) -- [与Linux标准库差异](#section6555642165713) - - [进程](#section11299104511409) - - [内存](#section175754484116) - - [文件系统](#section118191113134220) - - [信号](#section195939264421) - - [Time](#section20825124304213) +# 标准库 +- [标准库接口框架](#标准库接口框架) +- [操作实例](#操作实例) +- [与Linux标准库差异](#与linux标准库差异) + - [进程](#进程) + - [内存](#内存) + - [文件系统](#文件系统) + - [信号](#信号) + - [Time](#time) OpenHarmony内核使用musl libc库,支持标准POSIX接口,开发者可基于POSIX标准接口开发内核之上的组件及应用。 -## 标准库接口框架 -**图 1** POSIX接口框架 -![](figure/POSIX接口框架.png "POSIX接口框架") +## 标准库接口框架 + +**图1** POSIX接口框架 +![zh-cn_image_0000001172904117](figures/zh-cn_image_0000001172904117.png) musl libc库支持POSIX标准,涉及的系统调用相关接口由OpenHarmony内核适配支持 ,以满足接口对外描述的功能要求。 标准库支持接口的详细情况请参考C库的API文档,其中也涵盖了与POSIX标准之间的差异说明。 -## 操作实例 -在本示例中,主线程创建了THREAD\_NUM个子线程,每个子线程启动后等待被主线程唤醒,主线程成功唤醒所有子线程后,子线程继续执行直至生命周期结束,同时主线程通过pthread\_join方法等待所有线程执行结束。 +## 操作实例 + +在本示例中,主线程创建了THREAD_NUM个子线程,每个子线程启动后等待被主线程唤醒,主线程成功唤醒所有子线程后,子线程继续执行直至生命周期结束,同时主线程通过pthread_join方法等待所有线程执行结束。 ``` #include @@ -197,28 +198,36 @@ int main(int argc, char *argv[]) #endif /* __cplusplus */ ``` -## 与Linux标准库差异 + +## 与Linux标准库差异 本节描述了OpenHarmony内核承载的标准库与Linux标准库之间存在的关键差异。更多差异详见C库API文档说明。 -### 进程 -1. OpenHarmony用户态**进程**优先级只支持静态优先级且用户态可配置的优先级范围为10\(最高优先级\)-31\(最低优先级)。 -2. OpenHarmony用户态**线程**优先级只支持静态优先级且用户态可配置的优先级范围为0\(最高优先级\)-31\(最低优先级)。 -3. OpenHarmony进程调度策略只支持SCHED\_RR, 线程调度策略支持SCHED\_RR和SCHED\_FIFO。 +### 进程 + +1. OpenHarmony用户态**进程**优先级只支持静态优先级且用户态可配置的优先级范围为10(最高优先级)-31(最低优先级)。 -### 内存 +2. OpenHarmony用户态**线程**优先级只支持静态优先级且用户态可配置的优先级范围为0(最高优先级)-31(最低优先级)。 -**h2****与Linux mmap的差异** +3. OpenHarmony进程调度策略只支持SCHED_RR, 线程调度策略支持SCHED_RR和SCHED_FIFO。 -mmap接口原型为:void \*mmap \(void \*addr, size\_t length, int prot, int flags, int fd, off\_t offset\)。 + +### 内存 + +**h2与Linux mmap的差异** + +mmap接口原型为:void \*mmap (void \*addr, size_t length, int prot, int flags, int fd, off_t offset)。 其中,参数fd的生命周期实现与Linux glibc存在差异。具体体现在,glibc在成功调用mmap进行映射后,可以立即释放fd句柄。在OpenHarmony内核中,不允许用户在映射成功后立即关闭相关fd,只允许在取消映射munmap后再进行fd的close操作。如果用户不进行fd的close操作,操作系统将在进程退出时对该fd进行回收。 -**h2****代码举例** + +**h2代码举例** + Linux目前支持的情况如下: + ``` int main(int argc, char *argv[]) { @@ -241,8 +250,8 @@ int main(int argc, char *argv[]) } ``` -OpenHarmony支持的情况如下: +OpenHarmony支持的情况如下: ``` int main(int argc, char *argv[]) { @@ -266,7 +275,8 @@ int main(int argc, char *argv[]) } ``` -### 文件系统 + +### 文件系统 **系统目录**:用户无权限修改系统目录和设备挂载目录。包含/dev,/proc,/app,/bin,/data,/etc,/lib,/system,/usr目录。 @@ -274,14 +284,18 @@ int main(int argc, char *argv[]) 除**系统目录**与**用户目录**之外,用户可以自行创建文件夹进行设备的挂载。但是要注意,已挂载的文件夹及其子文件夹不允许重复或者嵌套挂载,非空文件夹不允许挂载。 -### 信号 -- 信号默认行为不支持STOP、CONTINUE、COREDUMP功能。 -- 无法通过信号唤醒正在睡眠状态(举例:进程调用sleep函数进入睡眠)的进程。原因:信号机制无唤醒功能,当且仅当进程被CPU调度运行时才能处理信号内容。 -- 进程退出后会发送SIGCHLD给父进程,发送动作无法取消。 -- 信号仅支持1-30号信号,接收方收到多次同一信号,仅执行一次回调函数。 +### 信号 + +- 信号默认行为不支持STOP、CONTINUE、COREDUMP功能。 + +- 无法通过信号唤醒正在睡眠状态(举例:进程调用sleep函数进入睡眠)的进程。原因:信号机制无唤醒功能,当且仅当进程被CPU调度运行时才能处理信号内容。 + +- 进程退出后会发送SIGCHLD给父进程,发送动作无法取消。 + +- 信号仅支持1-30号信号,接收方收到多次同一信号,仅执行一次回调函数。 -### Time -OpenHarmony当前时间精度以tick计算,系统默认10ms/tick。sleep、timeout系列函数时间误差<=20ms。 +### Time +OpenHarmony当前时间精度以tick计算,系统默认10ms/tick。sleep、timeout系列函数时间误差<=20ms。 diff --git a/zh-cn/device-dev/kernel/kernel-small-apx-structure.md b/zh-cn/device-dev/kernel/kernel-small-apx-structure.md index f291b962eb..7cd200e74a 100644 --- a/zh-cn/device-dev/kernel/kernel-small-apx-structure.md +++ b/zh-cn/device-dev/kernel/kernel-small-apx-structure.md @@ -1,7 +1,6 @@ -# 基本数据结构 +# 基本数据结构 -- **[双向链表](kernel-small-apx-dll.md)** - -- **[位操作](kernel-small-apx-bitwise.md)** +- **[双向链表](kernel-small-apx-dll.md)** +- **[位操作](kernel-small-apx-bitwise.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-apx.md b/zh-cn/device-dev/kernel/kernel-small-apx.md index e9e9b4b87a..b785fd1789 100644 --- a/zh-cn/device-dev/kernel/kernel-small-apx.md +++ b/zh-cn/device-dev/kernel/kernel-small-apx.md @@ -1,7 +1,6 @@ -# 附录 +# 附录 -- **[基本数据结构](kernel-small-apx-structure.md)** - -- **[标准库](kernel-small-apx-library.md)** +- **[基本数据结构](kernel-small-apx-structure.md)** +- **[标准库](kernel-small-apx-library.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-atomic.md b/zh-cn/device-dev/kernel/kernel-small-basic-atomic.md index 720d3668b3..1188ead10b 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-atomic.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-atomic.md @@ -1,14 +1,13 @@ -# 原子操作 +# 原子操作 -- [基本概念](#section1792118384594) -- [运行机制](#section1786635117596) -- [开发指导](#section2911115308) - - [接口说明](#section335914201010) - - [开发流程](#section12207371304) - - [编程实例](#section8538651511) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 在支持多任务的操作系统中,修改一块内存区域的数据需要“读取-修改-写入”三个步骤。然而同一内存区域的数据可能同时被多个任务访问,如果在修改数据的过程中被其他任务打断,就会造成该操作的执行结果无法预知。 @@ -16,205 +15,88 @@ ARMv6架构引入了LDREX和STREX指令,以支持对共享存储器更缜密的非阻塞同步。由此实现的原子操作能确保对同一数据的“读取-修改-写入”操作在它的执行期间不会被打断,即操作的原子性。 -## 运行机制 - -OpenHarmony系统通过对ARMv6架构中的LDREX和STREX进行封装,向用户提供了一套原子性的操作接口。 - -- LDREX Rx, \[Ry\] - 读取内存中的值,并标记对该段内存的独占访问: +## 运行机制 - - 读取寄存器Ry指向的4字节内存数据,保存到Rx寄存器中。 - - 对Ry指向的内存区域添加独占访问标记。 +OpenHarmony系统通过对ARMv6架构中的LDREX和STREX进行封装,向用户提供了一套原子性的操作接口。 -- STREX Rf, Rx, \[Ry\] +- LDREX Rx, [Ry] + 读取内存中的值,并标记对该段内存的独占访问: - 检查内存是否有独占访问标记,如果有则更新内存值并清空标记,否则不更新内存: + - 读取寄存器Ry指向的4字节内存数据,保存到Rx寄存器中。 + - 对Ry指向的内存区域添加独占访问标记。 - - 有独占访问标记 - - 将寄存器Rx中的值更新到寄存器Ry指向的内存。 - - 标志寄存器Rf置为0。 +- STREX Rf, Rx, [Ry] + 检查内存是否有独占访问标记,如果有则更新内存值并清空标记,否则不更新内存: - - 没有独占访问标记 - - 不更新内存。 - - 标志寄存器Rf置为1。 + - 有独占访问标记 + - 将寄存器Rx中的值更新到寄存器Ry指向的内存。 + - 标志寄存器Rf置为0。 + - 没有独占访问标记 + - 不更新内存。 + - 标志寄存器Rf置为1。 +- 判断标志寄存器 + - 标志寄存器为0时,退出循环,原子操作结束。 + - 标志寄存器为1时,继续循环,重新进行原子操作。 -- 判断标志寄存器 - - 标志寄存器为0时,退出循环,原子操作结束。 - - 标志寄存器为1时,继续循环,重新进行原子操作。 +## 开发指导 -## 开发指导 -### 接口说明 +### 接口说明 OpenHarmony LiteOS-A内核的原子操作模块提供下面几种功能,接口详细信息可以查看API参考。 -**表 1** 原子操作接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

-

LOS_AtomicRead

-

读取32bit原子数据

-

LOS_Atomic64Read

-

读取64bit原子数据

-

-

LOS_AtomicSet

-

设置32bit原子数据

-

LOS_Atomic64Set

-

设置64bit原子数据

-

-

LOS_AtomicAdd

-

对32bit原子数据做加法

-

LOS_Atomic64Add

-

对64bit原子数据做加法

-

LOS_AtomicInc

-

对32bit原子数据做加1

-

LOS_Atomic64Inc

-

对64bit原子数据做加1

-

LOS_AtomicIncRet

-

对32bit原子数据做加1并返回

-

LOS_Atomic64IncRet

-

对64bit原子数据做加1并返回

-

-

LOS_AtomicSub

-

对32bit原子数据做减法

-

LOS_Atomic64Sub

-

对64bit原子数据做减法

-

LOS_AtomicDec

-

对32bit原子数据做减1

-

LOS_Atomic64Dec

-

对64bit原子数据做减1

-

LOS_AtomicDecRet

-

对32bit原子数据做减1并返回

-

LOS_Atomic64DecRet

-

对64bit原子数据做减1并返回

-

交换

-

LOS_AtomicXchgByte

-

交换8bit内存数据

-

LOS_AtomicXchg16bits

-

交换16bit内存数据

-

LOS_AtomicXchg32bits

-

交换32bit内存数据

-

LOS_AtomicXchg64bits

-

交换64bit内存数据

-

先比较后交换

-

LOS_AtomicCmpXchgByte

-

比较相同后交换8bit内存数据

-

LOS_AtomicCmpXchg16bits

-

比较相同后交换16bit内存数据

-

LOS_AtomicCmpXchg32bits

-

比较相同后交换32bit内存数据

-

LOS_AtomicCmpXchg64bits

-

比较相同后交换64bit内存数据

-
- -### 开发流程 +**表1** 原子操作接口说明 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 读 | LOS_AtomicRead | 读取32bit原子数据 | +| | LOS_Atomic64Read |读取64bit原子数据| +| 写 | LOS_AtomicSet | 设置32bit原子数据 | +| | LOS_Atomic64Set |设置64bit原子数据| +| 加 | LOS_AtomicAdd | 对32bit原子数据做加法 | +| | LOS_Atomic64Add |对64bit原子数据做加法| +| | LOS_AtomicInc |对32bit原子数据做加1| +| | LOS_Atomic64Inc |对64bit原子数据做加1| +| | LOS_AtomicIncRet |对32bit原子数据做加1并返回| +| | LOS_Atomic64IncRet |对64bit原子数据做加1并返回| +| 减 | LOS_AtomicSub | 对32bit原子数据做减法 | +| | LOS_Atomic64Sub |对64bit原子数据做减法| +| | LOS_AtomicDec |对32bit原子数据做减1| +| | LOS_Atomic64Dec |对64bit原子数据做减1| +| | LOS_AtomicDecRet |对32bit原子数据做减1并返回| +| | LOS_Atomic64DecRet |对64bit原子数据做减1并返回| +| 交换 | LOS_AtomicXchgByte | 交换8bit内存数据 | +| | LOS_AtomicXchg16bits |交换16bit内存数据| +| | LOS_AtomicXchg32bits |交换32bit内存数据| +| | LOS_AtomicXchg64bits |交换64bit内存数据| +| 先比较后交换 | LOS_AtomicCmpXchgByte | 比较相同后交换8bit内存数据 | +| | LOS_AtomicCmpXchg16bits |比较相同后交换16bit内存数据| +| | LOS_AtomicCmpXchg32bits |比较相同后交换32bit内存数据| +| | LOS_AtomicCmpXchg64bits |比较相同后交换64bit内存数据| + + +### 开发流程 有多个任务对同一个内存数据进行加减或交换等操作时,使用原子操作保证结果的可预知性。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->原子操作接口仅支持整型数据。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 原子操作接口仅支持整型数据。 + -### 编程实例 +### 编程实例 **实例描述** 调用原子操作相关接口,观察结果: -1. 创建两个任务 - - 任务一用LOS\_AtomicInc对全局变量加100次。 - - 任务二用LOS\_AtomicDec对全局变量减100次。 +1. 创建两个任务 + - 任务一用LOS_AtomicInc对全局变量加100次。 + - 任务二用LOS_AtomicDec对全局变量减100次。 -2. 子任务结束后在主任务中打印全局变量的值。 +2. 子任务结束后在主任务中打印全局变量的值。 **示例代码** @@ -285,4 +167,3 @@ UINT32 Example_AtomicTaskEntry(VOID) ``` g_sum = 0 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-inner-reflect.md b/zh-cn/device-dev/kernel/kernel-small-basic-inner-reflect.md index 4eac07d960..81c2af0908 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-inner-reflect.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-inner-reflect.md @@ -1,88 +1,61 @@ -# 虚实映射 +# 虚实映射 -- [基本概念](#section9108144913615) -- [运行机制](#section12392621871) -- [开发指导](#section10264102013713) - - [接口说明](#section195320251578) - - [开发流程](#section152774210712) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) - -## 基本概念 +## 基本概念 虚实映射是指系统通过内存管理单元(MMU,Memory Management Unit)将进程空间的虚拟地址与实际的物理地址做映射,并指定相应的访问权限、缓存属性等。程序执行时,CPU访问的是虚拟内存,通过MMU页表条目找到对应的物理内存,并做相应的代码执行或数据读写操作。MMU的映射由页表(Page Table)来描述,其中保存虚拟地址和物理地址的映射关系以及访问权限等。每个进程在创建的时候都会创建一个页表,页表由一个个页表条目(Page Table Entry, PTE)构成,每个页表条目描述虚拟地址区间与物理地址区间的映射关系。MMU中有一块页表缓存,称为快表(TLB, Translation Lookaside Buffers),做地址转换时,MMU首先在TLB中查找,如果找到对应的页表条目可直接进行转换,提高了查询效率。CPU访问内存或外设的示意图如下: -**图 1** CPU访问内存或外设的示意图 -![](figure/CPU访问内存或外设的示意图.png "CPU访问内存或外设的示意图") - -## 运行机制 - -虚实映射其实就是一个建立页表的过程。MMU有多级页表,LiteOS-A内核采用二级页表描述进程空间。每个一级页表条目描述符占用4个字节,可表示1MiB的内存空间的映射关系,即1GiB用户空间(LiteOS-A内核中用户空间占用1GiB)的虚拟内存空间需要1024个。系统创建用户进程时,在内存中申请一块4KiB大小的内存块作为一级页表的存储区域,二级页表根据当前进程的需要做动态的内存申请。 - -- 用户程序加载启动时,会将代码段、数据段映射进虚拟内存空间(详细可参考[动态加载与链接](kernel-small-bundles-linking.md)),此时并没有物理页做实际的映射; -- 程序执行时,如下图粗箭头所示,CPU访问虚拟地址,通过MMU查找是否有对应的物理内存,若该虚拟地址无对应的物理地址则触发缺页异常,内核申请物理内存并将虚实映射关系及对应的属性配置信息写进页表,并把页表条目缓存至TLB,接着CPU可直接通过转换关系访问实际的物理内存; -- 若CPU访问已缓存至TLB的页表条目,无需再访问保存在内存中的页表,可加快查找速度。 - -**图 2** CPU访问内存示意图 -![](figure/CPU访问内存示意图.png "CPU访问内存示意图") - -## 开发指导 - -### 接口说明 - -**表 1** 虚实映射模块接口 - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

MMU相关操作

-

LOS_ArchMmuQuery

-

获取进程空间虚拟地址对应的物理地址以及映射属性。

-

LOS_ArchMmuMap

-

映射进程空间虚拟地址区间与物理地址区间。

-

LOS_ArchMmuUnmap

-

解除进程空间虚拟地址区间与物理地址区间的映射关系。

-

LOS_ArchMmuChangeProt

-

修改进程空间虚拟地址区间的映射属性。

-

LOS_ArchMmuMove

-

将进程空间一个虚拟地址区间的映射关系转移至另一块未使用的虚拟地址区间重新做映射。

-
- -### 开发流程 +**图1** CPU访问内存或外设的示意图 +![zh-cn_image_0000001133263576](figures/zh-cn_image_0000001133263576.png) + + +## 运行机制 + +虚实映射其实就是一个建立页表的过程。MMU支持多级页表,LiteOS-A内核采用二级页表描述进程空间。每个一级页表条目描述符占用4个字节,可表示1MiB的内存空间的映射关系,即1GiB用户空间(LiteOS-A内核中用户空间占用1GiB)的虚拟内存空间需要1024个。系统创建用户进程时,在内存中申请一块4KiB大小的内存块作为一级页表的存储区域,系统根据当前进程的需要会动态申请内存作为二级页表的存储区域。 + +- 用户程序加载启动时,会将代码段、数据段映射进虚拟内存空间(详细可参考[动态加载与链接](../kernel/kernel-small-bundles-linking.md)),此时并没有物理页做实际的映射; + +- 程序执行时,如下图粗箭头所示,CPU访问虚拟地址,通过MMU查找是否有对应的物理内存,若该虚拟地址无对应的物理地址则触发缺页异常,内核申请物理内存并将虚实映射关系及对应的属性配置信息写进页表,并把页表条目缓存至TLB,接着CPU可直接通过转换关系访问实际的物理内存; + +- 若CPU访问已缓存至TLB的页表条目,无需再访问保存在内存中的页表,可加快查找速度。 + +**图2** CPU访问内存示意图 +![zh-cn_image_0000001179103451](figures/zh-cn_image_0000001179103451.png) + + +## 开发指导 + + +### 接口说明 + +**表1** 虚实映射模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| MMU相关操作 | LOS_ArchMmuQuery | 获取进程空间虚拟地址对应的物理地址以及映射属性。 | +| | LOS_ArchMmuMap |映射进程空间虚拟地址区间与物理地址区间。| +| | LOS_ArchMmuUnmap |解除进程空间虚拟地址区间与物理地址区间的映射关系。| +| | LOS_ArchMmuChangeProt |修改进程空间虚拟地址区间的映射属性。| +| | LOS_ArchMmuMove |将进程空间一个虚拟地址区间的映射关系转移至另一块未使用的虚拟地址区间重新做映射。| + +### 开发流程 虚实映射相关接口的使用: -1. 通过LOS\_ArchMmuMap映射一块物理内存。 -2. 对映射的地址区间做相关操作: - - 通过LOS\_ArchMmuQuery可以查询相应虚拟地址区间映射的物理地址区间及映射属性; +1. 通过LOS_ArchMmuMap映射一块物理内存。 - - 通过LOS\_ArchMmuChangeProt修改映射属性; - - 通过LOS\_ArchMmuMove做虚拟地址区间的重映射。 +2. 对映射的地址区间做相关操作: + - 通过LOS_ArchMmuQuery可以查询相应虚拟地址区间映射的物理地址区间及映射属性; -3. 通过LOS\_ArchMmuUnmap解除映射关系。 + - 通过LOS_ArchMmuChangeProt修改映射属性; + - 通过LOS_ArchMmuMove做虚拟地址区间的重映射。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->上述接口的使用都是基于MMU初始化完成以及相关进程页表的建立,MMU在系统启动阶段已完成初始化,进程创建的时候会建立页表,开发者无需介入操作。 +3. 通过LOS_ArchMmuUnmap解除映射关系。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 上述接口的使用都是基于MMU初始化完成以及相关进程页表的建立,MMU在系统启动阶段已完成初始化,进程创建的时候会建立页表,开发者无需介入操作。 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-interrupt.md b/zh-cn/device-dev/kernel/kernel-small-basic-interrupt.md index 77646e13c7..f301f86be5 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-interrupt.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-interrupt.md @@ -1,21 +1,21 @@ -# 中断及异常处理 +# 中断及异常处理 -- [基本概念](#section439816296117) -- [运行机制](#section2792838318) -- [开发指导](#section15415165510110) - - [接口说明](#section57441612024) - - [开发流程](#section64332181221) - - [编程实例](#section204698276478) - - [结果验证](#section1466144215476) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [结果验证](#结果验证) - -## 基本概念 +## 基本概念 中断是指出现需要时,CPU暂停执行当前程序,转而执行新程序的过程。即在程序运行过程中,出现了一个必须由CPU立即处理的事务。此时,CPU暂时中止当前程序的执行转而处理这个事务,这个过程就叫做中断。通过中断机制,可以使CPU避免把大量时间耗费在等待、查询外设状态的操作上,大大提高系统实时性以及执行效率。 异常处理是操作系统对运行期间发生的异常情况(芯片硬件异常)进行处理的一系列动作,例如虚拟内存缺页异常、打印异常发生时函数的调用栈信息、CPU现场信息、任务的堆栈情况等。 -## 运行机制 + +## 运行机制 外设可以在没有CPU介入的情况下完成一定的工作,但某些情况下也需要CPU为其执行一定的工作。通过中断机制,在外设不需要CPU介入时,CPU可以执行其它任务,而当外设需要CPU时,产生一个中断信号,该信号连接至中断控制器。中断控制器是一方面接收其它外设中断引脚的输入,另一方面它会发出中断信号给CPU。可以通过对中断控制器编程来打开和关闭中断源、设置中断源的优先级和触发方式。常用的中断控制器有VIC(Vector Interrupt Controller)和GIC(General Interrupt Controller)。在ARM Cortex-A7中使用的中断控制器是GIC。CPU收到中断控制器发送的中断信号后,中断当前任务来响应中断请求。 @@ -23,78 +23,47 @@ 以ARMv7-a架构为例,中断和异常处理的入口为中断向量表,中断向量表包含各个中断和异常处理的入口函数。 -**图 1** 中断向量表 +**图1** 中断向量表 +![zh-cn_image_0000001199713709](figures/zh-cn_image_0000001199713709.png) -![](figure/zh-cn_image_0000001173449871.png) +## 开发指导 -## 开发指导 -### 接口说明 +### 接口说明 异常处理为内部机制,不对外提供接口,中断模块提供对外接口如下: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

创建和删除中断

-

LOS_HwiCreate

-

中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,会调用该中断处理程序

-

LOS_HwiDelete

-

删除中断

-

打开和关闭所有中断

-

LOS_IntUnLock

-

打开当前处理器所有中断响应

-

LOS_IntLock

-

关闭当前处理器所有中断响应

-

LOS_IntRestore

-

恢复到使用LOS_IntLock关闭所有中断之前的状态

-

获取系统支持的最大中断数

-

LOS_GetSystemHwiMaximum

-

获取系统支持的最大中断数

-
- -### 开发流程 - -1. 调用中断创建接口LOS\_HwiCreate创建中断。 -2. 调用LOS\_HwiDelete接口删除指定中断,此接口根据实际情况使用,判断是否需要删除中断。 - -### 编程实例 +| 功能分类 | **接口名称** | **描述** | +| -------- | -------- | -------- | +| 创建和删除中断 | LOS_HwiCreate | 中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,会调用该中断处理程序 | +| | LOS_HwiDelete |删除中断| +| 打开和关闭所有中断 | LOS_IntUnLock | 打开当前处理器所有中断响应 | +| | LOS_IntLock |关闭当前处理器所有中断响应| +| | LOS_IntRestore |恢复到使用LOS_IntLock关闭所有中断之前的状态| +| 获取系统支持的最大中断数 | LOS_GetSystemHwiMaximum | 获取系统支持的最大中断数 | + + +### 开发流程 + +1. 调用中断创建接口LOS_HwiCreate创建中断。 + +2. 调用LOS_HwiDelete接口删除指定中断,此接口根据实际情况使用,判断是否需要删除中断。 + + +### 编程实例 + 本实例实现如下功能: -1. 创建中断。 -2. 删除中断。 -代码实现如下,演示如何创建中断和删除中断,当指定的中断号HWI\_NUM\_TEST产生中断时,会调用中断处理函数: +1. 创建中断。 + +2. 删除中断。 + + +代码实现如下,演示如何创建中断和删除中断,当指定的中断号HWI_NUM_TEST产生中断时,会调用中断处理函数: + ``` #include "los_hwi.h" @@ -136,7 +105,8 @@ static UINT32 Example_Interrupt(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: @@ -144,4 +114,3 @@ static UINT32 Example_Interrupt(VOID) Hwi create success! Hwi delete success! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-memory-heap.md b/zh-cn/device-dev/kernel/kernel-small-basic-memory-heap.md index 41832c3fc2..b48497b6fe 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-memory-heap.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-memory-heap.md @@ -1,173 +1,108 @@ -# 堆内存管理 +# 堆内存管理 -- [基本概念](#section449414395916) -- [运行机制](#section465085575911) -- [开发指导](#section577019272015) - - [使用场景](#section326917198583) - - [接口说明](#section1032331584) - - [开发流程](#section07271773592) - - [编程实例](#section84931234145913) - - [结果验证](#section165233233917) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [使用场景](#使用场景) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [结果验证](#结果验证) - -## 基本概念 +## 基本概念 内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包括内存的初始化、分配以及释放。OpenHarmony LiteOS-A的堆内存管理提供内存初始化、分配、释放等功能。在系统运行过程中,堆内存管理模块通过对内存的申请/释放来管理用户和OS对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统的内存碎片问题。 -## 运行机制 + +## 运行机制 堆内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存(内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。与静态内存相比,动态内存管理的优点是按需分配,缺点是内存池中容易出现碎片。OpenHarmony LiteOS-A堆内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。动态内存核心算法框图如下: -**图 1** 动态内存核心算法 -![](figure/动态内存核心算法-19.png "动态内存核心算法-19") +**图1** 小型系统动态内存核心算法 +![zh-cn_image_0000001146437734](figures/zh-cn_image_0000001146437734.png) -根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:\[4, 127\]和\[27, 231\],如上图size class所示: +$$根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:[4, 127]和[2^{7}$, 2^{31}$],如上图size class所示: -1. 对\[4,127\]区间的内存进行等分,如上图下半部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。\[4,127\]区间的31个小区间内存对应31个比特位进行标记链表是否为空。 -2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见上图上半部分的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24\*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。 +1. 对[4,127]区间的内存进行等分,如图1下半部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。[4,127]区间的31个小区间内存对应31个比特位进行标记链表是否为空。 -例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间\[40,43\],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间\[2^9,2^9+2^6\],第31+2\*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。 +2. 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见图1上半部分的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24\*8=192个二级小区间,对应192个空闲链表和192个比特位进行标记链表是否为空。 -内存管理结构如下图所示: +例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间[40,43],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。当有580字节的空闲内存需要插入空闲链表时,对应二级小区间[2^9,2^9+2^6],第31+2\*8=47个空闲链表,并使用位图的第47个比特位来标记链表是否为空。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。 -**图 2** 动态内存管理结构图 -![](figure/动态内存管理结构图-20.png "动态内存管理结构图-20") +内存管理结构如图2所示: -- 内存池池头部分 +**图2** 小型系统动态内存管理结构图 +![zh-cn_image_0000001180855455](figures/zh-cn_image_0000001180855455.png) - 内存池池头部分包含内存池信息、位图标记数组和空闲链表数组。内存池信息包含内存池起始地址及堆区域总大小,内存池属性。位图标记数组有7个32位无符号整数组成,每个比特位标记对应的空闲链表是否挂载空闲内存块节点。空闲内存链表包含223个空闲内存头节点信息,每个空闲内存头节点信息维护内存节点头和空闲链表中的前驱、后继空闲内存节点。 +- 内存池池头部分 + 内存池池头部分包含内存池信息、位图标记数组和空闲链表数组。内存池信息包含内存池起始地址及堆区域总大小,内存池属性。位图标记数组有7个32位无符号整数组成,每个比特位标记对应的空闲链表是否挂载空闲内存块节点。空闲内存链表包含223个空闲内存头节点信息,每个空闲内存头节点信息维护内存节点头和空闲链表中的前驱、后继空闲内存节点。 -- 内存池节点部分 +- 内存池节点部分 + 包含3种类型节点:未使用空闲内存节点,已使用内存节点和尾节点。每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。空闲内存节点和已使用内存节点后面的内存区域是数据域,尾节点没有数据域。 - 包含3种类型节点:未使用空闲内存节点,已使用内存节点和尾节点。每个内存节点维护一个前序指针,指向内存池中上一个内存节点,还维护内存节点的大小和使用标记。空闲内存节点和已使用内存节点后面的内存区域是数据域,尾节点没有数据域。 +## 开发指导 -## 开发指导 -### 使用场景 +### 使用场景 堆内存管理的主要工作是动态分配并管理用户申请到的内存区间,主要用于用户需要使用大小不等的内存块的场景,当用户需要使用内存时,可以通过操作系统的动态内存申请函数索取指定大小的内存块。一旦使用完毕,通过内存释放函数释放所占用内存,使之可以重复使用。 -### 接口说明 -OpenHarmony LiteOS-A的堆内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 +### 接口说明 -**表 1** 堆内存管理接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

初始化和删除内存池

-

LOS_MemInit

-

初始化一块指定的动态内存池,大小为size

-

LOS_MemDeInit

-

删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效

-

申请、释放动态内存

-

LOS_MemAlloc

-

从指定动态内存池中申请size长度的内存

-

LOS_MemFree

-

释放从指定动态内存中申请的内存

-

LOS_MemRealloc

-

按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块

-

LOS_MemAllocAlign

-

从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存

-

获取内存池信息

-

LOS_MemPoolSizeGet

-

获取指定动态内存池的总大小

-

LOS_MemTotalUsedGet

-

获取指定动态内存池的总使用量大小

-

LOS_MemInfoGet

-

获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小

-

LOS_MemPoolList

-

打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效

-

获取内存块信息

-

LOS_MemFreeNodeShow

-

打印指定内存池的空闲内存块的大小及数量

-

检查指定内存池的完整性

-

LOS_MemIntegrityCheck

-

对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项OS\_SYS\_MEM\_SIZE的大小。 ->- 对齐分配内存接口LOS\_MemAllocAlign/LOS\_MemMallocAlign因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。 - -### 开发流程 +OpenHarmony LiteOS-A的堆内存管理主要为用户提供以下功能,接口详细信息可以查看API参考。 -本节介绍使用动态内存的典型场景开发流程。 +**表1** 堆内存管理接口 -1. 初始化LOS\_MemInit。 +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 初始化和删除内存池 | LOS_MemInit | 初始化一块指定的动态内存池,大小为size | +| | LOS_MemDeInit |删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效| +| 申请、释放动态内存 | LOS_MemAlloc | 从指定动态内存池中申请size长度的内存 | +| | LOS_MemFree |释放从指定动态内存中申请的内存| +| | LOS_MemRealloc |按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块| +| | LOS_MemAllocAlign |从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存| +| 获取内存池信息 | LOS_MemPoolSizeGet | 获取指定动态内存池的总大小 | +| | LOS_MemTotalUsedGet |获取指定动态内存池的总使用量大小| +| | LOS_MemInfoGet |获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小| +| | LOS_MemPoolList |打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效| +| 获取内存块信息 | LOS_MemFreeNodeShow | 打印指定内存池的空闲内存块的大小及数量 | +| 检查指定内存池的完整性 | LOS_MemIntegrityCheck | 对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效 | - 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。注:EndNode作为内存池末尾的节点,size为0。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项OS_SYS_MEM_SIZE的大小。 +> +> - 对齐分配内存接口LOS_MemAllocAlign/LOS_MemMallocAlign因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。 -1. 申请任意大小的动态内存LOS\_MemAlloc。 +### 开发流程 - 判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存块挂载到空闲内存链表上。 +本节介绍使用动态内存的典型场景开发流程。 +1. 初始化LOS_MemInit。 + 初始一个内存池后生成一个内存池控制头、尾节点EndNode,剩余的内存被标记为FreeNode内存节点。注:EndNode作为内存池末尾的节点,size为0。 -1. 释放动态内存LOS\_MemFree。 +1. 申请任意大小的动态内存LOS_MemAlloc。 + 判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存块挂载到空闲内存链表上。 - 回收内存块,供下一次使用。调用LOS\_MemFree释放内存块,则会回收内存块,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。 +1. 释放动态内存LOS_MemFree。 + 回收内存块,供下一次使用。调用LOS_MemFree释放内存块,则会回收内存块,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。 -### 编程实例 +### 编程实例 本实例执行以下步骤: -1. 初始化一个动态内存池。 -2. 从动态内存池中申请一个内存块。 -3. 在内存块中存放一个数据。 -4. 打印出内存块中的数据。 -5. 释放该内存块。 +1. 初始化一个动态内存池。 + +2. 从动态内存池中申请一个内存块。 + +3. 在内存块中存放一个数据。 + +4. 打印出内存块中的数据。 + +5. 释放该内存块。 示例代码如下: @@ -236,7 +171,8 @@ UINT32 ExampleDynMemEntry(VOID) } ``` -### 结果验证 + +### 结果验证 输出结果如下: @@ -246,4 +182,3 @@ Mem alloc success! *mem = 828 Mem free success! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.md b/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.md index ac56ca9cba..cdcb103fe7 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.md @@ -1,117 +1,72 @@ -# 物理内存管理 +# 物理内存管理 -- [基本概念](#section210891719217) -- [运行机制](#section111355315213) -- [开发指导](#section393116496217) - - [接口说明](#section13210155619214) - - [开发流程](#section178441091231) - - [编程实例](#section1258174015319) - - [结果验证](#section515091342819) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [结果验证](#结果验证) - -## 基本概念 +## 基本概念 物理内存是计算机上最重要的资源之一,指的是实际的内存设备提供的、可以通过CPU总线直接进行寻址的内存空间,其主要作用是为操作系统及程序提供临时存储空间。LiteOS-A内核管理物理内存是通过分页实现的,除了内核堆占用的一部分内存外,其余可用内存均以4KiB为单位划分成页帧,内存分配和内存回收便是以页帧为单位进行操作。内核采用伙伴算法管理空闲页面,可以降低一定的内存碎片率,提高内存分配和释放的效率,但是一个很小的块往往也会阻塞一个大块的合并,导致不能分配较大的内存块。 -## 运行机制 + +## 运行机制 如下图所示,LiteOS-A内核的物理内存使用分布视图,主要由内核镜像、内核堆及物理页组成。内核堆部分见堆内存管理一节。 -**图 1** 物理内存使用分布图 -![](figure/物理内存使用分布图.png "物理内存使用分布图") +**图1** 物理内存使用分布图 +![zh-cn_image_0000001179140185](figures/zh-cn_image_0000001179140185.png) 伙伴算法把所有空闲页帧分成9个内存块组,每组中内存块包含2的幂次方个页帧,例如:第0组的内存块包含2的0次方个页帧,即1个页帧;第8组的内存块包含2的8次方个页帧,即256个页帧。相同大小的内存块挂在同一个链表上进行管理。 -- 申请内存 - - 系统申请12KiB内存,即3个页帧时,9个内存块组中索引为3的链表挂着一块大小为8个页帧的内存块满足要求,分配出12KiB内存后还剩余20KiB内存,即5个页帧,将5个页帧分成2的幂次方之和,即4跟1,尝试查找伙伴进行合并。4个页帧的内存块没有伙伴则直接插到索引为2的链表上,继续查找1个页帧的内存块是否有伙伴,索引为0的链表上此时有1个,如果两个内存块地址连续则进行合并,并将内存块挂到索引为1的链表上,否则不做处理。 - - **图 2** 内存申请示意图 - ![](figure/内存申请示意图.png "内存申请示意图") - - -- 释放内存 - - 系统释放12KiB内存,即3个页帧,将3个页帧分成2的幂次方之和,即2跟1,尝试查找伙伴进行合并,索引为1的链表上有1个内存块,若地址连续则合并,并将合并后的内存块挂到索引为2的链表上,索引为0的链表上此时也有1个,如果地址连续则进行合并,并将合并后的内存块挂到索引为1的链表上,此时继续判断是否有伙伴,重复上述操作。 - - **图 3** 内存释放示意图 - ![](figure/内存释放示意图.png "内存释放示意图") - - -## 开发指导 - -### 接口说明 - -**表 1** 物理内存管理模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

申请物理内存

-

LOS_PhysPageAlloc

-

申请一个物理页

-

LOS_PhysPagesAlloc

-

申请物理页并挂在对应的链表上

-

LOS_PhysPagesAllocContiguous

-

申请多页地址连续的物理内存

-

释放物理内存

-

LOS_PhysPageFree

-

释放一个物理页

-

LOS_PhysPagesFree

-

释放挂在链表上的物理页

-

LOS_PhysPagesFreeContiguous

-

释放多页地址连续的物理内存

-

查询地址

-

LOS_VmPageGet

-

根据物理地址获取其对应的物理页结构体指针

-

LOS_PaddrToKVaddr

-

根据物理地址获取其对应的内核虚拟地址

-
- -### 开发流程 +- 申请内存 + 系统申请12KiB内存,即3个页帧时,9个内存块组中索引为3的链表挂着一块大小为8个页帧的内存块满足要求,分配出12KiB内存后还剩余20KiB内存,即5个页帧,将5个页帧分成2的幂次方之和,即4跟1,尝试查找伙伴进行合并。4个页帧的内存块没有伙伴则直接插到索引为2的链表上,继续查找1个页帧的内存块是否有伙伴,索引为0的链表上此时有1个,如果两个内存块地址连续则进行合并,并将内存块挂到索引为1的链表上,否则不做处理。 + + **图2** 内存申请示意图 + ![zh-cn_image_0000001189778871](figures/zh-cn_image_0000001189778871.png) + +- 释放内存 + 系统释放12KiB内存,即3个页帧,将3个页帧分成2的幂次方之和,即2跟1,尝试查找伙伴进行合并,索引为1的链表上有1个内存块,若地址连续则合并,并将合并后的内存块挂到索引为2的链表上,索引为0的链表上此时也有1个,如果地址连续则进行合并,并将合并后的内存块挂到索引为1的链表上,此时继续判断是否有伙伴,重复上述操作。 + + **图3** 内存释放示意图 + ![zh-cn_image_0000001143739220](figures/zh-cn_image_0000001143739220.png) + + +## 开发指导 + + +### 接口说明 + +**表1** 物理内存管理模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 申请物理内存 | LOS_PhysPageAlloc | 申请一个物理页 | +| | LOS_PhysPagesAlloc |申请物理页并挂在对应的链表上| +| | LOS_PhysPagesAllocContiguous |申请多页地址连续的物理内存| +| 释放物理内存 | LOS_PhysPageFree | 释放一个物理页 | +| | LOS_PhysPagesFree |释放挂在链表上的物理页| +| | LOS_PhysPagesFreeContiguous |释放多页地址连续的物理内存| +| 查询地址 | LOS_VmPageGet | 根据物理地址获取其对应的物理页结构体指针 | +| | LOS_PaddrToKVaddr |根据物理地址获取其对应的内核虚拟地址| + + +### 开发流程 内存申请时根据需要调用相关接口,小内存申请建议使用堆内存申请相关接口,4KiB及以上内存申请可以使用上述物理内存相关接口。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 物理内存申请相关接口需要在OsSysMemInit接口完成初始化之后再使用; ->- 内存申请的基本单位是页帧,即4KiB; ->- 物理内存申请时,有地址连续要求的使用LOS\_PhysPagesAllocContiguous接口,无地址连续的要求尽量使用LOS\_PhysPagesAlloc接口,将连续的大块内存留给有需要的模块使用。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 物理内存申请相关接口需要在OsSysMemInit接口完成初始化之后再使用; +> +> - 内存申请的基本单位是页帧,即4KiB; +> +> - 物理内存申请时,有地址连续要求的使用LOS_PhysPagesAllocContiguous接口,无地址连续的要求尽量使用LOS_PhysPagesAlloc接口,将连续的大块内存留给有需要的模块使用。 + -### 编程实例 +### 编程实例 编程示例主要是调用申请、释放接口对内存进行操作,包括申请一个页以及多个页的示例。 @@ -216,7 +171,8 @@ UINT32 ExamplePhyMemCaseEntry(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: @@ -225,4 +181,3 @@ LOS_PhysPagesAllocContiguous success LOS_PhysPagesAlloc success LOS_PhysPageAlloc success ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-memory-virtual.md b/zh-cn/device-dev/kernel/kernel-small-basic-memory-virtual.md index dd1b7d412e..51d6be2faf 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-memory-virtual.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-memory-virtual.md @@ -1,333 +1,107 @@ -# 虚拟内存管理 +# 虚拟内存管理 -- [基本概念](#section650193717411) -- [运行机制](#section072885512412) -- [开发指导](#section20956116050) - - [接口说明](#section166137221657) - - [开发流程](#section8752103914513) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) +## 基本概念 -## 基本概念 +虚拟内存管理是计算机系统管理内存的一种技术。每个进程都有连续的虚拟地址空间,虚拟地址空间的大小由CPU的位数决定,32位的硬件平台可以提供的最大的寻址空间为0-4GiB。整个4GiB空间分成两部分,LiteOS-A内核占据3GiB的高地址空间,1GiB的低地址空间留给用户态进程使用。各个进程空间的虚拟地址空间是独立的,代码、数据互不影响。 -虚拟内存管理是计算机系统管理内存的一种技术。每个进程都有连续的虚拟地址空间,虚拟地址空间的大小由CPU的位数决定,32位的硬件平台可以提供的最大的寻址空间为0-4GiB。整个4GiB空间分成两部分,LiteOS-A内核占据3GiB的高地址空间,1GiB的低地址空间留给进程使用。各个进程空间的虚拟地址空间是独立的,代码、数据互不影响。 +系统将虚拟内存分割为称为虚拟页的内存块,大小一般为4KiB或64KiB,LiteOS-A内核默认的页的大小是4KiB,根据需要可以对MMU(Memory Management Units)进行配置。虚拟内存管理操作的最小单位就是一个页,LiteOS-A内核中一个虚拟地址区间region包含地址连续的多个虚拟页,也可只有一个页。同样,物理内存也会按照页大小进行分割,分割后的每个内存块称为页帧。虚拟地址空间划分:内核态占高地址3GiB(0x40000000 ~ 0xFFFFFFFF),用户态占低地址1GiB(0x01000000 ~ 0x3F000000),具体见下表,详细可以查看或配置los_vm_zone.h。 -系统将虚拟内存分割为称为虚拟页的内存块,大小一般为4KiB或64KiB,LiteOS-A内核默认的页的大小是4KiB,根据需要可以对MMU(Memory Management Units)进行配置。虚拟内存管理操作的最小单位就是一个页,LiteOS-A内核中一个虚拟地址区间region包含地址连续的多个虚拟页,也可只有一个页。同样,物理内存也会按照页大小进行分割,分割后的每个内存块称为页帧。虚拟地址空间划分:内核态占高地址3GiB\(0x40000000 \~ 0xFFFFFFFF\),用户态占低地址1GiB\(0x01000000 \~ 0x3F000000\),具体见下表,详细可以查看或配置los\_vm\_zone.h。 +**表1** 内核态地址规划: -**表 1** 内核态地址规划: +| Zone名称 | 描述 | 属性 | +| -------- | -------- | -------- | +| DMA zone | 供IO设备的DMA使用。 | Uncache | +| Normal zone | 加载内核代码段、数据段、堆和栈的地址区间。 | Cache | +| high mem zone | 可以分配连续的虚拟内存,但其所映射的物理内存不一定连续。 | Cache | - - - - - - - - - - - - - - - - - - - -

Zone名称

-

描述

-

属性

-

DMA zone

-

供IO设备的DMA使用。

-

Uncache

-

Normal zone

-

加载内核代码段、数据段、堆和栈的地址区间。

-

Cache

-

high mem zone

-

可以分配连续的虚拟内存,但其所映射的物理内存不一定连续。

-

Cache

-
+**表2** 用户态虚地址规划: -**表 2** 用户态虚地址规划: +| Zone名称 | 描述 | 属性 | +| -------- | -------- | -------- | +| 代码段 | 用户态代码段地址区间。 | Cache | +| 堆 | 用户态堆地址区间。 | Cache | +| 栈 | 用户态栈地址区间。 | Cache | +| 共享库 | 用于加载用户态共享库的地址区间,包括mmap所映射的区间。 | Cache | - - - - - - - - - - - - - - - - - - - - - - - -

Zone名称

-

描述

-

属性

-

代码段

-

用户态代码段地址区间。

-

Cache

-

-

用户态堆地址区间。

-

Cache

-

-

用户态栈地址区间。

-

Cache

-

共享库

-

用于加载用户态共享库的地址区间,包括mmap所映射的区间。

-

Cache

-
-## 运行机制 +## 运行机制 虚拟内存管理中,虚拟地址空间是连续的,但是其映射的物理内存并不一定是连续的,如下图所示。可执行程序加载运行,CPU访问虚拟地址空间的代码或数据时存在两种情况: -- CPU访问的虚拟地址所在的页,如V0,已经与具体的物理页P0做映射,CPU通过找到进程对应的页表条目(详见[虚实映射](kernel-small-basic-inner-reflect.md)),根据页表条目中的物理地址信息访问物理内存中的内容并返回。 -- CPU访问的虚拟地址所在的页,如V2,没有与具体的物理页做映射,系统会触发缺页异常,系统申请一个物理页,并把相应的信息拷贝到物理页中,并且把物理页的起始地址更新到页表条目中。此时CPU重新执行访问虚拟内存的指令便能够访问到具体的代码或数据。 - -**图 1** 内存映射示意图 -![](figure/内存映射示意图.png "内存映射示意图") - -## 开发指导 - -### 接口说明 - -**表 3** 虚拟内存管理模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

获取进程空间系列接口

-

LOS_CurrSpaceGet

-

获取当前进程空间结构体指针

-

LOS_SpaceGet

-

获取虚拟地址对应的进程空间结构体指针

-

LOS_GetKVmSpace

-

获取内核进程空间结构体指针

-

LOS_GetVmallocSpace

-

获取vmalloc空间结构体指针

-

LOS_GetVmSpaceList

-

获取进程空间链表指针

-

虚拟地址区间region相关的操作

-

LOS_RegionFind

-

根据起始地址在进程空间内查找是否存在虚拟地址区间

-

LOS_RegionRangeFind

-

根据地址区间在进程空间内查找是否存在虚拟地址区间

-

LOS_IsRegionFileValid

-

判断虚拟地址区间region是否与文件关联映射

-

LOS_RegionAlloc

-

申请空闲的虚拟地址区间

-

LOS_RegionFree

-

释放进程空间内特定的region

-

LOS_RegionEndAddr

-

获取指定地址区间region的结束地址

-

LOS_RegionSize

-

获取region的大小

-

LOS_IsRegionTypeFile

-

判断是否为文件内存映射

-

LOS_IsRegionPermUserReadOnly

-

判断地址区间是否是用户空间只读属性

-

LOS_IsRegionFlagPrivateOnly

-

判断地址区间是否是具有私有属性

-

LOS_SetRegionTypeFile

-

设置文件内存映射属性

-

LOS_IsRegionTypeDev

-

判断是否为设备内存映射

-

LOS_SetRegionTypeDev

-

设置设备内存映射属性

-

LOS_IsRegionTypeAnon

-

判断是否为匿名映射

-

LOS_SetRegionTypeAnon

-

设置匿名映射属性

-

地址校验

-

LOS_IsUserAddress

-

判断地址是否在用户态空间

-

LOS_IsUserAddressRange

-

判断地址区间是否在用户态空间

-

LOS_IsKernelAddress

-

判断地址是否在内核空间

-

LOS_IsKernelAddressRange

-

判断地址区间是否在内核空间

-

LOS_IsRangeInSpace

-

判断地址区间是否在进程空间内

-

vmalloc操作

-

LOS_VMalloc

-

vmalloc申请内存

-

LOS_VFree

-

vmalloc释放内存

-

LOS_IsVmallocAddress

-

判断地址是否是通过vmalloc申请的

-

内存申请系列接口

-

LOS_KernelMalloc

-

申请小于16KiB的内存则通过堆内存池获取,否则申请多个连续物理页

-

LOS_KernelMallocAlign

-

申请具有对齐属性的内存,申请规则:申请小于16KiB的内存则通过堆内存池获取,否则申请多个连续物理页

-

LOS_KernelFree

-

释放内核堆内存

-

LOS_KernelRealloc

-

重新分配内核内存空间

-

其他

-

LOS_PaddrQuery

-

根据虚拟地址获取对应的物理地址

-

LOS_VmSpaceFree

-

释放进程空间,包括虚拟内存区间、页表等信息

-

LOS_VmSpaceReserve

-

在进程空间中预留一块内存空间

-

LOS_VaddrToPaddrMmap

-

将指定长度的物理地址区间与虚拟地址区间做映射,需提前申请物理地址区间

-

LOS_UserSpaceVmAlloc

-

根据地址、大小、权限等信息在用户进程空间内申请地址区间region

-
- -### 开发流程 +- CPU访问的虚拟地址所在的页,如V0,已经与具体的物理页P0做映射,CPU通过找到进程对应的页表条目(详见[虚实映射](../kernel/kernel-small-basic-inner-reflect.md)),根据页表条目中的物理地址信息访问物理内存中的内容并返回。 + +- CPU访问的虚拟地址所在的页,如V2,没有与具体的物理页做映射,系统会触发缺页异常,系统申请一个物理页,并把相应的信息拷贝到物理页中,并且把物理页的起始地址更新到页表条目中。此时CPU重新执行访问虚拟内存的指令便能够访问到具体的代码或数据。 + +**图1** 内存映射示意图 +![zh-cn_image_0000001179142959](figures/zh-cn_image_0000001179142959.png) + + +## 开发指导 + + +### 接口说明 + +**表3** 虚拟内存管理模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 获取进程空间系列接口 | LOS_CurrSpaceGet | 获取当前进程空间结构体指针 | +| | LOS_SpaceGet |获取虚拟地址对应的进程空间结构体指针| +| | LOS_GetKVmSpace |获取内核进程空间结构体指针| +| | LOS_GetVmallocSpace |获取vmalloc空间结构体指针| +| | LOS_GetVmSpaceList |获取进程空间链表指针| +| 虚拟地址区间region相关的操作 | LOS_RegionFind | 在进程空间内查找并返回指定地址对应的虚拟地址区间 | +| | LOS_RegionRangeFind |在进程空间内查找并返回指定地址范围对应的虚拟地址区间| +| | LOS_IsRegionFileValid |判断虚拟地址区间region是否与文件关联映射| +| | LOS_RegionAlloc |申请空闲的虚拟地址区间| +| | LOS_RegionFree |释放进程空间内特定的region| +| | LOS_RegionEndAddr |获取指定地址区间region的结束地址| +| | LOS_RegionSize |获取region的大小| +| | LOS_IsRegionTypeFile |判断是否为文件内存映射| +| | LOS_IsRegionPermUserReadOnly |判断地址区间是否是用户空间只读属性| +| | LOS_IsRegionFlagPrivateOnly |判断地址区间是否是具有私有属性| +| | LOS_SetRegionTypeFile |设置文件内存映射属性| +| | LOS_IsRegionTypeDev |判断是否为设备内存映射| +| | LOS_SetRegionTypeDev |设置设备内存映射属性| +| | LOS_IsRegionTypeAnon |判断是否为匿名映射| +| | LOS_SetRegionTypeAnon |设置匿名映射属性| +| 地址校验 | LOS_IsUserAddress | 判断地址是否在用户态空间 | +| | LOS_IsUserAddressRange |判断地址区间是否在用户态空间| +| | LOS_IsKernelAddress |判断地址是否在内核空间| +| | LOS_IsKernelAddressRange |判断地址区间是否在内核空间| +| | LOS_IsRangeInSpace |判断地址区间是否在进程空间内| +| vmalloc操作 | LOS_VMalloc | vmalloc申请内存 | +| | LOS_VFree |vmalloc释放内存| +| | LOS_IsVmallocAddress |判断地址是否是通过vmalloc申请的| +| 内存申请系列接口 | LOS_KernelMalloc | 当申请的内存小于16KiB时,系统从堆内存池分配内存;当申请的内存超过16KiB时,系统分配多个连续物理页用于内存分配 | +| | LOS_KernelMallocAlign |申请具有对齐属性的内存,申请规则同LOS_KernelMalloc接口| +| | LOS_KernelFree |释放由LOS_KernelMalloc和LOS_KernelMallocAlign接口申请的内存| +| | LOS_KernelRealloc |重新分配由LOS_KernelMalloc和LOS_KernelMallocAlign接口申请的内存| +| 其他 | LOS_PaddrQuery | 根据虚拟地址获取对应的物理地址 | +| | LOS_VmSpaceFree |释放进程空间,包括虚拟内存区间、页表等信息| +| | LOS_VmSpaceReserve |在进程空间中预留一块内存空间| +| | LOS_VaddrToPaddrMmap |将指定长度的物理地址区间与虚拟地址区间做映射,需提前申请物理地址区间| + + +### 开发流程 虚拟内存相关接口的使用: -1. 根据进程空间获取的系列接口可以得到进程空间结构体,进而可以读取结构体相应信息。 -2. 对虚拟地址区间做相关操作: - - 通过LOS\_RegionAlloc申请虚拟地址区间; +1. 根据进程空间获取的系列接口可以得到进程空间结构体,进而可以读取结构体相应信息。 - - 通过LOS\_RegionFind、LOS\_RegionRangeFind可以查询是否存在相应的地址区间; - - 通过LOS\_RegionFree释放虚拟地址区间。 +2. 对虚拟地址区间做相关操作: + - 通过LOS_RegionAlloc申请虚拟地址区间; -3. vmalloc接口及内存申请系列接口可以在内核中根据需要申请内存。 + - 通过LOS_RegionFind、LOS_RegionRangeFind可以查询是否存在相应的地址区间; + - 通过LOS_RegionFree释放虚拟地址区间。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->内存申请系列接口申请的内存要求物理内存是连续的,当系统内存无法满足大块连续内存的申请条件时会申请失败,一般适用于小块内存的申请;vmalloc相关接口申请的内存可以获得不连续的物理内存,但其是以页(当前系统一个页为4096字节)为单位的,当需要申请以页为整数倍的内存时可以通过vmalloc申请,例如文件系统中文件读取需要较大的缓存,便可以通过vmalloc相关接口申请内存。 +3. vmalloc接口及内存申请系列接口可以在内核中根据需要申请内存。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 内存申请系列接口申请的内存要求物理内存是连续的,当系统内存无法满足大块连续内存的申请条件时会申请失败,一般适用于小块内存的申请;vmalloc相关接口申请的内存可以获得不连续的物理内存,但其是以页(当前系统一个页为4096字节)为单位的,当需要申请以页为整数倍的内存时可以通过vmalloc申请,例如文件系统中文件读取需要较大的缓存,便可以通过vmalloc相关接口申请内存。 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-memory.md b/zh-cn/device-dev/kernel/kernel-small-basic-memory.md index 7c28c81ad3..20c76afadf 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-memory.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-memory.md @@ -1,11 +1,10 @@ -# 内存管理 +# 内存管理 -- **[堆内存管理](kernel-small-basic-memory-heap.md)** -- **[物理内存管理](kernel-small-basic-memory-physical.md)** +- **[堆内存管理](kernel-small-basic-memory-heap.md)** -- **[虚拟内存管理](kernel-small-basic-memory-virtual.md)** - -- **[虚实映射](kernel-small-basic-inner-reflect.md)** +- **[物理内存管理](kernel-small-basic-memory-physical.md)** +- **[虚拟内存管理](kernel-small-basic-memory-virtual.md)** +- **[虚实映射](kernel-small-basic-inner-reflect.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-process-process.md b/zh-cn/device-dev/kernel/kernel-small-basic-process-process.md index b9ee70a618..42ce52464f 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-process-process.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-process-process.md @@ -1,70 +1,70 @@ -# 进程 +# 进程 -- [基本概念](#section89346055119) -- [运行机制](#section174514474512) -- [开发指导](#section159637182521) - - [接口说明](#section1153124135212) - - [开发流程](#section1533674618526) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) +## 基本概念 -## 基本概念 +进程是系统资源管理的最小单元。OpenHarmony LiteOS-A内核提供的进程模块主要用于实现用户态进程的隔离,内核态被视为一个进程空间,不存在其它进程(KIdle除外,KIdle进程是系统提供的空闲进程,和KProcess共享一个进程空间)。 -进程是系统资源管理的最小单元。OpenHarmony LiteOS-A内核提供的进程模块主要用于实现用户态进程的隔离,内核态被视为一个进程空间,不存在其它进程\(KIdle除外,KIdle进程是系统提供的空闲进程,和KProcess共享一个进程空间)。 +- 进程模块主要为用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。 -- OpenHarmony 的进程模块主要为用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。 -- OpenHarmony 的进程采用抢占式调度机制,采用高优先级优先+同优先级时间片轮转的调度算法。 -- OpenHarmony 的进程一共有32个优先级\(0-31\),用户进程可配置的优先级有22个\(10-31\),最高优先级为10,最低优先级为31。 -- 高优先级的进程可抢占低优先级进程,低优先级进程必须在高优先级进程阻塞或结束后才能得到调度。 -- 每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。 -- 用户态根进程init由内核态创建,其它用户态子进程均由init进程fork而来。 +- 进程采用抢占式调度机制,采用高优先级优先+同优先级时间片轮转的调度算法。 -**进程状态说明:** +- 进程一共有32个优先级(0-31),用户进程可配置的优先级有22个(10-31),最高优先级为10,最低优先级为31。 -- 初始化(Init):进程正在被创建。 +- 高优先级的进程可抢占低优先级进程,低优先级进程必须在高优先级进程阻塞或结束后才能得到调度。 -- 就绪(Ready):进程在就绪列表中,等待CPU调度。 -- 运行(Running):进程正在运行。 -- 阻塞(Pending):进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。 -- 僵尸(Zombies):进程运行结束,等待父进程回收其控制块资源。 +- 每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。 -**图 1** 进程状态迁移示意图 -![](figure/进程状态迁移示意图.png "进程状态迁移示意图") +- 用户态根进程init由内核态创建,其它用户态子进程均由init进程fork而来。 -**进程状态迁移说明:** +**进程状态说明:** -- Init→Ready: +- 初始化(Init):进程正在被创建。 - 进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。 +- 就绪(Ready):进程在就绪列表中,等待CPU调度。 -- Ready→Running: +- 运行(Running):进程正在运行。 - 进程创建后进入就绪态,发生进程切换时,就绪列表中最高优先级的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存,但对外呈现的进程状态为运行态。 +- 阻塞(Pending):进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。 -- Running→Pending: +- 僵尸(Zombies):进程运行结束,等待父进程回收其控制块资源。 - 进程在最后一个线程转为阻塞态时, 进程内所有的线程均处于阻塞态,此时进程同步进入阻塞态,然后发生进程切换。 +**图1** 进程状态迁移示意图 +![zh-cn_image_0000001219007317](figures/zh-cn_image_0000001219007317.png) -- Pending→Ready: +**进程状态迁移说明:** - 阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态。 +- Init→Ready: + 进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。 -- Ready→Pending: +- Ready→Running: + 进程创建后进入就绪态,发生进程切换时,就绪列表中最高优先级的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存,但对外呈现的进程状态为运行态。 - 进程内的最后一个就绪态线程转为阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。 +- Running→Pending: + 进程在最后一个线程转为阻塞态时, 进程内所有的线程均处于阻塞态,此时进程同步进入阻塞态,然后发生进程切换。 -- Running→Ready: +- Pending→Ready: + 阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态。 - 进程由运行态转为就绪态的情况有以下两种: +- Ready→Pending: + 进程内的最后一个就绪态线程转为阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。 - 1. 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。 - 2. 若进程的调度策略为LOS\_SCHED\_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。 +- Running→Ready: + 进程由运行态转为就绪态的情况有以下两种: -- Running→Zombies: + 1. 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。 + 2. 若进程的调度策略为LOS_SCHED_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。 - 当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。 +- Running→Zombies: + 当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。 -## 运行机制 +## 运行机制 OpenHarmony 提供的进程模块主要用于实现用户态进程的隔离,支持用户态进程的创建、退出、资源回收、设置/获取调度参数、获取进程ID、设置/获取进程组ID等功能。 @@ -72,107 +72,40 @@ OpenHarmony 提供的进程模块主要用于实现用户态进程的隔离, 进程只是资源管理单元,实际运行是由进程内的各个线程完成的,不同进程内的线程相互切换时会进行进程空间的切换。 -**图 2** 进程管理示意图 - - -![](figure/zh-cn_image_0000001127519136.png) - -## 开发指导 - -### 接口说明 - -**表 1** 进程管理模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

进程调度参数控制

-

LOS_GetProcessScheduler

-

获取指定进程的调度策略

-

LOS_SetProcessScheduler

-

设置指定进程的调度参数,包括优先级和调度策略

-

LOS_GetProcessPriority

-

获取指定进程的优先级

-

LOS_SetProcessPriority

-

设置指定进程的优先级

-

等待回收子进程

-

LOS_Wait

-

等待子进程结束并回收子进程

-

进程组

-

LOS_GetProcessGroupID

-

获取指定进程的进程组ID

-

LOS_GetCurrProcessGroupID

-

获取当前进程的进程组ID

-

获取进程ID

-

LOS_GetCurrProcessID

-

获取当前进程的进程ID

-

用户及用户组

-

LOS_GetUserID

-

获取当前进程的用户ID

-

LOS_GetGroupID

-

获取当前进程的用户组ID

-

LOS_CheckInGroups

-

检查指定用户组ID是否在当前进程的用户组内

-

系统支持的最大进程数

-

LOS_GetSystemProcessMaximum

-

获取系统支持的最大进程数目

-
- -### 开发流程 +**图2** 进程管理示意图 +![zh-cn_image_0000001199736949](figures/zh-cn_image_0000001199736949.png) + + +## 开发指导 -不支持内核态进程创建,内核态不涉及进程相关开发。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- idle线程的数量跟随CPU核心数,每个CPU均有一个相应的idle线程。 ->- 不支持创建除KProcess和KIdle进程之外的其它内核态进程。 ->- 用户态进程通过系统调用进入内核态后创建的线程属于KProcess, 不属于当前用户态进程。 +### 接口说明 + +**表1** 进程管理模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 进程调度参数控制 | LOS_GetProcessScheduler | 获取指定进程的调度策略 | +| | LOS_SetProcessScheduler |设置指定进程的调度参数,包括优先级和调度策略| +| | LOS_GetProcessPriority |获取指定进程的优先级| +| | LOS_SetProcessPriority |设置指定进程的优先级| +| 等待回收子进程 | LOS_Wait | 等待子进程结束并回收子进程 | +| 进程组 | LOS_GetProcessGroupID | 获取指定进程的进程组ID | +| | LOS_GetCurrProcessGroupID |获取当前进程的进程组ID| +| 获取进程ID | LOS_GetCurrProcessID | 获取当前进程的进程ID | +| 用户及用户组 | LOS_GetUserID | 获取当前进程的用户ID | +| | LOS_GetGroupID |获取当前进程的用户组ID| +| | LOS_CheckInGroups |检查指定用户组ID是否在当前进程的用户组内| +| 系统支持的最大进程数 | LOS_GetSystemProcessMaximum | 获取系统支持的最大进程数目 | + + +### 开发流程 + +不支持内核态进程创建,内核态不涉及进程相关开发。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - idle线程的数量跟随CPU核心数,每个CPU均有一个相应的idle线程。 +> +> - 不支持创建除KProcess和KIdle进程之外的其它内核态进程。 +> +> - 用户态进程通过系统调用进入内核态后创建的线程属于KProcess, 不属于当前用户态进程。 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-process-scheduler.md b/zh-cn/device-dev/kernel/kernel-small-basic-process-scheduler.md index 9f9c08d6d2..880cc6a752 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-process-scheduler.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-process-scheduler.md @@ -1,63 +1,46 @@ -# 调度器 +# 调度器 -- [基本概念](#section123882355719) -- [运行机制](#section143015396572) -- [开发指导](#section10604192145816) - - [接口说明](#section207985910582) - - [开发流程](#section1015110331584) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) - -## 基本概念 +## 基本概念 OpenHarmony LiteOS-A内核 了高优先级优先+同优先级时间片轮转的抢占式调度机制,系统从启动开始基于real time的时间轴向前运行,使得该调度算法具有很好的实时性。 OpenHarmony 的调度算法将tickless机制天然嵌入到调度算法中,一方面使得系统具有更低的功耗,另一方面也使得tick中断按需响应,减少无用的tick中断响应,进一步提高系统的实时性。 -OpenHarmony 的进程调度策略支持SCHED\_RR,线程调度策略支持SCHED\_RR和SCHED\_FIFO。 +OpenHarmony 的进程调度策略支持SCHED_RR,线程调度策略支持SCHED_RR和SCHED_FIFO。 OpenHarmony 调度的最小单元为线程。 -## 运行机制 - -OpenHarmony 采用进程优先级队列+线程优先级队列的方式,进程优先级范围为0-31,共有32个进程优先级桶队列,每个桶队列对应一个线程优先级桶队列;线程优先级范围也为0-31,一个线程优先级桶队列也有32个优先级队列。 -**图 1** 调度优先级桶队列示意图 +## 运行机制 +OpenHarmony 采用进程优先级队列+线程优先级队列的方式,进程优先级范围为0-31,共有32个进程优先级桶队列,每个桶队列对应一个线程优先级桶队列;线程优先级范围也为0-31,一个线程优先级桶队列也有32个优先级队列。 -![](figure/zh-cn_image_0000001127520662.png) +**图1** 调度优先级桶队列示意图 +![zh-cn_image_0000001199705711](figures/zh-cn_image_0000001199705711.png) OpenHarmony 在系统启动内核初始化之后开始调度,运行过程中创建的进程或线程会被加入到调度队列,系统根据进程和线程的优先级及线程的时间片消耗情况选择最优的线程进行调度运行,线程一旦调度到就会从调度队列上删除,线程在运行过程中发生阻塞,会被加入到对应的阻塞队列中并触发一次调度,调度其它线程运行。如果调度队列上没有可以调度的线程,则系统就会选择KIdle进程的线程进行调度运行。 -**图 2** 调度流程示意图 +**图2** 调度流程示意图 +![zh-cn_image_0000001199706239](figures/zh-cn_image_0000001199706239.png) -![](figure/zh-cn_image_0000001176974089.png) +## 开发指导 -## 开发指导 -### 接口说明 +### 接口说明 - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

触发系统调度

-

LOS_Schedule

-

触发系统调度

-
+| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 触发系统调度 | LOS_Schedule | 触发系统调度 | -### 开发流程 ->![](../public_sys-resources/icon-note.gif) **说明:** ->系统启动初始化阶段,不允许触发调度。 +### 开发流程 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 系统启动初始化阶段,不允许触发调度。 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-process-thread.md b/zh-cn/device-dev/kernel/kernel-small-basic-process-thread.md index 5a534c847a..1041d75552 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-process-thread.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-process-thread.md @@ -1,14 +1,13 @@ -# 任务 +# 任务 -- [基本概念](#section138411646175417) -- [运行机制](#section1381918945512) -- [开发指导](#section10649727135519) - - [接口说明](#section78333315555) - - [开发流程](#section16229657115514) - - [编程实例](#section2809723165612) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 从系统的角度看,任务Task是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。 @@ -18,217 +17,109 @@ OpenHarmony 内核中同优先级进程内的任务统一调度、运行。 OpenHarmony 内核中的任务采用抢占式调度机制,同时支持时间片轮转调度和FIFO调度方式。 -OpenHarmony 内核的任务一共有32个优先级\(0-31\),最高优先级为0,最低优先级为31。 +OpenHarmony 内核的任务一共有32个优先级(0-31),最高优先级为0,最低优先级为31。 当前进程内, 高优先级的任务可抢占低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 **任务状态说明**: -- 初始化(Init):任务正在被创建。 +- 初始化(Init):任务正在被创建。 -- 就绪(Ready):任务在就绪列表中,等待CPU调度。 -- 运行(Running):任务正在运行。 -- 阻塞(Blocked):任务被阻塞挂起。Blocked状态包括:pending\(因为锁、事件、信号量等阻塞\)、suspended(主动pend)、delay\(延时阻塞\)、pendtime\(因为锁、事件、信号量时间等超时等待\)。 -- 退出(Exit):任务运行结束,等待父任务回收其控制块资源。 +- 就绪(Ready):任务在就绪列表中,等待CPU调度。 -**图 1** 任务状态迁移示意图 -![](figure/任务状态迁移示意图.png "任务状态迁移示意图") +- 运行(Running):任务正在运行。 -**任务状态迁移说明:** +- 阻塞(Blocked):任务被阻塞挂起。Blocked状态包括:pending(因为锁、事件、信号量等阻塞)、suspended(主动pend)、delay(延时阻塞)、pendtime(因为锁、事件、信号量时间等超时等待)。 -- Init→Ready: +- 退出(Exit):任务运行结束,等待父任务回收其控制块资源。 - 任务创建拿到控制块后为初始化阶段\(Init状态\),当任务初始化完成将任务插入调度队列,此时任务进入就绪状态。 +**图1** 任务状态迁移示意图 +![zh-cn_image_0000001173399977](figures/zh-cn_image_0000001173399977.png) -- Ready→Running: +**任务状态迁移说明:** - 任务创建后进入就绪态,发生任务切换时,就绪列表中最高优先级的任务被执行,从而进入运行态,此刻该任务从就绪列表中删除。 +- Init→Ready: + 任务创建拿到控制块后为初始化阶段(Init状态),当任务初始化完成将任务插入调度队列,此时任务进入就绪状态。 -- Running→Blocked: +- Ready→Running: + 任务创建后进入就绪态,发生任务切换时,就绪列表中最高优先级的任务被执行,从而进入运行态,此刻该任务从就绪列表中删除。 - 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪列表中剩余最高优先级任务。 +- Running→Blocked: + 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪列表中剩余最高优先级任务。 -- Blocked→Ready : +- Blocked→Ready : + 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态。 - 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态。 +- Ready→Blocked: + 任务也有可能在就绪态时被阻塞(挂起),此时任务状态会由就绪态转变为阻塞态,该任务从就绪列表中删除,不会参与任务调度,直到该任务被恢复。 -- Ready→Blocked: +- Running→Ready: + 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪列表中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,并加入就绪列表中。 - 任务也有可能在就绪态时被阻塞(挂起),此时任务状态会由就绪态转变为阻塞态,该任务从就绪列表中删除,不会参与任务调度,直到该任务被恢复。 +- Running→Exit: + 运行中的任务运行结束,任务状态由运行态变为退出态。若为设置了分离属性(LOS_TASK_STATUS_DETACHED)的任务,运行结束后将直接销毁。 -- Running→Ready: - 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪列表中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,并加入就绪列表中。 +## 运行机制 -- Running→Exit: +OpenHarmony 任务管理模块提供任务创建、任务延时、任务挂起和任务恢复、锁任务调度和解锁任务调度、根据ID查询任务控制块信息功能。 - 运行中的任务运行结束,任务状态由运行态变为退出态。若为设置了分离属性(LOS\_TASK\_STATUS\_DETACHED)的任务,运行结束后将直接销毁。 +用户创建任务时,系统会将任务栈进行初始化,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行任务入口函数。 -## 运行机制 +## 开发指导 -OpenHarmony 任务管理模块提供任务创建、任务延时、任务挂起和任务恢复、锁任务调度和解锁任务调度、根据ID查询任务控制块信息功能。 -用户创建任务时,系统会将任务栈进行初始化,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行任务入口函数。 +### 接口说明 -## 开发指导 - -### 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

任务的创建和删除

-

LOS_TaskCreateOnly

-

创建任务,并使该任务进入Init状态,不执行任务调度

-

LOS_TaskCreate

-

创建任务,并使该任务进入Ready状态,并调度

-

LOS_TaskDelete

-

删除指定的任务

-

任务状态控制

-

LOS_TaskResume

-

恢复挂起的任务

-

LOS_TaskSuspend

-

挂起指定的任务

-

LOS_TaskJoin

-

挂起当前任务,等待指定任务运行结束并回收其任务控制块资源

-

LOS_TaskDetach

-

修改任务的joinable属性为detach属性,detach属性的任务运行结束会自动回收任务控制块资源

-

LOS_TaskDelay

-

任务延时等待

-

LOS_TaskYield

-

显式放权,调整调用任务优先级的任务调度顺序

-

任务调度的控制

-

LOS_TaskLock

-

锁任务调度

-

LOS_TaskUnlock

-

解锁任务调度

-

任务优先级的控制

-

LOS_CurTaskPriSet

-

设置当前任务的优先级

-

LOS_TaskPriSet

-

设置指定任务的优先级

-

LOS_TaskPriGet

-

获取指定任务的优先级

-

任务信息获取

-

LOS_CurTaskIDGet

-

获取当前任务的ID

-

LOS_TaskInfoGet

-

获取指定任务的信息

-

任务绑核操作

-

LOS_TaskCpuAffiSet

-

绑定指定任务到指定cpu上运行,仅在多核下使用

-

LOS_TaskCpuAffiGet

-

获取指定任务的绑核信息,仅在多核下使用

-

任务调度参数的控制

-

LOS_GetTaskScheduler

-

获取指定任务的调度策略

-

LOS_SetTaskScheduler

-

设置指定任务的调度参数,包括优先级和调度策略

-

系统支持的最大任务数

-

LOS_GetSystemTaskMaximum

-

获取系统支持的最大任务数目

-
- -### 开发流程 +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 任务的创建和删除 | LOS_TaskCreateOnly | 创建任务,并使该任务进入Init状态,不执行任务调度 | +| | LOS_TaskCreate |创建任务,并使该任务进入Ready状态,并调度| +| | LOS_TaskDelete |删除指定的任务| +| 任务状态控制 | LOS_TaskResume | 恢复挂起的任务 | +| | LOS_TaskSuspend |挂起指定的任务| +| | LOS_TaskJoin |挂起当前任务,等待指定任务运行结束并回收其任务控制块资源| +| | LOS_TaskDetach |修改任务的joinable属性为detach属性,detach属性的任务运行结束会自动回收任务控制块资源| +| | LOS_TaskDelay |任务延时等待| +| | LOS_TaskYield |显式放权,调整调用任务优先级的任务调度顺序| +| 任务调度的控制 | LOS_TaskLock | 锁任务调度 | +| | LOS_TaskUnlock |解锁任务调度| +| 任务优先级的控制 | LOS_CurTaskPriSet | 设置当前任务的优先级 | +| | LOS_TaskPriSet |设置指定任务的优先级| +| | LOS_TaskPriGet |获取指定任务的优先级| +| 任务信息获取 | LOS_CurTaskIDGet | 获取当前任务的ID | +| | LOS_TaskInfoGet |获取指定任务的信息| +| 任务绑核操作 | LOS_TaskCpuAffiSet | 绑定指定任务到指定cpu上运行,仅在多核下使用 | +| | LOS_TaskCpuAffiGet |获取指定任务的绑核信息,仅在多核下使用| +| 任务调度参数的控制 | LOS_GetTaskScheduler | 获取指定任务的调度策略 | +| | LOS_SetTaskScheduler |设置指定任务的调度参数,包括优先级和调度策略| +| 系统支持的最大任务数 | LOS_GetSystemTaskMaximum | 获取系统支持的最大任务数目 | + + +### 开发流程 任务的典型开发流程: -1. 通过LOS\_TaskCreate创建一个任务。 - - 指定任务的执行入口函数 +1. 通过LOS_TaskCreate创建一个任务。 + - 指定任务的执行入口函数 + - 指定任务名 + - 指定任务的栈大小 + - 指定任务的优先级 + - 指定任务的属性,LOS_TASK_ATTR_JOINABLE和LOS_TASK_STATUS_DETACHED属性 + - 多核运行时,可以选择设置任务的绑核属性 + +2. 任务参与调度运行,执行用户指定的业务代码。 - - 指定任务名 - - 指定任务的栈大小 - - 指定任务的优先级 - - 指定任务的属性,LOS\_TASK\_ATTR\_JOINABLE和LOS\_TASK\_STATUS\_DETACHED属性 - - 多核运行时,可以选择设置任务的绑核属性 +3. 任务执行结束,如果设置了LOS_TASK_STATUS_DETACHED属性,则自动回收任务资源,如果任务设置了LOS_TASK_ATTR_JOINABLE属性,则需要调用LOS_TaskJoin回收任务资源,默认为LOS_TASK_STATUS_DETACHED属性。 -2. 任务参与调度运行,执行用户指定的业务代码。 -3. 任务执行结束,如果设置了LOS\_TASK\_STATUS\_DETACHED属性,则自动回收任务资源,如果任务设置了LOS\_TASK\_ATTR\_JOINABLE属性,则需要调用LOS_TaskJoin回收任务资源,默认为LOS\_TASK\_STATUS\_DETACHED属性。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 内核态具有最高权限,可以操作任意进程内的任务。 +> +> - 用户态进程通过系统调用进入内核态后创建的任务属于KProcess, 不属于当前用户态进程。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 内核态具有最高权限,可以操作任意进程内的任务。 ->- 用户态进程通过系统调用进入内核态后创建的任务属于KProcess, 不属于当前用户态进程。 -### 编程实例 +### 编程实例 代码实现如下: @@ -321,14 +212,12 @@ UINT32 ExampleTaskCaseEntry(VOID) /* 解锁任务调度,此时会发生任务调度,执行就绪列表中最高优先级任务 */ LOS_TaskUnlock(); - ret = LOS_TaskJoin(g_taskHiID, NULL); if (ret != LOS_OK) { PRINTK("Join ExampleTaskHi Failed!\n"); } else { PRINTK("Join ExampleTaskHi Success!\n"); } - while(1){}; return LOS_OK; } @@ -348,4 +237,3 @@ TaskHi LOS_TaskResume Success. TaskHi LOS_TaskDelete Success. Join ExampleTaskHi Success! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-process.md b/zh-cn/device-dev/kernel/kernel-small-basic-process.md index 65e9d7c4fc..e3cb98c285 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-process.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-process.md @@ -1,9 +1,8 @@ -# 进程管理 +# 进程管理 -- **[进程](kernel-small-basic-process-process.md)** -- **[线程](kernel-small-basic-process-thread.md)** - -- **[调度器](kernel-small-basic-process-scheduler.md)** +- **[进程](kernel-small-basic-process-process.md)** +- **[任务](kernel-small-basic-process-thread.md)** +- **[调度器](kernel-small-basic-process-scheduler.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-softtimer.md b/zh-cn/device-dev/kernel/kernel-small-basic-softtimer.md index f0233bc29e..54fa23cdeb 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-softtimer.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-softtimer.md @@ -1,29 +1,34 @@ -# 软件定时器 +# 软件定时器 -- [基本概念](#section4118241563) -- [运行机制](#section31079397569) -- [开发指导](#section18576131520577) - - [接口说明](#section3138019145719) - - [开发流程](#section1344817403575) - - [编程实例](#section114416313585) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) +## 基本概念 -## 基本概念 - -软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,Huawei LiteOS操作系统提供软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。 +软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,OpenHarmony LiteOS-A内核提供软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。 软件定时器功能上支持: -- 静态裁剪:能通过宏关闭软件定时器功能。 -- 软件定时器创建。 -- 软件定时器启动。 -- 软件定时器停止。 -- 软件定时器删除。 -- 软件定时器剩余Tick数获取。 +- 静态裁剪:能通过宏关闭软件定时器功能。 + +- 软件定时器创建。 + +- 软件定时器启动。 + +- 软件定时器停止。 + +- 软件定时器删除。 + +- 软件定时器剩余Tick数获取。 -## 运行机制 -软件定时器是系统资源,在模块初始化的时候已经分配了一块连续的内存,系统支持的最大定时器个数由los\_config.h中的LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT宏配置。软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。同一时刻设置的定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,OpenHarmony系统会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 +## 运行机制 + +软件定时器是系统资源,在模块初始化的时候已经分配了一块连续的内存,系统支持的最大定时器个数由los_config.h中的LOSCFG_BASE_CORE_SWTMR_LIMIT宏配置。软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。同一时刻设置的定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,OpenHarmony系统会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。 当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。 @@ -31,113 +36,88 @@ Tick中断处理函数结束后,软件定时器任务(优先级为最高) 定时器状态 -- OS\_SWTMR\_STATUS\_UNUSED(未使用) +- OS_SWTMR_STATUS_UNUSED(未使用) + 系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态。 - 系统在定时器模块初始化的时候将系统中所有定时器资源初始化成该状态。 +- OS_SWTMR_STATUS_CREATED(创建未启动/停止) + 在未使用状态下调用LOS_SwtmrCreate接口或者启动后调用LOS_SwtmrStop接口后,定时器将变成该状态。 -- OS\_SWTMR\_STATUS\_CREATED(创建未启动/停止) +- OS_SWTMR_STATUS_TICKING(计数) + 在定时器创建后调用LOS_SwtmrStart接口,定时器将变成该状态,表示定时器运行时的状态。 - 在未使用状态下调用LOS\_SwtmrCreate接口或者启动后调用LOS\_SwtmrStop接口后,定时器将变成该状态。 +定时器模式 -- OS\_SWTMR\_STATUS\_TICKING(计数) +OpenHarmony系统的软件定时器提供三类定时器机制: - 在定时器创建后调用LOS\_SwtmrStart接口,定时器将变成该状态,表示定时器运行时的状态。 +- 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 +- 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。 -定时器模式 +- 第三类也是单次触发定时器,但与第一类不同之处在于这类定时器超时后不会自动删除,需要调用定时器删除接口删除定时器。 -OpenHarmony系统的软件定时器提供三类定时器机制: -- 第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。 -- 第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。 -- 第三类也是单次触发定时器,但与第一类不同之处在于这类定时器超时后不会自动删除,需要调用定时器删除接口删除定时器。 +## 开发指导 -## 开发指导 -### 接口说明 +### 接口说明 OpenHarmony LiteOS-A内核的软件定时器模块提供下面几种功能,接口详细信息可以查看API参考。 -**表 1** 软件定时器接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

创建、删除定时器

-

LOS_SwtmrCreate

-

创建软件定时器

-

LOS_SwtmrDelete

-

删除软件定时器

-

启动、停止定时器

-

LOS_SwtmrStart

-

启动软件定时器

-

LOS_SwtmrStop

-

停止软件定时器

-

获得软件定时剩余Tick数

-

LOS_SwtmrTimeGet

-

获得软件定时器剩余Tick数

-
- -### 开发流程 +**表1** 软件定时器接口说明 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 创建、删除定时器 | LOS_SwtmrCreate | 创建软件定时器 | +| | LOS_SwtmrDelete |删除软件定时器| +| 启动、停止定时器 | LOS_SwtmrStart | 启动软件定时器 | +| | LOS_SwtmrStop |停止软件定时器| +| 获得软件定时剩余Tick数 | LOS_SwtmrTimeGet | 获得软件定时器剩余Tick数 | + + +### 开发流程 软件定时器的典型开发流程: -1. 配置软件定时器。 - - 确认配置项LOSCFG\_BASE\_CORE\_SWTMR和LOSCFG\_BASE\_IPC\_QUEUE为打开状态; - - 配置LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数; - - 配置OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度; +1. 配置软件定时器。 + - 确认配置项LOSCFG_BASE_CORE_SWTMR和LOSCFG_BASE_IPC_QUEUE为打开状态; + - 配置LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数; + - 配置OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度; + +2. 创建定时器LOS_SwtmrCreate。 + - 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器; + - 返回函数运行结果,成功或失败; + +3. 启动定时器LOS_SwtmrStart。 + +4. 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。 -2. 创建定时器LOS\_SwtmrCreate。 - - 创建一个指定计时时长、指定超时处理函数、指定触发模式的软件定时器; - - 返回函数运行结果,成功或失败; +5. 停止定时器LOS_SwtmrStop。 -3. 启动定时器LOS\_SwtmrStart。 -4. 获得软件定时器剩余Tick数LOS\_SwtmrTimeGet。 -5. 停止定时器LOS\_SwtmrStop。 -6. 删除定时器LOS\_SwtmrDelete。 +6. 删除定时器LOS_SwtmrDelete。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。 ->- 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。 ->- 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。 ->- 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。 ->- 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 软件定时器的回调函数中不要做过多操作,不要使用可能引起任务挂起或者阻塞的接口或操作。 +> +> - 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级设定为0,且不允许修改 。 +> +> - 系统可配置的软件定时器资源个数是指:整个系统可使用的软件定时器资源总个数,而并非是用户可使用的软件定时器资源个数。例如:系统软件定时器多占用一个软件定时器资源数,那么用户能使用的软件定时器资源就会减少一个。 +> +> - 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源。 +> +> - 创建单次不自删除属性的定时器,用户需要调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。 -### 编程实例 + +### 编程实例 **前置条件** -- 在los\_config.h中,将LOSCFG\_BASE\_CORE\_SWTMR配置项打开。 -- 配置好LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT最大支持的软件定时器数。 -- 配置好OS\_SWTMR\_HANDLE\_QUEUE\_SIZE软件定时器队列最大长度。 +- 在los_config.h中,将LOSCFG_BASE_CORE_SWTMR配置项打开。 -**编程示例** +- 配置好LOSCFG_BASE_CORE_SWTMR_LIMIT最大支持的软件定时器数。 + +- 配置好OS_SWTMR_HANDLE_QUEUE_SIZE软件定时器队列最大长度。 +**编程示例** ``` #include "los_swtmr.h" @@ -233,4 +213,3 @@ tick_last1=2101 g_timercount2 =10 tick_last1=2201 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-time.md b/zh-cn/device-dev/kernel/kernel-small-basic-time.md index 30e9f81eb1..7991f2a113 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-time.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-time.md @@ -1,97 +1,70 @@ -# 时间管理 +# 时间管理 -- [基本概念](#section12903185785119) -- [开发指导](#section430981720522) - - [接口说明](#section1040142705214) - - [开发流程](#section1381224710522) - - [编程实例](#section1344610245416) +- [基本概念](#基本概念) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 时间管理以系统时钟为基础。时间管理提供给应用程序所有和时间有关的服务。系统时钟是由定时/计数器产生的输出脉冲触发中断而产生的,一般定义为整数或长整数。输出脉冲的周期叫做一个“时钟滴答”。系统时钟也称为时标或者Tick。一个Tick的时长可以静态配置。用户是以秒、毫秒为单位计时,而操作系统时钟计时是以Tick为单位的,当用户需要对系统操作时,例如任务挂起、延时等,输入秒为单位的数值,此时需要时间管理模块对二者进行转换。 Tick与秒之间的对应关系可以配置。 -- **Cycle** +- **Cycle** + 系统最小的计时单位。Cycle的时长由系统主频决定,系统主频就是每秒钟的Cycle数。 - 系统最小的计时单位。Cycle的时长由系统主频决定,系统主频就是每秒钟的Cycle数。 +- **Tick** + Tick是操作系统的基本时间单位,对应的时长由系统主频及每秒Tick数决定,由用户配置。 +OpenHarmony系统的时间管理模块提供时间转换、统计、延迟功能以满足用户对时间相关需求的实现。 -- **Tick** - Tick是操作系统的基本时间单位,对应的时长由系统主频及每秒Tick数决定,由用户配置。 +## 开发指导 +用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系时,需要使用到时间管理模块的接口。 -OpenHarmony系统的时间管理模块提供时间转换、统计、延迟功能以满足用户对时间相关需求的实现。 -## 开发指导 +### 接口说明 -用户需要了解当前系统运行的时间以及Tick与秒、毫秒之间的转换关系时,需要使用到时间管理模块的接口。 +OpenHarmony LiteOS-A内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 -### 接口说明 +**表1** 时间管理相关接口说明 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 时间转换 | LOS_MS2Tick | 毫秒转换成Tick | +| | LOS_Tick2MS |Tick转换成毫秒| +| 时间统计 | LOS_TickCountGet | 获取当前Tick数 | +| | LOS_CyclePerTickGet |每个Tick的cycle数| -OpenHarmony LiteOS-A内核的时间管理提供下面几种功能,接口详细信息可以查看API参考。 -**表 1** 时间管理相关接口说明 - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

时间转换

-

LOS_MS2Tick

-

毫秒转换成Tick

-

LOS_Tick2MS

-

Tick转换成毫秒

-

时间统计

-

LOS_TickCountGet

-

获取当前Tick数

-

LOS_CyclePerTickGet

-

每个Tick的cycle数

-
- -### 开发流程 - -1. 调用时间转换接口; -2. 获取系统Tick数完成时间统计等。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 获取系统Tick数需要在系统时钟使能之后。 ->- 时间管理不是单独的功能模块,依赖于los\_config.h中的OS\_SYS\_CLOCK和LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND两个配置选项。 ->- 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间计算。 - -### 编程实例 +### 开发流程 + +1. 调用时间转换接口; + +2. 获取系统Tick数完成时间统计等。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 获取系统Tick数需要在系统时钟使能之后。 +> +> - 时间管理不是单独的功能模块,依赖于los_config.h中的OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND两个配置选项。 +> +> - 系统的Tick数在关中断的情况下不进行计数,故系统Tick数不能作为准确时间计算。 + + +### 编程实例 前置条件: -- 配置好LOSCFG\_BASE\_CORE\_TICK\_PER\_SECOND,即系统每秒的Tick数。 -- 配置好OS\_SYS\_CLOCK 系统时钟频率,单位:Hz。 +- 配置好LOSCFG_BASE_CORE_TICK_PER_SECOND,即系统每秒的Tick数。 + +- 配置好OS_SYS_CLOCK 系统时钟频率,单位:Hz。 **示例代码** 时间转换: - ``` VOID Example_TransformTime(VOID) { @@ -150,4 +123,3 @@ LOS_CyclePerTickGet = 49500 LOS_TickCountGet = 5042 LOS_TickCountGet after delay = 5242 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-event.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-event.md index 3d468594c4..ee8d3eec26 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-event.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-event.md @@ -1,40 +1,46 @@ -# 事件 +# 事件 + +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [事件控制块](#事件控制块) + - [事件运作原理](#事件运作原理) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [编程示例](#编程示例) + - [结果验证](#结果验证) + +## 基本概念 -- [基本概念](#section122115620816) -- [运行机制](#section94611116593) - - [事件控制块](#section1161415384467) - - [事件运作原理](#section187761153144617) +事件(Event)是一种任务间通信的机制,可用于任务间的同步。 -- [开发指导](#section44744471891) - - [接口说明](#section172373513919) - - [开发流程](#section1118215161013) - - [编程实例](#section19986143311020) - - [实例描述](#section128221510145718) - - [编程示例](#section71507479577) - - [结果验证](#section16570171645813) +多任务环境下,任务之间往往需要同步操作,一个等待即是一个同步。事件可以提供一对多、多对多的同步操作。 +- 一对多同步模型:一个任务等待多个事件的触发。可以是任意一个事件发生时唤醒任务处理事件,也可以是几个事件都发生后才唤醒任务处理事件。 -## 基本概念 +- 多对多同步模型:多个任务等待多个事件的触发。 -事件(Event)是一种任务间通信的机制,可用于任务间的同步。 +OpenHarmony LiteOS-A的事件模块提供的事件,具有如下特点: -多任务环境下,任务之间往往需要同步操作,一个等待即是一个同步。事件可以提供一对多、多对多的同步操作。 +- 任务通过创建事件控制块来触发事件或等待事件。 -- 一对多同步模型:一个任务等待多个事件的触发。可以是任意一个事件发生时唤醒任务处理事件,也可以是几个事件都发生后才唤醒任务处理事件。 -- 多对多同步模型:多个任务等待多个事件的触发。 +- 事件间相互独立,内部实现为一个32位无符号整型,每一位标识一种事件类型。第25位不可用,因此最多可支持31种事件类型。 -OpenHarmony LiteOS-A的事件模块提供的事件,具有如下特点: +- 事件仅用于任务间的同步,不提供数据传输功能。 + +- 多次向事件控制块写入同一事件类型,在被清零前等效于只写入一次。 + +- 多个任务可以对同一事件进行读写操作。 -- 任务通过创建事件控制块来触发事件或等待事件。 -- 事件间相互独立,内部实现为一个32位无符号整型,每一位标识一种事件类型。第25位不可用,因此最多可支持31种事件类型。 -- 事件仅用于任务间的同步,不提供数据传输功能。 -- 多次向事件控制块写入同一事件类型,在被清零前等效于只写入一次。 -- 多个任务可以对同一事件进行读写操作。 -- 支持事件读写超时机制。 +- 支持事件读写超时机制。 -## 运行机制 -### 事件控制块 +## 运行机制 + + +### 事件控制块 ``` /** @@ -46,7 +52,8 @@ typedef struct tagEvent { } EVENT_CB_S, *PEVENT_CB_S; ``` -### 事件运作原理 + +### 事件运作原理 **事件初始化**:会创建一个事件控制块,该控制块维护一个已处理的事件集合,以及等待特定事件的任务链表。 @@ -56,105 +63,80 @@ typedef struct tagEvent { 读事件条件满足与否取决于入参eventMask和mode,eventMask即需要关注的事件类型掩码。mode是具体处理方式,分以下三种情况: -- LOS\_WAITMODE\_AND:逻辑与,基于接口传入的事件类型掩码eventMask,只有这些事件都已经发生才能读取成功,否则该任务将阻塞等待或者返回错误码。 -- LOS\_WAITMODE\_OR:逻辑或,基于接口传入的事件类型掩码eventMask,只要这些事件中有任一种事件发生就可以读取成功,否则该任务将阻塞等待或者返回错误码。 -- LOS\_WAITMODE\_CLR:这是一种附加读取模式,需要与所有事件模式或任一事件模式结合使用(LOS\_WAITMODE\_AND | LOS\_WAITMODE\_CLR或 LOS\_WAITMODE\_OR | LOS\_WAITMODE\_CLR)。在这种模式下,当设置的所有事件模式或任一事件模式读取成功后,会自动清除事件控制块中对应的事件类型位。 +- LOS_WAITMODE_AND:逻辑与,基于接口传入的事件类型掩码eventMask,只有这些事件都已经发生才能读取成功,否则该任务将阻塞等待或者返回错误码。 + +- LOS_WAITMODE_OR:逻辑或,基于接口传入的事件类型掩码eventMask,只要这些事件中有任一种事件发生就可以读取成功,否则该任务将阻塞等待或者返回错误码。 + +- LOS_WAITMODE_CLR:这是一种附加读取模式,需要与所有事件模式或任一事件模式结合使用(LOS_WAITMODE_AND | LOS_WAITMODE_CLR或 LOS_WAITMODE_OR | LOS_WAITMODE_CLR)。在这种模式下,当设置的所有事件模式或任一事件模式读取成功后,会自动清除事件控制块中对应的事件类型位。 **事件清零**:根据指定掩码,去对事件控制块的事件集合进行清零操作。当掩码为0时,表示将事件集合全部清零。当掩码为0xffff时,表示不清除任何事件,保持事件集合原状。 **事件销毁**:销毁指定的事件控制块。 -**图 1** 事件运作原理图 -![](figure/事件运作原理图-21.png "事件运作原理图-21") +**图1** 小型系统事件运作原理图 +![zh-cn_image_0000001180952545](figures/zh-cn_image_0000001180952545.png) + -## 开发指导 +## 开发指导 -### 接口说明 + +### 接口说明 OpenHarmony LiteOS-A内核的事件模块提供下面几种功能。 -**表 1** 事件模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

初始化事件

-

LOS_EventInit

-

初始化一个事件控制块

-

读/写事件

-

LOS_EventRead

-

读取指定事件类型,超时时间为相对时间:单位为Tick

-

LOS_EventWrite

-

写指定的事件类型

-

清除事件

-

LOS_EventClear

-

清除指定的事件类型

-

校验事件掩码

-

LOS_EventPoll

-

根据用户传入的事件ID、事件掩码及读取模式,返回用户传入的事件是否符合预期

-

销毁事件

-

LOS_EventDestroy

-

销毁指定的事件控制块

-
- -### 开发流程 +**表1** 事件模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 初始化事件 | LOS_EventInit | 初始化一个事件控制块 | +| 读/写事件 | LOS_EventRead | 读取指定事件类型,超时时间为相对时间:单位为Tick | +| | LOS_EventWrite |写指定的事件类型| +| 清除事件 | LOS_EventClear | 清除指定的事件类型 | +| 校验事件掩码 | LOS_EventPoll | 根据用户传入的事件ID、事件掩码及读取模式,返回用户传入的事件是否符合预期 | +| 销毁事件 | LOS_EventDestroy | 销毁指定的事件控制块 | + + +### 开发流程 事件的典型开发流程: -1. 初始化事件控制块 -2. 阻塞读事件控制块 -3. 写入相关事件 -4. 阻塞任务被唤醒,读取事件并检查是否满足要求 -5. 处理事件控制块 -6. 事件控制块销毁 +1. 初始化事件控制块 + +2. 阻塞读事件控制块 + +3. 写入相关事件 + +4. 阻塞任务被唤醒,读取事件并检查是否满足要求 + +5. 处理事件控制块 + +6. 事件控制块销毁 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 进行事件读写操作时,事件的第25位为保留位,不可以进行位设置。 +> +> - 对同一事件反复写入,算作一次写入。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 进行事件读写操作时,事件的第25位为保留位,不可以进行位设置。 ->- 对同一事件反复写入,算作一次写入。 -### 编程实例 +## 编程实例 -### 实例描述 -示例中,任务Example\_TaskEntry创建一个任务Example\_Event,Example\_Event读事件阻塞,Example\_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。 +### 实例描述 -1. 在任务Example\_TaskEntry创建任务Example\_Event,其中任务Example\_Event优先级高于Example\_TaskEntry。 -2. 在任务Example\_Event中读事件0x00000001,阻塞,发生任务切换,执行任务Example\_TaskEntry。 -3. 在任务Example\_TaskEntry向任务Example\_Event写事件0x00000001,发生任务切换,执行任务Example\_Event。 -4. Example\_Event得以执行,直到任务结束。 -5. Example\_TaskEntry得以执行,直到任务结束。 +示例中,任务Example_TaskEntry创建一个任务Example_Event,Example_Event读事件阻塞,Example_TaskEntry向该任务写事件。可以通过示例日志中打印的先后顺序理解事件操作时伴随的任务切换。 -### 编程示例 +1. 在任务Example_TaskEntry创建任务Example_Event,其中任务Example_Event优先级高于Example_TaskEntry。 + +2. 在任务Example_Event中读事件0x00000001,阻塞,发生任务切换,执行任务Example_TaskEntry。 + +3. 在任务Example_TaskEntry向任务Example_Event写事件0x00000001,发生任务切换,执行任务Example_Event。 + +4. Example_Event得以执行,直到任务结束。 + +5. Example_TaskEntry得以执行,直到任务结束。 + + +### 编程示例 示例代码如下: @@ -237,7 +219,8 @@ UINT32 Example_EventEntry(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: @@ -248,4 +231,3 @@ Example_Event,read event :0x1 EventMask:1 EventMask:0 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-mutex.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-mutex.md index cf974087d3..7733c14375 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-mutex.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-mutex.md @@ -1,200 +1,121 @@ -# 互斥锁 +# 互斥锁 -- [基本概念](#section85865329185) -- [运行机制](#section8547454201819) -- [开发指导](#section2038861117194) - - [接口说明](#section11168318131917) - - [开发流程](#section4201191122116) - - [编程实例](#section10679328202117) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 互斥锁又称互斥型信号量,用于实现对共享资源的独占式处理。当有任务持有时,这个任务获得该互斥锁的所有权。当该任务释放它时,任务失去该互斥锁的所有权。当一个任务持有互斥锁时,其他任务将不能再持有该互斥锁。多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。 互斥锁属性包含3个属性:协议属性、优先级上限属性和类型属性。协议属性用于处理不同优先级的任务申请互斥锁,协议属性包含如下三种: -- LOS\_MUX\_PRIO\_NONE +- LOS_MUX_PRIO_NONE + 不对申请互斥锁的任务的优先级进行继承或保护操作。 + +- LOS_MUX_PRIO_INHERIT + 优先级继承属性,默认设置为该属性,对申请互斥锁的任务的优先级进行继承。在互斥锁设置为本协议属性情况下,申请互斥锁时,如果高优先级任务阻塞于互斥锁,则把持有互斥锁任务的优先级备份到任务控制块的优先级位图中,然后把任务优先级设置为和高优先级任务相同的优先级;持有互斥锁的任务释放互斥锁时,从任务控制块的优先级位图恢复任务优先级。 - 不对申请互斥锁的任务的优先级进行继承或保护操作。 +- LOS_MUX_PRIO_PROTECT + 优先级保护属性,对申请互斥锁的任务的优先级进行保护。在互斥锁设置为本协议属性情况下,申请互斥锁时,如果任务优先级小于互斥锁优先级上限,则把任务优先级备份到任务控制块的优先级位图中,然后把任务优先级设置为互斥锁优先级上限属性值;释放互斥锁时,从任务控制块的优先级位图恢复任务优先级。 -- LOS\_MUX\_PRIO\_INHERIT +互斥锁的类型属性用于标记是否检测死锁,是否支持递归持有,类型属性包含如下三种: - 优先级继承属性,默认设置为该属性,对申请互斥锁的任务的优先级进行继承。在互斥锁设置为本协议属性情况下,申请互斥锁时,如果高优先级任务阻塞于互斥锁,则把持有互斥锁任务的优先级备份到任务控制块的优先级位图中,然后把任务优先级设置为和高优先级任务相同的优先级;持有互斥锁的任务释放互斥锁时,从任务控制块的优先级位图恢复任务优先级。 +- LOS_MUX_NORMAL + 普通互斥锁,不会检测死锁。如果任务试图对一个互斥锁重复持有,将会引起这个线程的死锁。如果试图释放一个由别的任务持有的互斥锁,或者如果一个任务试图重复释放互斥锁都会引发不可预料的结果。 -- LOS\_MUX\_PRIO\_PROTECT +- LOS_MUX_RECURSIVE + 递归互斥锁,默认设置为该属性。在互斥锁设置为本类型属性情况下,允许同一个任务对互斥锁进行多次持有锁,持有锁次数和释放锁次数相同,其他任务才能持有该互斥锁。如果试图持有已经被其他任务持有的互斥锁,或者如果试图释放已经被释放的互斥锁,会返回错误码。 - 优先级保护属性,对申请互斥锁的任务的优先级进行保护。在互斥锁设置为本协议属性情况下,申请互斥锁时,如果任务优先级小于互斥锁优先级上限,则把任务优先级备份到任务控制块的优先级位图中,然后把任务优先级设置为互斥锁优先级上限属性值;释放互斥锁时,从任务控制块的优先级位图恢复任务优先级。 +- LOS_MUX_ERRORCHECK + 错误检测互斥锁,会自动检测死锁。在互斥锁设置为本类型属性情况下,如果任务试图对一个互斥锁重复持有,或者试图释放一个由别的任务持有的互斥锁,或者如果一个任务试图释放已经被释放的互斥锁,都会返回错误码。 -互斥锁的类型属性用于标记是否检测死锁,是否支持递归持有,类型属性包含如下三种: +## 运行机制 -- LOS\_MUX\_NORMAL +多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? - 普通互斥锁,不会检测死锁。如果任务试图对一个互斥锁重复持有,将会引起这个线程的死锁。如果试图释放一个由别的任务持有的互斥锁,或者如果一个任务试图重复释放互斥锁都会引发不可预料的结果。 +用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 -- LOS\_MUX\_RECURSIVE +**图1** 小型系统互斥锁运作示意图 +![zh-cn_image_0000001177654887](figures/zh-cn_image_0000001177654887.png) - 递归互斥锁,默认设置为该属性。在互斥锁设置为本类型属性情况下,允许同一个任务对互斥锁进行多次持有锁,持有锁次数和释放锁次数相同,其他任务才能持有该互斥锁。如果试图持有已经被其他任务持有的互斥锁,或者如果试图释放已经被释放的互斥锁,会返回错误码。 -- LOS\_MUX\_ERRORCHECK +## 开发指导 - 错误检测互斥锁,会自动检测死锁。在互斥锁设置为本类型属性情况下,如果任务试图对一个互斥锁重复持有,或者试图释放一个由别的任务持有的互斥锁,或者如果一个任务试图释放已经被释放的互斥锁,都会返回错误码。 +### 接口说明 -## 运行机制 +**表1** 互斥锁模块接口 -多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢? +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 初始化和销毁互斥锁 | LOS_MuxInit | 互斥锁初始化 | +| | LOS_MuxDestroy |销毁指定的互斥锁| +| 互斥锁的申请和释放 | LOS_MuxLock | 申请指定的互斥锁 | +| | LOS_MuxTrylock |尝试申请指定的互斥锁,不阻塞| +| | LOS_MuxUnlock |释放指定的互斥锁| +| 校验互斥锁 | LOS_MuxIsValid | 判断互斥锁释放有效 | +| 初始化和销毁互斥锁属性 | LOS_MuxAttrInit | 互斥锁属性初始化 | +| | LOS_MuxAttrDestroy |销毁指定的互斥锁属性| +| 设置和获取互斥锁属性 | LOS_MuxAttrGetType | 获取指定互斥锁属性的类型属性 | +| | LOS_MuxAttrSetType |设置指定互斥锁属性的类型属性| +| | LOS_MuxAttrGetProtocol |获取指定互斥锁属性的协议属性| +| | LOS_MuxAttrSetProtocol |设置指定互斥锁属性的协议属性| +| | LOS_MuxAttrGetPrioceiling |获取指定互斥锁属性的优先级上限属性| +| | LOS_MuxAttrSetPrioceiling |设置指定互斥锁属性的优先级上限属性| +| | LOS_MuxGetPrioceiling |获取互斥锁优先级上限属性| +| | LOS_MuxSetPrioceiling |设置互斥锁优先级上限属性| -用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。 -**图 1** 互斥锁运作示意图 -![](figure/互斥锁运作示意图-23.png "互斥锁运作示意图-23") - -## 开发指导 - -### 接口说明 - -**表 1** 互斥锁模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

初始化和销毁互斥锁

-

LOS_MuxInit

-

互斥锁初始化

-

LOS_MuxDestroy

-

销毁指定的互斥锁

-

互斥锁的申请和释放

-

LOS_MuxLock

-

申请指定的互斥锁

-

LOS_MuxTrylock

-

尝试申请指定的互斥锁,不阻塞

-

LOS_MuxUnlock

-

释放指定的互斥锁

-

校验互斥锁

-

LOS_MuxIsValid

-

判断互斥锁释放有效

-

初始化和销毁互斥锁属性

-

LOS_MuxAttrInit

-

互斥锁属性初始化

-

LOS_MuxAttrDestroy

-

销毁指定的互斥锁属性

-

设置和获取互斥锁属性

-

LOS_MuxAttrGetType

-

获取指定互斥锁属性的类型属性

-

LOS_MuxAttrSetType

-

设置指定互斥锁属性的类型属性

-

LOS_MuxAttrGetProtocol

-

获取指定互斥锁属性的协议属性

-

LOS_MuxAttrSetProtocol

-

设置指定互斥锁属性的协议属性

-

LOS_MuxAttrGetPrioceiling

-

获取指定互斥锁属性的优先级上限属性

-

LOS_MuxAttrSetPrioceiling

-

设置指定互斥锁属性的优先级上限属性

-

LOS_MuxGetPrioceiling

-

获取互斥锁优先级上限属性

-

LOS_MuxSetPrioceiling

-

设置互斥锁优先级上限属性

-
- -### 开发流程 +### 开发流程 互斥锁典型场景的开发流程: -1. 初始化互斥锁LOS\_MuxInit。 +1. 初始化互斥锁LOS_MuxInit。 -2. 申请互斥锁LOS\_MuxLock。 +2. 申请互斥锁LOS_MuxLock。 申请模式有三种:无阻塞模式、永久阻塞模式、定时阻塞模式。 -- 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功; -- 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行; -- 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用 户指定时间超时后,阻塞任务才会重新得以执行。 +- 无阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有任务持有,或者持有该互斥锁的任务和申请该互斥锁的任务为同一个任务,则申请成功; -3. 释放互斥锁LOS\_MuxUnlock。 +- 永久阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则,该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,直到有其他任务释放该互斥锁,阻塞任务才会重新得以执行; -- 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; -- 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。 +- 定时阻塞模式:任务需要申请互斥锁,若该互斥锁当前没有被占用,则申请成功。否则该任务进入阻塞态,系统切换到就绪任务中优先级高者继续执行。任务进入阻塞态后,指定时间超时前有其他任务释放该互斥锁,或者用 户指定时间超时后,阻塞任务才会重新得以执行。 -4. 销毁互斥锁LOS\_MuxDestroy。 +3. 释放互斥锁LOS_MuxUnlock。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 ->- 互斥锁不能在中断服务程序中使用。 ->- LiteOS-A内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 +- 如果有任务阻塞于指定互斥锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; -### 编程实例 +- 如果没有任务阻塞于指定互斥锁,则互斥锁释放成功。 + +4. 销毁互斥锁LOS_MuxDestroy。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 两个任务不能对同一把互斥锁加锁。如果某任务对已被持有的互斥锁加锁,则该任务会被挂起,直到持有该锁的任务对互斥锁解锁,才能执行对这把互斥锁的加锁操作。 +> +> - 互斥锁不能在中断服务程序中使用。 +> +> - LiteOS-A内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得互斥锁之后,应该尽快释放互斥锁。 + + +### 编程实例 **实例描述** 本实例实现如下流程: -1. 任务Example\_TaskEntry创建一个互斥锁,锁任务调度,创建两个任务Example\_MutexTask1、Example\_MutexTask2。Example\_MutexTask2优先级高于Example\_MutexTask1,解锁任务调度。 -2. Example\_MutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,Example\_MutexTask2挂起,Example\_MutexTask1被唤醒。 -3. Example\_MutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。10Tick超时时间到达后,Example\_MutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被Example\_MutexTask2持有,Example\_MutexTask1挂起。 -4. 100Tick休眠时间到达后,Example\_MutexTask2被唤醒, 释放互斥锁,唤醒Example\_MutexTask1。Example\_MutexTask1成功获取到互斥锁后,释放,删除互斥锁。 +1. 任务Example_TaskEntry创建一个互斥锁,锁任务调度,创建两个任务Example_MutexTask1、Example_MutexTask2。Example_MutexTask2优先级高于Example_MutexTask1,解锁任务调度。 + +2. Example_MutexTask2被调度,以永久阻塞模式申请互斥锁,并成功获取到该互斥锁,然后任务休眠100Tick,Example_MutexTask2挂起,Example_MutexTask1被唤醒。 + +3. Example_MutexTask1以定时阻塞模式申请互斥锁,等待时间为10Tick,因互斥锁仍被Example_MutexTask2持有,Example_MutexTask1挂起。10Tick超时时间到达后,Example_MutexTask1被唤醒,以永久阻塞模式申请互斥锁,因互斥锁仍被Example_MutexTask2持有,Example_MutexTask1挂起。 + +4. 100Tick休眠时间到达后,Example_MutexTask2被唤醒, 释放互斥锁,唤醒Example_MutexTask1。Example_MutexTask1成功获取到互斥锁后,释放,删除互斥锁。 **示例代码** @@ -314,4 +235,3 @@ task2 resumed and post the g_testMux task1 wait forever, get mutex g_testMux. task1 post and delete mutex g_testMux. ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-queue.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-queue.md index 49a07e82c3..2f6db05f81 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-queue.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-queue.md @@ -1,41 +1,46 @@ -# 消息队列 +# 消息队列 + +- [基本概念](#基本概念) +- [运行机制](#运行机制) + - [队列控制块](#队列控制块) + - [队列运作原理](#队列运作原理) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) +- [编程实例](#编程实例) + - [实例描述](#实例描述) + - [编程示例](#编程示例) + - [结果验证](#结果验证) + +## 基本概念 -- [基本概念](#section81171363232) -- [运行机制](#section1074515132316) - - [队列控制块](#section194431851201315) - - [队列运作原理](#section89875741418) +队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 -- [开发指导](#section827981242419) - - [接口说明](#section19327151642413) - - [开发流程](#section1390154210243) +任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时,挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。 -- [编程实例](#section27132341285) - - [实例描述](#section197311443141017) - - [编程示例](#section972214490107) - - [结果验证](#section19287165416106) +可以通过调整读队列和写队列的超时时间来调整读写接口的阻塞模式,如果将读队列和写队列的超时时间设置为0,就不会挂起任务,接口会直接返回,这就是非阻塞模式。反之,如果将都队列和写队列的超时时间设置为大于0的时间,就会以阻塞模式运行。 +消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用,可以使用队列实现任务异步通信,队列具有如下特性: -## 基本概念 +- 消息以先进先出的方式排队,支持异步读写。 -队列又称消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。 +- 读队列和写队列都支持超时机制。 -任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时,挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。 +- 每读取一条消息,就会将该消息节点设置为空闲。 -可以通过调整读队列和写队列的超时时间来调整读写接口的阻塞模式,如果将读队列和写队列的超时时间设置为0,就不会挂起任务,接口会直接返回,这就是非阻塞模式。反之,如果将都队列和写队列的超时时间设置为大于0的时间,就会以阻塞模式运行。 +- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列的消息节点大小)的消息。 -消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用,可以使用队列实现任务异步通信,队列具有如下特性: +- 一个任务能够从任意一个消息队列接收和发送消息。 + +- 多个任务能够从同一个消息队列接收和发送消息。 + +- 创建队列时所需的队列空间,接口内系统自行动态申请内存。 -- 消息以先进先出的方式排队,支持异步读写。 -- 读队列和写队列都支持超时机制。 -- 每读取一条消息,就会将该消息节点设置为空闲。 -- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列的消息节点大小)的消息。 -- 一个任务能够从任意一个消息队列接收和发送消息。 -- 多个任务能够从同一个消息队列接收和发送消息。 -- 创建队列时所需的队列空间,接口内系统自行动态申请内存。 -## 运行机制 +## 运行机制 -### 队列控制块 + +### 队列控制块 ``` /** @@ -57,120 +62,92 @@ typedef struct { 每个队列控制块中都含有队列状态,表示该队列的使用情况: -- OS\_QUEUE\_UNUSED:队列未被使用。 -- OS\_QUEUE\_INUSED:队列被使用中。 +- OS_QUEUE_UNUSED:队列未被使用。 + +- OS_QUEUE_INUSED:队列被使用中。 + + +### 队列运作原理 + +- 创建队列时,创建队列成功会返回队列ID。 -### 队列运作原理 +- 在队列控制块中维护着一个消息头节点位置Head和一个消息尾节点位置Tail,用于表示当前队列中消息的存储情况。Head表示队列中被占用的消息节点的起始位置。Tail表示被占用的消息节点的结束位置,也是空闲消息节点的起始位置。队列刚创建时,Head和Tail均指向队列起始位置。 -- 创建队列时,创建队列成功会返回队列ID。 -- 在队列控制块中维护着一个消息头节点位置Head和一个消息尾节点位置Tail,用于表示当前队列中消息的存储情况。Head表示队列中被占用的消息节点的起始位置。Tail表示被占用的消息节点的结束位置,也是空闲消息节点的起始位置。队列刚创建时,Head和Tail均指向队列起始位置。 -- 写队列时,根据readWriteableCnt\[1\]判断队列是否可以写入,不能对已满(readWriteableCnt\[1\]为0)队列进行写操作。写队列支持两种写入方式:向队列尾节点写入,也可以向队列头节点写入。尾节点写入时,根据Tail找到起始空闲消息节点作为数据写入对象,如果Tail已经指向队列尾部则采用回卷方式。头节点写入时,将Head的前一个节点作为数据写入对象,如果Head指向队列起始位置则采用回卷方式。 -- 读队列时,根据readWriteableCnt\[0\]判断队列是否有消息需要读取,对全部空闲(readWriteableCnt\[0\]为0)队列进行读操作会引起任务挂起。如果队列可以读取消息,则根据Head找到最先写入队列的消息节点进行读取。如果Head已经指向队列尾部则采用回卷方式。 -- 删除队列时,根据队列ID找到对应队列,把队列状态置为未使用,把队列控制块置为初始状态,并释放队列所占内存。 +- 写队列时,根据readWriteableCnt[1]判断队列是否可以写入,不能对已满(readWriteableCnt[1]为0)队列进行写操作。写队列支持两种写入方式:向队列尾节点写入,也可以向队列头节点写入。尾节点写入时,根据Tail找到起始空闲消息节点作为数据写入对象,如果Tail已经指向队列尾部则采用回卷方式。头节点写入时,将Head的前一个节点作为数据写入对象,如果Head指向队列起始位置则采用回卷方式。 -**图 1** 队列读写数据操作示意图 -![](figure/队列读写数据操作示意图.png "队列读写数据操作示意图") +- 读队列时,根据readWriteableCnt[0]判断队列是否有消息需要读取,对全部空闲(readWriteableCnt[0]为0)队列进行读操作会引起任务挂起。如果队列可以读取消息,则根据Head找到最先写入队列的消息节点进行读取。如果Head已经指向队列尾部则采用回卷方式。 + +- 删除队列时,根据队列ID找到对应队列,把队列状态置为未使用,把队列控制块置为初始状态,并释放队列所占内存。 + +**图1** 队列读写数据操作示意图 +![zh-cn_image_0000001132875772](figures/zh-cn_image_0000001132875772.png) 上图对读写队列做了示意,图中只画了尾节点写入方式,没有画头节点写入,但是两者是类似的。 -## 开发指导 - -### 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

创建/删除消息队列

-

LOS_QueueCreate

-

创建一个消息队列,由系统动态申请队列空间

-

LOS_QueueDelete

-

根据队列ID删除一个指定队列

-

读/写队列(不带拷贝)

-

LOS_QueueRead

-

读取指定队列头节点中的数据(队列节点中的数据实际上是一个地址)

-

LOS_QueueWrite

-

向指定队列尾节点中写入入参bufferAddr的值(即buffer的地址)

-

LOS_QueueWriteHead

-

向指定队列头节点中写入入参bufferAddr的值(即buffer的地址)

-

读/写队列(带拷贝)

-

LOS_QueueReadCopy

-

读取指定队列头节点中的数据

-

LOS_QueueWriteCopy

-

向指定队列尾节点中写入入参bufferAddr中保存的数据

-

LOS_QueueWriteHeadCopy

-

向指定队列头节点中写入入参bufferAddr中保存的数据

-

获取队列信息

-

LOS_QueueInfoGet

-

获取指定队列的信息,包括队列ID、队列长度、消息节点大小、头节点、尾节点、可读节点数量、可写节点数量、等待读操作的任务、等待写操作的任务

-
- -### 开发流程 - -1. 用LOS\_QueueCreate创建队列。创建成功后,可以得到队列ID。 -2. 通过LOS\_QueueWrite或者LOS\_QueueWriteCopy写队列。 -3. 通过LOS\_QueueRead或者LOS\_QueueReadCopy读队列。 -4. 通过LOS\_QueueInfoGet获取队列信息。 -5. 通过LOS\_QueueDelete删除队列。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 系统支持的最大队列数是指:整个系统的队列资源总个数,而非用户能使用的个数。例如:系统软件定时器多占用一个队列资源,那么用户能使用的队列资源就会减少一个。 ->- 创建队列时传入的队列名和flags暂时未使用,作为以后的预留参数。 ->- 队列接口函数中的入参timeOut是相对时间。 ->- LOS\_QueueReadCopy和LOS\_QueueWriteCopy及LOS\_QueueWriteHeadCopy是一组接口,LOS\_QueueRead和LOS\_QueueWrite及LOS\_QueueWriteHead是一组接口,每组接口需要配套使用。 ->- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,用户必须保证调用LOS\_QueueRead获取到的指针所指向的内存区域在读队列期间没有被异常修改或释放,否则可能导致不可预知的后果。 ->- 鉴于LOS\_QueueWrite和LOS\_QueueWriteHead和LOS\_QueueRead这组接口实际操作的是数据地址,也就意味着实际写和读的消息长度仅仅是一个指针数据,因此用户使用这组接口之前,需确保创建队列时的消息节点大小,为一个指针的长度,避免不必要的浪费和读取失败。 - -## 编程实例 - -### 实例描述 + +## 开发指导 + + +### 接口说明 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 创建/删除消息队列 | LOS_QueueCreate | 创建一个消息队列,由系统动态申请队列空间 | +| | LOS_QueueDelete |根据队列ID删除一个指定队列| +| 读/写队列(不带拷贝) | LOS_QueueRead | 读取指定队列头节点中的数据(队列节点中的数据实际上是一个地址) | +| | LOS_QueueWrite |向指定队列尾节点中写入入参bufferAddr的值(即buffer的地址)| +| | LOS_QueueWriteHead |向指定队列头节点中写入入参bufferAddr的值(即buffer的地址)| +| 读/写队列(带拷贝) | LOS_QueueReadCopy | 读取指定队列头节点中的数据 | +| | LOS_QueueWriteCopy |向指定队列尾节点中写入入参bufferAddr中保存的数据| +| | LOS_QueueWriteHeadCopy |向指定队列头节点中写入入参bufferAddr中保存的数据| +| 获取队列信息 | LOS_QueueInfoGet | 获取指定队列的信息,包括队列ID、队列长度、消息节点大小、头节点、尾节点、可读节点数量、可写节点数量、等待读操作的任务、等待写操作的任务 | + + +### 开发流程 + +1. 用LOS_QueueCreate创建队列。创建成功后,可以得到队列ID。 + +2. 通过LOS_QueueWrite或者LOS_QueueWriteCopy写队列。 + +3. 通过LOS_QueueRead或者LOS_QueueReadCopy读队列。 + +4. 通过LOS_QueueInfoGet获取队列信息。 + +5. 通过LOS_QueueDelete删除队列。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 系统支持的最大队列数是指:整个系统的队列资源总个数,而非用户能使用的个数。例如:系统软件定时器多占用一个队列资源,那么用户能使用的队列资源就会减少一个。 +> +> - 创建队列时传入的队列名和flags暂时未使用,作为以后的预留参数。 +> +> - 队列接口函数中的入参timeOut是相对时间。 +> +> - LOS_QueueReadCopy和LOS_QueueWriteCopy及LOS_QueueWriteHeadCopy是一组接口,LOS_QueueRead和LOS_QueueWrite及LOS_QueueWriteHead是一组接口,每组接口需要配套使用。 +> +> - 鉴于LOS_QueueWrite和LOS_QueueWriteHead和LOS_QueueRead这组接口实际操作的是数据地址,用户必须保证调用LOS_QueueRead获取到的指针所指向的内存区域在读队列期间没有被异常修改或释放,否则可能导致不可预知的后果。 +> +> - 鉴于LOS_QueueWrite和LOS_QueueWriteHead和LOS_QueueRead这组接口实际操作的是数据地址,也就意味着实际写和读的消息长度仅仅是一个指针数据,因此用户使用这组接口之前,需确保创建队列时的消息节点大小,为一个指针的长度,避免不必要的浪费和读取失败。 + + +## 编程实例 + + +### 实例描述 创建一个队列,两个任务。任务1调用写队列接口发送消息,任务2通过读队列接口接收消息。 -1. 通过LOS\_TaskCreate创建任务1和任务2。 -2. 通过LOS\_QueueCreate创建一个消息队列。 -3. 在任务1 SendEntry中发送消息。 -4. 在任务2 RecvEntry中接收消息。 -5. 通过LOS\_QueueDelete删除队列。 +1. 通过LOS_TaskCreate创建任务1和任务2。 + +2. 通过LOS_QueueCreate创建一个消息队列。 + +3. 在任务1 SendEntry中发送消息。 -### 编程示例 +4. 在任务2 RecvEntry中接收消息。 + +5. 通过LOS_QueueDelete删除队列。 + + +### 编程示例 示例代码如下: @@ -253,7 +230,8 @@ UINT32 ExampleQueue(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: @@ -263,4 +241,3 @@ create the queue success! recv message: test message delete the queue success! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-rwlock.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-rwlock.md index 89bb3b752c..be796b6ac5 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-rwlock.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-rwlock.md @@ -1,13 +1,12 @@ -# 读写锁 +# 读写锁 -- [基本概念](#section4692105214260) -- [运行机制](#section1239111562720) -- [开发指导](#section11643194275) - - [接口说明](#section15335332122717) - - [开发流程](#section14774114882714) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) - -## 基本概念 +## 基本概念 读写锁与互斥锁类似,可用来同步同一进程中的各个任务,但与互斥锁不同的是,其允许多个读操作并发重入,而写操作互斥。 @@ -15,120 +14,78 @@ 读写锁的使用规则: -- 保护区无写模式下的锁,任何任务均可以为其增加读模式下的锁。 -- 保护区处于无锁状态下,才可增加写模式下的锁。 +- 保护区无写模式下的锁,任何任务均可以为其增加读模式下的锁。 + +- 保护区处于无锁状态下,才可增加写模式下的锁。 多任务环境下往往存在多个任务访问同一共享资源的应用场景,读模式下的锁以共享状态对保护区访问,而写模式下的锁可被用于对共享资源的保护从而实现独占式访问。 这种共享-独占的方式非常适合多任务中读数据频率远大于写数据频率的应用中,提高应用多任务并发度。 -## 运行机制 + +## 运行机制 相较于互斥锁,读写锁如何实现读模式下的锁及写模式下的锁来控制多任务的读写访问呢? -- 若A任务首次获取了写模式下的锁,有其他任务来获取或尝试获取读模式下的锁,均无法再上锁。 - -- 若A任务获取了读模式下的锁,当有任务来获取或尝试获取读模式下的锁时,读写锁计数均加一。 - -## 开发指导 - -### 接口说明 - -**表 1** 读写锁模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

读写锁的创建和删除

-

LOS_RwlockInit

-

创建读写锁

-

LOS_RwlockDestroy

-

删除指定的读写锁

-

读模式下的锁的申请

-

LOS_RwlockRdLock

-

申请指定的读模式下的锁

-

LOS_RwlockTryRdLock

-

尝试申请指定的读模式下的锁

-

写模式下的锁的申请

-

LOS_RwlockWrLock

-

申请指定的写模式下的锁

-

LOS_RwlockTryWrLock

-

尝试申请指定的写模式下的锁

-

读写锁的释放

-

LOS_RwlockUnLock

-

释放指定读写锁

-

读写锁有效性判断

-

LOS_RwlockIsValid

-

判断读写锁有效性

-
- -### 开发流程 +- 若A任务首次获取了写模式下的锁,有其他任务来获取或尝试获取读模式下的锁,均无法再上锁。 + +- 若A任务获取了读模式下的锁,当有任务来获取或尝试获取读模式下的锁时,读写锁计数均加一。 + + +## 开发指导 + + +### 接口说明 + +**表1** 读写锁模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 读写锁的创建和删除 | LOS_RwlockInit | 创建读写锁 | +| | LOS_RwlockDestroy |删除指定的读写锁| +| 读模式下的锁的申请 | LOS_RwlockRdLock | 申请指定的读模式下的锁 | +| | LOS_RwlockTryRdLock |尝试申请指定的读模式下的锁| +| 写模式下的锁的申请 | LOS_RwlockWrLock | 申请指定的写模式下的锁 | +| | LOS_RwlockTryWrLock |尝试申请指定的写模式下的锁| +| 读写锁的释放 | LOS_RwlockUnLock | 释放指定读写锁 | +| 读写锁有效性判断 | LOS_RwlockIsValid | 判断读写锁有效性 | + + +### 开发流程 读写锁典型场景的开发流程: -1. 创建读写锁LOS\_RwlockInit。 +1. 创建读写锁LOS_RwlockInit。 -2. 申请读模式下的锁LOS\_RwlockRdLock或写模式下的锁LOS\_RwlockWrLock。 +2. 申请读模式下的锁LOS_RwlockRdLock或写模式下的锁LOS_RwlockWrLock。 申请读模式下的锁: -- 若无人持有锁,读任务可获得锁。 -- 若有人持有锁,读任务可获得锁,读取顺序按照任务优先级。 -- 若有人(非自己)持有写模式下的锁,则当前任务无法获得锁,直到写模式下的锁释放。 +- 若无人持有锁,读任务可获得锁。 + +- 若有人持有锁,读任务可获得锁,读取顺序按照任务优先级。 + +- 若有人(非自己)持有写模式下的锁,则当前任务无法获得锁,直到写模式下的锁释放。 申请写模式下的锁: -- 若该锁当前没有任务持有,或者持有该读模式下的锁的任务和申请该锁的任务为同一个任务,则申请成功,可立即获得写模式下的锁。 -- 若该锁当前已经存在读模式下的锁,且读取任务优先级较高,则当前任务挂起,直到读模式下的锁释放。 +- 若该锁当前没有任务持有,或者持有该读模式下的锁的任务和申请该锁的任务为同一个任务,则申请成功,可立即获得写模式下的锁。 -3.申请读模式下的锁和写模式下的锁均有三种:无阻塞模式、永久阻塞模式、定时阻塞模式,区别在于挂起任务的时间。 +- 若该锁当前已经存在读模式下的锁,且读取任务优先级较高,则当前任务挂起,直到读模式下的锁释放。 -4.释放读写锁LOS\_RwlockUnLock。 +3.申请读模式下的锁和写模式下的锁均有三种:无阻塞模式、永久阻塞模式、定时阻塞模式,区别在于挂起任务的时间。 -- 如果有任务阻塞于指定读写锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; +4.释放读写锁LOS_RwlockUnLock。 -- 如果没有任务阻塞于指定读写锁,则读写锁释放成功。 +- 如果有任务阻塞于指定读写锁,则唤醒被阻塞任务中优先级高的,该任务进入就绪态,并进行任务调度; -5. 删除读写锁LOS\_RwlockDestroy。 +- 如果没有任务阻塞于指定读写锁,则读写锁释放成功。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 读写锁不能在中断服务程序中使用。 ->- LiteOS-A内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得读写锁之后,应该尽快释放该锁。 ->- 持有读写锁的过程中,不得再调用LOS\_TaskPriSet等接口更改持有读写锁任务的优先级 +5. 删除读写锁LOS_RwlockDestroy。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 读写锁不能在中断服务程序中使用。 +> +> - LiteOS-A内核作为实时操作系统需要保证任务调度的实时性,尽量避免任务的长时间阻塞,因此在获得读写锁之后,应该尽快释放该锁。 +> +> - 持有读写锁的过程中,不得再调用LOS_TaskPriSet等接口更改持有读写锁任务的优先级 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-semaphore.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-semaphore.md index 69f8fae25a..fb78120cfa 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-semaphore.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-semaphore.md @@ -1,147 +1,114 @@ -# 信号量 +# 信号量 -- [基本概念](#section1577111168131) -- [运行机制](#section118423019134) -- [开发指导](#section01419503131) - - [接口说明](#section1232345431312) - - [开发流程](#section154261711141419) - - [编程实例](#section658135571417) - - [实例描述](#section125244411653) - - [编程示例](#section1742105514512) - - [结果验证](#section11297301617) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) + - [实例描述](#实例描述) + - [编程示例](#编程示例) + - [结果验证](#结果验证) - -## 基本概念 +## 基本概念 信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数,其值的含义分两种情况: -- 0,表示该信号量当前不可获取,因此可能存在正在等待该信号量的任务。 -- 正值,表示该信号量当前可被获取。 +- 0,表示该信号量当前不可获取,因此可能存在正在等待该信号量的任务。 + +- 正值,表示该信号量当前可被获取。 以同步为目的的信号量和以互斥为目的的信号量在使用上有如下不同: -- 用作互斥时,初始信号量计数值不为0,表示可用的共享资源个数。在需要使用共享资源前,先获取信号量,然后使用一个共享资源,使用完毕后释放信号量。这样在共享资源被取完,即信号量计数减至0时,其他需要获取信号量的任务将被阻塞,从而保证了共享资源的互斥访问。另外,当共享资源数为1时,建议使用二值信号量,一种类似于互斥锁的机制。 -- 用作同步时,初始信号量计数值为0。任务1获取信号量而阻塞,直到任务2或者某中断释放信号量,任务1才得以进入Ready或Running态,从而达到了任务间的同步。 +- 用作互斥时,初始信号量计数值不为0,表示可用的共享资源个数。在需要使用共享资源前,先获取信号量,然后使用一个共享资源,使用完毕后释放信号量。这样在共享资源被取完,即信号量计数减至0时,其他需要获取信号量的任务将被阻塞,从而保证了共享资源的互斥访问。另外,当共享资源数为1时,建议使用二值信号量,一种类似于互斥锁的机制。 + +- 用作同步时,初始信号量计数值为0。任务1因获取不到信号量而阻塞,直到任务2或者某中断释放信号量,任务1才得以进入Ready或Running态,从而达到了任务间的同步。 -## 运行机制 + +## 运行机制 **信号量控制块** ``` -/** - * 信号量控制块数据结构 - */ -typedef struct { - UINT16 semStat; /* 信号量状态 */ - UINT16 semType; /* 信号量类型 */ - UINT16 semCount; /* 信号量计数 */ - UINT16 semId; /* 信号量索引号 */ - LOS_DL_LIST semList; /* 挂接阻塞于该信号量的任务 */ -} LosSemCB; +/** * 信号量控制块数据结构*/typedefstruct { UINT16 semStat; /*信号量状态 */ UINT16 semType; /*信号量类型 */ UINT16 semCount; /*信号量计数 */ UINT16 semId; /*信号量索引号 */ LOS_DL_LIST semList; /*用于插入阻塞于信号量的任务 */} LosSemCB; ``` **信号量运作原理** 信号量允许多个任务在同一时刻访问共享资源,但会限制同一时刻访问此资源的最大任务数目。当访问资源的任务数达到该资源允许的最大数量时,会阻塞其他试图获取该资源的任务,直到有任务释放该信号量。 -- 信号量初始化 +- 信号量初始化 + 初始化时为配置的N个信号量申请内存(N值可以由用户自行配置,通过LOSCFG_BASE_IPC_SEM_LIMIT宏实现),并把所有信号量初始化成未使用,加入到未使用链表中供系统使用 - 初始化时为配置的N个信号量申请内存(N值可以由用户自行配置,通过LOSCFG\_BASE\_IPC\_SEM\_LIMIT宏实现),并把所有信号量初始化成未使用,加入到未使用链表中供系统使用 +- 信号量创建 + 从未使用的信号量链表中获取一个信号量,并设定初值。 -- 信号量创建 +- 信号量申请 + 若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 - 从未使用的信号量链表中获取一个信号量,并设定初值。 +- 信号量释放 + 若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 -- 信号量申请 +- 信号量删除 + 将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 - 若其计数器值大于0,则直接减1返回成功。否则任务阻塞,等待其它任务释放该信号量,等待的超时时间可设定。当任务被一个信号量阻塞时,将该任务挂到信号量等待任务队列的队尾。 +运行示意图如下图所示: -- 信号量释放 +**图1** 小型系统信号量运作示意图 +![zh-cn_image_0000001132774752](figures/zh-cn_image_0000001132774752.png) - 若没有任务等待该信号量,则直接将计数器加1返回。否则唤醒该信号量等待任务队列上的第一个任务。 -- 信号量删除 +## 开发指导 - 将正在使用的信号量置为未使用信号量,并挂回到未使用链表。 +### 接口说明 -运行示意图如下图所示: +**表1** 信号量模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 创建/删除信号量 | LOS_SemCreate | 创建信号量,返回信号量ID | +| | LOS_BinarySemCreate |创建二值信号量,其计数值最大为1| +| | LOS_SemDelete |删除指定的信号量| +| 申请/释放信号量 | LOS_SemPend | 申请指定的信号量,并设置超时时间 | +| | LOS_SemPost |释放指定的信号量| + + +### 开发流程 + +1. 创建信号量LOS_SemCreate,若要创建二值信号量则调用LOS_BinarySemCreate。 + +2. 申请信号量LOS_SemPend。 + +3. 释放信号量LOS_SemPost。 -**图 1** 信号量运作示意图 -![](figure/信号量运作示意图-22.png "信号量运作示意图-22") - -## 开发指导 - -### 接口说明 - -**表 1** 信号量模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

创建/删除信号量

-

LOS_SemCreate

-

创建信号量,返回信号量ID

-

LOS_BinarySemCreate

-

创建二值信号量,其计数值最大为1

-

LOS_SemDelete

-

删除指定的信号量

-

申请/释放信号量

-

LOS_SemPend

-

申请指定的信号量,并设置超时时间

-

LOS_SemPost

-

释放指定的信号量

-
- -### 开发流程 - -1. 创建信号量LOS\_SemCreate,若要创建二值信号量则调用LOS\_BinarySemCreate。 -2. 申请信号量LOS\_SemPend。 -3. 释放信号量LOS\_SemPost。 -4. 删除信号量LOS\_SemDelete。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->由于中断不能被阻塞,因此不能在中断中使用阻塞模式申请信号量。 - -### 编程实例 - -### 实例描述 +4. 删除信号量LOS_SemDelete。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 由于中断不能被阻塞,因此不能在中断中使用阻塞模式申请信号量。 + + +### 编程实例 + + +### 实例描述 本实例实现如下功能: -1. 测试任务ExampleSem创建一个信号量,锁任务调度,创建两个任务ExampleSemTask1、ExampleSemTask2, ExampleSemTask2优先级高于ExampleSemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务ExampleSem释放信号量。 -2. ExampleSemTask2得到信号量,被调度,然后任务休眠20Ticks,ExampleSemTask2延迟,ExampleSemTask1被唤醒。 -3. ExampleSemTask1定时阻塞模式申请信号量,等待时间为10Ticks,因信号量仍被ExampleSemTask2持有,ExampleSemTask1挂起,10Ticks后仍未得到信号量,ExampleSemTask1被唤醒,试图以永久阻塞模式申请信号量,ExampleSemTask1挂起。 -4. 20Tick后ExampleSemTask2唤醒, 释放信号量后,ExampleSemTask1得到信号量被调度运行,最后释放信号量。 -5. ExampleSemTask1执行完,400Ticks后任务ExampleSem被唤醒,执行删除信号量。 +1. 测试任务ExampleSem创建一个信号量,锁任务调度,创建两个任务ExampleSemTask1、ExampleSemTask2, ExampleSemTask2优先级高于ExampleSemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务ExampleSem释放信号量。 + +2. ExampleSemTask2得到信号量,被调度,然后任务休眠20Ticks,ExampleSemTask2延迟,ExampleSemTask1被唤醒。 -### 编程示例 +3. ExampleSemTask1定时阻塞模式申请信号量,等待时间为10Ticks,因信号量仍被ExampleSemTask2持有,ExampleSemTask1挂起,10Ticks后仍未得到信号量,ExampleSemTask1被唤醒,试图以永久阻塞模式申请信号量,ExampleSemTask1挂起。 + +4. 20Tick后ExampleSemTask2唤醒, 释放信号量后,ExampleSemTask1得到信号量被调度运行,最后释放信号量。 + +5. ExampleSemTask1执行完,400Ticks后任务ExampleSem被唤醒,执行删除信号量。 + + +### 编程示例 示例代码如下: @@ -258,7 +225,8 @@ UINT32 ExampleSem(VOID) } ``` -### 结果验证 + +### 结果验证 编译运行得到的结果为: @@ -270,4 +238,3 @@ ExampleSemTask1 timeout and try get sem g_semId wait forever. ExampleSemTask2 post sem g_semId. ExampleSemTask1 wait_forever and get sem g_semId. ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-mutex.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-mutex.md index ded2f23825..73d28d8a97 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-mutex.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-mutex.md @@ -1,64 +1,37 @@ -# 用户态快速互斥锁 +# 用户态快速互斥锁 -- [基本概念](#section643519912920) -- [运行机制](#section16834132502910) +- [基本概念](#基本概念) +- [运行机制](#运行机制) -## 基本概念 +## 基本概念 -Futex\(Fast userspace mutex,用户态快速互斥锁\)是内核提供的一种系统调用能力,通常作为基础组件与用户态的相关锁逻辑结合组成用户态锁,是一种用户态与内核态共同作用的锁,例如用户态mutex锁、barrier与cond同步锁、读写锁。其用户态部分负责锁逻辑,内核态部分负责锁调度。 +Futex(Fast userspace mutex,用户态快速互斥锁)是内核提供的一种系统调用能力,通常作为基础组件与用户态的相关锁逻辑结合组成用户态锁,是一种用户态与内核态共同作用的锁,例如用户态mutex锁、barrier与cond同步锁、读写锁。其用户态部分负责锁逻辑,内核态部分负责锁调度。 当用户态线程请求锁时,先在用户态进行锁状态的判断维护,若此时不产生锁的竞争,则直接在用户态进行上锁返回;反之,则需要进行线程的挂起操作,通过Futex系统调用请求内核介入来挂起线程,并维护阻塞队列。 当用户态线程释放锁时,先在用户态进行锁状态的判断维护,若此时没有其他线程被该锁阻塞,则直接在用户态进行解锁返回;反之,则需要进行阻塞线程的唤醒操作,通过Futex系统调用请求内核介入来唤醒阻塞队列中的线程。 -## 运行机制 + +## 运行机制 当用户态产生锁的竞争或释放需要进行相关线程的调度操作时,会触发Futex系统调用进入内核,此时会将用户态锁的地址传入内核,并在内核的Futex中以锁地址来区分用户态的每一把锁,因为用户态可用虚拟地址空间为1GiB,为了便于查找、管理,内核Futex采用哈希桶来存放用户态传入的锁。 -当前哈希桶共有80个,0\~63号桶用于存放私有锁(以虚拟地址进行哈希),64\~79号桶用于存放共享锁(以物理地址进行哈希),私有/共享属性通过用户态锁的初始化以及Futex系统调用入参确定。 +当前哈希桶共有80个,0~63号桶用于存放私有锁(以虚拟地址进行哈希),64~79号桶用于存放共享锁(以物理地址进行哈希),私有/共享属性通过用户态锁的初始化以及Futex系统调用入参确定。 -**图 1** Futex设计图 -![](figure/Futex设计图.jpg "Futex设计图") +**图1** Futex设计图 +![zh-cn_image_0000001127535690](figures/zh-cn_image_0000001127535690.jpg) -如图1,每个futex哈希桶中存放被futex\_list串联起来的哈希值相同的futex node,每个futex node对应一个被挂起的task,node中key值唯一标识一把用户态锁,具有相同key值的node被queue\_list串联起来表示被同一把锁阻塞的task队列。 +如图1,每个futex哈希桶中存放被futex_list串联起来的哈希值相同的futex node,每个futex node对应一个被挂起的task,node中key值唯一标识一把用户态锁,具有相同key值的node被queue_list串联起来表示被同一把锁阻塞的task队列。 Futex有以下三种操作: -**表 1** Futex模块接口 - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

设置线程等待

-

OsFutexWait

-

向Futex表中插入代表被阻塞的线程的node

-

唤醒被阻塞线程

-

OsFutexWake

-

唤醒一个被指定锁阻塞的线程

-

调整锁的地址

-

OsFutexRequeue

-

调整指定锁在Futex表中的位置

-
+**表1** Futex模块接口 ->![](../public_sys-resources/icon-note.gif) **说明:** ->Futex系统调用通常与用户态逻辑共同组成用户态锁,故推荐使用用户态POSIX接口的锁。 +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 设置线程等待 | OsFutexWait | 向Futex表中插入代表被阻塞的线程的node | +| 唤醒被阻塞线程 | OsFutexWake | 唤醒一个被指定锁阻塞的线程 | +| 调整锁的地址 | OsFutexRequeue | 调整指定锁在Futex表中的位置 | +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> Futex系统调用通常与用户态逻辑共同组成用户态锁,故推荐使用用户态POSIX接口的锁。 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-signal.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-signal.md index e99e4abe9a..52054b1086 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-signal.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans-user-signal.md @@ -1,86 +1,61 @@ -# 信号 +# 信号 -- [基本概念](#section172788254307) -- [运行机制](#section1249693812301) +- [基本概念](#基本概念) +- [运行机制](#运行机制) -## 基本概念 +## 基本概念 -信号\(signal\)是一种常用的进程间异步通信机制,用软件的方式模拟中断信号,当一个进程需要传递信息给另一个进程时,则会发送一个信号给内核,再由内核将信号传递至指定进程,而指定进程不必进行等待信号的动作。 +信号(signal)是一种常用的进程间异步通信机制,用软件的方式模拟中断信号,当一个进程需要传递信息给另一个进程时,则会发送一个信号给内核,再由内核将信号传递至指定进程,而指定进程不必进行等待信号的动作。 -## 运行机制 -信号的运作流程分为三个部分,如表1: - -**表 1** 信号的运作流程及相关接口(用户态接口) +## 运行机制 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

注册信号回调函数

-

signal

-

注册信号总入口及注册和去注册某信号的回调函数。

-

sigaction

-

功能同signal,但增加了信号发送相关的配置选项,目前仅支持SIGINFO结构体中的部分参数。

-

发送信号

-

kill

-

发送信号给某个进程或进程内发送消息给某线程,为某进程下的线程设置信号标志位。

-

pthread_kill

-

raise

-

alarm

-

abort

-

触发回调

-

-

由系统调用与中断触发,内核态与用户态切换前会先进入用户态指定函数并处理完相应回调函数,再回到原用户态程序继续运行。

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->信号机制为提供给用户态程序进程间通信的能力,故推荐使用上表1列出的用户态POSIX相关接口。 ->注册回调函数: ->``` ->void *signal(int sig, void (*func)(int))(int); ->``` ->a. 31 号信号,该信号用来注册该进程的回调函数处理入口,不可重复注册。 ->b. 0-30 号信号,该信号段用来注册与去注册回调函数。 ->注册回调函数: ->``` ->int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict); ->``` ->支持信号注册的配置修改和配置获取,目前仅支持SIGINFO的选项,SIGINFO内容见sigtimedwait接口内描述。 ->发送信号: ->a. 进程接收信号存在默认行为,单不支持POSIX标准所给出的STOP及COTINUE、COREDUMP功能。 ->b. 进程无法屏蔽SIGSTOP、SIGKILL、SIGCONT信号。 ->c. 某进程后被杀死后,若其父进程不回收该进程,其转为僵尸进程。 ->d. 进程接收到某信号后,直到该进程被调度后才会执行信号回调。 ->e. 进程结束后会发送SIGCHLD信号给父进程,该发送动作无法取消。 ->f. 无法通过信号唤醒处于DELAY状态的进程。 +信号的运作流程分为三个部分,如表1: +**表1** 信号的运作流程及相关接口(用户态接口) + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 注册信号回调函数 | signal | 注册信号总入口及注册和去注册某信号的回调函数。 | +| | sigaction |功能同signal,但增加了信号发送相关的配置选项,目前仅支持SIGINFO结构体中的部分参数。| +| 发送信号 | kill | 发送信号给某个进程或进程内发送消息给某线程,为某进程下的线程设置信号标志位。 | +| |pthread_kill|发送信号给某个进程或进程内发送消息给某线程,为某进程下的线程设置信号标志位。| +| |raise|发送信号给某个进程或进程内发送消息给某线程,为某进程下的线程设置信号标志位。| +| |alarm|发送信号给某个进程或进程内发送消息给某线程,为某进程下的线程设置信号标志位。| +| |abort|发送信号给某个进程或进程内发送消息给某线程,为某进程下的线程设置信号标志位。| +| 触发回调 | 无 | 由系统调用与中断触发,内核态与用户态切换前会先进入用户态指定函数并处理完相应回调函数,再回到原用户态程序继续运行。 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 信号机制为提供给用户态程序进程间通信的能力,故推荐使用上表1列出的用户态POSIX相关接口。 +> +> 注册回调函数: +> +> ``` +> void *signal(int sig, void (*func)(int))(int); +> ``` +> +> a. 31 号信号,该信号用来注册该进程的回调函数处理入口,不可重复注册。 +> +> b. 0-30 号信号,该信号段用来注册与去注册回调函数。 +> +> 注册回调函数: +> +> ``` +> int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict); +> ``` +> +> 支持信号注册的配置修改和配置获取,目前仅支持SIGINFO的选项,SIGINFO内容见sigtimedwait接口内描述。 +> +> 发送信号: +> +> a. 进程接收信号存在默认行为,单不支持POSIX标准所给出的STOP及COTINUE、COREDUMP功能。 +> +> b. 进程无法屏蔽SIGSTOP、SIGKILL、SIGCONT信号。 +> +> c. 某进程后被杀死后,若其父进程不回收该进程,其转为僵尸进程。 +> +> d. 进程接收到某信号后,直到该进程被调度后才会执行信号回调。 +> +> e. 进程结束后会发送SIGCHLD信号给父进程,该发送动作无法取消。 +> +> f. 无法通过信号唤醒处于DELAY状态的进程。 diff --git a/zh-cn/device-dev/kernel/kernel-small-basic-trans.md b/zh-cn/device-dev/kernel/kernel-small-basic-trans.md index 8650097970..02753beea7 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basic-trans.md +++ b/zh-cn/device-dev/kernel/kernel-small-basic-trans.md @@ -1,17 +1,16 @@ -# 内核通信机制 +# 内核通信机制 -- **[事件](kernel-small-basic-trans-event.md)** -- **[信号量](kernel-small-basic-trans-semaphore.md)** +- **[事件](kernel-small-basic-trans-event.md)** -- **[互斥锁](kernel-small-basic-trans-mutex.md)** +- **[信号量](kernel-small-basic-trans-semaphore.md)** -- **[消息队列](kernel-small-basic-trans-queue.md)** +- **[互斥锁](kernel-small-basic-trans-mutex.md)** -- **[读写锁](kernel-small-basic-trans-rwlock.md)** +- **[消息队列](kernel-small-basic-trans-queue.md)** -- **[用户态快速互斥锁](kernel-small-basic-trans-user-mutex.md)** - -- **[信号](kernel-small-basic-trans-user-signal.md)** +- **[读写锁](kernel-small-basic-trans-rwlock.md)** +- **[用户态快速互斥锁](kernel-small-basic-trans-user-mutex.md)** +- **[信号](kernel-small-basic-trans-user-signal.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-basics.md b/zh-cn/device-dev/kernel/kernel-small-basics.md index 5a2b5a5b7f..7cbf099b1f 100644 --- a/zh-cn/device-dev/kernel/kernel-small-basics.md +++ b/zh-cn/device-dev/kernel/kernel-small-basics.md @@ -1,17 +1,16 @@ -# 基础内核 +# 基础内核 -- **[中断及异常处理](kernel-small-basic-interrupt.md)** -- **[进程管理](kernel-small-basic-process.md)** +- **[中断及异常处理](kernel-small-basic-interrupt.md)** -- **[内存管理](kernel-small-basic-memory.md)** +- **[进程管理](kernel-small-basic-process.md)** -- **[内核通信机制](kernel-small-basic-trans.md)** +- **[内存管理](kernel-small-basic-memory.md)** -- **[时间管理](kernel-small-basic-time.md)** +- **[内核通信机制](kernel-small-basic-trans.md)** -- **[软件定时器](kernel-small-basic-softtimer.md)** - -- **[原子操作](kernel-small-basic-atomic.md)** +- **[时间管理](kernel-small-basic-time.md)** +- **[软件定时器](kernel-small-basic-softtimer.md)** +- **[原子操作](kernel-small-basic-atomic.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-new.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-new.md index 0f50e073d9..a3ee6348aa 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-new.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-new.md @@ -1,11 +1,11 @@ -# 适配新的文件系统 +# 适配新的文件系统 -- [基本概念](#section19480121811422) -- [适配Mount接口](#section147051940104212) -- [适配Lookup接口](#section11930181394317) -- [适配总结和注意事项](#section5617183014319) +- [基本概念](#基本概念) +- [适配Mount接口](#适配mount接口) +- [适配Lookup接口](#适配lookup接口) +- [适配总结和注意事项](#适配总结和注意事项) -## 基本概念 +## 基本概念 所谓对接VFS层,其实就是指实现VFS层定义的若干接口函数,可根据文件系统的特点和需要适配其中部分接口。一般情况下,支持文件读写,最小的文件系统适配看起来是这样的: @@ -28,11 +28,13 @@ struct VnodeOps g_yourFsVnodeOps = { FSMAP_ENTRY(yourfs_fsmap, "your fs name", g_yourFsMountOps, TRUE, TRUE); // 注册文件系统 ``` ->![](../public_sys-resources/icon-note.gif) **说明:** ->1. open和close接口不是必须要实现的接口,因为这两个接口是对文件的操作,对下层的文件系统一般是不感知的,只有当要适配的文件系统需要在open和close时做一些特别的操作时,才需要实现。 ->2. 适配文件系统,对基础知识的要求较高,适配者需要对要适配的文件系统的原理和实现具有深刻的理解,本节中不会事无巨细地介绍相关的基础知识,如果您在适配的过程中遇到疑问,建议参考kernel/liteos\_a/fs目录下已经适配好的文件系统的代码,可能就会豁然开朗。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 1. open和close接口不是必须要实现的接口,因为这两个接口是对文件的操作,对下层的文件系统一般是不感知的,只有当要适配的文件系统需要在open和close时做一些特别的操作时,才需要实现。 +> +> 2. 适配文件系统,对基础知识的要求较高,适配者需要对要适配的文件系统的原理和实现具有深刻的理解,本节中不会事无巨细地介绍相关的基础知识,如果您在适配的过程中遇到疑问,建议参考kernel/liteos_a/fs目录下已经适配好的文件系统的代码,可能就会豁然开朗。 -## 适配Mount接口 + +## 适配Mount接口 Mount是文件系统第一个被调用的接口,该接口一般会读取驱动的参数,根据配置对文件系统的进行初始化,最后生成文件系统的root节点。Mount接口的定义如下: @@ -55,7 +57,6 @@ struct Mount { 第三个参数const void \*data是mount命令传入的数据,可以根据文件系统的需要处理。 下面以JFFS2为例,详细看一下mount接口是如何适配的: - ``` int VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data) { @@ -127,10 +128,12 @@ const struct MountOps jffs_operations = { 总结: -1. 首先从驱动节点中获取需要的私有信息。 -2. 根据私有信息,生成文件系统的根节点。 +1. 首先从驱动节点中获取需要的私有信息。 + +2. 根据私有信息,生成文件系统的根节点。 -## 适配Lookup接口 + +## 适配Lookup接口 Lookup是查找文件的接口,它的函数原型是: @@ -201,23 +204,30 @@ int VfsJffs2Lookup(struct Vnode *parentVnode, const char *path, int len, struct 总结: -1. 从父节点获取私有数据; -2. 根据私有信息查询到目标文件的私有数据; -3. 通过目标文件的私有数据生成目标Vnode。 +1. 从父节点获取私有数据; + +2. 根据私有信息查询到目标文件的私有数据; -## 适配总结和注意事项 +3. 通过目标文件的私有数据生成目标Vnode。 + + +## 适配总结和注意事项 通过上面两个接口的适配,其实可以发现一个规律,不管是什么接口,基本都遵循下面的适配步骤: -1. 通过入参的vnode获取文件系统所需的私有数据。 -2. 使用私有数据完成接口的功能。 -3. 将结果包装成vnode或接口要求的其他返回格式,返回给上层。 +1. 通过入参的vnode获取文件系统所需的私有数据。 -核心的逻辑其实在使用私有数据完成接口的功能,这些接口都是些文件系统的通用功能,文件系统在移植前本身应该都有相应实现,所以关键是归纳总结出文件系统所需的私有数据是什么,将其存储在vnode中,供之后使用。一般情况下,私有数据的内容是可以唯一定位到文件在存储介质上位置的信息,大部分文件系统本身都会有类似数据结构可以直接使用,比如JFFS2的inode数据结构。 +2. 使用私有数据完成接口的功能。 ->![](../public_sys-resources/icon-caution.gif) **注意:** ->1. 访问文件时,不一定会调用文件系统中的Lookup接口,仅在上层的路径缓存失效时才会调用到。 ->2. 通过VfsHashGet找到了已经存在的Vnode,不要直接将其作为结果返回,其储存的信息可能已经失效,请更新相应字段后再返回。 ->3. Vnode会根据内存占用在后台自动释放,需要持久保存的信息,不要只保存在Vnode中。 ->4. Reclaim接口在Vnode释放时会自动调用,请在这个接口中释放私有数据中的资源。 +3. 将结果包装成vnode或接口要求的其他返回格式,返回给上层。 + +核心的逻辑其实在使用私有数据完成接口的功能,这些接口都是些文件系统的通用功能,文件系统在移植前本身应该都有相应实现,所以关键是归纳总结出文件系统所需的私有数据是什么,将其存储在vnode中,供之后使用。一般情况下,私有数据的内容是可以唯一定位到文件在存储介质上位置的信息,大部分文件系统本身都会有类似数据结构可以直接使用,比如JFFS2的inode数据结构。 +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** +> 1. 访问文件时,不一定会调用文件系统中的Lookup接口,仅在上层的路径缓存失效时才会调用到。 +> +> 2. 通过VfsHashGet找到了已经存在的Vnode,不要直接将其作为结果返回,其储存的信息可能已经失效,请更新相应字段后再返回。 +> +> 3. Vnode会根据内存占用在后台自动释放,需要持久保存的信息,不要只保存在Vnode中。 +> +> 4. Reclaim接口在Vnode释放时会自动调用,请在这个接口中释放私有数据中的资源。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-fat.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-fat.md index b9e1636f26..c7e5b7b67d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-fat.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-fat.md @@ -1,30 +1,32 @@ -# FAT +# FAT -- [基本概念](#section621393911385) -- [运行机制](#section10796155213381) -- [开发指导](#section144094483919) - - [开发流程](#section139086116394) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [开发流程](#开发流程) +## 基本概念 -## 基本概念 - -FAT文件系统是File Allocation Table(文件配置表)的简称,主要包括DBR区、FAT区、DATA区三个区域。其中,FAT区各个表项记录存储设备中对应簇的信息,包括簇是否被使用、文件下一个簇的编号、是否文件结尾等。FAT文件系统有FAT12、FAT16、FAT32等多种格式,其中,12、16、32表示对应格式中FAT表项的字节数,它们同时也限制了文件系统中的最大文件大小。FAT文件系统支持多种介质,特别在可移动存储介质(U盘、SD卡、移动硬盘等)上广泛使用,使嵌入式设备和Windows、Linux等桌面系统保持很好的兼容性,方便用户管理操作文件。 +FAT文件系统是File Allocation Table(文件配置表)的简称,主要包括DBR区、FAT区、DATA区三个区域。其中,FAT区各个表项记录存储设备中对应簇的信息,包括簇是否被使用、文件下一个簇的编号、是否文件结尾等。FAT文件系统有FAT12、FAT16、FAT32等多种格式,其中,12、16、32表示对应格式中FAT表项的比特数,它们同时也限制了文件系统中的最大文件大小。FAT文件系统支持多种介质,特别在可移动存储介质(U盘、SD卡、移动硬盘等)上广泛使用,使嵌入式设备和Windows、Linux等桌面系统保持很好的兼容性,方便用户管理操作文件。 OpenHarmony内核支持FAT12、FAT16与FAT32三种格式的FAT文件系统,具有代码量小、资源占用小、可裁切、支持多种物理介质等特性,并且与Windows、Linux等系统保持兼容,支持多设备、多分区识别等功能。OpenHarmony内核支持硬盘多分区,可以在主分区以及逻辑分区上创建FAT文件系统。 -## 运行机制 + +## 运行机制 FAT文件系统设计与物理布局的相关文档在互联网上非常丰富,请开发者自行搜索查看。 OpenHarmony LiteOS-A内核通过Bcache提升FAT文件系统性能,Bcache是block cache的简称。当发生读写时,Bcache会缓存读写扇区附近的扇区,以减少I/O次数,提高性能。Bcache的基本缓存单位为block,每个block大小一致(默认有28个block,每个block缓存64个扇区的数据)。当Bcache脏块率(脏扇区数/总扇区数)达到阈值时,会触发写回;如果脏块率未达到阈值,则不会将缓存数据写回磁盘。如果需要保证数据写回,开发者应当调用sync和fsync触发写回。FAT文件系统的部分接口也会触发写回操作(如close、umount等),但开发者不应当基于这些接口触发写回。 -## 开发指导 -### 开发流程 +## 开发指导 + + +### 开发流程 基本使用流程为挂载→操作→卸载。 -SD卡或MMC的设备名为mmcblk\[x\]p\[y\],文件系统类型为“vfat”。 +SD卡或MMC的设备名为mmcblk[x]p[y],文件系统类型为“vfat”。 示例: @@ -32,14 +34,19 @@ SD卡或MMC的设备名为mmcblk\[x\]p\[y\],文件系统类型为“vfat”。 mount("/dev/mmcblk0p0", "/mnt", "vfat", 0, NULL); ``` ->![](../public_sys-resources/icon-note.gif) **说明:** ->- FAT文件系统中,单个文件不能大于4 GiB。 ->- 当有两个SD卡插槽时,卡0和卡1不固定,先插上的为卡0,后插上的为卡1。 ->- 当多分区功能打开,存在多分区的情况下,卡0注册的设备节点/dev/mmcblk0\(主设备\)和/dev/mmcblk0p0\(次设备\)是同一个设备,禁止对主设备进行操作。 ->- 为避免SD卡使用异常或内存泄漏,SD卡使用过程中拔卡,用户必须先关闭正处于打开状态的文件和目录,并且卸载挂载节点。 ->- 在format操作之前,需要首先umount挂载点。 ->- 当Bcache功能生效时,需要注意: -> - 当mount函数的入参为MS\_NOSYNC时,FAT不会主动将cache的内容写回存储器件。FAT的如下接口(open、close、 unlink、rename、mkdir、rmdir、truncate)不会自动进行sync操作,速度可以提升,但是需要上层主动调用sync来进行数据同步,否则可能会数据丢失。 -> - Bcache有定时写回功能。在menuconfig中开启LOSCFG\_FS\_FAT\_CACHE\_SYNC\_THREAD选项,打开后系统会创建一个任务定时写回Bcache中的数据,默认每隔5秒检查Bcache中脏数据块比例,超过80%时进行sync操作,将Bcache中的脏数据全部写回磁盘。任务优先级、刷新时间间隔以及脏数据块比例的阈值可分别通过接口LOS\_SetSyncThreadPrio、 LOS\_SetSyncThreadInterval和LOS\_SetDirtyRatioThreshold设置。 -> - 当前cache的默认大小为28个块,每个块64个扇区。 - +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - FAT文件系统中,单个文件不能大于4 GiB。 +> +> - 当有两个SD卡插槽时,卡0和卡1不固定,先插上的为卡0,后插上的为卡1。 +> +> - 当多分区功能打开,存在多分区的情况下,卡0注册的设备节点/dev/mmcblk0(主设备)和/dev/mmcblk0p0(次设备)是同一个设备,禁止对主设备进行操作。 +> +> - 为避免SD卡使用异常或内存泄漏,SD卡使用过程中拔卡,用户必须先关闭正处于打开状态的文件和目录,并且卸载挂载节点。 +> +> - 在format操作之前,需要首先umount挂载点。 +> +> - 当Bcache功能生效时,需要注意: +> - 当mount函数的入参为MS_NOSYNC时,FAT不会主动将cache的内容写回存储器件。FAT的如下接口(open、close、 unlink、rename、mkdir、rmdir、truncate)不会自动进行sync操作,速度可以提升,但是需要上层主动调用sync来进行数据同步,否则可能会数据丢失。 +> +> - Bcache有定时写回功能。在menuconfig中开启LOSCFG_FS_FAT_CACHE_SYNC_THREAD选项,打开后系统会创建一个任务定时写回Bcache中的数据,默认每隔5秒检查Bcache中脏数据块比例,超过80%时进行sync操作,将Bcache中的脏数据全部写回磁盘。任务优先级、刷新时间间隔以及脏数据块比例的阈值可分别通过接口LOS_SetSyncThreadPrio、 LOS_SetSyncThreadInterval和LOS_SetDirtyRatioThreshold设置。 +> - 当前cache的默认大小为28个块,每个块64个扇区。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md index 8992d47a2f..150b222646 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.md @@ -1,28 +1,34 @@ -# JFFS2 +# JFFS2 -- [基本概念](#section11411110155919) -- [运行机制](#section23911025195913) -- [开发指导](#section179711119014) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) -## 基本概念 +## 基本概念 JFFS2是Journalling Flash File System Version 2(日志文件系统)的缩写,是针对MTD设备的日志型文件系统。 OpenHarmony内核的JFFS2主要应用于NOR FLASH闪存,其特点是:可读写、支持数据压缩、提供了崩溃/掉电安全保护、提供“写平衡”支持等。闪存与磁盘介质有许多差异,直接将磁盘文件系统运行在闪存设备上,会导致性能和安全问题。为解决这一问题,需要实现一个特别针对闪存的文件系统,JFFS2就是这样一种文件系统。 -## 运行机制 + +## 运行机制 关于JFFS2文件系统的在存储设备上的实际物理布局,及文件系统本身的规格说明,请参考JFFS2的[官方规格说明文档](https://sourceware.org/jffs2/)。 这里仅列举几个对开发者和使用者会有一定影响的JFFS2的重要机制/特征: -1. Mount机制及速度问题:按照JFFS2的设计,所有的文件会按照一定的规则,切分成大小不等的节点,依次存储到flash设备上。在mount流程中,需要获取到所有的这些节点信息并缓存到内存里。因此,mount速度和flash设备的大小和文件数量的多少成线性比例关系。这是JFFS2的原生设计问题,对于mount速度非常介意的用户,可以在内核编译时开启“Enable JFFS2 SUMMARY”选项,可以极大提升mount的速度。这个选项的原理是将mount需要的信息提前存储到flash上,在mount时读取并解析这块内容,使得mount的速度变得相对恒定。这个实际是空间换时间的做法,会消耗8%左右的额外空间。 -2. 写平衡的支持:由于flash设备的物理属性,读写都只能基于某个特定大小的“块”进行,为了防止某些特定的块磨损过于严重,在JFFS2中需要对写入的块进行“平衡”的管理,保证所有的块的写入次数都是相对平均的,进而保证flash设备的整体寿命。 -3. GC\(garbage collection\)机制:在JFFS2里发生删除动作,实际的物理空间并不会立即释放,而是由独立的GC线程来做空间整理和搬移等GC动作,和所有的GC机制一样,在JFFS2里的GC会对瞬时的读写性能有一定影响。另外,为了有空间能被用来做空间整理,JFFS2会对每个分区预留3块左右的空间,这个空间是用户不可见的。 -4. 压缩机制:当前使用的JFFS2,底层会自动的在每次读/写时进行解压/压缩动作,实际IO的大小和用户请求读写的大小并不会一样。特别在写入时,不能通过写入大小来和flash剩余空间的大小来预估写入一定会成功或者失败。 -5. 硬链接机制:JFFS2支持硬链接,底层实际占用的物理空间是一份,对于同一个文件的多个硬连接,并不会增加空间的占用;反之,只有当删除了所有的硬链接时,实际物理空间才会被释放。 +1. Mount机制及速度问题:按照JFFS2的设计,所有的文件会按照一定的规则,切分成大小不等的节点,依次存储到flash设备上。在mount流程中,需要获取到所有的这些节点信息并缓存到内存里。因此,mount速度和flash设备的大小和文件数量的多少成线性比例关系。这是JFFS2的原生设计问题,对于mount速度非常介意的用户,可以在内核编译时开启“Enable JFFS2 SUMMARY”选项,可以极大提升mount的速度。这个选项的原理是将mount需要的信息提前存储到flash上,在mount时读取并解析这块内容,使得mount的速度变得相对恒定。这个实际是空间换时间的做法,会消耗8%左右的额外空间。 + +2. 写平衡的支持:由于flash设备的物理属性,读写都只能基于某个特定大小的“块”进行,为了防止某些特定的块磨损过于严重,在JFFS2中需要对写入的块进行“平衡”的管理,保证所有的块的写入次数都是相对平均的,进而保证flash设备的整体寿命。 + +3. GC(garbage collection)机制:在JFFS2里发生删除动作,实际的物理空间并不会立即释放,而是由独立的GC线程来做空间整理和搬移等GC动作,和所有的GC机制一样,在JFFS2里的GC会对瞬时的读写性能有一定影响。另外,为了有空间能被用来做空间整理,JFFS2会对每个分区预留3块左右的空间,这个空间是用户不可见的。 + +4. 压缩机制:当前使用的JFFS2,底层会自动的在每次读/写时进行解压/压缩动作,实际IO的大小和用户请求读写的大小并不会一样。特别在写入时,不能通过写入大小来和flash剩余空间的大小来预估写入一定会成功或者失败。 -## 开发指导 +5. 硬链接机制:JFFS2支持硬链接,底层实际占用的物理空间是一份,对于同一个文件的多个硬连接,并不会增加空间的占用;反之,只有当删除了所有的硬链接时,实际物理空间才会被释放。 + + +## 开发指导 对于基于JFFS2和nor flash的开发,总体而言,与其他文件系统非常相似,因为都有VFS层来屏蔽了具体文件系统的差异,对外接口体现也都是标准的POSIX接口。 @@ -36,46 +42,19 @@ OpenHarmony内核的JFFS2主要应用于NOR FLASH闪存,其特点是:可读 ./mkfs.jffs2 -d rootfs/ -o rootfs.jffs2 ``` -**表 1** 指令含义表(更详细的介绍可以通过mkfs.jffs2 --help来查看) - - - - - - - - - - - - - - - - - - - - - - -

指令

-

含义

-

-s

-

页大小,不指定默认为4KiB

-

-e

-

eraseblock大小,不指定默认为64KiB

-

-p

-

镜像大小。在镜像文件后面,用0xFF填充至指定大小,不指定则用0xFF填充至eraseblock对齐。

-

-d

-

要制作成文件系统镜像的源目录

-

-o

-

要制成的镜像名称

-
+**表1** 指令含义表(更详细的介绍可以通过mkfs.jffs2 --help来查看) + +| 指令 | 含义 | +| -------- | -------- | +| -s | 页大小,不指定默认为4KiB | +| -e | eraseblock大小,不指定默认为64KiB | +| -p | 镜像大小。在镜像文件后面,用0xFF填充至指定大小,不指定则用0xFF填充至eraseblock对齐。 | +| -d | 要制作成文件系统镜像的源目录 | +| -o | 要制成的镜像名称 | **挂载JFFS2分区** -调用int mount\(const char \*source, const char \*target, const char \*filesystemtype, unsigned long mountflags, const void \*data\)函数实现设备节点和挂载点的挂载。 +调用int mount(const char \*source, const char \*target, const char \*filesystemtype, unsigned long mountflags, const void \*data)函数实现设备节点和挂载点的挂载。 该函数有五个参数,第一个参数const char \*source,表示设备节点,第二个参数const char \*target表示挂载点。第三个参数 const char \*filesystemtype,表示文件系统类型。 @@ -98,7 +77,7 @@ mount OK **卸载JFFS2分区** -调用int umount\(const char \*target\)函数卸载分区,只需要正确给出挂载点即可。 +调用int umount(const char \*target)函数卸载分区,只需要正确给出挂载点即可。 运行命令: @@ -112,4 +91,3 @@ OHOS # umount /jffs1 OHOS # umount /jffs1 umount ok ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md index d9bd6ff7ca..92dd330d58 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-nfs.md @@ -1,24 +1,26 @@ -# NFS +# NFS -- [基本概念](#section195414101464) -- [运行机制](#section165621321194618) -- [开发指导](#section7454935184611) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) -## 基本概念 +## 基本概念 NFS是Network File System(网络文件系统)的缩写。它最大的功能是可以通过网络,让不同的机器、不同的操作系统彼此分享其他用户的文件。因此,用户可以简单地将它看做是一个文件系统服务,在一定程度上相当于Windows环境下的共享文件夹。 -## 运行机制 + +## 运行机制 OpenHarmony LiteOS-A内核的NFS文件系统指的是NFS的客户端,NFS客户端能够将远程的NFS服务端分享的目录挂载到本地的机器中,运行程序和共享文件,但不占用当前系统的存储空间,在本地端的机器看起来,远程服务端的目录就好像是自己的一个磁盘一样。 -## 开发指导 -1. 搭建NFS服务器 +## 开发指导 + +1. 搭建NFS服务器 这里以Ubuntu操作系统为例,说明服务器端设置步骤。 -- 安装NFS服务器软件。 +- 安装NFS服务器软件。 设置好Ubuntu系统的下载源,保证网络连接好的情况下执行: @@ -26,14 +28,14 @@ OpenHarmony LiteOS-A内核的NFS文件系统指的是NFS的客户端,NFS客户 sudo apt-get install nfs-kernel-server ``` -- 创建用于挂载的目录并设置完全权限 +- 创建用于挂载的目录并设置完全权限 ``` mkdir -p /home/sqbin/nfs sudo chmod 777 /home/sqbin/nfs ``` -- 设置和启动NFS server。 +- 设置和启动NFS server。 修改NFS配置文件/etc/exports,添加如下一行: @@ -55,17 +57,17 @@ sudo /etc/init.d/nfs-kernel-server start sudo /etc/init.d/nfs-kernel-server restart ``` -1. 设置单板为NFS客户端 +1. 设置单板为NFS客户端 本指导中的NFS客户端指运行OpenHarmony内核的设备。 -- 硬件连接设置。 +- 硬件连接设置。 OpenHarmony内核设备连接到NFS服务器的网络。设置两者IP,使其处于同一网段。比如,设置NFS服务器的IP为10.67.212.178/24,设置OpenHarmony内核设备IP为10.67.212.3/24,注意:此IP为内网私有IP地址,用户使用时有差异,以用户实际IP为准。 OpenHarmony内核设备上的IP信息可通过ifconfig命令查看。 -- 启动网络,确保单板到NFS服务器之间的网络通畅。 +- 启动网络,确保单板到NFS服务器之间的网络通畅。 启动以太网或者其他类型网络,使用ping命令检查到服务器的网络是否通畅。 @@ -96,20 +98,26 @@ Mount nfs finished. 该命令将服务器10.67.212.178上的/home/sqbin/nfs目录挂载到OpenHarmony内核设备上的/nfs上。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->本例默认nfs server已经配置可用,即示例中服务器10.67.212.178上的/home/sqbin/nfs已配置可访问。 ->mount命令的格式为: ->``` ->mount nfs ->``` ->其中“SERVER\_IP”表示服务器的IP地址;“SERVER\_PATH”表示服务器端NFS共享目录路径;“CLIENT\_PATH”表示设备上的NFS路径,“nfs”表示客户端要挂载的路径,可以根据自己需要替换。 ->如果不想有NFS访问权限限制,可以在Linux命令行将NFS根目录权限设置成777: ->``` ->chmod -R 777 /home/sqbin/nfs ->``` ->至此,NFS客户端设置完毕。NFS文件系统已成功挂载。 - -1. 利用NFS共享文件 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 本例默认nfs server已经配置可用,即示例中服务器10.67.212.178上的/home/sqbin/nfs已配置可访问。 +> +> mount命令的格式为: +> +> ``` +> mount nfs +> ``` +> +> 其中“SERVER_IP”表示服务器的IP地址;“SERVER_PATH”表示服务器端NFS共享目录路径;“CLIENT_PATH”表示设备上的NFS路径,“nfs”表示客户端要挂载的路径,可以根据自己需要替换。 +> +> 如果不想有NFS访问权限限制,可以在Linux命令行将NFS根目录权限设置成777: +> +> ``` +> chmod -R 777 /home/sqbin/nfs +> ``` +> +> 至此,NFS客户端设置完毕。NFS文件系统已成功挂载。 + +1. 利用NFS共享文件 在NFS服务器下新建目录dir,并保存。在OpenHarmony内核下运行ls命令: @@ -125,10 +133,9 @@ Directory /nfs: drwxr-xr-x 0 u:0 g:0 dir ``` -可见,刚刚在NFS服务器上新建的dir目录已同步到客户端\(OpenHarmony内核系统\)的/nfs目录,两者保持同步。 - -同样地,在客户端\(OpenHarmony内核系统\)上创建文件和目录,在NFS服务器上也可以访问,读者可自行体验。 +可见,刚刚在NFS服务器上新建的dir目录已同步到客户端(OpenHarmony内核系统)的/nfs目录,两者保持同步。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->目前,NFS客户端仅支持NFS v3部分规范要求,因此对于规范支持不全的服务器,无法完全兼容。在开发测试过程中,建议使用Linux的NFS server,其对NFS支持很完善。 +同样地,在客户端(OpenHarmony内核系统)上创建文件和目录,在NFS服务器上也可以访问,读者可自行体验。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 目前,NFS客户端仅支持NFS v3部分规范要求,因此对于规范支持不全的服务器,无法完全兼容。在开发测试过程中,建议使用Linux的NFS server,其对NFS支持很完善。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md index d84d28862e..b266c65f59 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-procfs.md @@ -1,24 +1,26 @@ -# Procfs +# Procfs -- [基本概念](#section146801917174017) -- [运行机制](#section479762916408) -- [开发指导](#section1221174524014) - - [编程实例](#section52016575401) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 procfs是进程文件系统的简称,是一种虚拟文件系统,他用文件的形式,展示进程或其他系统信息。相比调用接口的方式获取信息,以文件操作的方式获取系统信息更为方便。 -## 运行机制 + +## 运行机制 OpenHarmony内核中,procfs在开机时会自动挂载到/proc目录下,仅支持内核模块创建文件节点来提供查询服务。 -## 开发指导 + +## 开发指导 procfs文件的创建无法使用一般的文件系统接口,需要使用ProcMkdir接口创建目录,使用CreateProcEntry接口创建文件。文件节点功能的开发就是实现read和write函数的钩子挂到CreateProcEntry创建的文件中。当用户使用读写procfs的文件时,就会调用到钩子函数来实现自定义的功能。 -### 编程实例 + +### 编程实例 下面我们以创建/proc/hello/world文件为例,实现如下功能: @@ -82,4 +84,3 @@ OHOS # Hello World! OHOS # echo "yo" > /proc/hello/world OHOS # your input is: yo ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md index 5aba9e3f23..81e69a70d9 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-ramfs.md @@ -1,18 +1,20 @@ -# Ramfs +# Ramfs -- [基本概念](#section9507151014420) -- [运行机制](#section1859711263447) -- [开发指导](#section163554380448) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) -## 基本概念 +## 基本概念 RAMFS是一个可动态调整大小的基于RAM的文件系统。RAMFS没有后备存储源。向RAMFS中进行的文件写操作也会分配目录项和页缓存,但是数据并不写回到任何其他存储介质上,掉电后数据丢失。 -## 运行机制 + +## 运行机制 RAMFS文件系统把所有的文件都放在 RAM 中,所以读/写操作发生在RAM中,可以用RAMFS来存储一些临时性或经常要修改的数据,例如/tmp和/var目录,这样既避免了对存储器的读写损耗,也提高了数据读写速度。 -## 开发指导 + +## 开发指导 挂载: @@ -58,7 +60,7 @@ rmdir(pathname) umount("/dev/shm") ``` ->![](../public_sys-resources/icon-caution.gif) **注意:** ->- RAMFS只能挂载一次,一次挂载成功后,后面不能继续挂载到其他目录。 ->- RAMFS属于调测功能,默认配置为关闭,正式产品中不要使用该功能。 - +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** +> - RAMFS只能挂载一次,一次挂载成功后,后面不能继续挂载到其他目录。 +> +> - RAMFS属于调测功能,默认配置为关闭,正式产品中不要使用该功能。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support.md index 045acb736f..36eda90509 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support.md @@ -1,13 +1,12 @@ -# 支持的文件系统 +# 支持的文件系统 -- **[FAT](kernel-small-bundles-fs-support-fat.md)** -- **[JFFS2](kernel-small-bundles-fs-support-jffs2.md)** +- **[FAT](kernel-small-bundles-fs-support-fat.md)** -- **[NFS](kernel-small-bundles-fs-support-nfs.md)** +- **[JFFS2](kernel-small-bundles-fs-support-jffs2.md)** -- **[Ramfs](kernel-small-bundles-fs-support-ramfs.md)** - -- **[Procfs](kernel-small-bundles-fs-support-procfs.md)** +- **[NFS](kernel-small-bundles-fs-support-nfs.md)** +- **[Ramfs](kernel-small-bundles-fs-support-ramfs.md)** +- **[Procfs](kernel-small-bundles-fs-support-procfs.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-virtual.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-virtual.md index f9eb12494b..e1c3227d81 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs-virtual.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs-virtual.md @@ -1,667 +1,112 @@ -# 虚拟文件系统 +# 虚拟文件系统 -- [基本概念](#section1253851143520) -- [运行机制](#section14915913123510) -- [开发指导](#section1759563620358) - - [接口说明](#section17865142133511) - - [开发流程](#section64113023616) - - [编程实例](#section236041883618) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 VFS(Virtual File System)是文件系统的虚拟层,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层,为用户提供统一的类Unix文件操作接口。由于不同类型的文件系统接口不统一,若系统中有多个文件系统类型,访问不同的文件系统就需要使用不同的非标准接口。而通过在系统中添加VFS层,提供统一的抽象接口,屏蔽了底层异构类型的文件系统的差异,使得访问文件系统的系统调用不用关心底层的存储介质和文件系统类型,提高开发效率。 OpenHarmony内核中,VFS框架是通过在内存中的树结构来实现的,树的每个结点都是一个Vnode结构体,父子结点的关系以PathCache结构体保存。VFS最主要的两个功能是: -- 查找节点。 -- 统一调用(标准)。 +- 查找节点。 -## 运行机制 +- 统一调用(标准)。 -当前,VFS层主要通过函数指针,实现对不同文件系统类型调用不同接口实现标准接口功能;通过Vnode与PathCache机制,提升路径搜索以及文件访问的性能;通过挂载点管理进行分区管理;通过FD管理进行进程间FD隔离等。下面将对这些机制进行简要说明。 -1. 文件系统操作函数指针:VFS层通过函数指针的形式,将统一调用按照不同的文件系统类型,分发到不同文件系统中进行底层操作。各文件系统的各自实现一套Vnode操作、挂载点操作以及文件操作接口,并以函数指针结构体的形式存储于对应Vnode、挂载点、File结构体中,实现VFS层对下访问。 -2. Vnode:Vnode是具体文件或目录在VFS层的抽象封装,它屏蔽了不同文件系统的差异,实现资源的统一管理。Vnode节点主要有以下几种类型: +## 运行机制 - - 挂载点:挂载具体文件系统,如/、/storage - - 设备节点:/dev目录下的节点,对应于一个设备,如/dev/mmcblk0 - - 文件/目录节点:对应于具体文件系统中的文件/目录,如/bin/init +当前,VFS层主要通过函数指针,实现对不同文件系统类型调用不同接口实现标准接口功能;通过Vnode与PathCache机制,提升路径搜索以及文件访问的性能;通过挂载点管理进行分区管理;通过FD管理进行进程间FD隔离等。下面将对这些机制进行简要说明。 - Vnode通过哈希以及LRU机制进行管理。当系统启动后,对文件或目录的访问会优先从哈希链表中查找Vnode缓存,若缓存没有命中,则并从对应文件系统中搜索目标文件或目录,创建并缓存对应的Vnode。当Vnode缓存数量达到上限时,将淘汰长时间未访问的Vnode,其中挂载点Vnode与设备节点Vnode不参与淘汰。当前系统中Vnode的规格默认为512,该规格可以通过LOSCFG\_MAX\_VNODE\_SIZE进行配置。Vnode数量过大,会造成较大的内存占用;Vnode数量过少,则会造成搜索性能下降。下图展示了Vnode的创建流程。 +1. 文件系统操作函数指针:VFS层通过函数指针的形式,将统一调用按照不同的文件系统类型,分发到不同文件系统中进行底层操作。各文件系统的各自实现一套Vnode操作、挂载点操作以及文件操作接口,并以函数指针结构体的形式存储于对应Vnode、挂载点、File结构体中,实现VFS层对下访问。 - **图 1** Vnode创建流程 - ![](figure/Vnode创建流程.png "Vnode创建流程") +2. Vnode:Vnode是具体文件或目录在VFS层的抽象封装,它屏蔽了不同文件系统的差异,实现资源的统一管理。Vnode节点主要有以下几种类型: + - 挂载点:挂载具体文件系统,如/、/storage + - 设备节点:/dev目录下的节点,对应于一个设备,如/dev/mmcblk0 + - 文件/目录节点:对应于具体文件系统中的文件/目录,如/bin/init + Vnode通过哈希以及LRU机制进行管理。当系统启动后,对文件或目录的访问会优先从哈希链表中查找Vnode缓存,若缓存没有命中,则并从对应文件系统中搜索目标文件或目录,创建并缓存对应的Vnode。当Vnode缓存数量达到上限时,将淘汰长时间未访问的Vnode,其中挂载点Vnode与设备节点Vnode不参与淘汰。当前系统中Vnode的规格默认为512,该规格可以通过LOSCFG_MAX_VNODE_SIZE进行配置。Vnode数量过大,会造成较大的内存占用;Vnode数量过少,则会造成搜索性能下降。下图展示了Vnode的创建流程。 -1. PathCache:PathCache是路径缓存,它通过哈希表存储,利用父节点Vnode的地址和子节点的文件名,可以从PathCache中快速查找到子节点对应的Vnode。下图展示了文件/目录的查找流程。 + **图1** Vnode创建流程 + ![zh-cn_image_0000001127393126](figures/zh-cn_image_0000001127393126.png) - **图 2** 文件查找流程 - ![](figure/文件查找流程.png "文件查找流程") +1. PathCache:PathCache是路径缓存,它通过哈希表存储,利用父节点Vnode的地址和子节点的文件名,可以从PathCache中快速查找到子节点对应的Vnode。下图展示了文件/目录的查找流程。 + **图2** 文件查找流程 + ![zh-cn_image_0000001175795145](figures/zh-cn_image_0000001175795145.png) +1. PageCache:PageCache是内核中文件的缓存。当前PageCache仅支持缓存二进制文件,在初次访问文件时通过mmap映射到内存中,下次再访问时,直接从PageCache中读取,可以提升对同一个文件的读写速度。另外基于PageCache可实现以文件为基底的进程间通信。 -1. PageCache:PageCache是内核中文件的缓存。当前PageCache仅支持缓存二进制文件,在初次访问文件时通过mmap映射到内存中,下次再访问时,直接从PageCache中读取,可以提升对同一个文件的读写速度。另外基于PageCache可实现以文件为基底的进程间通信。 -2. fd管理:Fd(File Descriptor)是描述一个打开的文件/目录的描述符。当前OpenHarmony内核中,fd总规格为896,分为三种类型: +2. fd管理:Fd(File Descriptor)是描述一个打开的文件/目录的描述符。当前OpenHarmony内核中,fd总规格为896,分为三种类型: + - 普通文件描述符,系统总规格为512。 + - Socket描述符,系统总规格为128。 + - 消息队列描述符,系统总规格为256。 - - 普通文件描述符,系统总规格为512。 - - Socket描述符,系统总规格为128。 - - 消息队列描述符,系统总规格为256。 + 当前OpenHarmony内核中,对不同进程中的fd进行隔离,即进程只能访问本进程的fd,所有进程的fd映射到全局fd表中进行统一分配管理。进程的文件描述符最多有256个。 - 当前OpenHarmony内核中,对不同进程中的fd进行隔离,即进程只能访问本进程的fd,所有进程的fd映射到全局fd表中进行统一分配管理。进程的文件描述符最多有256个。 +3. 挂载点管理:当前OpenHarmony内核中,对系统中所有挂载点通过链表进行统一管理。挂载点结构体中,记录了该挂载分区内的所有Vnode。当分区卸载时,会释放分区内的所有Vnode。 -3. 挂载点管理:当前OpenHarmony内核中,对系统中所有挂载点通过链表进行统一管理。挂载点结构体中,记录了该挂载分区内的所有Vnode。当分区卸载时,会释放分区内的所有Vnode。 -## 开发指导 +## 开发指导 -### 接口说明 + +### 接口说明 当前文件系统支持的接口如下表所示,表格中的“×”代表对应文件系统不支持该接口。 -**表 1** 支持接口列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

分类

-

接口名称

-

功能

-

FAT

-

JFFS2

-

NFS

-

TMPFS

-

PROCFS

-

文件操作

-

open

-

打开文件

-

-

-

-

-

-

read/pread/readv/preadv

-

读取文件

-

-

-

-

-

-

write/pwrite/writev/pwritev

-

写入文件

-

-

-

-

-

-

lseek

-

设置文件偏移

-

-

-

-

-

×

-

close

-

关闭文件

-

-

-

-

-

-

unlink

-

删除文件

-

-

-

-

-

×

-

fstat

-

查询文件信息

-

-

-

-

-

-

fallocate

-

预分配大小

-

-

×

-

×

-

×

-

×

-

truncate

-

文件截断

-

-

-

×

-

-

×

-

link

-

创建硬链接

-

×

-

-

×

-

×

-

×

-

symlink

-

创建软链接

-

-

-

×

-

×

-

×

-

readlink

-

读取软链接

-

-

-

×

-

×

-

×

-

dup

-

复制文件句柄

-

-

-

-

-

-

fsync

-

文件内容刷入设备

-

-

×

-

×

-

×

-

×

-

ioctl

-

设备控制

-

×

-

×

-

×

-

-

×

-

fcntl

-

文件控制操作

-

-

-

-

-

-

目录操作

-

mkdir

-

创建目录

-

-

-

-

-

×

-

opendir

-

打开目录

-

-

-

-

-

-

readdir

-

读取目录

-

-

-

-

-

-

closedir

-

关闭目录

-

-

-

-

-

-

telldir

-

获取目录偏移

-

-

-

-

-

-

seekdir

-

设置目录偏移

-

-

-

-

-

-

rewinddir

-

重置目录偏移

-

-

-

-

-

×

-

scandir

-

读取目录数据

-

-

-

-

-

-

rmdir

-

删除目录

-

-

-

-

-

×

-

chdir

-

切换当前路径

-

-

-

-

-

-

getcwd

-

获取当前路径

-

-

-

-

-

-

realpath

-

相对/绝对路径转换

-

-

-

-

-

-

rename

-

文件/目录重命名

-

-

-

-

-

×

-

chmod

-

修改文件/目录属性

-

-

-

×

-

×

-

×

-

chown

-

修改文件/目录所有者

-

-

-

×

-

×

-

×

-

stat/lstat

-

查询文件/目录信息

-

-

-

-

-

-

access

-

查询文件/目录访问权限

-

-

-

-

-

-

分区操作

-

mount

-

挂载分区

-

-

-

-

-

-

umount

-

卸载分区

-

-

-

-

-

×

-

statfs

-

查询挂载分区信息

-

-

-

-

-

-

format

-

格式化分区

-

-

×

-

×

-

×

-

×

-

sync

-

分区内容刷入设备

-

-

×

-

×

-

×

-

×

-
- -### 开发流程 +**表1** 支持接口列表 + +| 分类 | 接口**名称** | 功能 | FAT | JFFS2 | NFS | TMPFS | PROCFS | +| -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| 文件操作 | open | 打开文件 | √ | √ | √ | √ | √ | +| read/pread/readv/preadv | 读取文件 | √ | √ | √ | √ | √ | +| write/pwrite/writev/pwritev | 写入文件 | √ | √ | √ | √ | √ | +| lseek | 设置文件偏移 | √ | √ | √ | √ | × | +| close | 关闭文件 | √ | √ | √ | √ | √ | +| unlink | 删除文件 | √ | √ | √ | √ | × | +| fstat | 查询文件信息 | √ | √ | √ | √ | √ | +| fallocate | 预分配大小 | √ | × | × | × | × | +| truncate | 文件截断 | √ | √ | × | √ | × | +| link | 创建硬链接 | × | √ | × | × | × | +| symlink | 创建软链接 | √ | √ | × | × | × | +| readlink | 读取软链接 | √ | √ | × | × | × | +| dup | 复制文件句柄 | √ | √ | √ | √ | √ | +| fsync | 文件内容刷入设备 | √ | × | × | × | × | +| ioctl | 设备控制 | × | × | × | √ | × | +| fcntl | 文件控制操作 | √ | √ | √ | √ | √ | +| 目录操作 | mkdir | 创建目录 | √ | √ | √ | √ | × | +| opendir | 打开目录 | √ | √ | √ | √ | √ | +| readdir | 读取目录 | √ | √ | √ | √ | √ | +| closedir | 关闭目录 | √ | √ | √ | √ | √ | +| telldir | 获取目录偏移 | √ | √ | √ | √ | √ | +| seekdir | 设置目录偏移 | √ | √ | √ | √ | √ | +| rewinddir | 重置目录偏移 | √ | √ | √ | √ | × | +| scandir | 读取目录数据 | √ | √ | √ | √ | √ | +| rmdir | 删除目录 | √ | √ | √ | √ | × | +| chdir | 切换当前路径 | √ | √ | √ | √ | √ | +| getcwd | 获取当前路径 | √ | √ | √ | √ | √ | +| realpath | 相对/绝对路径转换 | √ | √ | √ | √ | √ | +| rename | 文件/目录重命名 | √ | √ | √ | √ | × | +| chmod | 修改文件/目录属性 | √ | √ | × | × | × | +| chown | 修改文件/目录所有者 | √ | √ | × | × | × | +| stat/lstat | 查询文件/目录信息 | √ | √ | √ | √ | √ | +| access | 查询文件/目录访问权限 | √ | √ | √ | √ | √ | +| 分区操作 | mount | 挂载分区 | √ | √ | √ | √ | √ | +| umount | 卸载分区 | √ | √ | √ | √ | × | +| statfs | 查询挂载分区信息 | √ | √ | √ | √ | √ | +| format | 格式化分区 | √ | × | × | × | × | +| sync | 分区内容刷入设备 | √ | × | × | × | × | + + +### 开发流程 文件系统的主要开发流程包括挂载/卸载分区,以及系列目录/文件操作。 -### 编程实例 + +### 编程实例 代码实现如下: @@ -784,11 +229,13 @@ int main(void) } ``` + **结果验证** + 编译运行得到的结果为: + ``` Hello OpenHarmony! ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-fs.md b/zh-cn/device-dev/kernel/kernel-small-bundles-fs.md index 17837bc1ed..0c7137b5eb 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-fs.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-fs.md @@ -1,16 +1,18 @@ -# 文件系统 +# 文件系统 文件系统(File System,或者简称FS),是操作系统中输入输出的一种主要形式,主要负责和内外部的存储设备交互。 + 文件系统对上通过C库提供的POSIX标准的操作接口,具体可以参考C库的API文档说明。对下,通过内核态的VFS虚拟层,屏蔽了各个具体文件系统的差异。基本架构如下: -**图 1** 文件系统的总体结构 -![](figure/文件系统的总体结构.png "文件系统的总体结构") -- **[虚拟文件系统](kernel-small-bundles-fs-virtual.md)** +**图1** 文件系统的总体结构 +![zh-cn_image_0000001125101908](figures/zh-cn_image_0000001125101908.png) + -- **[支持的文件系统](kernel-small-bundles-fs-support.md)** +- **[虚拟文件系统](kernel-small-bundles-fs-virtual.md)** -- **[适配新的文件系统](kernel-small-bundles-fs-new.md)** +- **[支持的文件系统](kernel-small-bundles-fs-support.md)** +- **[适配新的文件系统](kernel-small-bundles-fs-new.md)** diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-ipc.md b/zh-cn/device-dev/kernel/kernel-small-bundles-ipc.md index a44f54d389..21f61cb7ef 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-ipc.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-ipc.md @@ -1,70 +1,36 @@ -# 轻量级进程间通信 +# 轻量级进程间通信 -- [基本概念](#section1980994712918) -- [运行机制](#section849811592918) -- [开发指导](#section17571315171017) - - [接口说明](#section725022011103) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) - -## 基本概念 +## 基本概念 LiteIPC是OpenHarmony LiteOS-A内核提供的一种新型IPC(Inter-Process Communication,即进程间通信)机制,不同于传统的System V IPC机制,LiteIPC主要是为RPC(Remote Procedure Call,即远程过程调用)而设计的,而且是通过设备文件的方式对上层提供接口的,而非传统的API函数方式。 LiteIPC中有两个主要概念,一个是ServiceManager,另一个是Service。整个系统只能有一个ServiceManager,而Service可以有多个。ServiceManager有两个主要功能:一是负责Service的注册和注销,二是负责管理Service的访问权限(只有有权限的任务(Task)可以向对应的Service发送IPC消息)。 -## 运行机制 + +## 运行机制 首先将需要接收IPC消息的任务通过ServiceManager注册成为一个Service,然后通过ServiceManager为该Service任务配置访问权限,即指定哪些任务可以向该Service任务发送IPC消息。LiteIPC的核心思想就是在内核态为每个Service任务维护一个IPC消息队列,该消息队列通过LiteIPC设备文件向上层用户态程序分别提供代表收取IPC消息的读操作和代表发送IPC消息的写操作。 -## 开发指导 -### 接口说明 +## 开发指导 + -**表 1** LiteIPC模块接口(仅LiteOS-A内部使用) +### 接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

模块初始化

-

OsLiteIpcInit

-

初始化LiteIPC模块

-

IPC消息内存池

-

LiteIpcPoolInit

-

初始化进程的IPC消息内存池

-

LiteIpcPoolReInit

-

重新初始化进程的IPC消息内存池

-

LiteIpcPoolDelete

-

释放进程的IPC消息内存池

-

Service管理

-

LiteIpcRemoveServiceHandle

-

删除指定的Service

-
+**表1** LiteIPC模块接口(仅LiteOS-A内部使用) ->![](../public_sys-resources/icon-note.gif) **说明:** ->LiteIPC模块接口都只在LiteOS-A内部使用。 +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 模块初始化 | OsLiteIpcInit | 初始化LiteIPC模块 | +| IPC消息内存池 | LiteIpcPoolInit | 初始化进程的IPC消息内存池 | +| | LiteIpcPoolReInit |重新初始化进程的IPC消息内存池| +| | LiteIpcPoolDelete |释放进程的IPC消息内存池| +| Service管理 | LiteIpcRemoveServiceHandle | 删除指定的Service | +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> LiteIPC模块接口都只在LiteOS-A内部使用。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-linking.md b/zh-cn/device-dev/kernel/kernel-small-bundles-linking.md index f2cc18b372..d0d9e4768a 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-linking.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-linking.md @@ -1,82 +1,61 @@ -# 动态加载与链接 +# 动态加载与链接 -- [基本概念](#section208951139453) -- [运行机制](#section14140155320511) -- [开发指导](#section133501496612) - - [接口说明](#section874113201669) - - [开发流程](#section196712561563) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) - -## 基本概念 +## 基本概念 OpenHarmony系统的动态加载与链接机制主要是由内核加载器以及动态链接器构成,内核加载器用于加载应用程序以及动态链接器,动态链接器用于加载应用程序所依赖的共享库,并对应用程序和共享库进行符号重定位。与静态链接相比,动态链接是将应用程序与动态库推迟到运行时再进行链接的一种机制。 **动态链接的优势:** -1. 多个应用程序可以共享一份代码,最小加载单元为页,相对静态链接可以节约磁盘和内存空间。 -2. 共享库升级时,理论上将旧版本的共享库覆盖即可(共享库中的接口向下兼容),无需重新链接。 -3. 加载地址可以进行随机化处理,防止攻击,保证安全性。 +1. 多个应用程序可以共享一份代码,最小加载单元为页,相对静态链接可以节约磁盘和内存空间。 + +2. 共享库升级时,理论上将旧版本的共享库覆盖即可(共享库中的接口向下兼容),无需重新链接。 + +3. 加载地址可以进行随机化处理,防止攻击,保证安全性。 + + +## 运行机制 + +**图1** 动态加载流程 +![zh-cn_image_0000001133104502](figures/zh-cn_image_0000001133104502.png) + +1. 内核将应用程序ELF文件的PT_LOAD段信息映射至进程空间。对于ET_EXEC类型的文件,根据PT_LOAD段中p_vaddr进行固定地址映射;对于ET_DYN类型(位置无关的可执行程序,通过编译选项“-fPIE”得到)的文件,内核通过mmap接口选择base基址进行映射(load_addr = base + p_vaddr)。 -## 运行机制 +2. 若应用程序是静态链接的(静态链接不支持编译选项“-fPIE”),设置堆栈信息后跳转至应用程序ELF文件中e_entry指定的地址并运行;若程序是动态链接的,应用程序ELF文件中会有PT_INTERP段,保存动态链接器的路径信息(ET_DYN类型)。musl的动态链接器是libc-musl.so的一部分,libc-musl.so的入口即动态链接器的入口。内核通过mmap接口选择base基址进行映射,设置堆栈信息后跳转至base + e_entry(该e_entry为动态链接器的入口)地址并运行动态链接器。 -**图 1** 动态加载流程 -![](figure/动态加载流程.png "动态加载流程") +3. 动态链接器自举并查找应用程序依赖的所有共享库并对导入符号进行重定位,最后跳转至应用程序的e_entry(或base + e_entry),开始运行应用程序。 -1. 内核将应用程序ELF文件的PT\_LOAD段信息映射至进程空间。对于ET\_EXEC类型的文件,根据PT\_LOAD段中p\_vaddr进行固定地址映射;对于ET\_DYN类型(位置无关的可执行程序,通过编译选项“-fPIE”得到)的文件,内核通过mmap接口选择base基址进行映射(load\_addr = base + p\_vaddr)。 -2. 若应用程序是静态链接的(静态链接不支持编译选项“-fPIE”),设置堆栈信息后跳转至应用程序ELF文件中e\_entry指定的地址并运行;若程序是动态链接的,应用程序ELF文件中会有PT\_INTERP段,保存动态链接器的路径信息(ET\_DYN类型)。musl的动态链接器是libc-musl.so的一部分,libc-musl.so的入口即动态链接器的入口。内核通过mmap接口选择base基址进行映射,设置堆栈信息后跳转至base + e\_entry(该e\_entry为动态链接器的入口)地址并运行动态链接器。 -3. 动态链接器自举并查找应用程序依赖的所有共享库并对导入符号进行重定位,最后跳转至应用程序的e\_entry(或base + e\_entry),开始运行应用程序。 +**图2** 程序执行流程 +![zh-cn_image_0000001133264664](figures/zh-cn_image_0000001133264664.png) -**图 2** 程序执行流程 -![](figure/程序执行流程.png "程序执行流程") +1. 加载器与链接器调用mmap映射PT_LOAD段; -1. 加载器与链接器调用mmap映射PT\_LOAD段; -2. 内核调用map\_pages接口查找并映射pagecache已有的缓存; -3. 程序执行时,内存若无所需代码或数据时触发缺页中断,将elf文件内容读入内存,并将该内存块加入pagecache; -4. 将已读入文件内容的内存块与虚拟地址区间做映射; -5. 程序继续执行; +2. 内核调用map_pages接口查找并映射pagecache已有的缓存; -至此,程序将在不断地缺页中断中执行。 +3. 程序执行时,虚拟内存区间若无具体的物理内存做映射,系统将触发缺页中断,将elf文件内容读入物理内存,并将该内存块加入pagecache; -## 开发指导 +4. 将已读入文件内容的物理内存与虚拟地址区间做映射; -### 接口说明 +5. 程序继续执行; -LOS\_DoExecveFile -**函数原型:** +## 开发指导 -INT32 LOS\_DoExecveFile\(const CHAR \*fileName, CHAR \* const \*argv, CHAR \* const \*envp\); -**函数功能**:根据fileName执行一个新的用户程序。 +### 接口说明 -**参数说明:** +**表1** 内核加载器模块接口 - - - - - - - - - - - - - - - -

参数

-

描述

-

fileName

-

二进制可执行文件名,可以是路径名。

-

argv

-

程序执行所需的参数序列,以NULL结尾。无需参数时填入NULL。

-

envp

-

程序执行所需的新的环境变量序列,以NULL结尾。无需新的环境变量时填入NULL。

-
+| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 模块初始化 | LOS_DoExecveFile | 根据输入的参数执行指定的用户程序 | -### 开发流程 -LOS\_DoExecveFile接口一般由用户通过execve系列接口利用系统调用机制调用创建新的进程,内核不能直接调用该接口启动新进程。 +### 开发流程 +LOS_DoExecveFile接口一般由用户通过exec家族函数利用系统调用机制创建新的进程,内核不能直接调用该接口启动新进程。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-share.md b/zh-cn/device-dev/kernel/kernel-small-bundles-share.md index 89aaeb511f..326d2761fa 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-share.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-share.md @@ -1,25 +1,27 @@ -# 虚拟动态共享库 +# 虚拟动态共享库 -- [基本概念](#section174577181688) -- [运行机制](#section546363114810) +- [基本概念](#基本概念) +- [运行机制](#运行机制) -## 基本概念 +## 基本概念 VDSO(Virtual Dynamic Shared Object,虚拟动态共享库)相对于普通的动态共享库,区别在于其so文件不保存在文件系统中,存在于系统镜像中,由内核在运行时确定并提供给应用程序,故称为虚拟动态共享库。 OpenHarmony系统通过VDSO机制实现上层用户态程序可以快速读取内核相关数据的一种通道方法,可用于实现部分系统调用的加速,也可用于实现非系统敏感数据(硬件配置、软件配置)的快速读取。 -## 运行机制 + +## 运行机制 VDSO其核心思想就是内核看护一段内存,并将这段内存映射(只读)进用户态应用程序的地址空间,应用程序通过链接vdso.so后,将某些系统调用替换为直接读取这段已映射的内存从而避免系统调用达到加速的效果。 VDSO总体可分为数据页与代码页两部分: -- 数据页提供内核映射给用户进程的内核时数据; -- 代码页提供屏蔽系统调用的主要逻辑; +- 数据页提供内核映射给用户进程的内核时数据; + +- 代码页提供屏蔽系统调用的主要逻辑; -**图 1** VDSO系统设计 -![](figure/VDSO系统设计.jpg "VDSO系统设计") +**图1** VDSO系统设计 +![zh-cn_image_0000001173586763](figures/zh-cn_image_0000001173586763.jpg) 如图1所示,当前VDSO机制有以下几个主要步骤: @@ -33,7 +35,7 @@ VDSO总体可分为数据页与代码页两部分: ⑤ 用户程序在动态链接时对VDSO的符号进行绑定; -⑥ 当用户程序进行特定系统调用时(例如clock\_gettime\(CLOCK\_REALTIME\_COARSE, &ts\)),VDSO代码页会将其拦截; +⑥ 当用户程序进行特定系统调用时(例如clock_gettime(CLOCK_REALTIME_COARSE, &ts)),VDSO代码页会将其拦截; ⑦ VDSO代码页将正常系统调用转为直接读取映射好的VDSO数据页; @@ -41,7 +43,7 @@ VDSO总体可分为数据页与代码页两部分: ⑨ 将从VDSO数据页获取到的数据作为结果返回给用户程序; ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 当前VDSO机制支持LibC库clock\_gettime接口的CLOCK\_REALTIME\_COARSE与CLOCK\_MONOTONIC\_COARSE功能,clock\_gettime接口的使用方法详见POSIX标准。用户调用C库接口clock\_gettime\(CLOCK\_REALTIME\_COARSE, &ts\)或者clock\_gettime\(CLOCK\_MONOTONIC\_COARSE, &ts\)即可使用VDSO机制。 ->- 使用VDSO机制得到的时间精度会与系统tick中断的精度保持一致,适用于对时间没有高精度要求且短时间内会高频触发clock\_gettime或gettimeofday系统调用的场景,若有高精度要求,不建议采用VDSO机制。 - +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 当前VDSO机制支持LibC库clock_gettime接口的CLOCK_REALTIME_COARSE与CLOCK_MONOTONIC_COARSE功能,clock_gettime接口的使用方法详见POSIX标准。用户调用C库接口clock_gettime(CLOCK_REALTIME_COARSE, &ts)或者clock_gettime(CLOCK_MONOTONIC_COARSE, &ts)即可使用VDSO机制。 +> +> - 使用VDSO机制得到的时间精度会与系统tick中断的精度保持一致,适用于对时间没有高精度要求且短时间内会高频触发clock_gettime或gettimeofday系统调用的场景,若有高精度要求,不建议采用VDSO机制。 diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles-system.md b/zh-cn/device-dev/kernel/kernel-small-bundles-system.md index b2118533c9..da585ebaa0 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles-system.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles-system.md @@ -1,176 +1,176 @@ -# 系统调用 +# 系统调用 -- [基本概念](#section889710401734) -- [运行机制](#section195177541314) -- [开发指导](#section193492047135419) - - [开发流程](#section7165741122210) - - [编程实例](#section107131418224) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 OpenHarmony LiteOS-A实现了用户态与内核态的区分隔离,用户态程序不能直接访问内核资源,而系统调用则为用户态程序提供了一种访问内核资源、与内核进行交互的通道。 -## 运行机制 + +## 运行机制 如图1所示,用户程序通过调用System API(系统API,通常是系统提供的POSIX接口)进行内核资源访问与交互请求,POSIX接口内部会触发SVC/SWI异常,完成系统从用户态到内核态的切换,然后对接到内核的Syscall Handler(系统调用统一处理接口)进行参数解析,最终分发至具体的内核处理函数。 +**图1** 系统调用示意图 +![zh-cn_image_0000001132856572](figures/zh-cn_image_0000001132856572.png) +Syscall Handler的具体实现在kernel/liteos_a/syscall/los_syscall.c中OsArmA32SyscallHandle函数,在进入系统软中断异常时会调用此函数,并且按照kernel/liteos_a/syscall/syscall_lookup.h中的清单进行系统调用的入参解析,执行各系统调用最终对应的内核处理函数。 -**图 1** 系统调用示意图 -![](figure/系统调用示意图.png "系统调用示意图") +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 系统调用提供基础的用户态程序与内核的交互功能,不建议开发者直接使用系统调用接口,推荐使用内核提供的对外POSIX接口,若需要新增系统调用接口,详见开发指导。 +> +> - 内核向用户态提供的系统调用接口清单详见kernel/liteos_a/syscall/syscall_lookup.h,内核相应的系统调用对接函数清单详见kernel/liteos_a/syscall/los_syscall.h。 -Syscall Handler的具体实现在kernel/liteos\_a/syscall/los\_syscall.c中OsArmA32SyscallHandle函数,在进入系统软中断异常时会调用此函数,并且按照kernel/liteos\_a/syscall/syscall\_lookup.h中的清单进行系统调用的入参解析,执行各系统调用最终对应的内核处理函数。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 系统调用提供基础的用户态程序与内核的交互功能,不建议开发者直接使用系统调用接口,推荐使用内核提供的对外POSIX接口,若需要新增系统调用接口,详见开发指导。 ->- 内核向用户态提供的系统调用接口清单详见kernel/liteos\_a/syscall/syscall\_lookup.h,内核相应的系统调用对接函数清单详见kernel/liteos\_a/syscall/los\_syscall.h。 +## 开发指导 -## 开发指导 -### 开发流程 +### 开发流程 新增系统调用的典型开发流程如下: -1. 在LibC库中确定并添加新增的系统调用号。 -2. 在LibC库中新增用户态的函数接口声明及实现。 -3. 在内核系统调用头文件中确定并添加新增的系统调用号及对应内核处理函数的声明。 -4. 在内核中新增该系统调用对应的内核处理函数。 +1. 在LibC库中确定并添加新增的系统调用号。 + +2. 在LibC库中新增用户态的函数接口声明及实现。 + +3. 在内核系统调用头文件中确定并添加新增的系统调用号及对应内核处理函数的声明。 + +4. 在内核中新增该系统调用对应的内核处理函数。 -### 编程实例 + +### 编程实例 **示例代码**: -1. 在LibC库syscall.h.in中新增系统调用号 - - 如下所示,其中\_\_NR\_new\_syscall\_sample为新增系统调用号: - - ``` - ... - /* 当前现有的系统调用清单 */ - /* OHOS customized syscalls, not compatible with ARM EABI */ - #define __NR_OHOS_BEGIN 500 - #define __NR_pthread_set_detach (__NR_OHOS_BEGIN + 0) - #define __NR_pthread_join (__NR_OHOS_BEGIN + 1) - #define __NR_pthread_deatch (__NR_OHOS_BEGIN + 2) - #define __NR_creat_user_thread (__NR_OHOS_BEGIN + 3) - #define __NR_processcreat (__NR_OHOS_BEGIN + 4) - #define __NR_processtart (__NR_OHOS_BEGIN + 5) - #define __NR_printf (__NR_OHOS_BEGIN + 6) - #define __NR_dumpmemory (__NR_OHOS_BEGIN + 13) - #define __NR_mkfifo (__NR_OHOS_BEGIN + 14) - #define __NR_mqclose (__NR_OHOS_BEGIN + 15) - #define __NR_realpath (__NR_OHOS_BEGIN + 16) - #define __NR_format (__NR_OHOS_BEGIN + 17) - #define __NR_shellexec (__NR_OHOS_BEGIN + 18) - #define __NR_ohoscapget (__NR_OHOS_BEGIN + 19) - #define __NR_ohoscapset (__NR_OHOS_BEGIN + 20) - - #define __NR_new_syscall_sample (__NR_OHOS_BEGIN + 21) /* 新增的系统调用号 __NR_new_syscall_sample:521 */ - - #define __NR_syscallend (__NR_OHOS_BEGIN + 22) - ... - ``` - -2. 在LibC库中新增用户态接口的声明与实现 - - ``` - #include "stdio_impl.h" - #include "syscall.h" - ... - /* 新增系统调用用户态的接口实现 */ - void newSyscallSample(int num) - { - printf("user mode: num = %d\n", num); - __syscall(SYS_new_syscall_sample, num); - return; - } - ``` - -3. 在内核系统调用头文件中新增系统调用号 - - 如下所示,在third\_party/musl/porting/liteos\_a/kernel/include/bits/syscall.h文件中,\_\_NR\_new\_syscall\_sample为新增系统调用号。 - - ``` - ... - /* 当前现有的系统调用清单 */ - /* OHOS customized syscalls, not compatible with ARM EABI */ - #define __NR_OHOS_BEGIN 500 - #define __NR_pthread_set_detach (__NR_OHOS_BEGIN + 0) - #define __NR_pthread_join (__NR_OHOS_BEGIN + 1) - #define __NR_pthread_deatch (__NR_OHOS_BEGIN + 2) - #define __NR_creat_user_thread (__NR_OHOS_BEGIN + 3) - #define __NR_processcreat (__NR_OHOS_BEGIN + 4) - #define __NR_processtart (__NR_OHOS_BEGIN + 5) - #define __NR_printf (__NR_OHOS_BEGIN + 6) - #define __NR_dumpmemory (__NR_OHOS_BEGIN + 13) - #define __NR_mkfifo (__NR_OHOS_BEGIN + 14) - #define __NR_mqclose (__NR_OHOS_BEGIN + 15) - #define __NR_realpath (__NR_OHOS_BEGIN + 16) - #define __NR_format (__NR_OHOS_BEGIN + 17) - #define __NR_shellexec (__NR_OHOS_BEGIN + 18) - #define __NR_ohoscapget (__NR_OHOS_BEGIN + 19) - #define __NR_ohoscapset (__NR_OHOS_BEGIN + 20) - - #define __NR_new_syscall_sample (__NR_OHOS_BEGIN + 21) /* 新增的系统调用号 __NR_new_syscall_sample:521 */ - - #define __NR_syscallend (__NR_OHOS_BEGIN + 22) - ... - ``` - - 在kernel/liteos\_a/syscall/syscall\_lookup.h中,增加一行SYSCALL\_HAND\_DEF\(\_\_NR\_new\_syscall\_sample, SysNewSyscallSample, void, ARG\_NUM\_1\): - - ``` - ... - /* 当前现有的系统调用清单 */ - SYSCALL_HAND_DEF(__NR_chown, SysChown, int, ARG_NUM_3) - SYSCALL_HAND_DEF(__NR_chown32, SysChown, int, ARG_NUM_3) - #ifdef LOSCFG_SECURITY_CAPABILITY - SYSCALL_HAND_DEF(__NR_ohoscapget, SysCapGet, UINT32, ARG_NUM_2) - SYSCALL_HAND_DEF(__NR_ohoscapset, SysCapSet, UINT32, ARG_NUM_1) - #endif - /* 新增系统调用 */ - SYSCALL_HAND_DEF(__NR_new_syscall_sample, SysNewSyscallSample, void, ARG_NUM_1) - ... - ``` - -4. 在内核中新增内核该系统调用对应的处理函数 - - 如下所示,在kernel/liteos\_a/syscall/los\_syscall.h中,SysNewSyscallSample为新增系统调用的内核处理函数声明: - - ``` - ... - /* 当前现有的系统调用内核处理函数声明清单 */ - extern int SysClockSettime64(clockid_t clockID, const struct timespec64 *tp); - extern int SysClockGettime64(clockid_t clockID, struct timespec64 *tp); - extern int SysClockGetres64(clockid_t clockID, struct timespec64 *tp); - extern int SysClockNanoSleep64(clockid_t clk, int flags, const struct timespec64 *req, struct timespec64 *rem); - extern int SysTimerGettime64(timer_t timerID, struct itimerspec64 *value); - extern int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec64 *value, struct itimerspec64 *oldValue); - /* 新增的系统调用内核处理函数声明 */ - extern void SysNewSyscallSample(int num); - ... - ``` - - 新增的系统调用的内核处理函数实现如下: - - ``` - include "los_printf.h" - ... - /* 新增系统调用内核处理函数的实现 */ - void SysNewSyscallSample(int num) - { - PRINTK("kernel mode: num = %d\n", num); +1. 在LibC库syscall.h.in中新增系统调用号 + 如下所示,其中__NR_new_syscall_sample为新增系统调用号: + ``` + ... + /* 当前现有的系统调用清单 */ + /* OHOS customized syscalls, not compatible with ARM EABI */ + #define __NR_OHOS_BEGIN 500 + #define __NR_pthread_set_detach (__NR_OHOS_BEGIN + 0) + #define __NR_pthread_join (__NR_OHOS_BEGIN + 1) + #define __NR_pthread_deatch (__NR_OHOS_BEGIN + 2) + #define __NR_creat_user_thread (__NR_OHOS_BEGIN + 3) + #define __NR_processcreat (__NR_OHOS_BEGIN + 4) + #define __NR_processtart (__NR_OHOS_BEGIN + 5) + #define __NR_printf (__NR_OHOS_BEGIN + 6) + #define __NR_dumpmemory (__NR_OHOS_BEGIN + 13) + #define __NR_mkfifo (__NR_OHOS_BEGIN + 14) + #define __NR_mqclose (__NR_OHOS_BEGIN + 15) + #define __NR_realpath (__NR_OHOS_BEGIN + 16) + #define __NR_format (__NR_OHOS_BEGIN + 17) + #define __NR_shellexec (__NR_OHOS_BEGIN + 18) + #define __NR_ohoscapget (__NR_OHOS_BEGIN + 19) + #define __NR_ohoscapset (__NR_OHOS_BEGIN + 20) + + #define __NR_new_syscall_sample (__NR_OHOS_BEGIN + 21) /* 新增的系统调用号 __NR_new_syscall_sample:521 */ + + #define __NR_syscallend (__NR_OHOS_BEGIN + 22) + ... + ``` + +2. 在LibC库中新增用户态接口的声明与实现 + ``` + #include "stdio_impl.h" + #include "syscall.h" + ... + /* 新增系统调用用户态的接口实现 */ + void newSyscallSample(int num) + { + printf("user mode: num = %d\n", num); + __syscall(SYS_new_syscall_sample, num); return; - } - ``` + } + ``` + +3. 在内核系统调用头文件中新增系统调用号 + 如下所示,在third_party/musl/porting/liteos_a/kernel/include/bits/syscall.h文件中,__NR_new_syscall_sample为新增系统调用号。 + + ``` + ... + /* 当前现有的系统调用清单 */ + /* OHOS customized syscalls, not compatible with ARM EABI */ + #define __NR_OHOS_BEGIN 500 + #define __NR_pthread_set_detach (__NR_OHOS_BEGIN + 0) + #define __NR_pthread_join (__NR_OHOS_BEGIN + 1) + #define __NR_pthread_deatch (__NR_OHOS_BEGIN + 2) + #define __NR_creat_user_thread (__NR_OHOS_BEGIN + 3) + #define __NR_processcreat (__NR_OHOS_BEGIN + 4) + #define __NR_processtart (__NR_OHOS_BEGIN + 5) + #define __NR_printf (__NR_OHOS_BEGIN + 6) + #define __NR_dumpmemory (__NR_OHOS_BEGIN + 13) + #define __NR_mkfifo (__NR_OHOS_BEGIN + 14) + #define __NR_mqclose (__NR_OHOS_BEGIN + 15) + #define __NR_realpath (__NR_OHOS_BEGIN + 16) + #define __NR_format (__NR_OHOS_BEGIN + 17) + #define __NR_shellexec (__NR_OHOS_BEGIN + 18) + #define __NR_ohoscapget (__NR_OHOS_BEGIN + 19) + #define __NR_ohoscapset (__NR_OHOS_BEGIN + 20) + + #define __NR_new_syscall_sample (__NR_OHOS_BEGIN + 21) /* 新增的系统调用号 __NR_new_syscall_sample:521 */ + + #define __NR_syscallend (__NR_OHOS_BEGIN + 22) + ... + ``` + + 在kernel/liteos_a/syscall/syscall_lookup.h中,增加一行SYSCALL_HAND_DEF(__NR_new_syscall_sample, SysNewSyscallSample, void, ARG_NUM_1): + + ``` + ... + /* 当前现有的系统调用清单 */ + SYSCALL_HAND_DEF(__NR_chown, SysChown, int, ARG_NUM_3) + SYSCALL_HAND_DEF(__NR_chown32, SysChown, int, ARG_NUM_3) + #ifdef LOSCFG_SECURITY_CAPABILITY + SYSCALL_HAND_DEF(__NR_ohoscapget, SysCapGet, UINT32, ARG_NUM_2) + SYSCALL_HAND_DEF(__NR_ohoscapset, SysCapSet, UINT32, ARG_NUM_1) + #endif + /* 新增系统调用 */ + SYSCALL_HAND_DEF(__NR_new_syscall_sample, SysNewSyscallSample, void, ARG_NUM_1) + ... + ``` + +4. 在内核中新增内核该系统调用对应的处理函数 + 如下所示,在kernel/liteos_a/syscall/los_syscall.h中,SysNewSyscallSample为新增系统调用的内核处理函数声明: + + ``` + ... + /* 当前现有的系统调用内核处理函数声明清单 */ + extern int SysClockSettime64(clockid_t clockID, const struct timespec64 *tp); + extern int SysClockGettime64(clockid_t clockID, struct timespec64 *tp); + extern int SysClockGetres64(clockid_t clockID, struct timespec64 *tp); + extern int SysClockNanoSleep64(clockid_t clk, int flags, const struct timespec64 *req, struct timespec64 *rem); + extern int SysTimerGettime64(timer_t timerID, struct itimerspec64 *value); + extern int SysTimerSettime64(timer_t timerID, int flags, const struct itimerspec64 *value, struct itimerspec64 *oldValue); + /* 新增的系统调用内核处理函数声明 */ + extern void SysNewSyscallSample(int num); + ... + ``` + + 新增的系统调用的内核处理函数实现如下: + ``` + include "los_printf.h" + ... + /* 新增系统调用内核处理函数的实现 */ + void SysNewSyscallSample(int num) + { + PRINTK("kernel mode: num = %d\n", num); + return; + } + ``` **结果验证:** -用户态程序调用newSyscallSample\(10\)接口,得到输出结果如下: + +用户态程序调用newSyscallSample(10)接口,得到输出结果如下: + ``` /* 用户态接口与内核态接口均有输出,证明系统调用已使能 */ user mode: num = 10 kernel mode: num = 10 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-bundles.md b/zh-cn/device-dev/kernel/kernel-small-bundles.md index bd7edc2a22..50c911fead 100644 --- a/zh-cn/device-dev/kernel/kernel-small-bundles.md +++ b/zh-cn/device-dev/kernel/kernel-small-bundles.md @@ -1,13 +1,12 @@ -# 扩展组件 +# 扩展组件 -- **[系统调用](kernel-small-bundles-system.md)** -- **[动态加载与链接](kernel-small-bundles-linking.md)** +- **[系统调用](kernel-small-bundles-system.md)** -- **[虚拟动态共享库](kernel-small-bundles-share.md)** +- **[动态加载与链接](kernel-small-bundles-linking.md)** -- **[轻量级进程间通信](kernel-small-bundles-ipc.md)** - -- **[文件系统](kernel-small-bundles-fs.md)** +- **[虚拟动态共享库](kernel-small-bundles-share.md)** +- **[轻量级进程间通信](kernel-small-bundles-ipc.md)** +- **[文件系统](kernel-small-bundles-fs.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-memory-corrupt.md b/zh-cn/device-dev/kernel/kernel-small-debug-memory-corrupt.md index cc3e46c0d7..55d6f8edc5 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-memory-corrupt.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-memory-corrupt.md @@ -1,47 +1,55 @@ -# 踩内存检测 +# 踩内存检测 -- [基础概念](#section17368154517335) -- [功能配置](#section4696190123420) -- [开发指导](#section672362973417) - - [开发流程](#section026014863416) - - [编程实例](#section186311302356) +- [基础概念](#基础概念) +- [功能配置](#功能配置) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基础概念 +## 基础概念 踩内存检测机制作为内核的可选功能,用于检测动态内存池的完整性。通过该机制,可以及时发现内存池是否发生了踩内存问题,并给出错误信息,便于及时发现系统问题,提高问题解决效率,降低问题定位成本。 -## 功能配置 -LOSCFG\_BASE\_MEM\_NODE\_INTEGRITY\_CHECK:开关宏,默认关闭;若打开这个功能,可以在配置项中开启“Debug-\> Enable integrity check or not”。 +## 功能配置 + +LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK:开关宏,默认关闭;若打开这个功能,可以在配置项中开启“Debug-> Enable integrity check or not”。 1、开启这个功能,每次申请内存,会实时检测内存池的完整性。 -2、如果不开启该功能,也可以调用LOS\_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 +2、如果不开启该功能,也可以调用LOS_MemIntegrityCheck接口检测,但是每次申请内存时,不会实时检测内存完整性,而且由于节点头没有魔鬼数字(开启时才有,省内存),检测的准确性也会相应降低,但对于系统的性能没有影响,故根据实际情况开关该功能。 由于该功能只会检测出哪个内存节点被破坏了,并给出前节点信息(因为内存分布是连续的,当前节点最有可能被前节点破坏)。如果要进一步确认前节点在哪里申请的,需开启内存泄漏检测功能,通过LR记录,辅助定位。 ->![](../public_sys-resources/icon-caution.gif) **注意:** ->开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS\_MemIntegrityCheck接口检测。 +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** +> 开启该功能,节点头多了魔鬼数字字段,会增大节点头大小。由于实时检测完整性,故性能影响较大;若性能敏感的场景,可以不开启该功能,使用LOS_MemIntegrityCheck接口检测。 + + +## 开发指导 -## 开发指导 -### 开发流程 +### 开发流程 -通过调用LOS\_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 +通过调用LOS_MemIntegrityCheck接口检测内存池是否发生了踩内存,如果没有踩内存问题,那么接口返回0且没有log输出;如果存在踩内存问题,那么会输出相关log,详见下文编程实例的结果输出。 -### 编程实例 + +### 编程实例 本实例实现如下功能: -1. 申请两个物理上连续的内存块; -2. 通过memset构造越界访问,踩到下个节点的头4个字节; -3. 调用LOS\_MemIntegrityCheck检测是否发生踩内存。 +1. 申请两个物理上连续的内存块; + +2. 通过memset构造越界访问,踩到下个节点的头4个字节; + +3. 调用LOS_MemIntegrityCheck检测是否发生踩内存。 + **示例代码** + 代码实现如下: + ``` #include #include @@ -59,10 +67,13 @@ void MemIntegrityTest(void) } ``` + **结果验证** + 编译运行输出log如下: + ``` [ERR][OsMemMagicCheckPrint], 2028, memory check error! memory used but magic num wrong, magic num = 0x00000000 /* 提示信息,检测到哪个字段被破坏了,用例构造了将下个节点的头4个字节清零,即魔鬼数字字段 */ @@ -81,4 +92,3 @@ memory used but magic num wrong, magic num = 0x00000000 /* 提示信息,检 LR[2]:0x00000000 [ERR]Memory interity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* 被破坏节点和其前节点的地址 */ ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-memory-info.md b/zh-cn/device-dev/kernel/kernel-small-debug-memory-info.md index 25ce9e07f8..da1704adc6 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-memory-info.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-memory-info.md @@ -1,29 +1,31 @@ -# 内存信息统计 +# 内存信息统计 -- [基础概念](#section52691565235) -- [功能配置](#section470611682411) -- [开发指导](#section9368374243) - - [开发流程](#section679912407257) - - [编程实例](#section1025453412611) +- [基础概念](#基础概念) +- [功能配置](#功能配置) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基础概念 +## 基础概念 内存信息包括内存池大小、内存使用量、剩余内存大小、最大空闲内存、内存水线、内存节点数统计、碎片率等。 -- 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小; +- 内存水线:即内存池的最大使用量,每次申请和释放时,都会更新水线值,实际业务可根据该值,优化内存池大小; + +- 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)来度量 + +- 其他统计信息:调用接口LOS_MemInfoGet时,会扫描内存池的节点信息,统计出相关信息。 + -- 碎片率:衡量内存池的碎片化程度,碎片率高表现为内存池剩余内存很多,但是最大空闲内存块很小,可以用公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)来度量 +## 功能配置 -- 其他统计信息:调用接口LOS\_MemInfoGet时,会扫描内存池的节点信息,统计出相关信息。 +LOSCFG_MEM_WATERLINE:开关宏,默认关闭;若需要打开这个功能,可以在配置项中开启“Debug-> Enable memory pool waterline or not”。如需获取内存水线,需要打开该配置。 -## 功能配置 -LOSCFG\_MEM\_WATERLINE:开关宏,默认关闭;若需要打开这个功能,可以在配置项中开启“Debug-\> Enable memory pool waterline or not”。如需获取内存水线,需要打开该配置。 +## 开发指导 -## 开发指导 -### 开发流程 +### 开发流程 关键结构体介绍: @@ -40,22 +42,26 @@ typedef struct { } LOS_MEM_POOL_STATUS; ``` -- 内存水线获取:调用LOS\_MemInfoGet接口,第1个参数是内存池首地址,第2个参数是LOS\_MEM\_POOL\_STATUS类型的句柄,其中字段usageWaterLine即水线值。 +- 内存水线获取:调用LOS_MemInfoGet接口,第1个参数是内存池首地址,第2个参数是LOS_MEM_POOL_STATUS类型的句柄,其中字段usageWaterLine即水线值。 -- 内存碎片率计算:同样调用LOS\_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 +- 内存碎片率计算:同样调用LOS_MemInfoGet接口,可以获取内存池的剩余内存大小和最大空闲内存块大小,然后根据公式(fragment=100-100\*最大空闲内存块大小/剩余内存大小)得出此时的动态内存池碎片率。 -### 编程实例 + +### 编程实例 本实例实现如下功能: -1. 创建一个监控任务,用于获取内存池的信息; -2. 调用LOS\_MemInfoGet接口,获取内存池的基础信息; -3. 利用公式算出使用率及碎片率。 +1. 创建一个监控任务,用于获取内存池的信息; + +2. 调用LOS_MemInfoGet接口,获取内存池的基础信息; + +3. 利用公式算出使用率及碎片率。 + **示例代码** -代码实现如下: +代码实现如下: ``` #include #include @@ -67,7 +73,7 @@ void MemInfoTaskFunc(void) { LOS_MEM_POOL_STATUS poolStatus = {0}; - /* pool为要统计信息的内存地址,此处以OS_SYS_MEM_ADDR为例 */ + /* pool为要统计信息的内存地址,此处以OS_SYS_MEM_ADDR为例 */ void *pool = OS_SYS_MEM_ADDR; LOS_MemInfoGet(pool, &poolStatus); /* 算出内存池当前的碎片率百分比 */ @@ -96,11 +102,13 @@ int MemTest(void) } ``` + **结果验证** + 编译运行输出的结果如下: + ``` usage = 22, fragment = 3, maxFreeSize = 49056, totalFreeSize = 50132, waterLine = 1414 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-memory-leak.md b/zh-cn/device-dev/kernel/kernel-small-debug-memory-leak.md index bd226640d4..c565c5d007 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-memory-leak.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-memory-leak.md @@ -1,35 +1,38 @@ -# 内存泄漏检测 +# 内存泄漏检测 -- [基础概念](#section1026719436293) -- [功能配置](#section13991354162914) -- [开发指导](#section95828159308) - - [开发流程](#section369844416304) - - [编程实例](#section460801313313) +- [基础概念](#基础概念) +- [功能配置](#功能配置) +- [开发指导](#开发指导) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基础概念 +## 基础概念 内存泄漏检测机制作为内核的可选功能,用于辅助定位动态内存泄漏问题。开启该动能,动态内存机制会自动记录申请内存时的函数调用关系(下文简称LR)。如果出现泄漏,就可以利用这些记录的信息,找到内存申请的地方,方便进一步确认。 -## 功能配置 -1. LOSCFG\_MEM\_LEAKCHECK:开关宏,默认关闭;如需要打开这个功能,可以在配置项中开启“Debug-\> Enable Function call stack of Mem operation recorded”。 -2. LOS\_RECORD\_LR\_CNT:记录的LR层数,默认3层;每层LR消耗sizeof\(void \*\)字节数的内存。 -3. LOS\_OMIT\_LR\_CNT:忽略的LR层数,默认2层,即从调用LOS\_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下: - - LOS\_MemAlloc接口内部也有函数调用; - - 外部可能对LOS\_MemAlloc接口有封装; - - LOS\_RECORD\_LR\_CNT 配置的LR层数有限; +## 功能配置 + +1. LOSCFG_MEM_LEAKCHECK:开关宏,默认关闭;如需要打开这个功能,可以在配置项中开启“Debug-> Enable Function call stack of Mem operation recorded”。 + +2. LOS_RECORD_LR_CNT:记录的LR层数,默认3层;每层LR消耗sizeof(void \*)字节数的内存。 +3. LOS_OMIT_LR_CNT:忽略的LR层数,默认2层,即从调用LOS_MemAlloc的函数开始记录,可根据实际情况调整。为啥需要这个配置?有3点原因如下: + - LOS_MemAlloc接口内部也有函数调用; + - 外部可能对LOS_MemAlloc接口有封装; + - LOS_RECORD_LR_CNT 配置的LR层数有限; 正确配置这个宏,将无效的LR层数忽略,就可以记录有效的LR层数,节省内存消耗。 -## 开发指导 -### 开发流程 +## 开发指导 -该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS\_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。 -调用LOS\_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3\~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。 +### 开发流程 + +该调测功能可以分析关键的代码逻辑中是否存在内存泄漏。开启这个功能,每次申请内存时,会记录LR信息。在需要检测的代码段前后,调用LOS_MemUsedNodeShow接口,每次都会打印指定内存池已使用的全部节点信息,对比前后两次的节点信息,新增的节点信息就是疑似泄漏的内存节点。通过LR,可以找到具体申请的代码位置,进一步确认是否泄漏。 + +调用LOS_MemUsedNodeShow接口输出的节点信息格式如下:每1行为一个节点信息;第1列为节点地址,可以根据这个地址,使用GDB等手段查看节点完整信息;第2列为节点的大小,等于节点头大小+数据域大小;第3~5列为函数调用关系LR地址,可以根据这个值,结合汇编文件,查看该节点具体申请的位置。 ``` node size LR[0] LR[1] LR[2] @@ -41,23 +44,31 @@ node size LR[0] LR[1] LR[2] 0x100179cc: 0x5c 0x9b02c24e 0x9b02c246 0x9b008ef0 ``` ->![](../public_sys-resources/icon-caution.gif) **注意:** ->开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。 +> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** +> 开启内存检测会影响内存申请的性能,且每个内存节点都会记录LR地址,内存开销也加大。 + -### 编程实例 +### 编程实例 本实例实现如下功能:构建内存泄漏代码段。 -1. 调用OsMemUsedNodeShow接口,输出全部节点信息打印; -2. 申请内存,但没有释放,模拟内存泄漏; -3. 再次调用OsMemUsedNodeShow接口,输出全部节点信息打印; -4. 将两次log进行对比,得出泄漏的节点信息; -5. 通过LR地址,找出泄漏的代码位置; +1. 调用OsMemUsedNodeShow接口,输出全部节点信息打印; + +2. 申请内存,但没有释放,模拟内存泄漏; + +3. 再次调用OsMemUsedNodeShow接口,输出全部节点信息打印; + +4. 将两次log进行对比,得出泄漏的节点信息; + +5. 通过LR地址,找出泄漏的代码位置; + **示例代码** + 代码实现如下: + ``` #include #include @@ -73,10 +84,13 @@ void MemLeakTest(void) } ``` + **结果验证** + 编译运行输出log如下: + ``` node size LR[0] LR[1] LR[2] 0x20001b04: 0x24 0x08001a10 0x080035ce 0x080028fc @@ -95,15 +109,19 @@ node size LR[0] LR[1] LR[2] 0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 ``` + 对比两次log,差异如下,这些内存节点就是疑似泄漏的内存块: + ``` 0x20003ac4: 0x1d 0x08001458 0x080014e0 0x080041e6 0x20003ae0: 0x1d 0x080041ee 0x08000cc2 0x00000000 ``` + 部分汇编文件如下: + ``` MemLeakTest: 0x80041d4: 0xb510 PUSH {R4, LR} @@ -122,5 +140,5 @@ node size LR[0] LR[1] LR[2] 0x80041f6: 0x0000 MOVS R0, R0 ``` -其中,通过查找0x080041ee,就可以发现该内存节点是在MemLeakTest接口里申请的且是没有释放的。 +其中,通过查找0x080041ee,就可以发现该内存节点是在MemLeakTest接口里申请的且是没有释放的。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-memory.md b/zh-cn/device-dev/kernel/kernel-small-debug-memory.md index 34c35ba48d..91c812783b 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-memory.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-memory.md @@ -1,9 +1,8 @@ -# 内存调测 +# 内核态内存调测 -- **[内存信息统计](kernel-small-debug-memory-info.md)** -- **[内存泄漏检测](kernel-small-debug-memory-leak.md)** - -- **[踩内存检测](kernel-small-debug-memory-corrupt.md)** +- **[内存信息统计](kernel-small-debug-memory-info.md)** +- **[内存泄漏检测](kernel-small-debug-memory-leak.md)** +- **[踩内存检测](kernel-small-debug-memory-corrupt.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-other.md b/zh-cn/device-dev/kernel/kernel-small-debug-other.md index 4de7e4f03f..36811a2558 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-other.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-other.md @@ -1,7 +1,6 @@ -# 其他内核调测手段 +# 其他内核调测手段 -- **[临终遗言](kernel-small-debug-trace-other-lastwords.md)** - -- **[常见问题定位方法](kernel-small-debug-trace-other-faqs.md)** +- **[临终遗言](kernel-small-debug-trace-other-lastwords.md)** +- **[常见问题定位方法](kernel-small-debug-trace-other-faqs.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-perf.md b/zh-cn/device-dev/kernel/kernel-small-debug-perf.md deleted file mode 100644 index 6fa440f4f7..0000000000 --- a/zh-cn/device-dev/kernel/kernel-small-debug-perf.md +++ /dev/null @@ -1,506 +0,0 @@ -# Perf调测 - -- [基本概念](#section1) - -- [运行机制](#section2) - -- [接口说明](#section3) - - - [内核态](#section3.1) - - - [用户态](#section3.2) - -- [开发指导](#section4) - - - [内核态开发流程](#section4.1.1) - - - [内核态编程实例](#section4.1.2) - - - [内核态实例代码](#section4.1.3) - - - [内核态结果验证](#section4.1.4) - - - [用户态开发流程](#section4.2.1) - - - [用户态编程实例](#section4.2.2) - - - [用户态实例代码](#section4.2.3) - - - [用户态结果验证](#section4.2.4) - -## 基本概念 -Perf为性能分析工具,依赖PMU(Performance Monitoring Unit)对采样事件进行计数和上下文采集,统计出热点分布(hot spot)和热路径(hot path)。 - -## 运行机制 -基于事件采样原理,以性能事件为基础,当事件发生时,相应的事件计数器溢出发生中断,在中断处理函数中记录事件信息,包括当前的pc、当前运行的任务ID以及调用栈等信息。 - -Perf提供2种工作模式,计数模式和采样模式。 - -计数模式仅统计事件发生的次数和耗时,采样模式会收集上下文数据到环形buffer中,需要IDE进行数据解析生成热点函数与热点路径。 - -## 接口说明 - -### 内核态 - -OpenHarmony LiteOS-A内核的Perf模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_perf.h)参考。 - -**表 1** Perf模块接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

开启/停止Perf采样

-

LOS_PerfStart

-

开启采样

-

LOS_PerfStop

-

停止采样

-

配置Perf采样事件

-

LOS_PerfConfig

-

配置采样事件的类型、周期等

-

读取采样数据

-

LOS_PerfDataRead

-

读取采样数据到指定地址

-

注册采样数据缓冲区的钩子函数

-

LOS_PerfNotifyHookReg

-

注册缓冲区水线到达的处理钩子

-

LOS_PerfFlushHookReg

-

注册缓冲区刷cache的钩子

-
- -1. Perf采样事件的结构体为PerfConfigAttr,详细字段含义及取值详见kernel\include\los_perf.h。 - -2. 采样数据缓冲区为环形buffer,buffer中读过的区域可以覆盖写,未被读过的区域不能被覆盖写。 - -3. 缓冲区有限,用户可通过注册水线到达的钩子进行buffer溢出提醒或buffer读操作。默认水线值为buffer总大小的1/2。 - 示例如下: - ```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); - ``` - -4. 若perf采样的buffer涉及到cpu 跨cache,则用户可通过注册刷cache的钩子,进行cache同步。 - 示例如下: - ```c - VOID Example_PerfFlushHook(VOID *addr, UINT32 size) - { - OsCacheFlush(addr, size); /* platform interface */ - } - LOS_PerfNotifyHookReg(Example_PerfFlushHook); - ``` - 刷cache接口视具体的平台自行配置。 - -### 用户态 - -新增perf字符设备,位于"/dev/perf",通过对设备节点的read\write\ioctl,实现用户态perf的读写和控制: - -- read: 用户态读取perf记录数据 - -- write: 用户态采样事件配置 - -- ioctl: 用户态Perf控制操作,包括 - ```C - #define PERF_IOC_MAGIC 'T' - #define PERF_START _IO(PERF_IOC_MAGIC, 1) - #define PERF_STOP _IO(PERF_IOC_MAGIC, 2) - ``` - 分别对应Perf启动(LOS_PerfStart)、停止(LOS_PerfStop) - -具体的使用方法参见[用户态编程实例](#section4.2.2) - - - -## 开发指导 - -### 内核态开发流程 - -开启Perf调测的典型流程如下: - -1. 配置Perf模块相关宏。 - - 配置Perf控制宏LOSCFG_KERNEL_PERF,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Perf Feature"中打开: - - | 配置项 | menuconfig选项 | 含义 | 设置值 | - | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | - | LOSCFG_KERNEL_PERF | Enable Perf Feature | Perf模块的裁剪开关 | YES/NO | - | LOSCFG_PERF_CALC_TIME_BY_TICK | Time-consuming Calc Methods->By Tick | Perf计时单位为tick | YES/NO | - | LOSCFG_PERF_CALC_TIME_BY_CYCLE | Time-consuming Calc Methods->By Cpu Cycle | Perf计时单位为cycle | YES/NO | - | LOSCFG_PERF_BUFFER_SIZE | Perf Sampling Buffer Size | Perf采样buffer的大小 | INT | - | LOSCFG_PERF_HW_PMU | Enable Hardware Pmu Events for Sampling | 使能硬件PMU事件,需要目标平台支持硬件PMU | YES/NO | - | LOSCFG_PERF_TIMED_PMU | Enable Hrtimer Period Events for Sampling | 使能高精度周期事件,需要目标平台支持高精度定时器 | YES/NO | - | LOSCFG_PERF_SW_PMU | Enable Software Events for Sampling | 使能软件事件,需要开启LOSCFG_KERNEL_HOOK | INT | - -2. 调用LOS_PerfConfig配置需要采样的事件。 - - Perf提供2种模式的配置,及3大类型的事件配置: - - 2种模式:计数模式(仅统计事件发生次数)、采样模式(收集上下文如任务ID、pc、backtrace等)。 - - 3种事件类型:CPU硬件事件(cycle、branch、icache、dcache等)、高精度周期事件(cpu clock)、OS软件事件(task switch、mux pend、irq等)。 - -3. 在需要采样的代码起始点调用LOS_PerfStart(UINT32 sectionId), 入参sectionId标记不同的采样回话id。 - -4. 在需要采样的代码结束点调用LOS_PerfStop。 - -5. 调用输出缓冲区数据的接口LOS_PerfDataRead读取采样数据,并使用IDE工具进行解析。 - - -### 内核态编程实例 - - 本实例实现如下功能: - - 1. 创建perf测试任务。 - - 2. 配置采样事件。 - - 3. 启动perf。 - - 4. 执行需要统计的算法。 - - 5. 停止perf。 - - 6. 输出统计结果。 - -### 内核态示例代码 - -前提条件:在menuconfig菜单中完成perf模块的配置。 - -实例代码如下: - -```C -#include "los_perf.h" -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; - - PerfConfigAttr attr = { - .eventsCfg = { - .type = PERF_EVENT_TYPE_HW, - .events = { - [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, - [1] = {PERF_COUNT_HW_BRANCH_INSTRUCTIONS, 0xFFFFFF00}, - }, - .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); - 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; - /* 创建用于perf测试的任务 */ - memset(&perfTestTask, 0, sizeof(TSK_INIT_PARAM_S)); - perfTestTask.pfnTaskEntry = (TSK_ENTRY_FUNC)perfTestHwEvent; - perfTestTask.pcName = "TestPerfTsk"; /* 测试任务名称 */ - perfTestTask.uwStackSize = 0x800; - perfTestTask.usTaskPrio = 5; - perfTestTask.uwResved = LOS_TASK_STATUS_DETACHED; - ret = LOS_TaskCreate(&g_perfTestTaskId, &perfTestTask); - if(ret != LOS_OK){ - PRINT_ERR("PerfTestTask create failed.\n"); - return LOS_NOK; - } - return LOS_OK; -} -LOS_MODULE_INIT(perfTestHwEvent, LOS_INIT_LEVEL_KMOD_EXTENDED); -``` - -### 内核态结果验证 - -输出结果如下: - -```c ---------count mode---------- -[EMG] [cycles] eventType: 0xff: 5466989440 -[EMG] [branches] eventType: 0xc: 602166445 -------- sample mode---------- -[EMG] dump section data, addr: 0x8000000 length: 0x800000 -num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ... -hex: 00 ef ef ef 00 00 00 00 14 00 00 00 60 00 00 00 00 00 00 00 70 88 36 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 01 00 00 00 cc 55 30 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 -``` - -- 针对计数模式,系统在perf stop后会打印: - - 事件名称(cycles)、事件类型(0xff)、事件发生的次数(5466989440)。 - - 当采样事件为硬件PMU事件时,打印的事件类型为实际的硬件事件id,非enum PmuHWId中定义的抽象类型。 - -- 针对采样模式,系统在perf stop后会打印采样数据的地址和长度: - - dump section data, addr: (0x8000000) length: (0x5000) - - 用户可以通过JTAG口导出该片内存,再使用IDE线下工具解析。 - - 或者通过LOS_PerfDataRead将数据读到指定地址,进行查看或进一步处理。示例中OsPrintBuff为测试接口,其按字节打印Read到的采样数据,num表示第几个字节,hex表示该字节中的数值。 - -### 用户态开发流程 -通过在menuconfig配置"Driver->Enable PERF DRIVER",开启Perf驱动。该配置仅在内核Enable Perf Feature后,才可在Driver的选项中可见。 -1. 打开“/dev/perf”字符文件,进行读写和IOCTL操作; -2. 系统提供用户态的perf命令,该命令位于/bin目录下,cd bin 后可执行如下命令: -- ./perf start [id] 启动perf采样, id 为可选项,默认值为0 - -- ./perf stop 停止perf采样 - -- ./perf read \ 从采样缓冲区中读取nBytes数据并打印内容 - -- ./perf list 罗列-e支持的具体事件 - -- ./perf stat/record [option] \ 计数/采样模式命令 - -option可选如下: - -- -e,配置采样事件。可使用./perf list 中罗列的同类型事件。 - -- -p,配置事件采样周期。 - -- -o, 指定perf采样数据结果保存的文件路径。 - -- -t,任务Id过滤(白名单),只采取指定任务中的上下文。如果不指定改参数,则默认采集所有的任务。 - -- -s, 配置采样的具体上下文类型,可查阅los_perf.h中定义的PerfSampleType。 - -- -P, 进程Id过滤(白名单),只采取指定进程中的上下文。如果不指定改参数,则默认采集所有进程。 - -- -d, 是否进行分频(事件每发生64次累计+1),该选项仅在硬件cycle事件上生效。 - -command 为待统计的子程序。 - -用户态命令行的典型使用方法如下: - -./perf list 查看可使用的事件列表, 输出如下: - -```c -cycles [Hardware event] -instruction [Hardware event] -dcache [Hardware event] -dcache-miss [Hardware event] -icache [Hardware event] -icache-miss [Hardware event] -branch [Hardware event] -branch-miss [Hardware event] -clock [Timed event] -task-switch [Software event] -irq-in [Software event] -mem-alloc [Software event] -mux-pend [Software event] -``` -./perf stat -e cycles os_dump, 输出如下: - -```c -type: 0 -events[0]: 255, 0xffff -predivided: 0 -sampleType: 0x0 -needSample: 0 -usage os_dump [--help | -l | SERVICE] - --help: shows this help - -l: only list services, do not dump them - SERVICE: dumps only service SERVICE -time used: 0.058000(s) -[cycles] eventType: 0xff [core 0]: 21720647 -[cycles] eventType: 0xff [core 1]: 13583830 -``` - -./perf record -e cycles os_dump, 输出如下: - -```c -type: 0 -events[0]: 255, 0xffff -predivided: 0 -sampleType: 0x60 -needSample: 1 -usage os_dump [--help | -l | SERVICE] - --help: shows this help - -l: only list services, do not dump them - SERVICE: dumps only service SERVICE -dump perf data, addr: 0x408643d8 length: 0x5000 -time used: 0.059000(s) -save perf data success at /storage/data/perf.data -``` -> ![](../public_sys-resources/icon-note.gif)**说明** - - > 在进行./perf stat/record命令后,用户可多次执行./perf start 和 ./perf stop进行采样, 采样的事件配置为最近一次执行./perf stat/record 中设置的参数。 - -### 用户态编程实例 - - 本实例实现如下功能: - - 1. 打开perf字符设备。 - - 4. 写perf配置事件。 - - 3. 启动perf。 - - 5. 停止perf。 - - 6. 读取perf采样数据。 - -### 用户态示例代码 -实例代码如下 -```c -#include "fcntl.h" -#include "user_copy.h" -#include "sys/ioctl.h" -#include "fs/driver.h" -#include "los_dev_perf.h" -#include "los_perf.h" -#include "los_init.h" - -/* perf ioctl */ -#define PERF_IOC_MAGIC 'T' -#define PERF_START _IO(PERF_IOC_MAGIC, 1) -#define PERF_STOP _IO(PERF_IOC_MAGIC, 2) - -int main(int argc, char **argv) -{ - char *buf = NULL; - ssize_t len; - - int fd = open("/dev/perf", O_RDWR); - if (fd == -1) { - printf("Perf open failed.\n"); - exit(EXIT_FAILURE); - } - - PerfConfigAttr attr = { - .eventsCfg = { -#ifdef LOSCFG_PERF_HW_PMU - .type = PERF_EVENT_TYPE_HW, - .events = { - [0] = {PERF_COUNT_HW_CPU_CYCLES, 0xFFFF}, - }, -#elif defined LOSCFG_PERF_TIMED_PMU - .type = PERF_EVENT_TYPE_TIMED, - .events = { - [0] = {PERF_COUNT_CPU_CLOCK, 100}, - }, -#elif defined LOSCFG_PERF_SW_PMU - .type = PERF_EVENT_TYPE_SW, - .events = { - [0] = {PERF_COUNT_SW_TASK_SWITCH, 1}, - }, -#endif - .eventsNr = 1, /* 1 event */ - .predivided = 0, - }, - .taskIds = {0}, - .taskIdsNr = 0, - .processIds = {0}, - .processIdsNr = 0, - .needSample = 1, - .sampleType = PERF_RECORD_IP | PERF_RECORD_CALLCHAIN, - }; - (void)write(fd, &attr, sizeof(PerfConfigAttr)); /* perf config */ - - ioctl(fd, PERF_START, NULL); /* perf start */ - test(); - ioctl(fd, PERF_STOP, NULL); /* perf stop */ - - buf = (char *)malloc(LOSCFG_PERF_BUFFER_SIZE); - if (buf == NULL) { - printf("no memory for read perf 0x%x\n", LOSCFG_PERF_BUFFER_SIZE); - return -1; - } - - len = read(fd, buf, LOSCFG_PERF_BUFFER_SIZE); - OsPrintBuff(buf, len); /* print data */ - - free(buf); - close(fd); - return 0; -} -``` -### 用户态结果验证 -输出结果如下: - -```c -[EMG] dump section data, addr: 0x8000000 length: 0x800000 -num: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 ... -hex: 00 ef ef ef 00 00 00 00 14 00 00 00 60 00 00 00 00 00 00 00 70 88 36 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 01 00 00 00 cc 55 30 40 08 00 00 00 6b 65 72 6e 65 6c 00 00 -``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-process-cpu.md b/zh-cn/device-dev/kernel/kernel-small-debug-process-cpu.md index 67325d84c9..6213940dd4 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-process-cpu.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-process-cpu.md @@ -1,44 +1,42 @@ -# CPU占用率 +# CPU占用率 -- [基本概念](#section17683419227) -- [运行机制](#section593718536227) -- [开发指导](#section11284210152311) - - [接口说明](#section3745151592312) - - [开发流程](#section122901429182316) - - [编程实例](#section1765785212310) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [开发指导](#开发指导) + - [接口说明](#接口说明) + - [开发流程](#开发流程) + - [编程实例](#编程实例) - -## 基本概念 +## 基本概念 CPU(中央处理器,Central Processing Unit)占用率分为系统CPU占用率、进程CPU占用率、任务CPU占用率和中断CPU占用率。用户通过系统级的CPU占用率,判断当前系统负载是否超出设计规格。通过系统中各个进程/任务/中断的CPU占用情况,判断各个进程/任务/中断的CPU占用率是否符合设计的预期。 -- 系统CPU占用率(CPU Percent) - - 指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示系统满负荷运转。 +- 系统CPU占用率(CPU Percent) + 指周期时间内系统的CPU占用率,用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。系统CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示系统满负荷运转。 -- 进程CPU占用率 +- 进程CPU占用率 + 指单个进程的CPU占用率,用于表示单个进程在一段时间内的闲忙程度。进程CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该进程。 - 指单个进程的CPU占用率,用于表示单个进程在一段时间内的闲忙程度。进程CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该进程。 +- 任务CPU占用率 + 指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该任务。 -- 任务CPU占用率 +- 中断CPU占用率 + 指单个中断的CPU占用率,用于表示单个中断在一段时间内的闲忙程度。中断CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该中断。 - 指单个任务的CPU占用率,用于表示单个任务在一段时间内的闲忙程度。任务CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该任务。 -- 中断CPU占用率 +## 运行机制 - 指单个中断的CPU占用率,用于表示单个中断在一段时间内的闲忙程度。中断CPU占用率的有效表示范围为0~100,其精度(可通过配置调整)为百分比。100表示在一段时间内系统一直在运行该中断。 +OpenHarmony LiteOS-A内核CPUP(CPU Percent,CPU占用率)模块采用进程、任务和中断级记录的方式,在进程/任务切换时,记录进程/任务启动时间,进程/任务切出或者退出时,系统会累加整个进程/任务的占用时间; 在执行中断时系统会累加记录每个中断的执行时间。 +OpenHarmony 提供以下四种CPU占用率的信息查询: -## 运行机制 +- 系统CPU占用率 -OpenHarmony LiteOS-A内核CPUP(CPU Percent,CPU占用率)模块采用进程、任务和中断级记录的方式,在进程/任务切换时,记录进程/任务启动时间,进程/任务切出或者退出时,系统会累加整个进程/任务的占用时间; 在执行中断时系统会累加记录每个中断的执行时间。 +- 进程CPU占用率 -OpenHarmony 提供以下四种CPU占用率的信息查询: +- 任务CPU占用率 -- 系统CPU占用率 -- 进程CPU占用率 -- 任务CPU占用率 -- 中断CPU占用率 +- 中断CPU占用率 **CPU占用率的计算方法:** @@ -50,88 +48,59 @@ OpenHarmony 提供以下四种CPU占用率的信息查询: 中断CPU占用率=中断运行总时间/系统运行总时间 -## 开发指导 - -### 接口说明 - -**表 1** CPUP模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名称

-

描述

-

系统CPU占用率

-

LOS_HistorySysCpuUsage

-

获取系统历史CPU占用率

-

进程CPU占用率

-

LOS_HistoryProcessCpuUsage

-

获取指定进程历史CPU占用率

-

LOS_GetAllProcessCpuUsage

-

获取系统所有进程的历史CPU占用率

-

任务CPU占用率

-

LOS_HistoryTaskCpuUsage

-

获取指定任务历史CPU占用率

-

中断CPU占用率

-

LOS_GetAllIrqCpuUsage

-

获取系统所有中断的历史CPU占用率

-
- -### 开发流程 + +## 开发指导 + + +### 接口说明 + +**表1** CPUP模块接口 + +| 功能分类 | 接口**名称** | 描述 | +| -------- | -------- | -------- | +| 系统CPU占用率 | LOS_HistorySysCpuUsage | 获取系统历史CPU占用率 | +| 进程CPU占用率 | LOS_HistoryProcessCpuUsage | 获取指定进程历史CPU占用率 | +| | LOS_GetAllProcessCpuUsage |获取系统所有进程的历史CPU占用率| +| 任务CPU占用率 | LOS_HistoryTaskCpuUsage | 获取指定任务历史CPU占用率 | +| 中断CPU占用率 | LOS_GetAllIrqCpuUsage | 获取系统所有中断的历史CPU占用率 | + + +### 开发流程 CPU占用率的典型开发流程: -1. 调用获取系统历史CPU占用率函数LOS\_HistorySysCpuUsage。 -2. 调用获取指定进程历史CPU占用率函数LOS\_HistoryProcessCpuUsage。 - - 若进程已创建,则关中断,根据不同模式正常获取,恢复中断; - - 若进程未创建,则返回错误码; +1. 调用获取系统历史CPU占用率函数LOS_HistorySysCpuUsage。 -3. 调用获取所有进程CPU占用率函数LOS\_GetAllProcessCpuUsage。 - - 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断; - - 若CPUP未初始化或有非法入参,则返回错误码; +2. 调用获取指定进程历史CPU占用率函数LOS_HistoryProcessCpuUsage。 + - 若进程已创建,则关中断,根据不同模式正常获取,恢复中断; + - 若进程未创建,则返回错误码; -4. 调用获取指定任务历史CPU占用率函数LOS\_HistoryTaskCpuUsage。 - - 若任务已创建,则关中断,根据不同模式正常获取,恢复中断; - - 若任务未创建,则返回错误码; +3. 调用获取所有进程CPU占用率函数LOS_GetAllProcessCpuUsage。 + - 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断; + - 若CPUP未初始化或有非法入参,则返回错误码; -5. 调用获取所有中断CPU占用率函数LOS\_GetAllIrqCpuUsage。 - - 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断; - - 若CPUP未初始化或有非法入参,则返回错误码; +4. 调用获取指定任务历史CPU占用率函数LOS_HistoryTaskCpuUsage。 + - 若任务已创建,则关中断,根据不同模式正常获取,恢复中断; + - 若任务未创建,则返回错误码; +5. 调用获取所有中断CPU占用率函数LOS_GetAllIrqCpuUsage。 + - 若CPUP已初始化,则关中断,根据不同模式正常获取,恢复中断; + - 若CPUP未初始化或有非法入参,则返回错误码; -### 编程实例 + +### 编程实例 本实例实现如下功能: -1. 创建一个用于CPUP测试的任务。 -2. 获取当前系统CPUP。 -3. 以不同模式获取历史系统CPUP。 -4. 获取创建的测试任务的CPUP。 -5. 以不同模式获取创建的测试任务的CPUP。 +1. 创建一个用于CPUP测试的任务。 + +2. 获取当前系统CPUP。 + +3. 以不同模式获取历史系统CPUP。 + +4. 获取创建的测试任务的CPUP。 + +5. 以不同模式获取创建的测试任务的CPUP。 前提条件: @@ -192,4 +161,3 @@ entry cpup test example the history system cpu usage in all time: 3.0 cpu usage of the cpupTestTask in all time: TaskID:10 usage: 0.0 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-process.md b/zh-cn/device-dev/kernel/kernel-small-debug-process.md index 66046930ef..1a4cf04108 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-process.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-process.md @@ -1,5 +1,4 @@ -# 进程调测 - -- **[CPU占用率](kernel-small-debug-process-cpu.md)** +# 进程调测 +- **[CPU占用率](kernel-small-debug-process-cpu.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-build.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-build.md index 66e0d24b3f..546449c66a 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-build.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-build.md @@ -1,123 +1,114 @@ -# Shell命令编程实例 +# Shell命令编程实例 -- [实例描述](#section87143612316) -- [静态注册方式](#section1660495712314) -- [静态注册编程实例](#section1233411684113) -- [动态注册方式](#section6804126192412) -- [动态注册编程实例](#section2335121613418) +- [实例描述](#实例描述) +- [静态注册方式](#静态注册方式) +- [静态注册编程实例](#静态注册编程实例) +- [动态注册方式](#动态注册方式) +- [动态注册编程实例](#动态注册编程实例) -## 实例描述 +## 实例描述 在下面的两个例子中,演示如何使用静态注册命令方式和动态注册命令方式新增一个Shell命令:**test**。 -## 静态注册方式 -开发流程如下: - -1. 定义一个新增命令所要调用的执行函数cmd\_test。 - -2. 使用SHELLCMD\_ENTRY函数添加新增命令项。 - -3. 在链接选项liteos\_tables\_ldflags.mk中添加链接该新增命令项参数。 - -4. 重新编译代码后运行。 +## 静态注册方式 +开发流程如下: -## 静态注册编程实例 +1. 定义一个新增命令所要调用的执行函数cmd_test。 -1. 定义命令所要调用的函数cmd\_test: +2. 使用SHELLCMD_ENTRY函数添加新增命令项。 - ``` - #include "shell.h" - #include "shcmd.h" - int cmd_test(void) - { - printf("hello everybody!\n"); - return 0; - } - ``` +3. 在链接选项liteos_tables_ldflags.mk中添加链接该新增命令项参数。 -2. 新增命令项: +4. 重新编译代码后运行。 - ``` - SHELLCMD_ENTRY(test_shellcmd, CMD_TYPE_EX, "test", 0, (CMD_CBK_FUNC)cmd_test); - ``` -3. 在链接选项中添加链接该新增命令项参数: +## 静态注册编程实例 - 在liteos\_tables\_ldflags.mk文件的LITEOS\_TABLES\_LDFLAGS项下添加-utest\_shellcmd。 +1. 定义命令所要调用的函数cmd_test: + ``` + #include "shell.h" + #include "shcmd.h" + int cmd_test(void) + { + printf("hello everybody!\n"); + return 0; + } + ``` -4. 重新编译代码: +2. 新增命令项: + ``` + SHELLCMD_ENTRY(test_shellcmd, CMD_TYPE_EX, "test", 0, (CMD_CBK_FUNC)cmd_test); + ``` - ``` - make clean;make - ``` +3. 在链接选项中添加链接该新增命令项参数: + 在liteos_tables_ldflags.mk文件的LITEOS_TABLES_LDFLAGS项下添加-utest_shellcmd。 -5. 用help命令查看当前系统所有的注册命令,可以发现test命令已经注册。(以下命令集合仅供参考,以实际编译运行情况为准。) +4. 重新编译代码: + ``` + make clean;make + ``` - ``` - OHOS # help - *******************shell commands:************************* - - arp cat cd chgrp chmod chown cp cpup - date dhclient dmesg dns format free help hwi - ifconfig ipdebug kill log ls lsfd memcheck mkdir - mount netstat oom partinfo partition ping ping6 pwd - reset rm rmdir sem statfs su swtmr sync - systeminfo task telnet test tftp touch umount uname - watch writeproc - ``` +5. 用help命令查看当前系统所有的注册命令,可以发现test命令已经注册。(以下命令集合仅供参考,以实际编译运行情况为准。) + ``` + OHOS # help + ***shell commands:* + + arp cat cd chgrp chmod chown cp cpup + date dhclient dmesg dns format free help hwi + ifconfig ipdebug kill log ls lsfd memcheck mkdir + mount netstat oom partinfo partition ping ping6 pwd + reset rm rmdir sem statfs su swtmr sync + systeminfo task telnet test tftp touch umount uname + watch writeproc + ``` -## 动态注册方式 +## 动态注册方式 开发流程如下: -1. 使用osCmdReg函数添加新增命令项。 - -2. 重新编译后运行。 - - -## 动态注册编程实例 - -1. 在用户应用函数中调用osCmdReg函数动态注册命令。 - - ``` - #include "shell.h" - #include "shcmd.h" - int cmd_test(void) - { - printf("hello everybody!\n"); - return 0; - } - void app_init(void) - { - .... - .... - osCmdReg(CMD_TYPE_EX, "test", 0,(CMD_CBK_FUNC)cmd_test); - .... - } - ``` - -2. 重新编译代码: - - ``` - make clean;make - ``` - -3. 用help命令查看当前系统所有的注册命令,可以发现test命令已经注册。 - - ``` - OHOS # help - *******************shell commands:************************* - - arp cat cd chgrp chmod chown cp cpup - date dhclient dmesg dns format free help hwi - ifconfig ipdebug kill log ls lsfd memcheck mkdir - mount netstat oom partinfo partition ping ping6 pwd - reset rm rmdir sem statfs su swtmr sync - systeminfo task telnet test tftp touch umount uname - watch writeproc - ``` - - +1. 使用osCmdReg函数添加新增命令项。 + +2. 重新编译后运行。 + + +## 动态注册编程实例 + +1. 在用户应用函数中调用osCmdReg函数动态注册命令。 + ``` + #include "shell.h" + #include "shcmd.h" + int cmd_test(void) + { + printf("hello everybody!\n"); + return 0; + } + void app_init(void) + { + .... + .... + osCmdReg(CMD_TYPE_EX, "test", 0,(CMD_CBK_FUNC)cmd_test); + .... + } + ``` + +2. 重新编译代码: + ``` + make clean;make + ``` + +3. 用help命令查看当前系统所有的注册命令,可以发现test命令已经注册。 + ``` + OHOS # help + ***shell commands:* + + arp cat cd chgrp chmod chown cp cpup + date dhclient dmesg dns format free help hwi + ifconfig ipdebug kill log ls lsfd memcheck mkdir + mount netstat oom partinfo partition ping ping6 pwd + reset rm rmdir sem statfs su swtmr sync + systeminfo task telnet test tftp touch umount uname + watch writeproc + ``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md index 73dc510cc0..8f5d4734d3 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-cpup.md @@ -1,67 +1,51 @@ -# cpup +# cpup -- [命令功能](#section1842161614217) -- [命令格式](#section5629527427) -- [参数说明](#section133651361023) -- [使用指南](#section156611948521) -- [使用实例](#section68501605319) -- [输出说明](#section19871522144219) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 cpup命令用于查询系统CPU的占用率。 -## 命令格式 - -cpup \[_mode_\] \[_taskID_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

mode

-
  • 缺省:显示系统最近10s内的CPU占用率。
  • 0:显示系统最近10s内的CPU占用率。
  • 1:显示系统最近1s内的CPU占用率。
  • 其他数字:显示系统启动至今总的CPU 占用率。
-

[0,0xFFFFFFFF]

-

taskID

-

任务ID号

-

[0,0xFFFFFFFF]

-
- -## 使用指南 - -- 参数缺省时,显示系统10s前的CPU占用率。 -- 只有一个参数时,该参数为mode,显示系统相应时间前的CPU占用率。 -- 输入两个参数时,第一个参数为mode,第二个参数为taskID,显示对应ID号任务的相应时间前的CPU占用率。 - -## 使用实例 -举例:输入cpup 1 5 +## 命令格式 + +cpup [_mode_] [_taskID_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| mode | - 缺省:显示系统最近10s内的CPU占用率。
- 0:显示系统最近10s内的CPU占用率。
- 1:显示系统最近1s内的CPU占用率。
- 其他数字:显示系统启动至今总的CPU 占用率。 | [0,0xFFFFFFFF] | +| taskID | 任务ID号 | [0,0xFFFFFFFF] | + + +## 使用指南 -## 输出说明 +- 参数缺省时,显示系统10s前的CPU占用率。 -**示例** 指令输出结果 +- 只有一个参数时,该参数为mode,显示系统相应时间前的CPU占用率。 -```shell -OHOS # cpup 1 5 +- 输入两个参数时,第一个参数为mode,第二个参数为taskID,显示对应ID号任务的相应时间前的CPU占用率。 -pid 5 CpuUsage in 1s: 0.0 + +## 使用实例 + +举例:输入cpup 1 5 + + +## 输出说明 + +**示例**:指令输出结果 ``` +OHOS # cpup 1 5pid 5 +CpuUsage in 1s: 0.0 +``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-date.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-date.md index dbe3545207..d05bcc3e47 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-date.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-date.md @@ -1,80 +1,58 @@ -# date +# date -- [命令功能](#section56472016338) -- [命令格式](#section16635112512316) -- [参数说明](#section15896030039) -- [使用指南](#section116361036636) -- [使用实例](#section021711411237) -- [输出说明](#section17950184414312) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 date命令用于查询系统日期和时间。 -## 命令格式 + +## 命令格式 - date - date --help -- date +\[_Format_\] +- date +[_Format_] - date -u -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

使用帮助。

-

N/A

-

+Format

-

根据Format格式打印日期和时间。

-

--help中列出的占位符。

-

-u

-

显示UTC,而不是当前时区

-

N/A

-
- -## 使用指南 - -- date参数缺省时,默认显示系统UTC日期和时间。 -- --help、+Format、-u不能混合使用。 -- 目前命令不支持设置时间和日期。 - -## 使用实例 +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 使用帮助。 | N/A | +| +Format | 根据Format格式打印日期和时间。 | --help中列出的占位符。 | +| -u | 显示UTC,而不是当前时区 | N/A | + + +## 使用指南 + +- date参数缺省时,默认显示系统UTC日期和时间。 + +- --help、+Format、-u不能混合使用。 + +- 目前命令不支持设置时间和日期。 + + +## 使用实例 举例:输入 date +%Y--%m--%d -## 输出说明 -**示例** 按指定格式打印系统日期 +## 输出说明 + +示例:按指定格式打印系统日期 -```shell +``` OHOS:/$ date +%Y--%m--%d 1970--01--01 -``` \ No newline at end of file +``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md index 285837cbed..1a262cc869 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.md @@ -1,115 +1,66 @@ -# dmesg - -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) - -## 命令功能 - -dmesg命令用于控制内核dmesg缓存区。 - -## 命令格式 - -- dmesg - -- dmesg \[_-c/-C/-D/-E/-L/-U_\] - -- dmesg -s \[_size_\] - -- dmesg -l \[_level_\] - -- dmesg \> \[_fileA_\] - - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-c

-

打印缓存区内容并清空缓存区。

-

N/A

-

-C

-

清空缓存区。

-

N/A

-

-D/-E

-

关闭/开启控制台打印。

-

N/A

-

-L/-U

-

关闭/开启串口打印。

-

N/A

-

-s size

-

设置缓存区大小,size是要设置的大小。

-

1-81920

-

-l level

-

设置缓存等级。

-

0 - 5

-

> fileA

-

将缓存区内容写入文件。

-

N/A

-
- -## 使用指南 - -- 该命令依赖于LOSCFG\_SHELL\_DMESG,使用时通过menuconfig在配置项中开启"Enable Shell dmesg": - - Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell dmesg - -- dmesg参数缺省时,默认打印缓存区内容。 -- 各“ - ”选项不能混合使用。 - 1. 写入文件需确保已挂载文件系统。 - 2. 关闭串口打印会影响shell使用,建议先连接telnet再尝试关闭串口。 - - -## 使用实例 - -举例:输入dmesg \> dmesg.log。 - -## 输出说明 - -**示例** dmesg重定向到文件。 - -```shell +# dmesg + +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) + +## 命令功能 + +dmesg命令用于显示系统启动过程和运行过程中的信息。 + + +## 命令格式 + +dmesg + +dmesg [_-c/-C/-D/-E/-L/-U_] + +dmesg -s [_size_] + +dmesg -l [_level_] + +dmesg > [_fileA_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -c | 打印缓存区内容并清空缓存区。 | N/A | +| -C | 清空缓存区。 | N/A | +| -D/-E | 关闭/开启控制台打印。 | N/A | +| -L/-U | 关闭/开启串口打印。 | N/A | +| -s size | 设置缓存区大小 size是要设置的大小。 | N/A | +| -l level | 设置缓存等级。 | 0 - 5 | +| > fileA | 将缓存区内容重定向写入文件。 | N/A | + + +## 使用指南 + +- 该命令依赖于LOSCFG_SHELL_DMESG,使用时通过menuconfig在配置项中开启"Enable Shell dmesg": + Debug ---> Enable a Debug Version ---> Enable Shell ---> Enable Shell dmesg + +- dmesg参数缺省时,默认打印缓存区内容。 + +- 各“ - ”选项不能混合使用。 + 1. 写入文件需确保已挂载文件系统。 + 2. 关闭串口打印会影响shell使用,建议先连接telnet再尝试关闭串口。 + + +## 使用实例 + +举例:输入dmesg > dmesg.log。 + + +## 输出说明 + +**示例**:dmesg重定向到文件 +``` OHOS # dmesg > dmesg.log Dmesg write log to dmesg.log success ``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md index b4e4f0a9e0..53b5151643 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-exec.md @@ -1,60 +1,49 @@ -# exec +# exec -- [命令功能](#section4643204919313) -- [命令格式](#section6553153635) -- [参数说明](#section208971157532) -- [使用指南](#section213115219413) -- [使用实例](#section13736564418) -- [输出说明](#section194005101413) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 exec命令属于shell内置命令,目前实现最基础的执行用户态程序的功能。 -## 命令格式 -exec <_executable-file_\> +## 命令格式 -## 参数说明 +exec <_executable-file_> -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

executable-file

-

有效的可执行文件。

-

N/A

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| executable-file | 有效的可执行文件。 | N/A | + + +## 使用指南 该命令当前仅支持执行有效的二进制程序,程序成功执行,默认后台运行,但与Shell共用终端,可能会导致程序打印输出与Shell输出交错显示。 -## 使用实例 + +## 使用实例 举例: 输入exec helloworld。 -## 输出说明 + +## 输出说明 ``` OHOS # exec helloworld OHOS # hello world! ``` ->![](../public_sys-resources/icon-note.gif) **说明:** ->可执行文件执行后,先打印“OHOS \#”提示符原因:目前Shell “exec”命令执行均为后台执行,结果可能导致提示符提前打印。 - +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 可执行文件执行后,先打印“OHOS \#”提示符原因:目前Shell “exec”命令执行均为后台执行,结果可能导致提示符提前打印。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-free.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-free.md index 3ef00f87b0..18c5b5cce5 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-free.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-free.md @@ -1,98 +1,50 @@ -# free +# free -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 free命令可显示系统内存的使用情况。 -## 命令格式 - -free \[_-b | -k | -m | -g | -t_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

无参数

-

以Byte为单位显示。

-

N/A

-

--help/-h

-

查看free命令支持的参数列表。

-

N/A

-

-b

-

以Byte为单位显示。

-

N/A

-

-k

-

以KiB为单位显示。

-

N/A

-

-m

-

以MiB为单位显示。

-

N/A

-

-g

-

以GiB为单位显示。

-

N/A

-

-t

-

以TiB为单位显示。

-

N/A

-
- -## 使用指南 + +## 命令格式 + +free [_-b | -k | -m | -g | -t_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| 无参数 | 以Byte为单位显示。 | N/A | +| --help/-h | 查看free命令支持的参数列表。 | N/A | +| -b | 以Byte为单位显示。 | N/A | +| -k | 以KiB为单位显示。 | N/A | +| -m | 以MiB为单位显示。 | N/A | +| -g | 以GiB为单位显示。 | N/A | +| -t | 以TiB为单位显示。 | N/A | + + +## 使用指南 无。 -## 使用实例 -举例:分别输入free、free -k、free -m。 +## 使用实例 + +举例:分别输入free、free -k、free -m. -## 输出说明 -**示例** 以三种方式显示内存使用情况 +## 输出说明 -```shell +``` OHOS:/$ free total used free shared buffers Mem: 2819652 2754468 65184 0 0 @@ -110,39 +62,12 @@ Mem: 2 2 0 0 0 Swap: 0 0 0 ``` -**表 2** 输出元素说明 - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

total

-

表示系统动态内存池总量。

-

used

-

表示已使用内存总量。

-

free

-

表示未被分配的内存大小。

-

shared

-

表示共享内存大小。

-

buffers

-

表示缓冲区内存大小。

-
+**表2** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| total | 表示系统动态内存池总量。 | +| used | 表示已使用内存总量。 | +| free | 表示未被分配的内存大小。 | +| shared | 表示共享内存大小。 | +| buffers | 表示缓冲区内存大小。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-help.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-help.md index a5e1a75b0f..164b3c8fb4 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-help.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-help.md @@ -1,41 +1,48 @@ -# help +# help -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 help命令用于显示当前操作系统内所有操作指令和部分toybox指令。 -## 命令格式 + +## 命令格式 help -## 参数说明 + +## 参数说明 无。 -## 使用指南 + +## 使用指南 help用于显示当前操作系统内所有操作指令。 -## 使用实例 -举例:输入help。 +## 使用实例 -## 输出说明 +举例:输入help -**示例** 查看系统内所有操作指令 -```shell -OHOS:/$ help -OHOS:/$ help -*******************shell commands:************************* +## 输出说明 +查看系统内所有操作指令。 + +``` +After shell prompt "OHOS # ": +Use ` [args ...]` to run built-in shell commands listed above. +Use `exec [args ...]` or `./ [args ...]` to run external commands. + +OHOS:/$ help +***shell commands:* arp cat cat_logmpp cd chgrp chmod chown cp cpup date dhclient dmesg dns format free help hi3881 hwi @@ -46,18 +53,13 @@ reset rm rmdir sem shm stack statfs su swtmr sync systeminfo task telnet touch umount uname v2p vmm watch writeproc - After shell prompt "OHOS # ": Use ` [args ...]` to run built-in shell commands listed above. Use `exec [args ...]` or `./ [args ...]` to run external commands. - -*******************toybox commands:************************ - +***toybox commands: chgrp chmod chown cp date du free help ifconfig kill ls mkdir mount mv ping ps reboot rm rmdir top touch umount uname - Use `toybox help [command]` to show usage information for a specific command. - Use `shell` to enter interactive legacy shell. Use `alias` to display command aliases. ``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md index d80b73dd65..7e260a4715 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-hwi.md @@ -1,162 +1,124 @@ -# hwi +# hwi -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 hwi命令查询当前中断信息 -## 命令格式 + +## 命令格式 hwi -## 参数说明 + +## 参数说明 无。 -## 使用指南 -- 输入hwi即显示当前中断号、中断次数及注册中断名称。 -- 若开关LOSCFG\_CPUP\_INCLUDE\_IRQ打开,则还会显示各个中断的处理时间(cycles)、CPU占用率以及中断类型。 +## 使用指南 + +- 输入hwi即显示当前中断号、中断次数及注册中断名称。 + +- 若开关LOSCFG_CPUP_INCLUDE_IRQ打开,则还会显示各个中断的处理时间ATime、CPU占用率以及中断类型。 + -## 使用实例 +## 使用实例 举例:输入hwi -## 输出说明 - -- 显示中断信息(LOSCFG\_CPUP\_INCLUDE\_IRQ关闭) - -```shell -OHOS # hwi - InterruptNo Count Name - 0: 0: - 1: 1025641: - 2: 0: - 29: 824049: - 37: 0: rtc_alarm - 38: 24: uart_pl011 - 48: 3: GPIO - 59: 0: - 62: 530: MMC_IRQ - 63: 70: MMC_IRQ - 64: 280: ETH - 67: 58: tde - 68: 0: JPGE_0 - 69: 0: IVE - 70: 0: VGS - 72: 0: VEDU_0 - 73: 0: nnie0 - 74: 0: nnie_gdc0 - 75: 0: VPSS - 76: 0: VI_PROC0 - 77: 0: JPEGD_0 - 83: 49455: HIFB_SOFT_INT - 87: 0: AIO interrupt - 88: 0: VI_CAP0 - 89: 0: MIPI_RX - 90: 49455: VO int - 91: 49456: HIFB Int - 96: 17601: MMC_IRQ - 100: 0: SPI_HI35XX - 101: 0: SPI_HI35XX - 102: 0: SPI_HI35XX - -``` - -- 显示中断信息(LOSCFG\_CPUP\_INCLUDE\_IRQ打开) - -```shell -OHOS # hwi - InterruptNo Count ATime(us) CPUUSE CPUUSE10s CPUUSE1s Mode Name - 0: 0 0 0.0 0.0 0.0 normal - 1: 937031 0 0.1 0.1 0.1 normal - 2: 0 0 0.0 0.0 0.0 normal - 29: 726166 5 0.54 0.57 0.59 normal - 37: 0 0 0.0 0.0 0.0 normal rtc_alarm - 38: 17 5 0.0 0.0 0.0 normal uart_pl011 - 48: 3 4 0.0 0.0 0.0 normal GPIO - 59: 0 0 0.0 0.0 0.0 normal - 62: 531 1 0.0 0.0 0.0 normal MMC_IRQ - 63: 69 1 0.0 0.0 0.0 normal MMC_IRQ - 64: 292 2 0.0 0.0 0.0 normal ETH - 67: 54 76 0.0 0.0 0.0 shared tde - 68: 0 0 0.0 0.0 0.0 shared JPGE_0 - 69: 0 0 0.0 0.0 0.0 shared IVE - 70: 0 0 0.0 0.0 0.0 shared VGS - 72: 0 0 0.0 0.0 0.0 shared VEDU_0 - 73: 0 0 0.0 0.0 0.0 shared nnie0 - 74: 0 0 0.0 0.0 0.0 shared nnie_gdc0 - 75: 0 0 0.0 0.0 0.0 shared VPSS - 76: 0 0 0.0 0.0 0.0 shared VI_PROC0 - 77: 0 0 0.0 0.0 0.0 shared JPEGD_0 - 83: 45529 8 0.5 0.5 0.5 shared HIFB_SOFT_INT - 87: 0 0 0.0 0.0 0.0 shared AIO interrupt - 88: 0 0 0.0 0.0 0.0 shared VI_CAP0 - 89: 0 0 0.0 0.0 0.0 shared MIPI_RX - 90: 45534 11 0.6 0.7 0.7 shared VO int - 91: 45533 2 0.1 0.1 0.1 shared HIFB Int - 96: 17383 2 0.0 0.0 0.0 normal MMC_IRQ - 100: 0 0 0.0 0.0 0.0 normal SPI_HI35XX - 101: 0 0 0.0 0.0 0.0 normal SPI_HI35XX - 102: 0 0 0.0 0.0 0.0 normal SPI_HI35XX -``` - -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

InterruptNo

-

中断号。

-

Count

-

中断次数。

-

Name

-

注册中断名称。

-

CYCLECOST

-

中断的处理时间(cycles)。

-

CPUUSE

-

CPU占用率。

-

CPUUSE10s

-

最近10s CPU占用率。

-

CPUUSE1s

-

最近1s CPU占用率。

-

mode

-

中断类型:

-
  • normal: 非共享中断。
  • shared: 共享中断。
-
+## 输出说明 + +- 显示中断信息(LOSCFG_CPUP_INCLUDE_IRQ关闭) + ``` + OHOS # hwi + InterruptNo Count Name + 0: 0: + 1: 1025641: + 2: 0: + 29: 824049: + 37: 0: rtc_alarm + 38: 24: uart_pl011 + 48: 3: GPIO + 59: 0: + 62: 530: MMC_IRQ + 63: 70: MMC_IRQ + 64: 280: ETH + 67: 58: tde + 68: 0: JPGE_0 + 69: 0: IVE + 70: 0: VGS + 72: 0: VEDU_0 + 73: 0: nnie0 + 74: 0: nnie_gdc0 + 75: 0: VPSS + 76: 0: VI_PROC0 + 77: 0: JPEGD_0 + 83: 49455: HIFB_SOFT_INT + 87: 0: AIO interrupt + 88: 0: VI_CAP0 + 89: 0: MIPI_RX + 90: 49455: VO int + 91: 49456: HIFB Int + 96: 17601: MMC_IRQ + 100: 0: SPI_HI35XX + 101: 0: SPI_HI35XX + 102: 0: SPI_HI35XX + ``` + +- 显示中断信息(LOSCFG_CPUP_INCLUDE_IRQ打开) + ``` + OHOS # hwi + InterruptNo Count ATime(us) CPUUSE CPUUSE10s CPUUSE1s Mode Name + 0: 0 0 0.0 0.0 0.0 normal + 1: 937031 0 0.1 0.1 0.1 normal + 2: 0 0 0.0 0.0 0.0 normal + 29: 726166 5 0.54 0.57 0.59 normal + 37: 0 0 0.0 0.0 0.0 normal rtc_alarm + 38: 17 5 0.0 0.0 0.0 normal uart_pl011 + 48: 3 4 0.0 0.0 0.0 normal GPIO + 59: 0 0 0.0 0.0 0.0 normal + 62: 531 1 0.0 0.0 0.0 normal MMC_IRQ + 63: 69 1 0.0 0.0 0.0 normal MMC_IRQ + 64: 292 2 0.0 0.0 0.0 normal ETH + 67: 54 76 0.0 0.0 0.0 shared tde + 68: 0 0 0.0 0.0 0.0 shared JPGE_0 + 69: 0 0 0.0 0.0 0.0 shared IVE + 70: 0 0 0.0 0.0 0.0 shared VGS + 72: 0 0 0.0 0.0 0.0 shared VEDU_0 + 73: 0 0 0.0 0.0 0.0 shared nnie0 + 74: 0 0 0.0 0.0 0.0 shared nnie_gdc0 + 75: 0 0 0.0 0.0 0.0 shared VPSS + 76: 0 0 0.0 0.0 0.0 shared VI_PROC0 + 77: 0 0 0.0 0.0 0.0 shared JPEGD_0 + 83: 45529 8 0.5 0.5 0.5 shared HIFB_SOFT_INT + 87: 0 0 0.0 0.0 0.0 shared AIO interrupt + 88: 0 0 0.0 0.0 0.0 shared VI_CAP0 + 89: 0 0 0.0 0.0 0.0 shared MIPI_RX + 90: 45534 11 0.6 0.7 0.7 shared VO int + 91: 45533 2 0.1 0.1 0.1 shared HIFB Int + 96: 17383 2 0.0 0.0 0.0 normal MMC_IRQ + 100: 0 0 0.0 0.0 0.0 normal SPI_HI35XX + 101: 0 0 0.0 0.0 0.0 normal SPI_HI35XX + 102: 0 0 0.0 0.0 0.0 normal SPI_HI35XX + ``` + + **表1** 输出说明 + + | 输出 | 说明 | + | -------- | -------- | + | InterruptNo | 中断号。 | + | Count | 中断次数。 | + | Name | 注册中断名称。 | + | ATime | 中断的处理时间。 | + | CPUUSE | CPU占用率。 | + | CPUUSE10s | 最近10s CPU占用率。 | + | CPUUSE1s | 最近1s CPU占用率。 | + | mode | 中断类型:
- normal:  非共享中断。
- shared:  共享中断。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md index dbcead042d..255a6ae259 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-kill.md @@ -1,144 +1,103 @@ -# kill +# kill -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 命令用于发送特定信号给指定进程。 -## 命令格式 - -kill \[-l \[_signo_\] | _-s signo_ | _-signo_\] _pid..._ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看kill命令支持的参数列表

-

N/A

-

-l

-

列出信号名称和编号。

-

N/A

-

-s

-

发送信号

-

N/A

-

signo

-

信号ID。

-

[1,30]

-

pid

-

进程ID。

-

[1,MAX_INT]

-
- ->![](../public_sys-resources/icon-notice.gif) **须知:** ->signo有效范围为\[0,64\],建议取值范围为\[1,30\],其余为保留内容。 - -## 使用指南 -- 必须指定发送的信号编号及进程号。 +## 命令格式 -- 进程编号取值范围根据系统配置变化,例如系统最大支持pid为256,则取值范围缩小为\[1-256\]。 +kill [-l [_signo_] | _-s signo_ | _-signo_] _pid..._ -## 使用实例 +## 参数说明 -- 查看当前进程列表,查看需要杀死的进程PID(42)。 +**表1** 参数说明 -``` -OHOS:/$ ps - - allCpu(%): 4.67 sys, 195.33 idle - - PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName - 1 -1 1 0 Pending 0x33b000 0xbb000 0x4db02 0.0 init - 2 -1 2 0 Pending 0xdabc08 0 0xdabc08 1.14 KProcess - 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d24c2 0.0 foundation - 4 1 4 8 Pending 0x362000 0xbb000 0x5c6ff 0.0 bundle_daemon - 5 1 5 1 Pending 0xdfa000 0x2e7000 0x1484f0 0.0 appspawn - 6 1 6 0 Pending 0x688000 0x137000 0x11bca0 0.0 media_server - 7 1 7 0 Pending 0x9d2000 0x103000 0xa1cdf 0.88 wms_server - 8 1 8 2 Pending 0x1f5000 0x48000 0x47dc2 0.2 mksh - 10 5 5 101 Pending 0x11ec000 0x2f9000 0x206047 0.93 com.huawei.launcher - 12 1 12 0 Pending 0x4d4000 0x112000 0xe0882 0.0 deviceauth_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 - 15 1 15 0 Pending 0x61f000 0x13b000 0x168071 0.45 softbus_server - 42 8 42 2 Pending 0x1c1000 0x3a000 0x1106a 0.9 test_demo - 43 8 43 2 Running 0x1d7000 0x3a000 0x1e577 0.0 toybox -``` +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看kill命令支持的参数列表 | N/A | +| -l | 列出信号名称和编号。 | N/A | +| -s | 发送信号 | N/A | +| signo | 信号ID。 | [1,30] | +| pid | 进程ID。 | [1,MAX_INT] | -发送信号9(SIGKILL默认行为为立即终止进程)给42号进程**test\_demo**(用户态进程):**kill -s 9 42**(kill -9 42效果相同),并查看当前进程列表,42号进程已终止。 +> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** +> signo有效范围为[0,64],建议取值范围为[1,30],其余为保留内容。 -``` -OHOS:/$ kill -s 9 42 -OHOS:/$ -[1] + Killed ./nfs/test_demo -OHOS:/$ ps - - allCpu(%): 4.73 sys, 195.27 idle - - PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName - 1 -1 1 0 Pending 0x33b000 0xbb000 0x4e01c 0.0 init - 2 -1 2 0 Pending 0xda5fa4 0 0xda5fa4 1.14 KProcess - 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d29dc 0.0 foundation - 4 1 4 8 Pending 0x362000 0xbb000 0x5cc19 0.0 bundle_daemon - 5 1 5 1 Pending 0xdfa000 0x2e7000 0x148a0a 0.0 appspawn - 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server - 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.89 wms_server - 8 1 8 2 Pending 0x1f5000 0x48000 0x482dc 0.2 mksh - 10 5 5 101 Pending 0x11ec000 0x2f9000 0x206561 0.93 com.huawei.launcher - 12 1 12 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_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 - 15 1 15 0 Pending 0x61f000 0x13b000 0x16858b 0.51 softbus_server - 45 8 45 2 Running 0x1d7000 0x3a000 0x1e9f5 0.0 toybox -``` + +## 使用指南 + +- 必须指定发送的信号编号及进程号。 + +- 进程编号取值范围根据系统配置变化,例如系统最大支持pid为256,则取值范围缩小为[1-256]。 + + +## 使用实例 + +- 查看当前进程列表,查看需要杀死的进程PID(42)。 + ``` + OHOS:/$ ps + allCpu(%): 4.67 sys, 195.33 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4db02 0.0 init + 2 -1 2 0 Pending 0xdabc08 0 0xdabc08 1.14 KProcess + 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d24c2 0.0 foundation + 4 1 4 8 Pending 0x362000 0xbb000 0x5c6ff 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x1484f0 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11bca0 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa1cdf 0.88 wms_server + 8 1 8 2 Pending 0x1f5000 0x48000 0x47dc2 0.2 mksh + 10 5 5 101 Pending 0x11ec000 0x2f9000 0x206047 0.93 com.huawei.launcher + 12 1 12 0 Pending 0x4d4000 0x112000 0xe0882 0.0 deviceauth_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 + 15 1 15 0 Pending 0x61f000 0x13b000 0x168071 0.45 softbus_server + 42 8 42 2 Pending 0x1c1000 0x3a000 0x1106a 0.9 test_demo + 43 8 43 2 Running 0x1d7000 0x3a000 0x1e577 0.0 toybox + ``` + +- 发送信号9(SIGKILL默认行为为立即终止进程)给42号进程test_demo(用户态进程):kill -s 9 42(kill -9 42效果相同),并查看当前进程列表,42号进程已终止。 + ``` + OHOS:/$ kill -s 9 42 + OHOS:/$ + [1] + Killed ./nfs/test_demo + OHOS:/$ ps + allCpu(%): 4.73 sys, 195.27 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4e01c 0.0 init + 2 -1 2 0 Pending 0xda5fa4 0 0xda5fa4 1.14 KProcess + 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d29dc 0.0 foundation + 4 1 4 8 Pending 0x362000 0xbb000 0x5cc19 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x148a0a 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.89 wms_server + 8 1 8 2 Pending 0x1f5000 0x48000 0x482dc 0.2 mksh + 10 5 5 101 Pending 0x11ec000 0x2f9000 0x206561 0.93 com.huawei.launcher + 12 1 12 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_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 + 15 1 15 0 Pending 0x61f000 0x13b000 0x16858b 0.51 softbus_server + 45 8 45 2 Running 0x1d7000 0x3a000 0x1e9f5 0.0 toybox + ``` - 发送不存在的信号值 kill -100 31 -## 输出说明 + +## 输出说明 发送成功或失败输出结果如下。 -**示例 1** 发送信号给指定进程 +**示例 1** 发送信号给指定进程 -```shell +``` OHOS:/$ kill -s 9 42 OHOS:/$ [1] + Killed ./nfs/test_demo @@ -146,12 +105,11 @@ OHOS:/$ 信号发送成功会显示的提示进程已被杀死。 -**示例 2** 信号发送失败 +**示例 2** 信号发送失败 -```shell +``` OHOS:/$ kill -100 31 kill: Unknown signal '(null)' ``` 信号发送失败,示例2所示原因为信号发送命令参数无效,请排查信号编号及进程编号是否有效。 - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-log.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-log.md index 8edb4bcf12..58c39c7625 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-log.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-log.md @@ -1,79 +1,66 @@ -# log +# log -- [命令功能](#section128219131856) -- [命令格式](#section3894181710519) -- [参数说明](#section7693122310515) -- [使用指南](#section1982111281512) -- [使用实例](#section176301333259) -- [输出说明](#section14354765415) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 -log命令用于修改&查询日志配置。 +log命令用于修改&查询日志配置。 -## 命令格式 -log level \[_levelNum_\] +## 命令格式 -## 参数说明 +log level [_levelNum_] -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

levelNum

-

配置日志打印等级。

-

[0,5]

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -- 该命令依赖于LOSCFG\_SHELL\_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk": +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| levelNum | 配置日志打印等级。 | [0,5] | - Debug ---\> Enable a Debug Version ---\> Enable Shell ---\> Enable Shell lK。 -- log level命令用于配置日志的打印等级,包括6个等级 +## 使用指南 - TRACE\_EMG = 0, +- 该命令依赖于LOSCFG_SHELL_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk": + Debug ---> Enable a Debug Version ---> Enable Shell ---> Enable Shell lK。 - TRACE\_COMMON = 1, +- log level命令用于配置日志的打印等级,包括6个等级 + TRACE_EMG = 0, - TRACE\_ERROR = 2, + TRACE_COMMON = 1, - TRACE\_WARN = 3, + TRACE_ERROR = 2, - TRACE\_INFO = 4, + TRACE_WARN = 3, - TRACE\_DEBUG = 5 + TRACE_INFO = 4, - 若level不在有效范围内,会打印提示信息。 + TRACE_DEBUG = 5 -- 若log level命令不加\[levelNum\]参数,则默认查看当前打印等级,并且提示使用方法。 + 若level不在有效范围内,会打印提示信息。 -- 开源小型系统源码设置level 为4或者5会有超多打印。 +- 若log level命令不加[levelNum]参数,则默认查看当前打印等级,并且提示使用方法。 -## 使用实例 +- 开源小型系统源码设置level 为4或者5会有超多打印。 + + +## 使用实例 举例:输入log level 3 -## 输出说明 -**示例** 设置当前日志打印级别为3 +## 输出说明 + +**示例**:设置当前日志打印级别为3 -```shell +``` OHOS # log level 3 Set current log level WARN ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md index 989f35f97a..a27fa6a622 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-memcheck.md @@ -1,48 +1,53 @@ -# memcheck +# memcheck -- [命令功能](#section191633812516) -- [命令格式](#section428816435510) -- [参数说明](#section1939943304411) -- [使用指南](#section228914491951) -- [使用实例](#section17373205314515) -- [输出说明](#section13406205385413) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 检查动态申请的内存块是否完整,是否存在内存越界造成节点损坏。 -## 命令格式 + +## 命令格式 memcheck -## 参数说明 + +## 参数说明 无。 -## 使用指南 -- 当内存池所有节点完整时,输出"system memcheck over, all passed!"。 -- 当内存池存在节点不完整时,输出被损坏节点的内存块信息。 +## 使用指南 + +- 当内存池所有节点完整时,输出"system memcheck over, all passed!"。 + +- 当内存池存在节点不完整时,输出被损坏节点的内存块信息。 + -## 使用实例 +## 使用实例 举例: - 输入memcheck + - 输入memcheck出现内存越界 -## 输出说明 -**示例 1** 当前没有内存越界 +## 输出说明 -```shell +**示例1:**当前没有内存越界 +``` OHOS # memcheck system memcheck over, all passed! ``` -**示例 2** 出现内存越界 - -```shell +**示例2:**出现内存越界 +``` [L0S DLnkCheckMenl 349, memory check stFreeNodeInfo.pstPrev:0x7e0d31f3 is out of legal mem range[0x80ba5f40, 0х83d00000] cur node: 0x81f2ce0c @@ -53,7 +58,7 @@ puмExcBuffAddr pc = 0x803ad7a4 puwExcBuffAddr lr = 0x803ad7a4 puwExcBuffAddr sp = 0х80cb7de0 puwExcBuffAddr fp = 0x80cb7dec -*******backtrace begin******* +***backtrace begin*** traceback 0 -- lr = 0х8037cb84 traceback 0 -- fp = 0х80cb7e1c traceback 1 -- lr = 0х8037033c @@ -65,4 +70,3 @@ traceback 3 -- fp = 0х80cb7ea4 traceback 4 -- lr = 0x803ad9e8 traceback 4 -- fp = 9x11111111 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md index dc61c380e0..79680602c6 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-oom.md @@ -1,86 +1,63 @@ -# oom +# oom -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [输出说明](#section12742311179) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 查看和设置低内存阈值以及pagecache内存回收阈值。 -## 命令格式 -- oom +## 命令格式 + +oom + +oom -i [_interval_] + +oom -m [_mem byte_] + +oom -r [_mem byte_] + +oom -h | --help + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -i [interval] | 设置oom线程任务检查的时间间隔。 | 100ms ~ 10000ms | +| -m [mem byte] | 设置低内存阈值。 | 0MB ~ 1MB,0MB表示不做低内存阈值检查。 | +| -r [mem byte] | 设置pagecache内存回收阈值。 | 低内存阈值 ~ 系统可用最大内存。 | +| -h \| --help | 使用帮助。 | N/A | + + +## 使用指南 + +参数缺省时,显示oom功能当前配置信息。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 当系统内存不足时,会打印出内存不足的提示信息。 -- oom -i \[_interval_\] - -- oom -m \[_mem byte_\] - -- oom -r \[_mem byte_\] - -- oom -h | --help - - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-i [interval]

-

设置oom线程任务检查的时间间隔。

-

100ms ~ 10000ms

-

-m [mem byte]

-

设置低内存阈值。

-

0MB ~ 1MB,0MB表示不做低内存阈值检查。

-

-r [mem byte]

-

设置pagecache内存回收阈值。

-

低内存阈值 ~ 系统可用最大内存。

-

-h | --help

-

使用帮助。

-

N/A

-
- -## 使用指南 - -- 参数缺省时,显示oom功能当前配置信息。 - - >![](../public_sys-resources/icon-note.gif) **说明:** - >当系统内存不足时,会打印出内存不足的提示信息。 + +## 使用实例 + +举例: + +- oom - oom -i 100 -## 输出说明 -**示例 1** oom缺省打印配置信息 +## 输出说明 + +**示例1:**oom缺省打印配置信息 -```shell +``` OHOS:/$ oom [oom] oom loop task status: enabled oom low memory threshold: 0x80000(byte) @@ -90,7 +67,7 @@ OHOS:/$ oom 系统内存不足时打印提示信息 -```shell +``` T:20 Enter:IT MEM 00M 001 [oom] OS is in low memory state total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte) ,free: 0x7f000(byte), low memory threshold: 0x80000(byte) @@ -126,7 +103,7 @@ R10 = 0xa0a0a0a R11 = 0x20e20c8c R12 = 0х0 CPSR = 0х80000010 -*******backtrace beain******* +***backtrace beain*** 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 2 -- 1r = 0x9396ab0 fp = 0x20e20cec lr in /usr/bin/testsuits app -> 0х19fab0 @@ -135,48 +112,22 @@ 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 ``` -**示例 2** 设置 oom 线程任务检查的时间间隔 -```shell +**示例2**:设置 oom 线程任务检查的时间间隔 + + +``` OHOS:/$ oom -i 100 [oom] set oom check interval (100)ms successful ``` -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

[oom] OS is in low memory state

-

total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte)

-

操作系统处于低内存状态。

-

整个系统可用物理内存为0x1bcf000 byte,已经使用了 0x1b50000 byte, 还剩0x7f000 byte,当前设置的低内存阈值为0x80000 byte。

-

[oom] candidate victim process init pid: 1, actual phy mem byte: 82602

-

打印当前各个进程的内存使用情况,init进程实际使用82602byte,其中共享内存按照比例算的。

-

[oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558

-

UserProcess12进程实际使用25951558byte内存。

-

[oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558

-

当前使用内存最多的进程是UserProcess12。

-

excFrom: User!

-

当系统处于低内存的情况下,UserProcess12进程再去申请内存时失败退出。

-
+ +**表2** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| [oom] OS is in low memory state
total physical memory: 0x1bcf000(byte), used: 0x1b50000(byte), free: 0x7f000(byte), low memory threshold: 0x80000(byte) | 操作系统处于低内存状态。
整个系统可用物理内存为0x1bcf000 byte,已经使用了 0x1b50000 byte, 还剩0x7f000 byte,当前设置的低内存阈值为0x80000 byte。 | +| [oom] candidate victim process init pid: 1, actual phy mem byte: 82602 | 打印当前各个进程的内存使用情况,init进程实际占用物理内存82602byte。 | +| [oom] candidate victim process UserProcess12 pid: 12, actual phy mem byte: 25951558 | UserProcess12进程实际使用25951558byte内存。 | +| [oom] max phy mem used process UserProcess12 pid: 12, actual phy mem: 25951558 | 当前使用内存最多的进程是UserProcess12。 | +| excFrom: User! | 当系统处于低内存的情况下,UserProcess12进程再去申请内存时失败退出。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md index 16627c7f06..542993c710 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-pmm.md @@ -1,39 +1,42 @@ -# pmm +# pmm -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 查看系统内存物理页及pagecache物理页使用情况。 -## 命令格式 + +## 命令格式 pmm -## 参数说明 + +## 参数说明 无 -## 使用指南 + +## 使用指南 Debug版本才具备的命令。 -## 使用实例 + +## 使用实例 举例:输入pmm -## 输出说明 -**示例** 查看物理页使用情况 +## 输出说明 -```shell +**示例:**查看物理页使用情况 +``` OHOS # pmm - phys_seg base size free_pages -------- ------- ---------- --------- 0x4065552c 0x809b0000 0x07550000 22344 @@ -50,7 +53,6 @@ active anon 0 inactive anon 0 active file 1385 inactice file 84 - pmm pages: total = 30032, used = 7688, free = 22344 pathCache number = 325 pathCache memory size = 17621(B) @@ -58,59 +60,16 @@ Vnode number = 67 Vnode memory size = 10720(B) ``` -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

phys_seg

-

物理页控制块地址信息

-

base

-

第一个物理页地址,即物理页内存起始地址

-

size

-

物理页内存大小

-

free_pages

-

空闲物理页数量

-

active anon

-

pagecache中,活跃的匿名页数量

-

inactive anon

-

pagecache中,不活跃的匿名页数量

-

active file

-

pagecache中,活跃的文件页数量

-

inactive file

-

pagecache中,不活跃的文件页数量

-

pmm pages

-

total:总的物理页数,used:已使用的物理页数,free:空闲的物理页数

-
+**表1** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| phys_seg | 物理页控制块地址信息 | +| base | 第一个物理页地址,即物理页内存起始地址 | +| size | 物理页内存大小 | +| free_pages | 空闲物理页数量 | +| active anon | pagecache中,活跃的匿名页数量 | +| inactive anon | pagecache中,不活跃的匿名页数量 | +| active file | pagecache中,活跃的文件页数量 | +| inactive file | pagecache中,不活跃的文件页数量 | +| pmm pages | total:总的物理页数,used:已使用的物理页数,free:空闲的物理页数 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md index 9ee15a22d1..6fbd707bb8 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reboot.md @@ -1,33 +1,37 @@ -# reboot - -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) - -## 命令功能 - -reboot命令用于重启设备。 - -## 命令格式 - -reboot - -## 参数说明 - -无。 - -## 使用指南 - -reboot命令输入后,设备会立刻重启。 - -## 使用实例 - -reboot - -## 输出说明 - -无。 - +# reboot + +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) + +## 命令功能 + +reboot命令用于重启设备。 + + +## 命令格式 + +reboot + + +## 参数说明 + +无。 + + +## 使用指南 + +reboot命令输入后,设备会立刻重启。 + + +## 使用实例 + +reboot + + +## 输出说明 + +无。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md index c359250aa2..e0eb5fe640 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-reset.md @@ -1,33 +1,37 @@ -# reset +# reset -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section12742311179) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 reset命令用于重启设备。 -## 命令格式 + +## 命令格式 reset -## 参数说明 + +## 参数说明 无。 -## 使用指南 + +## 使用指南 reset命令输入后,设备会立刻重启。 -## 使用实例 + +## 使用实例 reset -## 输出说明 -无。 +## 输出说明 +无。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md index 3b8d57161a..e0b1c8c6ae 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sem.md @@ -1,123 +1,128 @@ -# sem +# sem -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section1975118519456) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 sem命令用于查询系统内核信号量相关信息。 -## 命令格式 -sem \[_ID__ / fulldata_\] +## 命令格式 -## 参数说明 +sem [_ID__ / fulldata_] -**表 1** 参数说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

ID

-

信号ID号。

-

[0, 0xFFFFFFFF]

-

fulldata

-

查询所有在用的信号量信息,打印信息包括如下:SemID, Count, Original Count, Creater TaskEntry, Last Access Time。

-

N/A

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -- 参数缺省时,显示所有的信号量的使用数及信号量总数。 -- sem后加ID,显示对应ID信号量的使用数。 -- 参数fulldata依赖于LOSCFG\_DEBUG\_SEMAPHORE,使用时通过menuconfig在配置项中开启"Enable Semaphore Debugging": +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| ID | 信号量ID。 | [0, 1023]或[0x0, 0x3FF] | +| fulldata | 查询所有在用的信号量信息,打印信息包括如下:SemID, Count, Original Count, Creater TaskEntry, Last Access Time。 | N/A | - Debug ---\> Enable a Debug Version ---\> Enable Debug LiteOS Kernel Resource ---\> Enable Semaphore Debugging +## 使用指南 -## 使用实例 +- 参数缺省时,显示所有的信号量的使用数及信号量总数。 -举例:输入 sem fulldata +- sem后加ID,显示对应ID信号量的使用数。 -## 输出说明 +- 参数fulldata依赖于LOSCFG_DEBUG_SEMAPHORE,使用时通过menuconfig在配置项中开启"Enable Semaphore Debugging": + Debug ---> Enable a Debug Version ---> Enable Debug LiteOS Kernel Resource ---> Enable Semaphore Debugging -**示例** 查询所有在用的信号量信息 -```shell -OHOS # sem +## 使用实例 + +- 输入sem + +- 配置LOSCFG_DEBUG_SEMAPHORE标志,输入 sem fulldata + + +## 输出说明 +**示例1**:查询所有在用的信号量信息 +``` +OHOS # sem SemID Count ---------- ----- 0x00000000 1 - SemID Count ---------- ----- 0x00000001 0 - SemID Count ---------- ----- 0x00000002 0 - SemID Count ---------- ----- 0x00000003 1 - SemID Count ---------- ----- 0x00000004 0 - SemID Count ---------- ----- 0x00000005 1 - SemID Count ---------- ----- 0x00000006 0 ``` -**表 2** 输出说明 - - - - - - - - - - - - - - -

输出

-

说明

-

SemID

-

信号量ID。

-

Count

-

信号量使用数。

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->● sem命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 ->● sem命令的ID参数在\[0, 1023\]范围内时,返回对应ID的信号量的状态(如果对应ID的信号量未被使用则进行提示);其他取值时返回参数错误的提示。 +**表2** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| SemID | 信号量ID。 | +| Count | 信号量使用数。 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> ● sem命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 +> +> ● sem命令的ID参数在[0, 1023]范围内时,返回对应ID的信号量的状态(如果对应ID的信号量未被使用则进行提示);其他取值时返回参数错误的提示。 + +**示例2:**查询所有在用的信号量信息 +``` +OHOS # sem fulldata +Used Semaphore List: + SemID Count OriginalCount Creater(TaskEntry) LastAccessTime + ------ ------ ------------- ------------------ -------------- + 0xb 0x0 0x0 0x404978fc 0xa1 + 0xc 0x0 0x0 0x404978fc 0xa1 + 0xd 0x0 0x0 0x404978fc 0x12c + 0x10 0x0 0x0 0x404978fc 0x195 + 0xf 0x0 0x0 0x404978fc 0x195 + 0x11 0x0 0x0 0x4041a998 0x1d5 + 0x15 0x0 0x0 0x404978fc 0x273 + 0x14 0x0 0x0 0x404978fc 0x273 + 0x18 0x0 0x0 0x404978fc 0x352 + 0x17 0x0 0x0 0x404978fc 0x352 + 0x16 0x0 0x0 0x404978fc 0x352 + 0x1d 0x1 0x1 0x404978fc 0x385 + 0x1e 0x1 0x1 0x404978fc 0x388 + 0x1f 0x1 0x1 0x404978fc 0x38d + 0x20 0x1 0x1 0x404978fc 0x38f + 0x21 0x1 0x1 0x404978fc 0x392 + 0x3d 0x1 0x1 0x404978fc 0x395 + 0x3b 0x1 0x1 0x404978fc 0x395 + 0x3c 0x1 0x1 0x404978fc 0x395 + 0x39 0x1 0x1 0x404978fc 0x395 + 0x3a 0x1 0x1 0x404978fc 0x395 + 0x33 0x1 0x1 0x404978fc 0x395 + 0x35 0x1 0x1 0x404978fc 0x395 + 0x34 0x1 0x1 0x404978fc 0x395 + 0x38 0x1 0x1 0x404978fc 0x395 +``` + +**表3** 输出说明 +| 输出 | 说明 | +| -------- | -------- | +| SemID | 信号量ID。 | +| Count | 信号量使用数。 | +| OriginalCount | 信号量原始计数。 | +| Creater | 信号量的创建线程的入口函数地址。 | +| LastAccessTime | 上次访问时间。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md index 22c5d25781..4f1c7ff7e0 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-stack.md @@ -1,39 +1,42 @@ -# stack +# stack -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 查看系统各堆栈使用情况。 -## 命令格式 + +## 命令格式 stack -## 参数说明 + +## 参数说明 无。 -## 使用指南 + +## 使用指南 无。 -## 使用实例 -举例:输入stack +## 使用实例 -## 输出说明 +输入:stack -**示例** 系统堆栈使用情况 -```shell -OHOS # stack +## 输出说明 +**示例:**系统堆栈使用情况 +``` +OHOS # stack stack name cpu id stack addr total size used size ---------- ------ --------- -------- -------- svc_stack 1 0x405c4000 0x2000 0x484 @@ -42,39 +45,12 @@ OHOS # stack exc_stack 0 0x405c9000 0x1000 0x0 ``` -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

stack name

-

系统堆栈名

-

cpu id

-

cpu 号

-

stack addr

-

栈地址

-

total size

-

堆栈大小

-

used size

-

堆栈实际使用大小

-
+**表1** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| stack name | 系统堆栈名 | +| cpu id | cpu 号 | +| stack addr | 栈地址 | +| total size | 堆栈大小 | +| used size | 堆栈实际使用大小 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-su.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-su.md index 3c84c74d27..47ff47672a 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-su.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-su.md @@ -1,65 +1,50 @@ -# su +# su -- [命令功能](#section297810431676) -- [命令格式](#section157131147876) -- [参数说明](#section04145521671) -- [使用指南](#section14615155610719) -- [使用实例](#section13338150985) -- [输出说明](#section125021924194613) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 su用于变更为其他使用者的身份。 -## 命令格式 - -su \[_uid_\] \[_gid_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

uid

-

目标用户的用户id值。

-
[0,60000]

-

gid

-

目标用户的群组id值。

-
[0,60000]

-
- -## 使用指南 - -- su命令缺省切换到root用户,uid默认为0,gid为0。 -- 在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。 -- 输入参数超出范围时,会打印提醒输入正确范围参数。 - -## 使用实例 + +## 命令格式 + +su [_uid_] [_gid_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| uid | 目标用户的用户id值。 | - 为空。
- [0,60000] | +| gid | 目标用户的群组id值。 | - 为空。
- [0,60000] | + + +## 使用指南 + +- su命令缺省切换到root用户,uid默认为0,gid为0。 + +- 在su命令后的输入参数uid和gid就可以切换到该uid和gid的用户。 + +- 输入参数超出范围时,会打印提醒输入正确范围参数。 + + +## 使用实例 举例:su 1000 1000 -## 输出说明 -**示例** 从当前用户切换至uid为1000,gid为1000的用户 +## 输出说明 -```shell +**示例:**切换到为uid为1000,gid为1000的用户 +``` OHOS # ls Directory /data/system/param: -rw-r--r-- 0 u:0 g:0 hello_1.txt @@ -70,4 +55,3 @@ Directory /data/system/param: -rw-r--r-- O u:1000 g:1000 hello 2.txt -гw-r--r-- 0 u:0 g:0 hello_1.txt ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md index 48e4f83a58..6b8e069740 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-swtmr.md @@ -1,143 +1,90 @@ -# swtmr +# swtmr -- [命令功能](#section166171064814) -- [命令格式](#section424011111682) -- [参数说明](#section1268410459465) -- [使用指南](#section169806213815) -- [使用实例](#section16676026389) -- [输出说明](#section1541991614710) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 swtmr命令用于查询系统软件定时器相关信息。 -## 命令格式 -swtmr \[_ID_\] +## 命令格式 -## 参数说明 +swtmr [_ID_] -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

ID

-

软件定时器ID号。

-

[0,0xFFFFFFFF]

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -- 参数缺省时,默认显示所有软件定时器的相关信息。 -- swtmr后加ID号时,显示ID对应的软件定时器相关信息。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| ID | 软件定时器ID号。 | [0,0xFFFFFFFF] | -## 使用实例 + +## 使用指南 + +- 参数缺省时,默认显示所有软件定时器的相关信息。 + +- swtmr后加ID号时,显示ID对应的软件定时器相关信息。 + + +## 使用实例 举例: - swtmr + - swtmr 1 -## 输出说明 -**示例 1** 查询所有软件定时器相关信息 +## 输出说明 -```shell +**示例1:**查询所有软件定时器相关信息 +``` OHOS # swtmr - SwTmrID State Mode Interval Count Arg handlerAddr ---------- ------- ------- --------- ------- ---------- -------- 0x00000000 Ticking Period 100 77 0x40802a50 0x4037b8a0 - SwTmrID State Mode Interval Count Arg handlerAddr ---------- ------- ------- --------- ------- ---------- -------- 0x00000001 Ticking Period 1000 876 0x00000000 0x4037fc04 - SwTmrID State Mode Interval Count Arg handlerAddr ---------- ------- ------- --------- ------- ---------- -------- 0x00000002 Ticking Period 100 76 0x00000000 0x403727f4 - SwTmrID State Mode Interval Count Arg handlerAddr ---------- ------- ------- --------- ------- ---------- -------- 0x00000016 Ticking NSD 10 6 0x8021e000 0x401fe7d8 - SwTmrID State Mode Interval Count Arg handlerAddr ---------- ------- ------- --------- ------- ---------- -------- 0x00000079 Ticking NSD 30000 1749 0x406189d8 0x40160e1c ``` -**示例 2** 查询对应 ID 的软件定时器信息 - -```shell +**示例2:**查询对应 ID 的软件定时器信息 +``` OHOS # swtmr 1 - SwTmrID State Mode Interval Count Arg handlerAddr ---------- ------- ------- --------- ------- ---------- -------- 0x00000001 Ticking Period 1000 841 0x00000000 0x4037fc04 ``` -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

SwTmrID

-

软件定时器ID。

-

State

-

软件定时器状态。

-

状态可能为:"UnUsed", "Created", "Ticking"。

-

Mode

-

软件定时器模式。

-

模式可能为:"Once", "Period", "NSD(单次定时器,定时结束后不会自动删除)"。

-

Interval

-

软件定时器使用的Tick数。

-

Count

-

软件定时器已经工作的次数。

-

Arg

-

传入的参数。

-

handlerAddr

-

回调函数的地址。

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->- swtmr命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 ->- swtmr命令的ID参数在\[0, 当前软件定时器个数 - 1\]范围内时,返回对应ID的软件定时器的状态;其他取值时返回错误提示。 - +**表2** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| SwTmrID | 软件定时器ID。 | +| State | 软件定时器状态。
状态可能为:"UnUsed", "Created", "Ticking"。 | +| Mode | 软件定时器模式。
模式可能为:"Once", "Period", "NSD(单次定时器,定时结束后不会自动删除)"。 | +| Interval | 软件定时器使用的Tick数。 | +| Count | 软件定时器已经工作的次数。 | +| Arg | 传入的参数。 | +| handlerAddr | 回调函数的地址。 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - swtmr命令的ID参数输入形式以十进制形式表示或十六进制形式表示皆可。 +> +> - swtmr命令的ID参数在[0, 当前软件定时器个数 - 1]范围内时,返回对应ID的软件定时器的状态;其他取值时返回错误提示。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md index 6daeaee0ac..832a60701d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-sysinfo.md @@ -1,39 +1,42 @@ -# systeminfo +# systeminfo -- [命令功能](#section863016434820) -- [命令格式](#section139791817795) -- [参数说明](#section19472339164813) -- [使用指南](#section285522592) -- [使用实例](#section9471171015105) -- [输出说明](#section1657011114915) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 systeminfo命令用于显示当前操作系统内资源使用情况,包括任务、信号量、互斥量、队列、定时器等。 -## 命令格式 + +## 命令格式 systeminfo -## 参数说明 + +## 参数说明 无。 -## 使用指南 + +## 使用指南 无。 -## 使用实例 + +## 使用实例 举例:输入systeminfo -## 输出说明 -**示例** 查看系统资源使用情况 +## 输出说明 -```shell +**示例:**查看系统资源使用情况 +``` OHOS:/$ systeminfo - Module Used Total Enabled -------------------------------------------- Task 96 256 YES @@ -42,59 +45,16 @@ OHOS:/$ systeminfo SwTmr 20 1024 YES ``` -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

Module

-

模块名称。

-

Used

-

当前使用量。

-

Total

-

最大可用量。

-

Enabled

-

模块是否开启。

-

Task

-

任务。

-

Sem

-

信号量。

-

Mutex

-

互斥量。

-

Queue

-

队列。

-

SwTmr

-

定时器。

-
+**表1** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| Module | 模块名称。 | +| Used | 当前使用量。 | +| Total | 最大可用量。 | +| Enabled | 模块是否开启。 | +| Task | 任务。 | +| Sem | 信号量。 | +| Mutex | 互斥量。 | +| Queue | 队列。 | +| SwTmr | 定时器。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-task.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-task.md index a6a6fee99c..2cb47608d3 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-task.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-task.md @@ -1,60 +1,48 @@ -# task +# task -- [命令功能](#section0533181714106) -- [命令格式](#section1014412308101) -- [参数说明](#section116057158506) -- [使用指南](#section2053502951112) -- [使用实例](#section12629113381116) -- [输出说明](#section19299103465015) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 task命令用于查询进程及线程信息。 -## 命令格式 + +## 命令格式 task/task -a -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-a

-

查看更多信息。

-

N/A

-
- -## 使用指南 + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -a | 查看更多信息。 | N/A | + + +## 使用指南 参数缺省时默认打印部分任务信息。 -## 使用实例 + +## 使用实例 举例:输入task -## 输出说明 -**示例** 查询任务部分信息 +## 输出说明 -```shell -OHOS # task +**示例:**查询任务部分信息 +``` +OHOS # task allCpu(%): 3.54 sys, 196.46 idle - PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName 1 -1 1 0 Pending 0x33b000 0xbb000 0x4dc8b 0.0 init 2 -1 2 0 Pending 0x193318e 0 0x193318e 1.11 KProcess @@ -69,7 +57,6 @@ OHOS # task 12 1 12 0 Pending 0x34f000 0xbd000 0x519ee 0.0 sensor_service 13 1 13 2 Pending 0x34e000 0xb3000 0x523d9 0.0 ai_server 14 1 14 0 Pending 0x61f000 0x13b000 0x16841c 0.50 softbus_server - TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName 23 1 0x3 -1 Pending 0x3000 0xe44 0.0 0 init 1 2 0x1 -1 Pending 0x4000 0x2c4 0.37 0 Swt_Task @@ -79,74 +66,19 @@ OHOS # task 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread ``` -**表 2** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

PID

-

进程ID。

-

PPID

-

父进程ID。

-

PGID

-

进程组ID。

-

UID

-

用户ID。

-

Status

-

任务当前的状态。

-

CPUUSE10s

-

10秒内CPU使用率。

-

PName

-

进程名。

-

TID

-

任务ID。

-

StackSize

-

任务堆栈的大小。

-

WaterLine

-

栈使用的峰值。

-

MEMUSE

-

内存使用量。

-

TaskName

-

任务名。

-
+**表2** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| PID | 进程ID。 | +| PPID | 父进程ID。 | +| PGID | 进程组ID。 | +| UID | 用户ID。 | +| Status | 任务当前的状态。 | +| CPUUSE10s | 10秒内CPU使用率。 | +| PName | 进程名。 | +| TID | 任务ID。 | +| StackSize | 任务堆栈的大小。 | +| WaterLine | 栈使用的峰值。 | +| MEMUSE | 内存使用量。 | +| TaskName | 任务名。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-top.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-top.md index b6126ec614..e6465cac25 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-top.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-top.md @@ -1,176 +1,102 @@ -# top - -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) - -## 命令功能 - -top命令用于查询进程及线程信息。 - -## 命令格式 - -top \[_-a_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看top命令支持的参数列表。

-

N/A

-

-a

-

显示更详细的信息。

-

N/A

-
- -## 使用指南 - -参数缺省时默认打印部分任务信息。 - -## 使用实例 - -举例:输入top - -## 输出说明 - -**示例** top 命令显示详情 - -```shell -OHOS:/$ top - - allCpu(%): 4.68 sys, 195.32 idle - - PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName - 1 -1 1 0 Pending 0x33b000 0xbb000 0x4e01c 0.0 init - 2 -1 2 0 Pending 0xd838c0 0 0xd838c0 1.16 KProcess - 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d29dc 0.0 foundation - 4 1 4 8 Pending 0x362000 0xbb000 0x5cc19 0.0 bundle_daemon - 5 1 5 1 Pending 0xdfa000 0x2e7000 0x148a0a 0.0 appspawn - 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server - 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.87 wms_server - 8 1 8 2 Pending 0x1f5000 0x48000 0x462dc 0.0 mksh - 9 5 5 101 Pending 0x11ea000 0x2f9000 0x204561 0.94 com.huawei.launcher - 11 1 11 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_service - 12 1 12 0 Pending 0x34f000 0xbd000 0x51cb3 0.0 sensor_service - 13 1 13 2 Pending 0x34e000 0xb3000 0x5269e 0.0 ai_server - 14 1 14 0 Pending 0x61f000 0x13b000 0x16858b 0.45 softbus_server - 43 8 43 2 Running 0x1d7000 0x3a000 0x1e9f5 0.0 toybox - - TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName - 23 1 0x3 -1 Pending 0x3000 0xcf4 0.0 0 init - 1 2 0x1 -1 Pending 0x4000 0x2c4 0.33 0 Swt_Task - 2 2 0x3 -1 Pending 0x4000 0x204 0.0 0 system_wq - 3 2 0x2 -1 Pending 0x4000 0x514 0.75 0 Swt_Task - 4 2 0x3 -1 Pending 0x1000 0x3ac 0.0 0 ResourcesTask - 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread - 8 2 0x3 -1 Pending 0x4e20 0xa6c 0.0 0 PlatformWorkerThread - 9 2 0x3 -1 Pending 0x4e20 0xbf4 0.0 0 PlatformWorkerThread - 10 2 0x3 -1 Pending 0x3000 0x4dc 0.0 0 bcache_async_task - 11 2 0x3 -1 PendTime 0x4000 0x3e4 0.5 0 hi_vdec_thread - 12 2 0x3 -1 Pending 0x2710 0x224 0.0 0 LiteOS usb pnp notify handle kt - 13 2 0x3 -1 Pending 0x3000 0x37c 0.0 0 bcache_async_task - 14 2 0x3 -1 Pending 0x4000 0x204 0.0 0 vibrator_queue - 15 2 0x3 -1 Pending 0x20000 0x35c 0.0 0 eth_irq_Task - 16 2 0x3 -1 PendTime 0x2000 0x354 0.0 0 MessageDispatcher - 18 2 0x3 -1 Pending 0x2710 0x200 0.0 0 GPIO_IRQ_TSK_0_4 - 19 2 0x3 -1 Pending 0x4000 0x204 0.0 0 dispWQ - 20 2 0x3 -1 Pending 0x4000 0x204 0.0 0 hdf_sensor_test_work_queue - 21 2 0x3 -1 PendTime 0x6000 0x40c 0.2 0 tcpip_thread - 22 2 0x3 -1 Pending 0x4000 0x36c 0.0 0 SendToSer - 61 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_GIANT_Task - 63 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_NGIAN_ISOC_Task - 64 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_NGIAN_BULK_TasK -``` - -**表2** 输出元素说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

PID

-

进程ID。

-

PPID

-

父进程ID。

-

PGID

-

进程组ID。

-

UID

-

用户ID。

-

Status

-

任务当前的状态。

-

CPUUSE10s

-

10秒内CPU使用率。

-

PName

-

进程名。

-

TID

-

任务ID。

-

StackSize

-

任务堆栈的大小。

-

WaterLine

-

栈使用的峰值。

-

MEMUSE

-

内存使用量。

-

TaskName

-

任务名。

-
+# top + +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) + +## 命令功能 + +top命令用于查询进程及线程信息。 + + +## 命令格式 + +top [_-a_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 缺省值 | 取值范围 | +| -------- | -------- | -------- | -------- | +| --help | 查看top命令支持的参数列表。 | N/A | | +| -a | 显示更详细的信息。 | N/A | | + + +## 使用指南 + +参数缺省时默认打印部分任务信息。 + + +## 使用实例 + +举例:输入top + + +## 输出说明 + +**示例1** top 命令显示详情 +``` +OHOS:/$ top + allCpu(%): 4.68 sys, 195.32 idle + PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName + 1 -1 1 0 Pending 0x33b000 0xbb000 0x4e01c 0.0 init + 2 -1 2 0 Pending 0xd838c0 0 0xd838c0 1.16 KProcess + 3 1 3 7 Pending 0x72e000 0x1a3000 0x1d29dc 0.0 foundation + 4 1 4 8 Pending 0x362000 0xbb000 0x5cc19 0.0 bundle_daemon + 5 1 5 1 Pending 0xdfa000 0x2e7000 0x148a0a 0.0 appspawn + 6 1 6 0 Pending 0x688000 0x137000 0x11c1ba 0.0 media_server + 7 1 7 0 Pending 0x9d2000 0x103000 0xa21f9 0.87 wms_server + 8 1 8 2 Pending 0x1f5000 0x48000 0x462dc 0.0 mksh + 9 5 5 101 Pending 0x11ea000 0x2f9000 0x204561 0.94 com.huawei.launcher + 11 1 11 0 Pending 0x4d4000 0x112000 0xe0d9c 0.0 deviceauth_service + 12 1 12 0 Pending 0x34f000 0xbd000 0x51cb3 0.0 sensor_service + 13 1 13 2 Pending 0x34e000 0xb3000 0x5269e 0.0 ai_server + 14 1 14 0 Pending 0x61f000 0x13b000 0x16858b 0.45 softbus_server + 43 8 43 2 Running 0x1d7000 0x3a000 0x1e9f5 0.0 toybox + TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName + 23 1 0x3 -1 Pending 0x3000 0xcf4 0.0 0 init + 1 2 0x1 -1 Pending 0x4000 0x2c4 0.33 0 Swt_Task + 2 2 0x3 -1 Pending 0x4000 0x204 0.0 0 system_wq + 3 2 0x2 -1 Pending 0x4000 0x514 0.75 0 Swt_Task + 4 2 0x3 -1 Pending 0x1000 0x3ac 0.0 0 ResourcesTask + 7 2 0x3 -1 Pending 0x4e20 0xa5c 0.0 0 PlatformWorkerThread + 8 2 0x3 -1 Pending 0x4e20 0xa6c 0.0 0 PlatformWorkerThread + 9 2 0x3 -1 Pending 0x4e20 0xbf4 0.0 0 PlatformWorkerThread + 10 2 0x3 -1 Pending 0x3000 0x4dc 0.0 0 bcache_async_task + 11 2 0x3 -1 PendTime 0x4000 0x3e4 0.5 0 hi_vdec_thread + 12 2 0x3 -1 Pending 0x2710 0x224 0.0 0 LiteOS usb pnp notify handle kt + 13 2 0x3 -1 Pending 0x3000 0x37c 0.0 0 bcache_async_task + 14 2 0x3 -1 Pending 0x4000 0x204 0.0 0 vibrator_queue + 15 2 0x3 -1 Pending 0x20000 0x35c 0.0 0 eth_irq_Task + 16 2 0x3 -1 PendTime 0x2000 0x354 0.0 0 MessageDispatcher + 18 2 0x3 -1 Pending 0x2710 0x200 0.0 0 GPIO_IRQ_TSK_0_4 + 19 2 0x3 -1 Pending 0x4000 0x204 0.0 0 dispWQ + 20 2 0x3 -1 Pending 0x4000 0x204 0.0 0 hdf_sensor_test_work_queue + 21 2 0x3 -1 PendTime 0x6000 0x40c 0.2 0 tcpip_thread + 22 2 0x3 -1 Pending 0x4000 0x36c 0.0 0 SendToSer + 61 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_GIANT_Task + 63 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_NGIAN_ISOC_Task + 64 2 0x3 -1 Pending 0x4000 0x244 0.0 0 USB_NGIAN_BULK_TasK +``` + +**表2** 输出元素说明 + +| 输出 | 说明 | +| -------- | -------- | +| PID | 进程ID。 | +| PPID | 父进程ID。 | +| PGID | 进程组ID。 | +| UID | 用户ID。 | +| Status | 任务当前的状态。 | +| CPUUSE10s | 10秒内CPU使用率。 | +| PName | 进程名。 | +| TID | 任务ID。 | +| StackSize | 任务堆栈的大小。 | +| WaterLine | 栈使用的峰值。 | +| MEMUSE | 内存使用量。 | +| TaskName | 任务名。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md index 913f54dd16..0d9f9fe060 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-uname.md @@ -1,98 +1,64 @@ -# uname +# uname -- [命令功能](#section01) -- [命令格式](#section02) -- [使用指南](#section03) -- [使用实例](#section04) -- [输出说明](#section05) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 uname命令用于显示当前操作系统的名称,版本创建时间,系统名称,版本信息等。 -## 命令格式 - -uname \[_-a | -s | -r | -m | -n | -v | --help_\] - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

--help

-

显示uname指令格式提示。

-

无参数

-

默认显示操作系统名称。

-

-a

-

显示全部信息。

-

-s

-

显示操作系统名称。

-

-r

-

显示内核发行版本。

-

-m

-

显示系统架构名称。

-

-n

-

显示主机的网络域名称。

-

-v

-

显示版本信息。

-
- -## 使用指南 + +## 命令格式 + +uname [_-a | -s | -r | -m | -n | -v | --help_] + + +**表1** 参数说明 + +| 参数 | 参数说明 | +| -------- | -------- | +| --help | 显示uname指令格式提示。 | +| 无参数 | 默认显示操作系统名称。 | +| -a | 显示全部信息。 | +| -s | 显示操作系统名称。 | +| -r | 显示内核发行版本。 | +| -m | 显示系统架构名称。 | +| -n | 显示主机的网络域名称。 | +| -v | 显示版本信息。 | + + +## 使用指南 - uname用于显示当前操作系统名称。 - 除参数--help和-a以外,其他参数可以相互搭配使用;uname -a 等价于 uname -srmnv。 -## 使用实例 +## 使用实例 举例: - uname -a + - uname -ms -## 输出说明 -**示例 1** 查看系统详细信息 +## 输出说明 + +**示例1:** 查看系统信息 -```shell +``` OHOS:/$ uname -a Huawei LiteOS hisilicon 2.0.0.37 Huawei LiteOS 2.0.0.37 Oct 21 2021 17:39:32 Cortex-A7 OHOS:/$ ``` -**示例 2** 只查看操作系统名称和系统架构名称 +**示例2:** 只查看操作系统名称和系统架构名称 -```shell +``` OHOS:/$ uname -ms Huawei LiteOS Cortex-A7 OHOS:/$ diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md index 3a45813818..f9203eba06 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-vmm.md @@ -1,79 +1,53 @@ -# vmm +# vmm -- [命令功能](#section445335110416) -- [命令格式](#section1795712553416) -- [参数说明](#section92544592410) -- [使用指南](#section104151141252) -- [使用实例](#section11545171957) -- [输出说明](#section075617368542) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 查看进程的虚拟内存使用情况。 -## 命令格式 - -- vmm \[_-a / -h / --help_\] - -- vmm \[_pid_\] - - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-a

-

输出所有进程的虚拟内存使用情况。

-

N/A

-

-h | --help

-

命令格式说明。

-

N/A

-

pid

-

进程ID,说明指定进程的虚拟内存使用情况。

-

[0,63]

-
- -## 使用指南 + +## 命令格式 + +- vmm [_-a / -h / --help_] + +- vmm [_pid_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -a | 输出所有进程的虚拟内存使用情况。 | N/A | +| -h \| --help | 命令格式说明。 | N/A | +| pid | 进程ID,说明指定进程的虚拟内存使用情况。 | [0,63] | + + +## 使用指南 命令缺省输出所有进程的虚拟内存使用情况。 -## 使用实例 + +## 使用实例 举例:输入vmm 3 -## 输出说明 -**示例** PID为3的进程虚拟内存使用信息 +## 输出说明 -```shell +**示例:**PID为3的进程虚拟内存使用信息 +``` OHOS # vmm 3 - PID aspace name base size pages ---- ------ ---- ---- ----- ---- 3 0x408c0118 foundation 0x01000000 0x3e000000 800 - region name base size mmu_flags pages pg/ref ------ ---- ---- ---- --------- ----- ----- 0x408cb364 /bin/foundation 0x06da3000 0x00001000 CH US RD 1 1 @@ -93,91 +67,25 @@ OHOS # vmm 3 0x408c3ce0 /lib/libc++.so 0x23cb0000 0x00001000 CH US RD WR 1 1 ``` -**表 2** 进程基本信息 - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

PID

-

进程ID

-

aspace

-

进程虚拟内存控制块地址信息

-

name

-

进程名

-

base

-

虚拟内存起始地址

-

size

-

虚拟内存大小

-

pages

-

已使用的物理页数量

-
- -**表 3** 虚拟内存区间信息 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

region

-

虚拟区间控制块地址信息

-

name

-

虚拟区间类型

-

base

-

虚拟区间起始地址

-

size

-

虚拟区间大小

-

mmu_flags

-

虚拟区间mmu映射属性

-

pages

-

已使用的物理页数量(包括共享内存部分)

-

pg/ref

-

已使用的物理页数量

-
+**表2** 进程基本信息 + +| 输出 | 说明 | +| -------- | -------- | +| PID | 进程ID | +| aspace | 进程虚拟内存控制块地址信息 | +| name | 进程名 | +| base | 虚拟内存起始地址 | +| size | 虚拟内存大小 | +| pages | 已使用的物理页数量 | + +**表3** 虚拟内存区间信息 + +| 输出 | 说明 | +| -------- | -------- | +| region | 虚拟区间控制块地址信息 | +| name | 虚拟区间类型 | +| base | 虚拟区间起始地址 | +| size | 虚拟区间大小 | +| mmu_flags | 虚拟区间mmu映射属性 | +| pages | 已使用的物理页数量(包括共享内存部分) | +| pg/ref | 已使用的物理页数量 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md index 7a7bb9c456..7798cb435e 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-watch.md @@ -1,105 +1,55 @@ -# watch +# watch -- [命令功能](#section20643141481314) -- [命令格式](#section1075441721316) -- [参数说明](#section1472810220135) -- [使用指南](#section186772414131) -- [使用实例](#section4764192791314) -- [输出说明](#section5791253155517) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 watch命令用于周期性的监视一个命令的运行结果。 -## 命令格式 + +## 命令格式 - watch -- watch \[_-c/-n/-t/--count/--interval/-no-title/--over_\] \[_command_\] - - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

缺省值

-

取值范围

-

-c / --count

-

命令执行的总次数。

-

0xFFFFFF

-

(0,0xFFFFFF]

-

-n / --interval

-

命令周期性执行的时间间隔(s)。

-

1s

-

(0,0xFFFFFF]

-

-t / -no-title

-

关闭顶端的时间显示。

-

N/A

-

N/A

-

command

-

需要监测的命令。

-

N/A

-

N/A

-

--over

-

关闭当前监测指令。

-

N/A

-

N/A

-
- -## 使用指南 +- watch [_-c/-n/-t/--count/--interval/-no-title/--over_] [_command_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 缺省值 | 取值范围 | +| -------- | -------- | -------- | -------- | +| -c / --count | 命令执行的总次数。 | 0xFFFFFF | (0,0xFFFFFF] | +| -n / --interval | 命令周期性执行的时间间隔(s)。 | 1s | (0,0xFFFFFF] | +| -t / -no-title | 关闭顶端的时间显示。 | N/A | N/A | +| command | 需要监测的命令。 | N/A | N/A | +| --over | 关闭当前监测指令。 | N/A | N/A | + + +## 使用指南 watch运行过程中可以执行**watch --over**结束本次watch命令。 -## 使用实例 -举例:watch -n 2 -c 6 task +## 使用实例 -## 输出说明 +watch -n 2 -c 6 task -**示例** watch task 结果 -```shell +## 输出说明 + +**示例**:每隔2秒运行一次task命令,一共运行6次 +``` OHOS # watch -n 2 -c 6 task Thu Jan 1 23:57:13 1970 - OHOS # allCpu(%): 3.55 sys, 196.45 idle - PID PPID PGID UID Status VirtualMem ShareMem PhysicalMem CPUUSE10s PName 1 -1 1 0 Pending 0x33b000 0xbb000 0x4dc8b 0.0 init 2 -1 2 0 Running 0x19524f2 0 0x19524f2 1.14 KProcess @@ -114,7 +64,6 @@ OHOS # 12 1 12 0 Pending 0x34f000 0xbd000 0x519ee 0.0 sensor_service 13 1 13 2 Pending 0x34e000 0xb3000 0x523d9 0.0 ai_server 14 1 14 0 Pending 0x61f000 0x13b000 0x16841c 0.51 softbus_server - TID PID Affi CPU Status StackSize WaterLine CPUUSE10s MEMUSE TaskName 23 1 0x3 -1 Pending 0x3000 0xe44 0.0 0 init 1 2 0x1 -1 Pending 0x4000 0x2c4 0.64 0 Swt_Task @@ -134,7 +83,3 @@ OHOS # 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 ``` - ->![](../public_sys-resources/icon-note.gif) **说明:** ->示例中,总共有6次task命令打印,每次间隔2秒,示例1为最后一次打印详情。 - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd.md index 0345b3c4c3..679c2b5d16 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd.md @@ -1,51 +1,50 @@ -# 系统命令 +# 系统命令 -- **[cpup](kernel-small-debug-shell-cmd-cpup.md)** -- **[date](kernel-small-debug-shell-cmd-date.md)** +- **[cpup](kernel-small-debug-shell-cmd-cpup.md)** -- **[dmesg](kernel-small-debug-shell-cmd-dmesg.md)** +- **[date](kernel-small-debug-shell-cmd-date.md)** -- **[du](kernel-small-debug-shell-file-du.md)** +- **[dmesg](kernel-small-debug-shell-cmd-dmesg.md)** -- **[exec](kernel-small-debug-shell-cmd-exec.md)** +- **[exec](kernel-small-debug-shell-cmd-exec.md)** -- **[free](kernel-small-debug-shell-cmd-free.md)** +- **[free](kernel-small-debug-shell-cmd-free.md)** -- **[help](kernel-small-debug-shell-cmd-help.md)** +- **[help](kernel-small-debug-shell-cmd-help.md)** -- **[hwi](kernel-small-debug-shell-cmd-hwi.md)** +- **[hwi](kernel-small-debug-shell-cmd-hwi.md)** -- **[kill](kernel-small-debug-shell-cmd-kill.md)** +- **[kill](kernel-small-debug-shell-cmd-kill.md)** -- **[log](kernel-small-debug-shell-cmd-log.md)** +- **[log](kernel-small-debug-shell-cmd-log.md)** -- **[memcheck](kernel-small-debug-shell-cmd-memcheck.md)** +- **[memcheck](kernel-small-debug-shell-cmd-memcheck.md)** -- **[oom](kernel-small-debug-shell-cmd-oom.md)** +- **[oom](kernel-small-debug-shell-cmd-oom.md)** -- **[pmm](kernel-small-debug-shell-cmd-pmm.md)** +- **[pmm](kernel-small-debug-shell-cmd-pmm.md)** -- **[reboot](kernel-small-debug-shell-cmd-reboot.md)** +- **[reset](kernel-small-debug-shell-cmd-reset.md)** -- **[reset](kernel-small-debug-shell-cmd-reset.md)** +- **[sem](kernel-small-debug-shell-cmd-sem.md)** -- **[sem](kernel-small-debug-shell-cmd-sem.md)** +- **[stack](kernel-small-debug-shell-cmd-stack.md)** -- **[stack](kernel-small-debug-shell-cmd-stack.md)** +- **[su](kernel-small-debug-shell-cmd-su.md)** -- **[su](kernel-small-debug-shell-cmd-su.md)** +- **[swtmr](kernel-small-debug-shell-cmd-swtmr.md)** -- **[swtmr](kernel-small-debug-shell-cmd-swtmr.md)** +- **[systeminfo](kernel-small-debug-shell-cmd-sysinfo.md)** -- **[systeminfo](kernel-small-debug-shell-cmd-sysinfo.md)** +- **[task](kernel-small-debug-shell-cmd-task.md)** -- **[task](kernel-small-debug-shell-cmd-task.md)** +- **[uname](kernel-small-debug-shell-cmd-uname.md)** -- **[top](kernel-small-debug-shell-cmd-top.md)** +- **[vmm](kernel-small-debug-shell-cmd-vmm.md)** -- **[uname](kernel-small-debug-shell-cmd-uname.md)** +- **[watch](kernel-small-debug-shell-cmd-watch.md)** -- **[vmm](kernel-small-debug-shell-cmd-vmm.md)** +- **[reboot](kernel-small-debug-shell-cmd-reboot.md)** -- **[watch](kernel-small-debug-shell-cmd-watch.md)** +- **[top](kernel-small-debug-shell-cmd-top.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-details.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-details.md index efb71a669d..fb349660da 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-details.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-details.md @@ -1,13 +1,13 @@ -# Shell命令使用详解 +# Shell命令使用详解 本章节介绍了系统关键命令的功能、格式、参数范围、使用指南和使用实例。 -不在本文档范围内的命令,详见[help](kernel-small-debug-shell-cmd-help.md)命令的输出内容,也可以通过命令的“-h | --help”选项,查看该命令的使用帮助。 -- **[系统命令](kernel-small-debug-shell-cmd.md)** +不在本文档范围内的命令,详见[help](../kernel/kernel-small-debug-shell-cmd-help.md)命令的输出内容,也可以通过命令的“-h | --help”选项,查看该命令的使用帮助。 -- **[文件命令](kernel-small-debug-shell-file.md)** -- **[网络命令](kernel-small-debug-shell-net.md)** +- **[系统命令](kernel-small-debug-shell-cmd.md)** +- **[文件命令](kernel-small-debug-shell-file.md)** +- **[网络命令](kernel-small-debug-shell-net.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-error.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-error.md index a76b3054e7..70b6dd5d2e 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-error.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-error.md @@ -1,7 +1,8 @@ -# 用户态异常信息说明 +# 用户态异常信息说明 用户态在运行过程中,可能由于各种原因出现用户态系统异常,异常信息如下所示: + ``` ##################excFrom: User!#################### prefetch_abort fault fsr:0x5, far:0x00000000 @@ -30,7 +31,7 @@ R10 = 0x0 R11 = 0x3717cd64 R12 = 0x0 CPSR = 0x40000030 -*******backtrace begin******* +***backtrace begin*** traceback 0 -- lr = 0x229123a4 fp = 0x0 lr in /lib/libc.so --> 0x213a4 PID PPID PGID UID Status CPUUSE CPUUSE10s CPUUSE1s Policy Priority MTID TaskTotal Mode PName @@ -58,79 +59,75 @@ traceback 0 -- lr = 0x229123a4 fp = 0x0 lr in /lib/libc.so --> 0x213a4 system memcheck over, all passed! ``` -其中,主要包含如下几方面信息: - -1. 用户态异常基本信息: - - ``` - prefetch_abort fault fsr:0x5, far:0x00000000 - Translation fault, section - excType: prefetch abort - processName = shell - processID = 3 - process aspace = 0x01000000 -> 0x3f000000 - taskName = shell - taskID = 4 - task user stack = 0x3707d000 -> 0x3717d000 - ``` - -2. 寄存器相关信息。 - - ``` - pc = 0x0 - ulr = 0x2000424 in /bin/shell ---> 0x424 - usp = 0x3717cd60fp = 0x3717cd64 - R0 = 0x1 - R1 = 0x0 - R2 = 0x0 - R3 = 0x1 - R4 = 0x3717cf58 - R5 = 0x0 - R6 = 0x3717cf54 - R7 = 0x200043c - R8 = 0x84 - R9 = 0x229a7560 - R10 = 0x0 - R11 = 0x3717cd64 - R12 = 0x0 - CPSR = 0x40000030 - ``` -3. 调用栈信息。 - - ``` - *******backtrace begin******* - traceback 0 -- lr = 0x229123a4 fp = 0x0 lr in /lib/libc.so --> 0x213a4 - ``` - -4. 进程线程基本信息。 - - ``` - PID PPID PGID UID Status CPUUSE CPUUSE10s CPUUSE1s Policy Priority MTID TaskTotal Mode PName - 1 -1 1 0 Ready 0.0 0.0 0.0 RR 28 16 1 user init - 2 -1 2 0 Pend 10.1 10.1 0.0 RR 0 0 14 kernel KProcess - 3 1 3 0 Running 0.0 0.0 0.0 RR 28 4 1 user shell - - TID PID Status StackSize WaterLine Policy Priority MEMUSE TaskName - 16 1 Ready 0x3000 0x978 RR 31 0x8b0c init - 0 2 Pend 0x1000 0x1d4 RR 5 0 ResourcesTask - 2 2 Pend 0x4000 0x4ec RR 0 0 Swt_Task - 3 2 Pend 0x4000 0x1d4 RR 1 0 system_wq - 5 2 Pend 0x4000 0x1fc RR 9 0 SendToSer - 6 2 PendTime 0x6000 0x204 RR 5 0 tcpip_thread - 7 2 Pend 0x3000 0x1fc RR 5 0 sdmci_detect - 8 2 Pend 0x4000 0x204 RR 5 0 USB_GIANT_Task - 9 2 Pend 0x4000 0x204 RR 1 0 USB_NGIAN_ISOC_Task - 10 2 Pend 0x4000 0x204 RR 2 0 USB_NGIAN_BULK_Task - 11 2 Pend 0x4000 0x690 RR 5 0xbb0 USB_EXPLR_Task - 12 2 Pend 0x4000 0x204 RR 5 0 USB_CXFER_Task - 13 2 Pend 0x20000 0x1e4 RR 3 0xac20 eth_irq_Task - 14 2 Pend 0x4000 0x1d4 RR 10 0 jffs2_gc_thread - 15 2 Pend 0x2000 0x1f4 RR 4 0 hisi_frw - 4 3 Running 0x3000 0x838 RR 31 0x1100 shell - system memcheck over, all passed! - ``` - - 可以根据以上信息,分析用户态异常的具体原因。 +其中,主要包含如下几方面信息: +1. 用户态异常基本信息: + ``` + prefetch_abort fault fsr:0x5, far:0x00000000 + Translation fault, section + excType: prefetch abort + processName = shell + processID = 3 + process aspace = 0x01000000 -> 0x3f000000 + taskName = shell + taskID = 4 + task user stack = 0x3707d000 -> 0x3717d000 + ``` + +2. 寄存器相关信息。 + ``` + pc = 0x0 + ulr = 0x2000424 in /bin/shell ---> 0x424 + usp = 0x3717cd60fp = 0x3717cd64 + R0 = 0x1 + R1 = 0x0 + R2 = 0x0 + R3 = 0x1 + R4 = 0x3717cf58 + R5 = 0x0 + R6 = 0x3717cf54 + R7 = 0x200043c + R8 = 0x84 + R9 = 0x229a7560 + R10 = 0x0 + R11 = 0x3717cd64 + R12 = 0x0 + CPSR = 0x40000030 + ``` + +3. 调用栈信息。 + ``` + ***backtrace begin*** + traceback 0 -- lr = 0x229123a4 fp = 0x0 lr in /lib/libc.so --> 0x213a4 + ``` + +4. 进程线程基本信息。 + ``` + PID PPID PGID UID Status CPUUSE CPUUSE10s CPUUSE1s Policy Priority MTID TaskTotal Mode PName + 1 -1 1 0 Ready 0.0 0.0 0.0 RR 28 16 1 user init + 2 -1 2 0 Pend 10.1 10.1 0.0 RR 0 0 14 kernel KProcess + 3 1 3 0 Running 0.0 0.0 0.0 RR 28 4 1 user shell + + TID PID Status StackSize WaterLine Policy Priority MEMUSE TaskName + 16 1 Ready 0x3000 0x978 RR 31 0x8b0c init + 0 2 Pend 0x1000 0x1d4 RR 5 0 ResourcesTask + 2 2 Pend 0x4000 0x4ec RR 0 0 Swt_Task + 3 2 Pend 0x4000 0x1d4 RR 1 0 system_wq + 5 2 Pend 0x4000 0x1fc RR 9 0 SendToSer + 6 2 PendTime 0x6000 0x204 RR 5 0 tcpip_thread + 7 2 Pend 0x3000 0x1fc RR 5 0 sdmci_detect + 8 2 Pend 0x4000 0x204 RR 5 0 USB_GIANT_Task + 9 2 Pend 0x4000 0x204 RR 1 0 USB_NGIAN_ISOC_Task + 10 2 Pend 0x4000 0x204 RR 2 0 USB_NGIAN_BULK_Task + 11 2 Pend 0x4000 0x690 RR 5 0xbb0 USB_EXPLR_Task + 12 2 Pend 0x4000 0x204 RR 5 0 USB_CXFER_Task + 13 2 Pend 0x20000 0x1e4 RR 3 0xac20 eth_irq_Task + 14 2 Pend 0x4000 0x1d4 RR 10 0 jffs2_gc_thread + 15 2 Pend 0x2000 0x1f4 RR 4 0 hisi_frw + 4 3 Running 0x3000 0x838 RR 31 0x1100 shell + system memcheck over, all passed! + ``` + + 可以根据以上信息,分析用户态异常的具体原因。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cat.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cat.md index 9e04dbf213..e0c9dbd150 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cat.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cat.md @@ -1,57 +1,45 @@ -# cat +# cat -- [命令功能](#section16710153391315) -- [命令格式](#section1699392313158) -- [参数说明](#section1677217374136) -- [使用指南](#section186772414131) -- [使用实例](#section12158131814561) -- [输出说明](#section183926225561) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 cat用于显示文本文件的内容。 -## 命令格式 -cat \[_pathname_\] +## 命令格式 -## 参数说明 +cat [_pathname_] -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

pathname

-

文件路径。

-

已存在的文件。

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| pathname | 文件路径。 | 已存在的文件。 | + + +## 使用指南 cat用于显示文本文件的内容。 -## 使用实例 + +## 使用实例 举例:cat hello-harmony.txt -## 输出说明 -**示例** 查看 hello-harmony.txt 文件的信息 +## 输出说明 -```shell +**示例**:查看 hello-harmony.txt 文件的信息 +``` OHOS # cat hello-harmony.txt OHOS # Hello Harmony ;) ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cd.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cd.md index ccaa2af58e..d3498566ed 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cd.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cd.md @@ -1,64 +1,58 @@ -# cd +# cd -- [命令功能](#section11690184921316) -- [命令格式](#section75695409569) -- [参数说明](#section71961353181311) -- [使用指南](#section3629759111317) -- [使用实例](#section211620301412) -- [输出说明](#section1968117214577) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 cd命令用来改变当前目录。 -## 命令格式 -cd \[_path_\] +## 命令格式 -## 参数说明 +cd [_path_] -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

path

-

文件路径。

-

用户必须具有指定目录中的执行(搜索)许可权。

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -- 未指定目录参数时,会跳转至根目录。 -- cd后加路径名时,跳转至该路径。 -- 路径名以 /(斜杠)开头时,表示根目录。 -- .(点)表示当前目录。 -- ..(点点)表示父目录。 -- cd - 可以在最近访问的两个目录切换。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| path | 文件路径。 | 用户必须具有指定目录中的执行(搜索)许可权。 | -## 使用实例 + +## 使用指南 + +- 未指定目录参数时,会跳转至根目录。 + +- cd后加路径名时,跳转至该路径。 + +- 路径名以 /(斜杠)开头时,表示根目录。 + +- .(点)表示当前目录。 + +- ..(点点)表示父目录。 + +- cd - 可以在最近访问的两个目录切换。 + + +## 使用实例 举例:cd .. -## 输出说明 -**示例** 显示结果如下 +## 输出说明 -```shell +**示例**:显示结果如下 + +``` OHOS:/nfs$ cd ../ OHOS:/$ ls bin etc nfs sdcard system tmp vendor dev lib proc storage test usr ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md index 0d12a471cf..26b96436f0 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chgrp.md @@ -1,65 +1,48 @@ -# chgrp +# chgrp -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 chgrp用于修改文件的群组。 -## 命令格式 - -chgrp \[_group_\] \[_pathname_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

group

-

文件群组。

-

[0,0xFFFFFFFF]

-

pathname

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 + +## 命令格式 + +chgrp [_group_] [_pathname_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| group | 文件群组。 | [0,0xFFFFFFFF] | +| pathname | 文件路径。 | 已存在的文件。 | + + +## 使用指南 - 在需要修改的文件名前加上文件群组值就可以修改该文件的所属组。 + - fatfs文件系统不支持修改用户组id。 -## 使用实例 + +## 使用实例 举例:chgrp 100 testfile -## 输出说明 -**示例** 修改 /dev目录下testfile 文件的群组为100 +## 输出说明 -```shell +**示例:**修改 dev/目录下testfile 文件的群组为100 +``` OHOS:/dev$ ll testfile -rw-r--r-- 0 0 0 0 1970-01-01 00:00 testfile OHOS:/dev$ chgrp 100 testfile diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chmod.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chmod.md index 8dec87d6b6..918dc9f36c 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chmod.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chmod.md @@ -1,64 +1,49 @@ -# chmod +# chmod -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 chmod用于修改文件操作权限。 -## 命令格式 - -chmod \[_mode_\] \[_filename_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

mode

-

文件或文件夹权限,用8进制表示对应User、Group、及Other(拥有者、群组、其他组)的权限。

-

[0,777]

-

filename

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 + +## 命令格式 + +chmod [_mode_] [_filename_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| mode | 文件或文件夹权限,用8进制表示对应User、Group、及Others(拥有者、群组、其他组)的权限。 | [0,777] | +| filename | 文件路径。 | 已存在的文件。 | + + +## 使用指南 - 在需要修改的文件名前加上文件权限值就可以修改该文件的权限值。 + - fatfs文件系统所有创建的文件和挂载节点的权限属性保持一致,目前节点的权限只有用户读写权限,group和others权限不生效;且只允许修改用户读写权限,读写权限只有rw和ro两种。其他文件系统无限制。 -## 使用实例 + +## 使用实例 举例:修改hello-harmony.txt 文件权限为644和777。 -## 输出说明 -**示例** 修改/dev目录下 hello-harmony.txt 文件的权限 +## 输出说明 -```shell +**示例:**修改/dev目录下 hello-harmony.txt 文件的权限 + +``` OHOS:/dev$ chmod 644 hello-harmony.txt OHOS:/dev$ ll hello-harmony.txt -rw-r--r-- 0 0 0 0 1970-01-01 00:00 hello-harmony.txt @@ -66,4 +51,3 @@ OHOS:/dev$ chmod 777 hello-harmony.txt OHOS:/dev$ ll hello-harmony.txt -rwxrwxrwx 0 0 0 0 1970-01-01 00:00 hello-harmony.txt ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chown.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chown.md index 6a68dafbed..4a4e73f448 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chown.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-chown.md @@ -1,63 +1,47 @@ -# chown +# chown -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 chown用于修改指定文件的拥有者。 -## 命令格式 - -chown \[_owner_\] \[_pathname_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

owner

-

文件拥有者。

-

[0,0xFFFFFFFF]

-

pathname

-

文件路径。

-

已存在的文件。

-
- -## 使用指南 + +## 命令格式 + +chown [_owner_] [_pathname_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| owner | 文件拥有者。 | [0,0xFFFFFFFF] | +| pathname | 文件路径。 | 已存在的文件。 | + + +## 使用指南 修改文件的所有者,目前fatfs不支持修改。 -## 使用实例 + +## 使用实例 举例:chown 100 testfile -## 输出说明 -**示例 1** 修改 /dev下的testfile 文件的uid为100 +## 输出说明 -```shell +示例 1 修改 /dev下的testfile 文件的uid为100 + +``` OHOS:/dev$ touch testfile OHOS:/dev$ ll testfile -rw-r--r-- 0 0 100 0 1970-01-01 00:00 testfile diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cp.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cp.md index 13718a5a57..2e69107f50 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cp.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-cp.md @@ -1,79 +1,61 @@ -# cp +# cp -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 拷贝文件,创建一份副本。 -## 命令格式 - -cp \[_SOURCEFILE_\] \[_DESTFILE_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

使用帮助。

-

N/A

-

SOURCEFILE

-

源文件路径。

-

目前只支持文件,不支持目录;支持多文件同时拷贝。

-

DESTFILE

-

目的文件路径。

-

支持目录以及文件。

-
- -## 使用指南 - -- 同一路径下,源文件与目的文件不能重名。 -- 源文件必须存在,且不为目录。 -- 源文件路径支持“\*”和“?”通配符,“\*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。 -- 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。 -- 目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。 -- 目的文件不存在时创建新文件,已存在则覆盖。 - -> ![](../public_sys-resources/icon-notice.gif) **须知:** -> + +## 命令格式 + +cp [_SOURCEFILE_] [_DESTFILE_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 使用帮助。 | N/A | +| SOURCEFILE | 源文件路径。 | 目前只支持文件,不支持目录;支持多文件同时拷贝。 | +| DESTFILE | 目的文件路径。 | 支持目录以及文件。 | + + +## 使用指南 + +- 同一路径下,源文件与目的文件不能重名。 + +- 源文件必须存在,且不为目录。 + +- 源文件路径支持“\*”和“?”通配符,“\*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。 + +- 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。 + +- 目的路径为文件时,所在目录必须存在。此时拷贝文件的同时为副本重命名。 + +- 目的文件不存在时创建新文件,已存在则覆盖。 + +> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** > 拷贝系统重要资源时,会对系统造成死机等重大未知影响,如用于拷贝/dev/uartdev-1 文件时,会产生系统卡死现象。 -## 使用实例 + +## 使用实例 举例:cp hello-OHOS.txt hello-harmony.txt ./tmp/ -## 输出说明 -**示例** 同时拷贝两个文件至指定目录 +## 输出说明 -```shell +**示例:**同时拷贝两个文件至指定目录 + +``` OHOS:/$ ls bin hello-OHOS.txt proc system vendor dev hello-harmony.txt sdcard userdata diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-du.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-du.md index 1ba75a22e2..2d589fb8b9 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-du.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-du.md @@ -1,92 +1,53 @@ -# du - -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) - -## 命令功能 - -du显示指定的文件所占用的磁盘空间。 - -## 命令格式 - -du \[_-kKmh_\] \[_file..._\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看du命令支持的参数列表。

-

N/A

-

-k

-

显示占用的块,每块1024bytes(默认)。

-

N/A

-

-K

-

显示占用的块,每块512bytes(posix)。

-

N/A

-

-m

-

兆字节为单位。

-

N/A

-

-h

-

以K,M,G为单位,提高信息的可读性(例如,1K 243M 2G)。

-

N/A

-

file

-

指定的需要统计的文件。

-

N/A

-
- -## 使用指南 - -- 不支持统计目录的大小,只支持统计文件的大小。 -- file的内容既为文件名,不能包含其所在的目录。 - -## 使用实例 - -举例:du -h testfile - -## 输出说明 - -**示例** 显示结果如下 - -```shell -OHOS:/$ du -h testfile -1.8K testfile -``` +# du + +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) + +## 命令功能 + +du显示指定的文件所占用的磁盘空间。 + + +## 命令格式 + +du [_-kKmh_] [_file..._] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看du命令支持的参数列表。 | N/A | +| -k | 显示占用的块,每块1024bytes(默认)。 | N/A | +| -K | 显示占用的块,每块512bytes(posix标准)。 | N/A | +| -m | 兆字节为单位。 | N/A | +| -h | 以K,M,G为单位,提高信息的可读性(例如,1K 243M 2G)。 | N/A | +| file | 指定的需要统计的文件。 | N/A | + + +## 使用指南 + +- 不支持统计目录的大小,只支持统计文件的大小。 + +- file的内容既为文件名,不能包含其所在的目录。 + + +## 使用实例 + +举例:du -h testfile + + +## 输出说明 + +**示例:**显示结果如下 + +``` +OHOS:/$ du-h testfile +1.8K testfile +``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-format.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-format.md index e1631934f0..e998feb1b1 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-format.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-format.md @@ -1,71 +1,53 @@ -# format +# format -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 format指令用于格式化磁盘。 -## 命令格式 - -format <_dev\_inodename_\> <_sectors_\> <_option_\> \[_label_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

dev_inodename

-

设备名。

-

sectors

-

分配的单元内存或扇区大小,如果输入0表示参数为空。(取值必须为0或2的幂,fat32下最大值为128,取值0表示自动选择合适的簇大小,不同size的分区,可用的簇大小范围不同,错误的簇大小指定可能导致格式化失败)。

-

option

-
格式化选项,用来选择文件系统的类型,有如下几种参数选择:
  • 0x01:FMT_FAT
  • 0x02:FMT_FAT32
  • 0x07:FMT_ANY
  • 0x08:FMT_ERASE (USB不支持该选项)
-
-

传入其他值皆为非法值,将由系统自动选择格式化方式。若格式化U盘时低格位为 1,会出现错误打印。

-

label

-

该参数为可选参数,输入值应为字符串,用来指定卷标名。当输入字符串"null"时,则把之前设置的卷标名清空。

-
- -## 使用指南 - -- format指令用于格式化磁盘,设备名可以在dev目录下查找。format时必须安装存储卡。 -- format只能格式化U盘、sd和mmc卡,对Nand flash和Nor flash格式化不起作用。 -- sectors参数必须传入合法值,传入非法参数可能引发异常。 - -## 使用实例 - -举例:输入format /dev/mmcblk1 128 2 - -## 输出说明 - -**示例** 格式化mmc卡 - -```shell + +## 命令格式 + +format <_dev_inodename_> <_sectors_> <_option_> [_label_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | +| -------- | -------- | +| dev_inodename | 设备名。 | +| sectors | 分配的单元内存或扇区大小,如果输入0表示参数为空。(取值必须为0或2的幂,fat32下最大值为128,取值0表示自动选择合适的簇大小,不同size的分区,可用的簇大小范围不同,错误的簇大小指定可能导致格式化失败)。 | +| option | 格式化选项,用来选择文件系统的类型,有如下几种参数选择:
- 0x01:FMT_FAT
- 0x02:FMT_FAT32
- 0x07:FMT_ANY
- 0x08:FMT_ERASE (USB不支持该选项)
传入其他值皆为非法值,将由系统自动选择格式化方式。若格式化U盘时低格位为 1,会出现错误打印。 | +| label | 该参数为可选参数,输入值应为字符串,用来指定卷标名。当输入字符串"null"时,则把之前设置的卷标名清空。 | + + +## 使用指南 + +- format指令用于格式化磁盘,设备名可以在dev目录下查找。format时必须安装存储卡。 + +- format只能格式化U盘、sd和mmc卡,对Nand flash和Nor flash格式化不起作用。 + +- sectors参数必须传入合法值,传入非法参数可能引发异常。 + + +## 使用实例 + +举例:输入format /dev/mmcblk0 128 2 + + +## 输出说明 + +**示例**:格式化mmc卡 + +``` OHOS # format /dev/mmcblk1 128 2 Format to FAT32, 128 sectors per cluster. format /dev/mmcblk1 Success diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-ls.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-ls.md index 5dee2d60e8..aed513028d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-ls.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-ls.md @@ -1,309 +1,102 @@ -# ls +# ls -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 ls命令用来显示当前目录的内容。 -## 命令格式 -ls \[_-ACHLSZacdfhiklmnopqrstux1_\] \[_--color_\[_=auto_\]\] \[_directory..._\] +## 命令格式 -> **说明:** 系统启动过程中已经通过 alias 为 ls=toybox ls --color=auto 、ll = ls -alF 、 la=ls -A 和 l=ls -CF 赋能,使这几个命令的初始行为就和linux相同(详细效果见输出说明)。所以若要查看help列表,请输入'toybox ls --help'。 +ls [_-ACHLSZacdfhiklmnopqrstux1_] [_--color_[_=auto_]] [_directory..._] -## 参数说明 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 系统启动过程中已经通过 alias 为 ls=toybox ls --color=auto 、ll = ls -alF 、 la=ls -A 和 l=ls -CF 赋能,使这几个命令的初始行为就和linux相同(详细效果见输出说明)。所以若要查看help列表,请输入'toybox ls --help'。 -**表 1** 展示功能参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看ls命令支持的参数列表,使用方式。

-

N/A

-

-a

-

显示所有文件包括.hidden隐藏类型的文件。

-

N/A

-

-b

-

转义非图形字符。

-

N/A

-

-c

-

使用ctime作为文件的时间戳。"ls -lc"

-

N/A

-

-d

-

只显示path名称不显示path所包含的内容。

-

N/A

-

-i

-

显示文件的节点号。

-

N/A

-

-p

-

在path名称后放一个"/"。

-

N/A

-

-q

-

显示不可打印字符比如'?'。

-

N/A

-

-s

-

统计目录和其成员所占用的内存大小,单位为1024字节。

-

N/A

-

-u

-

以文件的最后访问时间为时间戳,配合 -l 一起使用。

-

N/A

-

-A

-

列出所有文件除了.和..

-

N/A

-

-H

-

跟随命令行符号链接。

-

N/A

-

-L

-

跟随符号链接。

-

N/A

-

-Z

-

安全上下文。

-

N/A

-

path

-

path为空时,显示当前目录的内容。

-

path为无效文件名时,显示失败,提示:

-

ls error: No such directory。

-

path为有效目录路径时,会显示对应目录下的内容。

-

1.为空。

-

2.有效的目录路径。

-
+## 参数说明 -**表2** 输出格式参数说明 +**表1** 展示功能参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-1

-

每行列出一个文件。

-

N/A

-

-c

-

列,垂直排序。

-

N/A

-

-g

-

类似于 -l 但没有所有者。

-

N/A

-

-h

-

统计path目录下文件的总大小,单位为KiB。

-

N/A

-

-l

-

详细的显示path目录下文件的信息。

-

N/A

-

-m

-

文件之间添加逗号。

-

N/A

-

-n

-

类似 -l 数字格式显示uid/gid。

-

N/A

-

-o

-

类似 -l 但显示列表不包括组。

-

N/A

-

-x

-

列,水平排序。

-

N/A

-

-ll

-

文件的时间属性显示纳秒。

-

N/A

-

--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.

-
+| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看ls命令支持的参数列表,使用方式。 | N/A | +| -a | 显示所有文件包括.hidden隐藏类型的文件。 | N/A | +| -b | 转义非图形字符。 | N/A | +| -c | 使用ctime作为文件的时间戳,必须和-l参数一块使用。 | N/A | +| -d | 只显示path名称不显示path所包含的内容。 | N/A | +| -i | 显示文件的节点号。 | N/A | +| -p | 在path名称后放一个"/"。 | N/A | +| -q | 显示不可打印字符比如'?'。 | N/A | +| -s | 统计目录和其成员所占用的内存大小,单位为1024字节。 | N/A | +| -u | 以文件的最后访问时间为时间戳,配合 -l 一起使用。 | N/A | +| -A | 列出所有文件除了.和.. | N/A | +| -H | 跟随命令行符号链接。 | N/A | +| -L | 跟随符号链接。 | N/A | +| -Z | 安全上下文。 | N/A | +| path | path为空时,显示当前目录的内容。
path为无效文件名时,显示失败,提示:
ls error: No such directory。
path为有效目录路径时,会显示对应目录下的内容。 | 1.为空。
2.有效的目录路径 | -**表3** 排序参数说明(默认为按首字母排序) +**表2** 输出格式参数说明 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-f

-

不排序。

-

N/A

-

-r

-

按首字母反向排序。

-

N/A

-

-t

-

按文件的最后修改时间排序,最近时间为排头。

-

N/A

-

-S

-

按文件大小来排序,大文件为排头。

-

N/A

-
+| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -1 | 每行列出一个文件。 | N/A | +| -c | 列,垂直排序。 | N/A | +| -g | 类似于 -l 但没有所有者。 | N/A | +| -h | 统计path目录下文件的总大小,单位为KiB。 | N/A | +| -l | 详细的显示path目录下文件的信息。 | N/A | +| -m | 文件之间添加逗号。 | N/A | +| -n | 类似 -l 数字格式显示uid/gid。 | N/A | +| -o | 类似 -l 但显示列表不包括组。 | N/A | +| -x | 列,水平排序。 | N/A | +| -ll | 文件的时间属性显示纳秒。 | N/A | +| --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. | -## 使用指南 +**表3** 排序参数说明(默认为按首字母排序) -- ls命令显示当前目录的内容。 -- ll可以显示文件的大小。 -- proc下ll无法统计文件大小,显示为0。 -- dev、proc、无法统计文件时间信息。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -f | 不排序。 | N/A | +| -r | 按首字母反向排序。 | N/A | +| -t | 按文件的最后修改时间排序,最近时间为排头。 | N/A | +| -S | 按文件大小来排序,大文件为排头。 | N/A | -> ![](../public_sys-resources/icon-notice.gif) **须知:** -> + +## 使用指南 + +无 +> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** > fatfs的文件节点信息继承其父节点,父节点号为0。故在hi3516dv300开发板上ls -i显示的文件节点号全为0。 -## 使用实例 + +## 使用实例 举例: - ls + - ll -## 输出说明 -**示例 1** ls命令查看当前路径下的内容 +## 输出说明 -```shell +**示例1:**ls命令查看当前路径下的内容 + +``` OHOS:/$ ls bin etc nfs sdcard system usr dev lib proc storage userdata vendor ``` -**示例 2** ll命令查看当前路径下的内容 +**示例2:**ll命令查看当前路径下的内容 -```shell +``` OHOS:/$ ll total 20 drwxrwxrwx 1 0 0 2048 2021-11-21 17:52 bin/ diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md index bf08c22222..0e80d339eb 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-lsfd.md @@ -1,32 +1,36 @@ -# lsfd +# lsfd -- [命令功能](#section2053406181716) -- [命令格式](#section523771017172) -- [使用指南](#section27241213201719) -- [使用实例](#section442617197173) -- [输出说明](#section42491639151813) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 lsfd命令用来显示当前已经打开的文件描述符及对应的文件名。 -## 命令格式 + +## 命令格式 lsfd -## 使用指南 + +## 使用指南 lsfd命令显示当前已经打开文件的fd号以及文件的名字。 -## 使用实例 + +## 使用实例 举例:输入lsfd -## 输出说明 -**示例** lsfd输出说明 +## 输出说明 + +**示例:**lsfd输出说明 -```shell +``` OHOS # lsfd fd filename 3 /dev/console1 @@ -62,6 +66,3 @@ OHOS # lsfd 33 /dev/lite_ipc 34 /dev/lite_ipc ``` - - - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md index 1b8df8029d..65c54877ff 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mkdir.md @@ -1,114 +1,75 @@ -# mkdir +# mkdir -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 mkdir命令用来创建一个目录。 -## 命令格式 - -mkdir \[_-vp_\] \[_-m mode_\] \[_dirname..._\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看mkdir命令支持的参数列表

-

N/A

-

-m

-

设置即将创建目录的权限。

-

N/A

-

-p

-

递归逐级创建父子目录。

-

N/A

-

-v

-

打印创建目录过程中的详细信息。

-

N/A

-

directory

-

需要创建的目录。

-

N/A

-
- -## 使用指南 - -- mkdir后加所需要创建的目录名会在当前目录下创建目录。 -- mkdir后加路径,再加上需要创建的目录名,即在指定目录下创建目录。 -- mkdir后加参数,提供目录权限定制,目录逐级创建等功能。 - -> ![](../public_sys-resources/icon-notice.gif) **须知:** -> + +## 命令格式 + +mkdir [_-vp_] [_-m mode_] [_dirname..._] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看mkdir命令支持的参数列表 | N/A | +| -m | 设置即将创建目录的权限。 | N/A | +| -p | 递归逐级创建父子目录。 | N/A | +| -v | 打印创建目录过程中的详细信息。 | N/A | +| directory | 需要创建的目录。 | N/A | + + +## 使用指南 + +> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** > fatfs文件系统所有创建的文件和其挂载节点的权限属性保持一致,目前节点的权限只有用户读写权限,group和others权限不生效, -> +> > 且只有读写位可设置,有rw和ro两种,因此mkdir在附加-m参数时,创建的目录权限仅有777和555两种,可执行权限也不生效。 -## 使用实例 + +## 使用实例 举例: - mkdir testpath + - mkdir -m 777 testpath + - mkdir -pv testpath01/testpath02/testpath03 -## 输出说明 -**示例 1** 创建默认文件 +## 输出说明 -```shell +``` OHOS:/tmp$ mkdir testpath OHOS:/tmp$ ll total 2 drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/ ``` -**示例 2** 创建指定mode的目录 +示例 2 创建指定mode的目录 -```shell +``` OHOS:/tmp$ mkdir -m 777 testpath OHOS:/tmp$ ll total 2 drwxrwxrwx 1 0 0 2048 1979-12-31 00:00 testpath/ ``` -**示例 3** 逐级创建目录 +示例 3 逐级创建目录 -```shell +``` OHOS:/tmp$ mkdir -pv testpath01/testpath02/testpath03 mkdir: created directory 'testpath01' mkdir: created directory 'testpath01/testpath02' diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mount.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mount.md index 1ff71d655e..83ee18743d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mount.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mount.md @@ -1,92 +1,51 @@ -# mount +# mount -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 mount命令用来将设备挂载到指定目录。 -## 命令格式 - -mount \[_-f_\] \[_-t TYPE_\] \[_-o OPTION,_\] \[\[_DEVICE_\] _DIR_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看mount命令支持的参数列表。

-

N/A

-

-f

-

佯装挂载动作(实际不做挂载)。

-

N/A

-

-t

-

文件系统的种类。

-

TYPE:vfat, yaffs, jffs, ramfs, nfs,procfs, romfs.

-

-o

-

挂载选项。

-

N/A

-

DEVICE

-

要挂载的设备(格式为设备所在路径)。

-

系统拥有的设备。

-

DIR

-

指定目录。

-

用户必须具有指定目录中的执行(搜索)许可权。

-

N/A

-
- -## 使用指南 + +## 命令格式 + +mount [_-f_] [_-t TYPE_] [_-o OPTION,_] [[_DEVICE_] _DIR_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看mount命令支持的参数列表。 | N/A | +| -f | 佯装挂载动作(实际不做挂载)。 | N/A | +| -t | 文件系统的种类。 | TYPE:vfat, yaffs, jffs, ramfs, nfs,procfs, romfs. | +| -o | 挂载选项。 | N/A | +| DEVICE | 要挂载的设备(格式为设备所在路径)。 | 系统拥有的设备。 | +| DIR | 指定目录。
用户必须具有指定目录中的执行(搜索)许可权。 | N/A | + + +## 使用指南 mount后加需要挂载的设备信息、指定目录以及设备文件格式,就能成功挂载文件系统到指定目录。 -## 使用实例 + +## 使用实例 举例:mount -t nfs 192.168.1.3:/nfs nfs -## 输出说明 -**示例** 将服务器端nfs目录192.168.1.3:/nfs挂载到当前系统下新建的/nfs目录: +## 输出说明 -```shell +**示例:**将服务器端nfs目录192.168.1.3:/nfs挂载到当前系统下新建的/nfs目录: + +``` OHOS:/$ mkdir nfs OHOS:/$ mount -t nfs 192.168.1.3:/nfs nfs Mount nfs on 192.168.1.3:/nfs, uid:0, gid:0 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mv.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mv.md index 1c57edf36c..abbd83e9ec 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mv.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-mv.md @@ -1,135 +1,91 @@ -# mv - -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) - -## 命令功能 - -移动文件 - -## 命令格式 - -mv \[_-fivn_\] _SOURCE... DEST_ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

使用帮助。

-

N/A

-

-f

-

通过删除目标文件强制复制。

-

N/A

-

-i

-

若指定移动的源目录或文件与目标中目录或文件同名,则会先询问是否覆盖旧文件,输入 y 直接覆盖,输入 n 取消该操作。

-

N/A

-

-n

-

不要覆盖任何已存在的文件或目录。

-

N/A

-

-v

-

目前本参数toybox官方最新代码虽然支持,但同样也不生效。

-

N/A

-

SOURCE

-

源文件路径。

-

目前只支持文件,不支持目录;支持多文件同时移动。

-

DEST

-

目的文件路径。

-

支持目录以及文件。

-
- -## 使用指南 - -- 源文件路径支持“\*”和“?”通配符,“\*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。 -- 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。 -- 目的路径为文件时,所在目录必须存在。 -- 目的文件已存在则会覆盖。 - -## 使用实例 - -举例: - -- mv -i test.txt testpath/ - -- mv test?.txt testpath/ (移动 test3.txt testA.txt test_.txt) - - -## 输出说明 - -**示例 1** 显示结果如下 - -```shell -OHOS:/$ touch test.txt -OHOS:/$ mkdir testpath -OHOS:/$ touch testpath/test.txt -OHOS:/$ mv -i test.txt testpath/ -mv: overwrite 'testpath//test.txt' (Y/n):y -OHOS:/$ ls -bin etc proc storage testpath usr -dev lib sdcard system userdata vendor -OHOS:/$ cp testpath/test.txt ./ -OHOS:/$ ls -bin etc proc storage test.txt userdata vendor -dev lib sdcard system testpath usr -OHOS:/$ mv -i test.txt testpath/ -mv: overwrite 'testpath//test.txt' (Y/n):n -OHOS:/$ ls -bin etc proc storage test.txt userdata vendor -dev lib sdcard system testpath usr -``` - -**示例 2** 通配符使用 - -```shell -OHOS:/$ ls -bin etc proc storage test.txt testA.txt testpath usr -dev lib sdcard system test3.txt test_.txt userdata vendor -OHOS:/$ mv test?.txt testpath/ -OHOS:/$ ls -bin etc proc storage test.txt userdata vendor -dev lib sdcard system testpath usr -OHOS:/$ ls testpath/ -test.txt test3.txt testA.txt test_.txt -``` +# mv + +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) + +## 命令功能 + +移动文件。 + + +## 命令格式 + +mv [_-fivn_] _SOURCE... DEST_ + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -help | 使用帮助。 | N/A | +| -f | 通过删除目标文件强制复制。 | N/A | +| -i | 若指定移动的源目录或文件与目标中目录或文件同名,则会先询问是否覆盖旧文件,输入 y 直接覆盖,输入 n 取消该操作。 | N/A | +| -n | 不要覆盖任何已存在的文件或目录。 | N/A | +| -v | 目前本参数toybox官方最新代码虽然支持,但同样也不生效。 | N/A | +| SOURCE | 源文件路径。 | 目前只支持文件,不支持目录;支持多文件同时移动。 | +| DEST | 目的文件路径。 | 支持目录以及文件。 | + + +## 使用指南 + +- 源文件路径支持“\*”和“?”通配符,“\*”代表任意多个字符,“?”代表任意单个字符。目的路径不支持通配符。当源路径可匹配多个文件时,目的路径必须为目录。 + +- 目的路径为目录时,该目录必须存在。此时目的文件以源文件命名。 + +- 目的路径为文件时,所在目录必须存在。 + +- 目的文件已存在则会覆盖。 + + +## 使用实例 + +举例: + +- mv -i test.txt testpath/ + +- mv test?.txt testpath/ (移动 test3.txt testA.txt test_.txt) + + +## 输出说明 + +**示例 1** 显示结果如下 + +``` +OHOS:/$ touch test.txt +OHOS:/$ mkdir testpath +OHOS:/$ touch testpath/test.txt +OHOS:/$ mv -i test.txt testpath/ +mv: overwrite 'testpath//test.txt' (Y/n):y +OHOS:/$ ls +bin etc proc storage testpath usr +dev lib sdcard system userdata vendor +OHOS:/$ cp testpath/test.txt ./ +OHOS:/$ ls +bin etc proc storage test.txt userdata vendor +dev lib sdcard system testpath usr +OHOS:/$ mv -i test.txt testpath/ +mv: overwrite 'testpath//test.txt' (Y/n):n +OHOS:/$ ls +bin etc proc storage test.txt userdata vendor +dev lib sdcard system testpath usr +``` + +**示例 2** 通配符使用 + +``` +OHOS:/$ ls +bin etc proc storage test.txt testA.txt testpath usr +dev lib sdcard system test3.txt test_.txt userdata vendor +OHOS:/$ mv test?.txt testpath/ +OHOS:/$ ls +bin etc proc storage test.txt userdata vendor +dev lib sdcard system testpath usr +OHOS:/$ ls testpath/ +test.txt test3.txt testA.txt test_.txt +``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md index 8c768cff95..15e1680b8b 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partinfo.md @@ -1,58 +1,47 @@ -# partinfo +# partinfo -- [命令功能](#section1777503617199) -- [命令格式](#section185501447132114) -- [参数说明](#section1304151212252) -- [使用指南](#section4566131982520) -- [使用实例](#section4351134942514) -- [输出说明](#section66689331412) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 partinfo命令用于查看系统识别的硬盘,SD卡多分区信息。 -## 命令格式 -partinfo <_dev\_inodename_\> +## 命令格式 -## 参数说明 +partinfo <_dev_inodename_> -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

dev_inodename

-

要查看的分区名字。

-

合法的分区名。

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -无。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| dev_inodename | 要查看的分区名字。 | 合法的分区名。 | -## 使用实例 + +## 使用指南 + +无 + + +## 使用实例 举例:partinfo /dev/mmcblk0p0 -## 输出说明 -**示例** 查看系统分区信息 +## 输出说明 -```shell -OHOS # partinfo /dev/mmcblk0p0 +**示例**:查看系统分区信息 +``` +OHOS # partinfo /dev/mmcblk0p0 part info : disk id : 0 part_id in system: 1 @@ -62,4 +51,3 @@ part filesystem : 00 part sec start : 20480 part sec count : 102400 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partition.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partition.md index 0717a670b8..a7d0c1e6a2 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partition.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-partition.md @@ -1,65 +1,49 @@ -# partition +# partition -- [命令功能](#section255095212257) -- [命令格式](#section10258056122515) -- [参数说明](#section177200581256) -- [使用指南](#section17866411262) -- [使用实例](#section1927174202610) -- [输出说明](#section11321011223) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 partition命令用来查看flash分区信息。 -## 命令格式 - -partition \[_nand / spinor_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

nand

-

显示nand flash分区信息。

-

N/A

-

spinor

-

显示spinor flash分区信息。

-

N/A

-
- -## 使用指南 - -- partition命令用来查看flash分区信息。 -- 仅当使能yaffs文件系统时才可以查看nand flash分区信息,使能jffs或romfs文件系统时可以查看spinor flash分区信息。 - -## 使用实例 + +## 命令格式 + +partition [_nand / spinor_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| nand | 显示NAND Flash分区信息。 | N/A | +| spinor | 显示SPI NOR Flash分区信息。 | N/A | + + +## 使用指南 + +- partition命令用来查看flash分区信息。 + +- 仅当使能yaffs文件系统时才可以查看nand flash分区信息,使能jffs或romfs文件系统时可以查看spinor flash分区信息。 + + +## 使用实例 举例:partition spinor -## 输出说明 + +## 输出说明 查看spinor flash分区信息 -```shell +``` OHOS # partition spinor spinor partition num:0, blkdev name:/dev/spinorblk0, mountpt:/, startaddr:0x00500000, length:0x00a00000 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-pwd.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-pwd.md index 108f538119..b5d77d67c7 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-pwd.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-pwd.md @@ -1,38 +1,42 @@ -# pwd +# pwd -- [命令功能](#section197737712267) -- [命令格式](#section1544061016267) -- [参数说明](#section599112120262) -- [使用指南](#section66901116152615) -- [使用实例](#section7427181922612) -- [输出说明](#section116313389418) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 pwd命令用来显示当前路径。 -## 命令格式 + +## 命令格式 pwd -## 参数说明 + +## 参数说明 无。 -## 使用指南 + +## 使用指南 pwd 命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / (斜线)分隔。第一个 / 表示根目录, 最后一个目录是当前目录。 -## 使用实例 + +## 使用实例 举例:输入pwd -## 输出说明 -**示例** 查看当前路径 +## 输出说明 -```shell +**示例**:查看当前路径 + +``` OHOS:/sdcard/nfs$ pwd /sdcard/nfs ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rm.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rm.md index d9c59e6ffb..c6d29a3f5e 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rm.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rm.md @@ -1,82 +1,57 @@ -# rm +# rm -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 rm命令用来删除文件或文件夹。 -## 命令格式 - -rm \[_-fv_\] _FILE or rm_ \[_-rv_\] \[_PATH_ | _filename_\]... - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-r

-

删除空目录或非空目录。

-

N/A

-

-f

-

强制删除:不需要确认,删除不存的文件在也不报错。

-

N/A

-

-v

-

显示删除的过程。

-

N/A

-

PATH/filename

-

要删除文件或文件夹的名称,支持输入路径。

-

N/A

-
- -## 使用指南 - -- rm命令能同时删除多个文件或文件夹。 -- rm -r命令可以删除非空目录。 -- 删除不存在的文件会报错。 - -## 使用实例 + +## 命令格式 + +rm [_-fv_] _FILE or rm_ [_-rv_] [_PATH_ | _filename_]... + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -r | 删除空目录或非空目录。 | N/A | +| -f | 强制删除:不需要确认,删除不存的文件在也不报错。 | N/A | +| -v | 显示删除的过程。 | N/A | +| PATH/filename | 要删除文件或文件夹的名称,支持输入路径。 | N/A | + + +## 使用指南 + +- rm命令能同时删除多个文件或文件夹。 + +- rm -r命令可以删除非空目录。 + +- 删除不存在的文件会报错。 + + +## 使用实例 举例: - 输入rm testfile + - 输入rm -r testpath/ -## 输出说明 -**示例 1** 用 rm 命令删除文件 testfile +## 输出说明 + +**示例 1** 用 rm 命令删除文件 testfile -```shell +``` OHOS:/$ ls bin etc proc storage testfile usr dev lib sdcard system userdata vendor @@ -86,9 +61,9 @@ bin etc proc storage userdata vendor dev lib sdcard system usr ``` -**示例 2** 用 rm -r 删除非空目录 testpath +**示例 2** 用 rm -r 删除非空目录 testpath -```shell +``` OHOS:/$ ls bin etc proc storage testpath usr dev lib sdcard system userdata vendor diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md index c73affdd12..a889240396 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-rmdir.md @@ -1,79 +1,53 @@ -# rmdir +# rmdir -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 rmdir命令用来删除一个目录。 -## 命令格式 - -rmdir \[_-p_\] \[_dirname..._\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看rmdir命令支持的参数列表。

-

N/A

-

-p

-

删除路径。

-

N/A

-

--ignore-fail-on-non-empty

-

忽略删除非空目录导致的故障。

-

N/A

-

dir

-

需要删除目录的名称,删除目录必须为空,支持输入路径。

-

N/A

-
- -## 使用指南 - -- rmdir命令只能用来删除目录。 -- rmdir一次只能删除一个目录。 -- rmdir只能删除空目录。 - -## 使用实例 + +## 命令格式 + +rmdir [_-p_] [_dirname..._] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看rmdir命令支持的参数列表。 | N/A | +| -p | 删除路径。 | N/A | +| --ignore-fail-on-non-empty | 忽略删除非空目录导致的故障。 | N/A | +| dir | 需要删除目录的名称,删除目录必须为空,支持输入路径。 | N/A | + + +## 使用指南 + +- rmdir命令只能用来删除目录。 + +- rmdir一次只能删除一个目录。 + +- rmdir只能删除空目录。 + + +## 使用实例 举例:输入rmdir dir -## 输出说明 -**示例** 删除一个名为 dir 的目录 +## 输出说明 + +**示例:**删除一个名为 dir 的目录 -```shell +``` OHOS:/test$ mkdir dir OHOS:/test$ ls dir diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-statfs.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-statfs.md index 628c69d674..c84a645400 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-statfs.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-statfs.md @@ -1,55 +1,43 @@ -# statfs +# statfs -- [命令功能](#section153921657152613) -- [命令格式](#section135391102717) -- [参数说明](#section074312314279) -- [使用指南](#section133816772712) -- [使用实例](#section526149182717) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) -## 命令功能 +## 命令功能 statfs命令用来打印文件系统的信息,如该文件系统类型、总大小、可用大小等信息。 -## 命令格式 -statfs \[_directory_\] +## 命令格式 -## 参数说明 +statfs [_directory_] -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

directory

-

文件系统的路径。

-

必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| directory | 文件系统的路径。 | 必须是存在的文件系统,并且其支持statfs命令,当前支持的文件系统有:JFFS2,FAT,NFS。 | + + +## 使用指南 打印信息因文件系统而异。 -## 使用实例 -以nfs文件系统为例: +## 使用实例 -输入statfs /nfs +以nfs文件系统为例: -**示例** 但因nfs文件系统信息 +statfs /nfs -```shell +**示例**:statfs输出说明 +``` OHOS # statfs ./nfs statfs got: f_type = 26985 @@ -58,9 +46,7 @@ statfs got: free_clusters = 499254808 avail_clusters = 499254808 f_namelen = 255 - ./nfs total size: 808742490112 Bytes free size: 255618461696 Bytes ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-sync.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-sync.md index 3a6702d049..d019481a30 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-sync.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-sync.md @@ -1,34 +1,39 @@ -# sync +# sync -- [命令功能](#section1285017122274) -- [命令格式](#section4731516162712) -- [参数说明](#section9352418122714) -- [使用指南](#section10725192142717) -- [使用实例](#section414434814354) -- [输出说明](#section19618121710317) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 sync命令用于同步缓存数据(文件系统的数据)到sd卡。 -## 命令格式 + +## 命令格式 sync -## 参数说明 + +## 参数说明 无。 -## 使用指南 -- sync命令用来刷新缓存,当没有sd卡插入时不进行操作。 -- 有sd卡插入时缓存信息会同步到sd卡,成功返回时无显示。 +## 使用指南 + +- sync命令用来刷新缓存,当没有sd卡插入时不进行操作。 + +- 有sd卡插入时缓存信息会同步到sd卡,成功返回时无显示。 -## 使用实例 + +## 使用实例 举例:输入sync,有sd卡时同步到sd卡,无sd卡时不操作。 -## 输出说明 -无。 +## 输出说明 +无。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-touch.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-touch.md index a22e0cd453..6b6984cda4 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-touch.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-touch.md @@ -1,72 +1,57 @@ -# touch +# touch -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section405) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 -- touch命令用来在指定的目录下创建一个不存在的空文件。 -- touch命令操作已存在的文件会成功,不会更新时间戳。 +- touch命令用来在指定的目录下创建一个不存在的空文件。 -## 命令格式 +- touch命令操作已存在的文件会成功,不会更新时间戳。 -touch \[_filename_\] -## 参数说明 +## 命令格式 -**表 1** 参数说明 +touch [_filename_] - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看touch命令支持的参数列表

-

N/A

-

filename

-

需要创建文件的名称。

-

N/A

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -- touch命令用来创建一个空文件,该文件可读写。 -- 使用touch命令允许一次创建多个文件。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看touch命令支持的参数列表 | N/A | +| filename | 需要创建文件的名称。 | N/A | - >![](../public_sys-resources/icon-notice.gif) **须知:** - >在系统重要资源路径下使用touch命令创建文件,会对系统造成死机等未知影响,如在/dev路径下执行touch uartdev-0,会产生系统卡死现象。 -## 使用实例 +## 使用指南 + +- touch命令用来创建一个空文件,该文件可读写。 + +- 使用touch命令允许一次创建多个文件。 + > ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** + > 在系统重要资源路径下使用touch命令创建文件,会对系统造成死机等未知影响,如在/dev路径下执行touch uartdev-0,会产生系统卡死现象。 + + +## 使用实例 举例: - touch file.c + - touch testfile1 testfile2 testfile3 -## 输出说明 -**示例 1** 创建一个名为 file.c 的文件 +## 输出说明 + +**示例 1** 创建一个名为 file.c 的文件 -```shell +``` OHOS:/tmp$ ls OHOS:/tmp$ touch file.c OHOS:/tmp$ ls @@ -78,7 +63,8 @@ total 0 **示例 2** 同时创建三个文件 -```shell +``` +*OHOS:/tmp$ OHOS:/tmp$ touch testfile1 testfile2 testfile3 OHOS:/tmp$ ll total 0 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-umount.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-umount.md index 46beb6e133..1a759d5c75 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-umount.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-umount.md @@ -1,90 +1,62 @@ -# umount +# umount -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 umount命令用来卸载指定文件系统。 -## 命令格式 - -umount \[_-a \[-t TYPE\]_\] \[_dir_\] - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看umount命令支持的参数列表。

-

N/A

-

-a

-

卸载所有已挂载的目录。

-

N/A

-

-t

-

同-a选项一起使用,限制-a,只卸载-t所指定的文件系统类型。

-

N/A

-

dir

-

需要卸载文件系统对应的目录。

-

系统已挂载的文件系统的目录。

-
- -## 使用指南 + +## 命令格式 + +umount [_-a [-t TYPE]_] [_dir_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看umount命令支持的参数列表。 | N/A | +| -a | 卸载所有已挂载的目录。 | N/A | +| -t | 同-a选项一起使用,限制-a的卸载范围,只卸载-t所指定的文件系统类型的挂载目录。 | N/A | +| dir | 需要卸载的文件系统对应的目录。 | 系统已挂载的文件系统的目录 | + + +## 使用指南 umount后加上需要卸载的指定文件系统的目录,即将指定文件系统卸载。 -## 使用实例 + +## 使用实例 举例: - umount ./nfs -- umount -a -t nfs ./nfs -## 输出说明 +- umount -a -t nfs + -将已在./nfs挂载的文件系统卸载掉。 +## 输出说明 -**示例 1** umount输出示例 +将已在./nfs挂载的文件系统卸载掉 -```shell +**示例 1** umount输出示例 + +``` OHOS:/$ umount ./nfs/ umount ok ``` -**示例 2** umount指定文件类型 +**示例 2** 卸载所有已挂载的nfs类型的目录 -```shell -OHOS:/$ umount -a -t nfs ./nfs/ +``` +OHOS:/$ umount -a-t nfs umount ok ``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-write.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-write.md index 09fb29883a..c7ab7fcf66 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-write.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file-write.md @@ -1,69 +1,52 @@ -# writeproc +# writeproc -- [命令功能](#section366714216619) -- [命令格式](#section8833164614615) -- [参数说明](#section12809111019453) -- [使用指南](#section15935131220717) -- [使用实例](#section79281818476) -- [输出说明](#section12742311179) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 proc fs支持传入字符串参数,需要每个文件实现自己的写方法。 -## 命令格式 - -writeproc <_data_\> \>\> /proc/<_filename_\> - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

data

-

要输入的字符串,以空格为结束符,如需输入空格,请用""包裹。

-

N/A

-

filename

-

data要传入的proc文件。

-

N/A

-
- -## 使用指南 + +## 命令格式 + +writeproc <_data_> >> /proc/<_filename_> + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| data | 要输入的字符串,以空格为结束符,如需输入空格,请用""包裹。 | N/A | +| filename | data要传入的proc文件。 | N/A | + + +## 使用指南 proc文件实现自身的write函数,调用writeproc命令后会将入参传入write函数。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->procfs不支持多线程访问。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> procfs不支持多线程访问。 + -## 使用实例 +## 使用实例 -举例:writeproc test \>\> /proc/uptime +举例:writeproc test >> /proc/uptime -## 输出说明 -OHOS \# writeproc test \>\> /proc/uptime +## 输出说明 -\[INFO\]write buf is: test +OHOS \# writeproc test >> /proc/uptime -test \>\> /proc/uptime +[INFO]write buf is: test ->![](../public_sys-resources/icon-note.gif) **说明:** ->uptime proc文件临时实现write函数,INFO日志为实现的测试函数打印的日志。 +test >> /proc/uptime +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> uptime proc文件临时实现write函数,INFO日志为实现的测试函数打印的日志。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file.md index 903ec8967f..fad2fc2cf6 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-file.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-file.md @@ -1,45 +1,48 @@ -# 文件命令 +# 文件命令 -- **[cat](kernel-small-debug-shell-file-cat.md)** -- **[cd](kernel-small-debug-shell-file-cd.md)** +- **[cat](kernel-small-debug-shell-file-cat.md)** -- **[chgrp](kernel-small-debug-shell-file-chgrp.md)** +- **[cd](kernel-small-debug-shell-file-cd.md)** -- **[chmod](kernel-small-debug-shell-file-chmod.md)** +- **[chgrp](kernel-small-debug-shell-file-chgrp.md)** -- **[chown](kernel-small-debug-shell-file-chown.md)** +- **[chmod](kernel-small-debug-shell-file-chmod.md)** -- **[cp](kernel-small-debug-shell-file-cp.md)** +- **[chown](kernel-small-debug-shell-file-chown.md)** -- **[format](kernel-small-debug-shell-file-format.md)** +- **[cp](kernel-small-debug-shell-file-cp.md)** -- **[ls](kernel-small-debug-shell-file-ls.md)** +- **[format](kernel-small-debug-shell-file-format.md)** -- **[lsfd](kernel-small-debug-shell-file-lsfd.md)** +- **[ls](kernel-small-debug-shell-file-ls.md)** -- **[mkdir](kernel-small-debug-shell-file-mkdir.md)** +- **[lsfd](kernel-small-debug-shell-file-lsfd.md)** -- **[mount](kernel-small-debug-shell-file-mount.md)** +- **[mkdir](kernel-small-debug-shell-file-mkdir.md)** -- **[mv](kernel-small-debug-shell-file-mv.md)** +- **[mount](kernel-small-debug-shell-file-mount.md)** -- **[partinfo](kernel-small-debug-shell-file-partinfo.md)** +- **[partinfo](kernel-small-debug-shell-file-partinfo.md)** -- **[partition](kernel-small-debug-shell-file-partition.md)** +- **[partition](kernel-small-debug-shell-file-partition.md)** -- **[pwd](kernel-small-debug-shell-file-pwd.md)** +- **[pwd](kernel-small-debug-shell-file-pwd.md)** -- **[rm](kernel-small-debug-shell-file-rm.md)** +- **[rm](kernel-small-debug-shell-file-rm.md)** -- **[rmdir](kernel-small-debug-shell-file-rmdir.md)** +- **[rmdir](kernel-small-debug-shell-file-rmdir.md)** -- **[statfs](kernel-small-debug-shell-file-statfs.md)** +- **[statfs](kernel-small-debug-shell-file-statfs.md)** -- **[sync](kernel-small-debug-shell-file-sync.md)** +- **[sync](kernel-small-debug-shell-file-sync.md)** -- **[touch](kernel-small-debug-shell-file-touch.md)** +- **[touch](kernel-small-debug-shell-file-touch.md)** -- **[writeproc](kernel-small-debug-shell-file-write.md)** +- **[writeproc](kernel-small-debug-shell-file-write.md)** -- **[umount](kernel-small-debug-shell-file-umount.md)** +- **[umount](kernel-small-debug-shell-file-umount.md)** + +- **[du](kernel-small-debug-shell-file-du.md)** + +- **[mv](kernel-small-debug-shell-file-mv.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-guide.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-guide.md index 44be99dfcd..b25733026d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-guide.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-guide.md @@ -1,165 +1,88 @@ -# Shell命令开发指导 +# Shell命令开发指导 -- [开发指导](#section13408945163812) +- [开发指导](#开发指导) -## 开发指导 +## 开发指导 新增Shell命令的典型开发流程如下: -1. 包含如下头文件: - - ``` - #include "shell.h" - #include "shcmd.h" - ``` - -2. 注册命令。用户可以选择静态注册命令方式和系统运行时动态注册命令方式,静态注册命令方式一般用在系统常用命令注册,动态注册命令方式一般用在用户命令注册。 - - 1. 静态注册命令方式: - - 1. 通过宏的方式注册。 - - 这个宏的原型为: - - ``` - SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) - ``` - - **表 1** SHELLCMD\_ENTRY参数详解 - - - - - - - - - - - - - - - - - - - - - - -

参数

-

描述

-

l

-

静态注册全局变量名(注意:不与系统中其他symbol重名)。

-

cmdType

-

命令类型:

-
  • CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。

    -
  • CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。

    -
-

cmdKey

-

命令关键字,函数在Shell中访问的名称。

-

paraNum

-

调用的执行函数的入参最大个数,暂不支持。

-

cmdHook

-

命令执行函数地址,即命令实际执行函数。

-
- - 如: - - ``` - SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) - ``` - - 2. 在build/mk/liteos\_tables\_ldflags.mk中添加相应选项: - - 如:上述“ls”命令注册时,需在build/mk/liteos\_tables\_ldflags.mk中添加“-uls\_shellcmd”。其中-u后面跟SHELLCMD\_ENTRY的第一个参数。 - - 2. 动态注册命令方式: - - 注册函数原型: - - ``` - UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) - ``` - - **表 2** UINT32 osCmdReg参数详解 - - - - - - - - - - - - - - - - - - - -

参数

-

描述

-

cmdType

-

命令类型:

-
  • CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。

    -
  • CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。

    -
-

cmdKey

-

命令关键字,函数在Shell中访问的名称。

-

paraNum

-

调用的执行函数的入参最大个数,暂不支持该参数;当前为默认值XARGS(0xFFFFFFFF)。

-

cmdHook

-

命令执行函数地址,即命令实际执行函数。

-
- - 如: - - ``` - osCmdReg(CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) - ``` - - >![](../public_sys-resources/icon-note.gif) **说明:** - >命令关键字必须是唯一的,也即两个不同的命令项不能拥有相同的命令关键字,否则只会执行其中一个。 - >Shell在执行用户命令时,如果存在多个命令关键字相同的命令,只会执行其中在"help"命令中排序在最前面的一个。 - -3. 添加内置命令函数原型。 - - ``` - UINT32 osShellCmdLs(UINT32 argc, CHAR **argv) - ``` - - **表 3** osShellCmdLs参数说明 - - - - - - - - - - - - - -

参数

-

参数描述

-

argc

-

Shell命令中,参数个数。

-

argv

-

为指针数组,每个元素指向一个字符串,可以根据选择命令类型,决定是否要把命令关键字传入给注册函数。

-
- -4. 输入Shell命令,有两种输入方式: - - 在串口工具中直接输入Shell命令。 - - - 在telnet工具中输入Shell命令(telnet使用方式详见[telnet](kernel-small-debug-shell-net-telnet.md))。 +1. 包含如下头文件: + ``` + #include "shell.h" + #include "shcmd.h" + ``` +2. 注册命令。用户可以选择静态注册命令方式和系统运行时动态注册命令方式,静态注册命令方式一般用在系统常用命令注册,动态注册命令方式一般用在用户命令注册。 + 1. 静态注册命令方式: + + 1. 通过宏的方式注册。 + 这个宏的原型为: + + ``` + SHELLCMD_ENTRY(l, cmdType, cmdKey, paraNum, cmdHook) + ``` + + **表1** SHELLCMD_ENTRY参数详解 + + | 参数 | 描述 | + | -------- | -------- | + | l | 静态注册全局变量名(注意:不与系统中其他symbol重名)。 | + | cmdType | 命令类型:
- CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls  /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。
- CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。 | + | cmdKey | 命令关键字,函数在Shell中访问的名称。 | + | paraNum | 调用的执行函数的入参最大个数,暂不支持。 | + | cmdHook | 命令执行函数地址,即命令实际执行函数。 | + + 如: + + ``` + SHELLCMD_ENTRY(ls_shellcmd, CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) + ``` + 2. 在build/mk/liteos_tables_ldflags.mk中添加相应选项: + 如:上述“ls”命令注册时,需在build/mk/liteos_tables_ldflags.mk中添加“-uls_shellcmd”。其中-u后面跟SHELLCMD_ENTRY的第一个参数。 + 2. 动态注册命令方式: + + 注册函数原型: + + ``` + UINT32 osCmdReg(CmdT ype cmdType, CHAR *cmdKey, UINT32 paraNum, CmdCallBackFunc cmdProc) + ``` + + **表2** UINT32 osCmdReg参数详解 + + | 参数 | 描述 | + | -------- | -------- | + | cmdType | 命令类型:
- CMD_TYPE_EX:不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls  /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。
- CMD_TYPE_STD:支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。 | + | cmdKey | 命令关键字,函数在Shell中访问的名称。 | + | paraNum | 调用的执行函数的入参最大个数,暂不支持该参数;当前为默认值XARGS(0xFFFFFFFF)。 | + | cmdHook | 命令执行函数地址,即命令实际执行函数。 | + + 如: + + ``` + osCmdReg(CMD_TYPE_EX, "ls", XARGS, (CMD_CBK_FUNC)osShellCmdLs) + ``` + + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** + > 命令关键字必须是唯一的,也即两个不同的命令项不能拥有相同的命令关键字,否则只会执行其中一个。 + > + > Shell在执行用户命令时,如果存在多个命令关键字相同的命令,只会执行其中在"help"命令中排序在最前面的一个。 + +3. 添加内置命令函数原型。 + + ``` + UINT32 osShellCmdLs(UINT32 argc, CHAR **argv) + ``` + + **表3** osShellCmdLs参数说明 + + | 参数 | 参数描述 | + | -------- | -------- | + | argc | Shell命令中,参数个数。 | + | argv | 为指针数组,每个元素指向一个字符串,可以根据选择命令类型,决定是否要把命令关键字传入给注册函数。 | + +4. 输入Shell命令,有两种输入方式: + + - 在串口工具中直接输入Shell命令。 + - 在telnet工具中输入Shell命令(telnet使用方式详见[telnet](../kernel/kernel-small-debug-shell-net-telnet.md))。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-magickey.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-magickey.md index 3bb14abaf1..b7b694b4bc 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-magickey.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-magickey.md @@ -1,38 +1,36 @@ -# 魔法键使用方法 +# 魔法键使用方法 -- [使用场景](#section2350114718546) -- [使用方法](#section3305151511559) +- [使用场景](#使用场景) +- [使用方法](#使用方法) -## 使用场景 +## 使用场景 在系统运行出现无响应等情况时,可以通过魔法键功能确定系统是否被锁中断(魔法键也无响应)或者查看系统任务运行状态等信息。 在中断有响应的情况下,可以通过魔法键查看task信息中 cpup(CPU占用率)看是哪个任务长时间占用CPU导致系统其他任务无响应(一般为比较高优先级任务一直抢占CPU,导致低优先级任务无响应)。 -## 使用方法 -1. 配置宏LOSCFG\_ENABLE\_MAGICKEY。 +## 使用方法 -魔法键依赖于宏LOSCFG\_ENABLE\_MAGICKEY,使用时通过menuconfig在配置项中开启“Enable MAGIC KEY”: +1. 配置宏LOSCFG_ENABLE_MAGICKEY。 -Debug ---\> Enable MAGIC KEY;若关闭该选项,则魔法键失效。 +魔法键依赖于宏LOSCFG_ENABLE_MAGICKEY,使用时通过menuconfig在配置项中开启“Enable MAGIC KEY”: ->![](../public_sys-resources/icon-note.gif) **说明:** ->1. 可以在menuconfig中,将光标移动到LOSCFG\_ENABLE\_MAGICKEY上,输入“?”,查看帮助信息。 +Debug ---> Enable MAGIC KEY;若关闭该选项,则魔法键失效。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 1. 可以在menuconfig中,将光标移动到LOSCFG_ENABLE_MAGICKEY上,输入“?”,查看帮助信息。 2. 输入“ctrl + r”键,打开魔法键检测功能。 在连接UART或者USB转虚拟串口的情况下,输入“ctrl + r” 键,打开魔法键检测功能,输出 “Magic key on”;再输入一次后,则关闭魔法键检测功能,输出“Magic key off”。魔法键功能如下: -- ctrl + z:帮助键,输出相关魔法键简单介绍; +- ctrl + z:帮助键,输出相关魔法键简单介绍; -- ctrl + t:输出任务相关信息; +- ctrl + t:输出任务相关信息; -- ctrl + p:系统主动进入panic,输出panic相关信息后,系统会挂住; +- ctrl + p:系统主动进入panic,输出panic相关信息后,系统会挂住; -- ctrl + e:系统进行简单完整性内存池检查,检查出错会输出相关错误信息,检查正常会输出“system memcheck over, all passed!”。 - - ->![](../public_sys-resources/icon-notice.gif) **须知:** ->魔法键检测功能打开情况下,如果需要通过UART或者USB转虚拟串口输入特殊字符需避免与魔法键值重复,否则魔法键会被误触发,而原有设计功能可能出现错误。 +- ctrl + e:系统进行简单完整性内存池检查,检查出错会输出相关错误信息,检查正常会输出“system memcheck over, all passed!”。 +> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** +> 魔法键检测功能打开情况下,如果需要通过UART或者USB转虚拟串口输入特殊字符需避免与魔法键值重复,否则魔法键会被误触发,而原有设计功能可能出现错误。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-arp.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-arp.md index 34c657e197..24cee72fb4 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-arp.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-arp.md @@ -1,117 +1,62 @@ -# arp +# arp -- [命令功能](#section201149459368) -- [命令格式](#section579813484364) -- [参数说明](#section168065311366) -- [使用指南](#section19190125723612) -- [使用实例](#section10383416372) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) -## 命令功能 +## 命令功能 在以太网中,主机之间的通信是直接使用MAC地址(非IP地址)来通信的,所以,对于使用IP通信的协议,必须能够将IP地址转换成MAC地址,才能在局域网(以太网)内通信。解决这个问题的方法就是主机存储一张IP和MAC地址对应的表,即ARP缓存,主机要往一个局域网内的目的IP地址发送IP包时,就可以从ARP缓存表中查询到目的MAC地址。ARP缓存是由TCP/IP协议栈维护的,用户可通过ARP命令查看和修改ARP表。 -## 命令格式 - -- arp - -- arp \[_-i IF_\] -s _IPADDR HWADDR_ - -- arp \[_-i IF_\] -d _IPADDR_ - - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-

打印整个ARP缓存的内容。

-

N/A

-

-i IF

-

指定的网络接口(可选参数)。

-

N/A

-

-s IPADDR

-

HWADDR

-

增加一条ARP表项,后面的参数是局域网中另一台主机的IP地址及其对应的MAC地址。

-

N/A

-

-d IPADDR

-

删除一条ARP表项。

-

N/A

-
- -## 使用指南 - -- arp命令用来查询和修改TCP/IP协议栈的ARP缓存表,增加非同一子网内的IP地址的ARP表项是没有意义的,协议栈会返回失败。 -- 命令需要启动TCP/IP协议栈后才能使用。 - -## 使用实例 + +## 命令格式 + +arp + +arp [_-i IF_] -s _IPADDR HWADDR_ + +arp [_-i IF_] -d _IPADDR_ + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| 无 | 打印整个ARP缓存的内容。 | N/A | +| -i IF | 指定的网络接口(可选参数)。 | N/A | +| -s IPADDR
HWADDR | 增加一条ARP表项,后面的参数是局域网中另一台主机的IP地址及其对应的MAC地址。 | N/A | +| -d IPADDR | 删除一条ARP表项。 | N/A | + + +## 使用指南 + +- arp命令用来查询和修改TCP/IP协议栈的ARP缓存表,增加非同一子网内的IP地址的ARP表项是没有意义的,协议栈会返回失败。 + +- 命令需要启动TCP/IP协议栈后才能使用。 + + +## 使用实例 举例: 输入arp -**示例** 打印整个 ARP 缓存表 - -```shell +**示例:**打印整个 ARP 缓存表 +``` OHOS # arp Address HWaddress Iface Type 192.168.1.10 E6:2B:99:2C:4B:20 eth0 static ``` -**表 2** 参数说明 - - - - - - - - - - - - - - - - - - - -

参数

-

说明

-

Address

-

表示网络设备的IPv4地址。

-

HWaddress

-

表示网络设备的MAC地址。

-

Iface

-

表示该ARP表项使用的接口名。

-

Type

-

表示该ARP表项是动态的还是静态的,动态是指ARP表项由协议栈自动创建,静态是指ARP表项是由用户增加的。

-
+**表2** 参数说明 +| 参数 | 说明 | +| -------- | -------- | +| Address | 表示网络设备的IPv4地址。 | +| HWaddress | 表示网络设备的MAC地址。 | +| Iface | 表示该ARP表项使用的接口名。 | +| Type | 表示该ARP表项是动态的还是静态的,动态是指ARP表项由协议栈自动创建,静态是指ARP表项是由用户增加的。 | diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md index 01be24bbbb..fe91b3e697 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-dhclient.md @@ -1,76 +1,48 @@ -# dhclient +# dhclient -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) -## 命令功能 +## 命令功能 设置和查看dhclient的参数。 -## 命令格式 - -- dhclient <_netif name_\> - -- dhclient -x <_netif name_\> - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-h | --help

-

查看dhclient命令支持的参数列表,及使用方式。

-

N/A

-

<netif name>

-

启动对应网卡的dhcp请求。

-

网卡名字,eth0。

-

-x <netif name>

-

关闭对应网卡的dhcp功能。

-

网卡名字,eth0。

-
- -## 使用指南 - -无。 - -## 使用实例 + +## 命令格式 + +- dhclient <_netif name_> + +- dhclient -x <_netif name_> + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -h \| --help | 查看dhclient命令支持的参数列表,及使用方式。 | N/A | +| <netif name> | 启动对应网卡的dhcp请求。 | 网卡名字,eth0。 | +| -x <netif name> | 关闭对应网卡的dhcp功能。 | 网卡名字,eth0。 | + + +## 使用指南 举例: - dhclient eth0 + - dhclient -x eth0 -## 输出说明 +## 使用实例 -**示例 1** 启动网卡eth0的dhcp请求 +**示例1:**启动网卡eth0的dhcp请求 -```shell +``` OHOS:/$ dhclient eth0 OHOS:/$ ifconfig lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 @@ -81,9 +53,11 @@ eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 OHOS:/$ ``` -**示例 2** 关闭网卡eth0的dhcp请求 -```shell +**示例2:**关闭网卡eth0的dhcp请求 + + +``` OHOS:/$ dhclient -x eth0 NetifStatusCallback(eth0): nsc event: 0xf0 OHOS:/$ ifconfig @@ -93,4 +67,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 HWaddr 42:da:81:bc:58:94 MTU:1500 Running Default Link UP ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md index 75aa986e55..47cf1a1ecb 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ifconfig.md @@ -1,320 +1,155 @@ -# ifconfig +# ifconfig -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 ifconfig命令用来查询和设置网卡的IP地址、网络掩码、网关、硬件mac地址等参数。并能够启用/关闭网卡。 -## 命令格式 -ifconfig [option] +## 命令格式 + +ifconfig [option] option: -- \[_-a_\] - -- <_interface_\> <_address_\> \[_netmask _\] \[_gateway _\] -- \[_hw ether _\] \[_mtu _\] - -- \[_inet6 add _\] - -- \[_inet6 del _\] - -- \[_up|down_\] - - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

不带参数

-

打印所有网卡的IP地址、网络掩码、网关、硬件mac地址、MTU、运行状态等信息。

-

N/A

-

-a

-

打印协议栈收发数据信息。

-

N/A

-

interface

-

指定网卡名,比如eth0。

-

N/A

-

address

-

设置IP地址,比如192.168.1.10,需指定网卡名。

-

N/A

-

netmask

-

设置子网掩码,后面要掩码参数,比如255.255.255.0。

-

N/A

-

gateway

-

设置网关,后面跟网关参数,比如192.168.1.1。

-

N/A

-

hw ether

-

设置mac地址, 后面是MAC地址,比如00:11:22:33:44:55。目前只支持ether硬件类型。

-

N/A

-

mtu

-

设置mtu大小,后面是mtu大小,比如1000。

-
  • 仅支持ipv4情况下的范围为

    [68,1500]。

    -
  • 支持ipv6情况下的范围为

    [1280,1500]。

    -
-

add

-

设置ipv6的地址,比如2001:a:b:c:d:e:f:d,需指定网卡名和inet6。

-

N/A

-

del

-

删除ipv6的地址,需指定网卡名和inet6。

-

N/A

-

up

-

启用网卡数据处理,需指定网卡名。

-

N/A

-

down

-

关闭网卡数据处理,需指定网卡名。

-

N/A

-
- -## 使用指南 - -- 命令需要启动TCP/IP协议栈后才能使用。 -- 由于IP冲突检测需要反应时间,每次使用ifconfig设置IP后会有2S左右的延时。 - -## 使用实例 +- [_-a_] + +- <_interface_> <_address_> [_netmask <mask>_] [_gateway <address>_] + +- [_hw ether <address>_] [_mtu <size>_] + +- [_inet6 add <address>_] + +- [_inet6 del <address>_] + +- [_up|down_] + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| 不带参数 | 打印所有网卡的IP地址、网络掩码、网关、硬件mac地址、MTU、运行状态等信息。 | N/A | +| -a | 打印协议栈收发数据信息。 | N/A | +| interface | 指定网卡名,比如eth0。 | N/A | +| address | 设置IP地址,比如192.168.1.10,需指定网卡名。 | N/A | +| netmask | 设置子网掩码,后面要掩码参数,比如255.255.255.0。 | N/A | +| gateway | 设置网关,后面跟网关参数,比如192.168.1.1。 | N/A | +| hw ether | 设置mac地址, 后面是MAC地址,比如00:11:22:33:44:55。目前只支持ether硬件类型。 | N/A | +| mtu | 设置mtu大小,后面是mtu大小,比如1000。 | - 仅支持ipv4情况下的范围为
  [68,1500]。
- 支持ipv6情况下的范围为
  [1280,1500]。 | +| add | 设置ipv6的地址,比如2001:a:b:c:d:e:f:d,需指定网卡名和inet6。 | N/A | +| del | 删除ipv6的地址,需指定网卡名和加"inet6"选项,详见示例。 | N/A | +| up | 启用网卡数据处理,需指定网卡名。 | N/A | +| down | 关闭网卡数据处理,需指定网卡名。 | N/A | + + +## 使用指南 + +- 命令需要启动TCP/IP协议栈后才能使用。 + +- 由于IP冲突检测需要反应时间,每次使用ifconfig设置IP后会有2S左右的延时。 + + +## 使用实例 - 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 eth0 inet6 add 2001:a:b:c:d:e:f:d + - ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d -## 输出说明 - -**示例 1** 设置网络参数 - -```shell -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 -lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 - ip6: ::1/64 - HWaddr 00 MTU:0 Running Link UP -eth0 ip:192.168.100.31 netmask:255.255.255.0 gateway:192.168.100.1 - HWaddr 00:49:cb:6c:a1:31 MTU:1500 Running Default Link UP -``` - -输出的各参数说明如下表所示: - -**表 2** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

说明

-

ip

-

板子IP地址。

-

netmask

-

网络掩码。

-

gateway

-

网关。

-

HWaddr

-

板子硬件mac地址。

-

MTU

-

网络最大传输单元。

-

Running/Stop

-

网卡是否正在运行。

-

Default

-

有这项说明此网卡连接到默认网关。

-

Link UP/Down

-

网卡连接状态。

-
- -**示例 2** 获取协议栈统计信息 - -```shell -OHOS # ifconfig -a -RX packets:6922 errors:0 ip dropped:4312 link dropped:67 overrun:0 bytes:0 (0.0 B) -RX packets(ip6):3 errors:0 dropped:0 overrun:0 bytes:0 (0.0 B) -TX packets:1394 errors:0 link dropped:67 overrun:0 bytes:0(0.0 B) -TX packets(ip6):3 errors:0 overrun:0 bytes:0(0.0 B) -``` - -输出的各参数说明如下表所示: - -**表 3** ifconfig -a 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

说明

-

RX packets

-

IP层已接收的正常数据包的个数。

-

RX error

-

IP层已接收的错误数据包的个数,错误类型包括长度错误,校验错误,IP option错误,IP首部protocol错误等。

-

RX dropped

-

IP层已丢弃的数据包的个数,丢弃原因包括数据包错误,封包无法转发,本地网卡处于关闭状态等。

-

RX overrun

-

MAC层向上层协议栈投递封包失败的个数,失败原因主要是协议栈资源不足。

-

RX bytes

-

IP层已接收的正常数据包的总长度,不包括重组未完成的分片的长度。

-

TX packets

-

IP层已正常发送或转发的数据包的个数。

-

TX error

-

IP层发送失败的数据包的个数,失败原因包括封包无法路由,封包在协议栈内处理失败等。

-

TX dropped

-

MAC层由于发送失败而丢弃的数据包个数,失败原因包括网卡驱动处理封包失败等。

-

TX overrun

-

暂未使用。

-

TX bytes

-

IP层已正常发送或者转发的数据包的总长度。

-
- -**示例 3** 设置IPv6的地址信息 - -```shell -OHOS:/$ ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d -NetifStatusCallback(eth0): nsc event: 0x8 -NetifStatusCallback(eth0): nsc status changed: 0 -NetifStatusCallback(eth0): nsc event: 0x200 -NetifStatusCallback(eth0): nsc event: 0x8 -NetifStatusCallback(eth0): nsc status changed: 1 -NetifStatusCallback(eth0): nsc event: 0x200 -NetifStatusCallback(eth0): nsc event: 0x200 -OHOS:/$ ifconfig -lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 - ip6: ::1/64 - HWaddr 00 MTU:0 Running Link UP -eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 - ip6: 2001:A:B:C:D:E:F:D/64 - HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP -``` - -**示例 4** 删除IPv6的地址信息 - -```shell -OHOS:/$ ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d -NetifStatusCallback(eth0): nsc event: 0x200 -OHOS:/$ ifconfig -lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 - ip6: ::1/64 - HWaddr 00 MTU:0 Running Link UP -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 -``` +## 输出说明 + +- **示例1:**设置网络参数 + ``` + 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 + lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP + eth0 ip:192.168.100.31 netmask:255.255.255.0 gateway:192.168.100.1 + HWaddr 00:49:cb:6c:a1:31 MTU:1500 Running Default Link UP + ``` + + 输出的各参数说明如下表所示: + + **表2** 参数说明 + + | 参数 | 说明 | + | -------- | -------- | + | ip | 板子IP地址。 | + | netmask | 网络掩码。 | + | gateway | 网关。 | + | HWaddr | 板子硬件mac地址。 | + | MTU | 网络最大传输单元。 | + | Running/Stop | 网卡是否正在运行。 | + | Default | 有这项说明此网卡连接到默认网关。 | + | Link UP/Down | 网卡连接状态。 | + +- **示例2:**获取协议栈统计信息 + ``` + OHOS # ifconfig -a + RX packets:6922 errors:0 ip dropped:4312 link dropped:67 overrun:0 bytes:0 (0.0 B) + RX packets(ip6):3 errors:0 dropped:0 overrun:0 bytes:0 (0.0 B) + TX packets:1394 errors:0 link dropped:67 overrun:0 bytes:0(0.0 B) + TX packets(ip6):3 errors:0 overrun:0 bytes:0(0.0 B) + ``` + + 输出的各参数说明如下表所示: + + **表3** ifconfig -a 参数说明 + + | 参数 | 说明 | + | -------- | -------- | + | RX packets | IP层已接收的正常数据包的个数。 | + | RX error | IP层已接收的错误数据包的个数,错误类型包括长度错误,校验错误,IP option错误,IP首部protocol错误等。 | + | RX dropped | IP层已丢弃的数据包的个数,丢弃原因包括数据包错误,封包无法转发,本地网卡处于关闭状态等。 | + | RX overrun | MAC层向上层协议栈投递封包失败的个数,失败原因主要是协议栈资源不足。 | + | RX bytes | IP层已接收的正常数据包的总长度,不包括重组未完成的分片的长度。 | + | TX packets | IP层已正常发送或转发的数据包的个数。 | + | TX error | IP层发送失败的数据包的个数,失败原因包括封包无法路由,封包在协议栈内处理失败等。 | + | TX dropped | MAC层由于发送失败而丢弃的数据包个数,失败原因包括网卡驱动处理封包失败等。 | + | TX overrun | 暂未使用。 | + | TX bytes | IP层已正常发送或者转发的数据包的总长度。 | + +- **示例3**:设置IPv6的地址信息 + ``` + OHOS:/$ ifconfig eth0 inet6 add 2001:a:b:c:d:e:f:d + NetifStatusCallback(eth0): nsc event: 0x8 + NetifStatusCallback(eth0): nsc status changed: 0 + NetifStatusCallback(eth0): nsc event: 0x200 + NetifStatusCallback(eth0): nsc event: 0x8 + NetifStatusCallback(eth0): nsc status changed: 1 + NetifStatusCallback(eth0): nsc event: 0x200 + NetifStatusCallback(eth0): nsc event: 0x200 + OHOS:/$ ifconfig + lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP + eth0 ip:192.168.1.10 netmask:255.255.255.0 gateway:192.168.1.1 + ip6: 2001:A:B:C:D:E:F:D/64 + HWaddr 66:2f:e5:bd:24:e6 MTU:1500 Running Default Link UP + ``` + +- **示例4**:删除IPv6的地址信息 + ``` + OHOS:/$ ifconfig eth0 inet6 del 2001:a:b:c:d:e:f:d + NetifStatusCallback(eth0): nsc event: 0x200 + OHOS:/$ ifconfig + lo ip:127.0.0.1 netmask:255.0.0.0 gateway:127.0.0.1 + ip6: ::1/64 + HWaddr 00 MTU:0 Running Link UP + 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 + ``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md index e34e37d124..21a6344fca 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ipdebug.md @@ -1,27 +1,29 @@ -# ipdebug +# ipdebug -- [命令功能](#section10191115553720) -- [命令格式](#section124061758123713) -- [使用指南](#section171837113810) -- [输出说明](#section561416467104) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [使用示例](#使用示例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 ipdebug是控制台命令,是一个调试ipv6信息非常有用的工具,它可以显示IPV6地址前缀,邻居条目信息,目的地缓存条目以及默认的路由条目。 -## 命令格式 + +## 命令格式 ipdebug -## 使用指南 + +## 使用示例 举例:输入命令ipdebug。 -## 输出说明 -**示例** ipdebug打印信息如下: +## 输出说明 -```shell +**示例:**ipdebug打印信息如下: +``` OHOS # ipdebug ================= || Prefix List || @@ -56,4 +58,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 -------------------------------------------------------------------- ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-netstat.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-netstat.md index 10806a9510..9bdae8e0b8 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-netstat.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-netstat.md @@ -1,37 +1,41 @@ -# netstat +# netstat -- [命令功能](#section13469162113816) -- [命令格式](#section795712373812) -- [参数说明](#section17629431193817) -- [使用指南](#section5277153519380) -- [使用实例](#section108141437163820) -- [输出说明](#section1357015107117) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 netstat是控制台命令,是一个监测TCP/IP网络的非常有用的工具,它可以显示实际的网络连接以及每一个网络接口设备的状态信息。netstat用于显示与TCP、UDP协议相关的统计数据,一般用于检验本设备(单板)各端口的网络连接情况。 -## 命令格式 + +## 命令格式 netstat -## 参数说明 -无。 +## 参数说明 + +无 + -## 使用指南 +## 使用指南 + +netstat -无。 -## 使用实例 +## 使用实例 举例:输入netstat -## 输出说明 -**示例** netstat 打印信息 +## 输出说明 -```shell +**示例:**netstat 打印信息 +``` OHOS # netstat ========== total sockets 128 ====== unused sockets 119 ========== Proto Recv-Q Send-Q Local Address Foreign Address State @@ -39,7 +43,6 @@ tcp 0 0 192.168.1.10:578 192.168.1.3:2049 tcp 0 0 192.168.1.10:58653 0.0.0.0:0 LISTEN tcp 0 0 192.168.1.10:58652 0.0.0.0:0 LISTEN tcp 0 0 192.168.1.10:58651 0.0.0.0:0 LISTEN - Proto Recv-Q Send-Q Local Address Foreign Address udp 0 0 127.0.0.1:62177 127.0.0.1:62178 udp 0 0 0.0.0.0:5684 0.0.0.0:0 @@ -48,49 +51,16 @@ udp 0 0 127.0.0.1:62180 127.0.0.1:62179 udp 0 0 127.0.0.1:62178 127.0.0.1:62177 ``` -**表 1** 输出说明 - - - - - - - - - - - - - - - - - - - - - - - - - -

输出

-

说明

-

Proto

-

协议类型。

-

Recv-Q

-

未被用户读取的数据量。

-

对于Listen TCP,此值为已完成三次握手,但是未被用户accept的TCP连接的数量。

-

Send-Q

-

对TCP连接,已发送但未确认的数据量。

-

对UDP连接,由于IP地址解析未完成而缓存的数据量。

-

Local Address

-

本地地址和端口。

-

Foreign Address

-

远程地址和端口。

-

State

-

TCP连接状态,UDP此项无意义。

-
- ->![](../public_sys-resources/icon-note.gif) **说明:** ->形如“========== total sockets 32 ====== unused sockets 22 BootTime 27 s ========== ”,表示一共32个套接字,未使用套接字22个,距系统启动已经过27秒。 +**表1** 输出说明 + +| 输出 | 说明 | +| -------- | -------- | +| Proto | 协议类型。 | +| Recv-Q | 未被用户读取的数据量。
对于Listen TCP,此值为已完成三次握手,但是未被用户accept的TCP连接的数量。 | +| Send-Q | 对TCP连接,已发送但未确认的数据量。
对UDP连接,由于IP地址解析未完成而缓存的数据量。 | +| Local Address | 本地地址和端口。 | +| Foreign Address | 远程地址和端口。 | +| State | TCP连接状态,UDP此项无意义。 | + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 形如“========== total sockets 32 ====== unused sockets 22 BootTime 27 s ========== ”,表示一共32个套接字,未使用套接字22个,距系统启动已经过27秒。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md index 1bbb46ba2a..be948a9348 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ntpdate.md @@ -1,52 +1,42 @@ -# ntpdate +# ntpdate -- [命令功能](#section38494293815) -- [命令格式](#section5503114413387) -- [参数说明](#section136934472383) -- [使用指南](#section121401651173816) -- [使用实例](#section3431554203811) -- [输出说明](#section18638194610115) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 命令用于从服务器同步系统时间。 -## 命令格式 -ntpdate \[_SERVER\_IP1_\] \[_SERVER\_IP2_\]... +## 命令格式 -## 参数说明 +ntpdate [_SERVER_IP1_] [_SERVER_IP2_]... -**表 1** 参数说明 - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

SERVER_IP

-

NTP服务器IP。

-

N/A

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -直接执行ntpdate \[_SERVER\_IP1_\] \[_SERVER\_IP2_\]... ntpdate会获取第一个有效服务器IP的时间并显示。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| SERVER_IP | NTP服务器IP。 | N/A | -## 使用实例 + +## 使用指南 + +直接执行ntpdate [_SERVER_IP1_] [_SERVER_IP2_]... ntpdate会获取第一个有效服务器IP的时间并显示。 + + +## 使用实例 举例:使用ntpdate命令更新系统时间:ntpdate 192.168.1.3。 -## 输出说明 + +## 输出说明 ``` OHOS # ntpdate 192.168.1.3 @@ -54,4 +44,3 @@ time server 192.168.1.3: Mon Jun 13 09:24:25 2016 ``` 因为板子和服务器时区的不同,获取后的显示时间可能和服务器时间有数小时的差别。 - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping.md index 80a1f466e0..cde5341cbd 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping.md @@ -1,114 +1,63 @@ -# ping +# ping -- [命令功能](#section01) -- [命令格式](#section02) -- [参数说明](#section03) -- [使用指南](#section04) -- [使用实例](#section05) -- [输出说明](#section06) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 ping命令用于测试网络连接是否正常。 -## 命令格式 - -ping _\[-4\] \[-c cnt\] \[-f\] \[-i interval\] \[-q\] \[-s size\] _ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

--help

-

查看ping命令支持的参数列表

-

N/A

-

-4

-

强制以IPV4通讯协议ping目标地址。

-

0-65500

-

-c CNT

-

执行的次数,不带本参数则默认为3次。

-

1-65535

-

-f

-

隐式的ping IPv4地址,其默认参数配置等价于"-c 15 -i 0.2"

-

N/A

-

-i interval

-

发送两次ping包的时间间隔,单位毫秒。

-

1-200

-

-q

-

隐式的ping IPv4地址,如果主机还存活,则在返回 true 后停止ping。

-

N/A

-

-s SIZE

-

设置每个ping包的大小,SIZE是以字节为单位的数据(默认为56字节)。

-

0-4088

-

IP

-

要测试是否网络连通的IPv4地址。

-

N/A

-
- -## 使用指南 - -- ping命令用来测试到目的IP的网络连接是否正常,参数为目的IP地址。 -- 如果目的IP不可达,会显示请求超时。 -- 如果显示发送错误,说明没有到目的IP的路由。 -- 命令需要启动TCP/IP协议栈后才能使用。 - -## 使用实例 + +## 命令格式 + +ping _[-4] [-c cnt] [-f] [-i interval] [-q] [-s size] <IP>_ + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| --help | 查看ping命令支持的参数列表 | N/A | +| -4 | 强制以IPV4通讯协议ping目标地址。 | 0-65500 | +| -c CNT | 执行的次数,不带本参数则默认为3次。 | 1-65535 | +| -f | 隐式的ping IPv4地址,其默认参数配置等价于"-c 15 -i 0.2" | N/A | +| -i interval | 发送两次ping包的时间间隔,单位毫秒。 | 1-200 | +| -q | 隐式的ping IPv4地址,如果主机还存活,则在返回 true 后停止ping。 | N/A | +| -s SIZE | 设置每个ping包的大小,SIZE是以字节为单位的数据(默认为56字节)。 | 0-4088 | +| IP | 要测试是否网络连通的IPv4地址。 | N/A | + + +## 使用指南 + +- ping命令用来测试到目的IP的网络连接是否正常,参数为目的IP地址。 + +- 如果目的IP不可达,会显示请求超时。 + +- 如果显示发送错误,说明没有到目的IP的路由。 + +- 命令需要启动TCP/IP协议栈后才能使用。 + + +## 使用实例 举例:输入ping 192.168.1.3 -## 输出说明 -**示例** ping tftp 服务器地址 +## 输出说明 -```shell +**示例:**ping tftp 服务器地址 +``` OHOS:/$ ping 192.168.1.3 Ping 192.168.1.3 (192.168.1.3): 56(84) bytes. 84 bytes from 192.168.1.3: icmp_seq=0 ttl=0 time=0 ms 84 bytes from 192.168.1.3: icmp_seq=0 ttl=0 time=1 ms 84 bytes from 192.168.1.3: icmp_seq=0 ttl=0 time=0 ms - --- 192.168.1.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss round-trip min/avg/max = 0/0/0 ms diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping6.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping6.md index 252a4bfb1b..aaf2c26060 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping6.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-ping6.md @@ -1,126 +1,97 @@ -# ping6 +# ping6 -- [命令功能](#section1057291313393) -- [命令格式](#section199901315123919) -- [参数说明](#section4679319113919) -- [使用指南](#section1127917226399) -- [使用实例](#section7211192553917) -- [输出说明](#section4846145221215) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 ping6用于测试IPv6网络连接是否正常。 -## 命令格式 - -ping6 _\[-c count\] \[-I interface / sourceAddress\] destination_ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-c count

-

执行的次数,不带本参数则默认为4次。

-

1~65535

-

-I interface

-

指定网卡执行IPv6 ping操作。

-

N/A

-

-I sourceAddress

-

指定源IPv6地址执行ping操作。

-

N/A

-

destination

-

目标主机地址。

-

N/A

-
- -## 使用指南 - -- 如果目的IPv6地址不可达,会显示请求超时。 -- 如果显示发送错误,说明没有到目的IPV6的路由。 -- 命令需要启动TCP/IP协议栈后才能使用。 - -## 使用实例 - -- ping6 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 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b - -## 输出说明 - -1. 输入ping6 2001:a:b:c:d:e:f:b - - ``` - OHOS # ping6 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=4 time<1 ms - --- 2001:a:b:c:d:e:f:b/64 ping statistics --- - 4 packets transmitted, 4 received, 0.00% packet loss, time 20ms - rtt min/avg/max = 0/0.00/0 ms - ``` - -2. 输入 ping6 -c 3 2001:a:b:c:d:e:f:b 指定3次进行网络测试 - - ``` - OHOS # ping6 -c 3 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms - --- 2001:a:b:c:d:e:f:b/64 ping statistics --- - 3 packets transmitted, 3 received, 0.00% packet loss, time 20ms - rtt min/avg/max = 0/0.00/0 ms - ``` - -3. 输入 ping6 -I eth0 2001:a:b:c:d:e:f:b 使用指定网卡接口eth0测试IPv6。 - - ``` - OHOS # ping6 -I eth0 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time=10 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=4 time<1 ms - --- 2001:a:b:c:d:e:f:b/64 ping statistics --- - 4 packets transmitted, 4 received, 0.00% packet loss, time 30msrtt min/avg/max = 0/2.50/10 ms - ``` - -4. 输入 ping6 -I 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b 使用指定的源IPv6地址2001:a:b:c:d:e:f:d进行测试。 - - ``` - OHOS # ping6 -I 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms - 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=4 time<1 ms - --- 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 - ``` +## 命令格式 +ping6 _[-c count] [-I interface / sourceAddress] destination_ + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -c count | 执行的次数,不带本参数则默认为4次。 | 1~65535 | +| -I interface | 指定网卡执行IPv6 ping操作。 | N/A | +| -I sourceAddress | 指定源IPv6地址执行ping操作。 | N/A | +| destination | 目标主机地址。 | N/A | + + +## 使用指南 + +- 如果目的IPv6地址不可达,会显示请求超时。 + +- 如果显示发送错误,说明没有到目的IPV6的路由。 + +- 命令需要启动TCP/IP协议栈后才能使用。 + + +## 使用实例 + +- ping6 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 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b + + +## 输出说明 + +1. 输入ping6 2001:a:b:c:d:e:f:b + ``` + OHOS # ping6 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=4 time<1 ms + --- 2001:a:b:c:d:e:f:b/64 ping statistics --- + 4 packets transmitted, 4 received, 0.00% packet loss, time 20ms + rtt min/avg/max = 0/0.00/0 ms + ``` + +2. 输入 ping6 -c 3 2001:a:b:c:d:e:f:b 指定3次进行网络测试 + ``` + OHOS # ping6 -c 3 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms + --- 2001:a:b:c:d:e:f:b/64 ping statistics --- + 3 packets transmitted, 3 received, 0.00% packet loss, time 20ms + rtt min/avg/max = 0/0.00/0 ms + ``` + +3. 输入 ping6 -I eth0 2001:a:b:c:d:e:f:b 使用指定网卡接口eth0测试IPv6。 + ``` + OHOS # ping6 -I eth0 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time=10 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=4 time<1 ms + --- 2001:a:b:c:d:e:f:b/64 ping statistics --- + 4 packets transmitted, 4 received, 0.00% packet loss, time 30msrtt min/avg/max = 0/2.50/10 ms + ``` + +4. 输入 ping6 -I 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b 使用指定的源IPv6地址2001:a:b:c:d:e:f:d进行测试。 + ``` + OHOS # ping6 -I 2001:a:b:c:d:e:f:d 2001:a:b:c:d:e:f:b PING 2001:A:B:C:D:E:F:B with 56 bytes of data. + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=1 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=2 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=3 time<1 ms + 56 bytes from 2001:A:B:C:D:E:F:B : icmp_seq=4 time<1 ms + --- 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 + ``` diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-telnet.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-telnet.md index a249d9457f..208968d164 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-telnet.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-telnet.md @@ -1,69 +1,51 @@ -# telnet +# telnet -- [命令功能](#section3551830123913) -- [命令格式](#section14897133233918) -- [参数说明](#section977718353392) -- [使用指南](#section134991538183916) -- [使用实例](#section1097414426398) -- [输出说明](#section11846624191310) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 本命令用于启动或关闭telnet server服务。 -## 命令格式 -telnet \[_on | off_\] +## 命令格式 -## 参数说明 +telnet [_on | off_] -**表 1** 参数说明 - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

on

-

启动telnet server服务。

-

N/A

-

off

-

关闭telnet server服务。

-

N/A

-
+## 参数说明 -## 使用指南 +**表1** 参数说明 -- telnet启动要确保网络驱动及网络协议栈已经初始化完成,且板子的网卡是link up状态。 -- 暂时无法支持多个客户端(telnet + IP)同时连接开发板。 +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| on | 启动telnet server服务。 | N/A | +| off | 关闭telnet server服务。 | N/A | - >![](../public_sys-resources/icon-notice.gif) **须知:** - >telnet属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 +## 使用指南 -## 使用实例 +- telnet启动要确保网络驱动及网络协议栈已经初始化完成,且板子的网卡是link up状态。 + +- 暂时无法支持多个客户端(telnet + IP)同时连接开发板。 + > ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** + > telnet属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 + + +## 使用实例 举例:输入telnet on -## 输出说明 -**示例** 输入 telnet on +## 输出说明 -```shell +**示例:**输入 telnet on + +``` OHOS # telnet on OHOS # start telnet server successfully, waiting for connection. ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-tftp.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-tftp.md index b9dd0d1586..7a343193bf 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-tftp.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net-tftp.md @@ -1,82 +1,53 @@ -# tftp +# tftp -- [命令功能](#section15142134573911) -- [命令格式](#section20958174917394) -- [参数说明](#section576613532395) -- [使用指南](#section149795134408) -- [使用实例](#section148921918114015) -- [输出说明](#section7872155631313) +- [命令功能](#命令功能) +- [命令格式](#命令格式) +- [参数说明](#参数说明) +- [使用指南](#使用指南) +- [使用实例](#使用实例) +- [输出说明](#输出说明) -## 命令功能 +## 命令功能 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供简单、低开销的文件传输服务。端口号为69。 tftp命令可以从TFTP服务器上下载文件。 -## 命令格式 - -./bin/tftp _<-g/-p\>_ _-l_ _\[FullPathLocalFile\] -r \[RemoteFile\] \[Host\]_ - -## 参数说明 - -**表 1** 参数说明 - - - - - - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

取值范围

-

-g/-p

-

文件传输方向:

-
  • -g 从TFTP服务器获取文件。
  • -p 上传文件到TFTP服务器。
-

N/A

-

-l FullPathLocalFile

-

本地文件完整路径。

-

N/A

-

-r RemoteFile

-

服务端文件名。

-

N/A

-

Host

-

服务端IP。

-

N/A

-
- -## 使用指南 - -1. 在服务器端搭建TFTP服务器,并进行正确配置。 -2. OpenHarmony单板使用tftp命令上传、下载文件。 -3. 传输的文件大小是有限制的不能大于32M。 - - >![](../public_sys-resources/icon-notice.gif) **须知:** - >tftp属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 - - -## 使用实例 + +## 命令格式 + +./bin/tftp _<-g/-p>__-l__[FullPathLocalFile] -r [RemoteFile] [Host]_ + + +## 参数说明 + +**表1** 参数说明 + +| 参数 | 参数说明 | 取值范围 | +| -------- | -------- | -------- | +| -g/-p | 文件传输方向:
- -g 从TFTP服务器获取文件。
- -p 上传文件到TFTP服务器。 | N/A | +| -l FullPathLocalFile | 本地文件完整路径。 | N/A | +| -r RemoteFile | 服务端文件名。 | N/A | +| Host | 服务端IP。 | N/A | + + +## 使用指南 + +1. 在服务器端搭建TFTP服务器,并进行正确配置。 + +2. OpenHarmony单板使用tftp命令上传、下载文件。 + +3. 传输的文件大小是有限制的不能大于32M。 + > ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** + > tftp属于调测功能,默认配置为关闭,正式产品中禁止使用该功能。 + + +## 使用实例 举例:从服务器下载out文件。 -## 输出说明 + +## 输出说明 ``` OHOS # ./bin/tftp -g -l /nfs/out -r out 192.168.1.2 @@ -84,4 +55,3 @@ TFTP transfer finish ``` tftp命令执行后,传输正常完成会显示TFTP transfer finish, 失败的话会显示其他的打印信息帮助定位问题。 - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net.md index 06774740b0..a3d24f0cac 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-net.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-net.md @@ -1,22 +1,22 @@ -# 网络命令 +# 网络命令 -- **[arp](kernel-small-debug-shell-net-arp.md)** -- **[dhclient](kernel-small-debug-shell-net-dhclient.md)** +- **[arp](kernel-small-debug-shell-net-arp.md)** -- **[ifconfig](kernel-small-debug-shell-net-ifconfig.md)** +- **[dhclient](kernel-small-debug-shell-net-dhclient.md)** -- **[ipdebug](kernel-small-debug-shell-net-ipdebug.md)** +- **[ifconfig](kernel-small-debug-shell-net-ifconfig.md)** -- **[netstat](kernel-small-debug-shell-net-netstat.md)** +- **[ipdebug](kernel-small-debug-shell-net-ipdebug.md)** -- **[ntpdate](kernel-small-debug-shell-net-ntpdate.md)** +- **[netstat](kernel-small-debug-shell-net-netstat.md)** -- **[ping](kernel-small-debug-shell-net-ping.md)** +- **[ntpdate](kernel-small-debug-shell-net-ntpdate.md)** -- **[ping6](kernel-small-debug-shell-net-ping6.md)** +- **[ping](kernel-small-debug-shell-net-ping.md)** -- **[telnet](kernel-small-debug-shell-net-telnet.md)** +- **[ping6](kernel-small-debug-shell-net-ping6.md)** -- **[tftp](kernel-small-debug-shell-net-tftp.md)** +- **[telnet](kernel-small-debug-shell-net-telnet.md)** +- **[tftp](kernel-small-debug-shell-net-tftp.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell-overview.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell-overview.md index 0b194732bc..0b9e6fb087 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell-overview.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell-overview.md @@ -1,36 +1,35 @@ -# Shell介绍 +# Shell介绍 -- [注意事项](#section12298165312328) +- [注意事项](#注意事项) OpenHarmony内核提供的Shell支持调试常用的基本功能,包含系统、文件、网络和动态加载相关命令。同时OpenHarmony内核的Shell支持添加新的命令,可以根据需求来进行定制。 -- 系统相关命令:提供查询系统任务、内核信号量、系统软件定时器、CPU占用率、当前中断等相关信息的能力。 -- 文件相关命令:支持基本的ls、cd等功能。 +- 系统相关命令:提供查询系统任务、内核信号量、系统软件定时器、CPU占用率、当前中断等相关信息的能力。 -- 网络相关命令:支持查询接到开发板的其他设备的IP、查询本机IP、测试网络连接、设置开发板的AP和station模式等相关功能。 +- 文件相关命令:支持基本的ls、cd等功能。 - 新增命令的详细流程可参见[Shell命令开发指导](kernel-small-debug-shell-guide.md)和[Shell命令编程实例](kernel-small-debug-shell-build.md)。 +- 网络相关命令:支持查询接到开发板的其他设备的IP、查询本机IP、测试网络连接、设置开发板的AP和station模式等相关功能。 + 新增命令的详细流程可参见[Shell命令开发指导](../kernel/kernel-small-debug-shell-guide.md)和[Shell命令编程实例](../kernel/kernel-small-debug-shell-build.md)。 -## 注意事项 -在使用Shell功能的过程中,需要注意以下几点: - -- Shell功能支持使用exec命令来运行可执行文件。 -- Shell功能支持默认模式下英文输入。如果出现用户在UTF-8格式下输入了中文字符的情况,只能通过回退三次来删除。 +## 注意事项 -- Shell功能支持shell命令、文件名及目录名的Tab键联想补全。若有多个匹配项,则根据共同字符, 打印多个匹配项。对于过多的匹配项(打印多于24行),将会进行打印询问(Display all num possibilities?(y/n)),用户可输入y选择全部打印,或输入n退出打印,选择全部打印并打印超过24行后,会进行--More--提示,此时按回车键继续打印,按q键退出(支持Ctrl+c退出\)。 +在使用Shell功能的过程中,需要注意以下几点: -- Shell端工作目录与系统工作目录是分开的,即通过Shell端cd pwd等命令是对Shell端工作目录进行操作,通过chdir getcwd等命令是对系统工作目录进行操作,两个工作目录相互之间没有联系。当文件系统操作命令入参是相对路径时要格外注意。 +- Shell功能支持使用exec命令来运行可执行文件。 -- 在使用网络Shell指令前,需要先调用tcpip\_init函数完成网络初始化并完成telnet连接后才能起作用,内核默认不初始化tcpip\_init。 +- Shell功能支持默认模式下英文输入。如果出现用户在UTF-8格式下输入了中文字符的情况,只能通过回退三次来删除。 -- 不建议使用Shell命令对/dev目录下的设备文件进行操作,这可能会引起不可预知的结果。 +- Shell功能支持shell命令、文件名及目录名的Tab键联想补全。若有多个匹配项,则根据共同字符, 打印多个匹配项。对于过多的匹配项(打印多于24行),将会进行打印询问(Display all num possibilities?(y/n)),用户可输入y选择全部打印,或输入n退出打印,选择全部打印并打印超过24行后,会进行--More--提示,此时按回车键继续打印,按q键退出(支持Ctrl+c退出)。 -- Shell功能不符合POSIX标准,仅供调试使用。 +- Shell端工作目录与系统工作目录是分开的,即通过Shell端cd、pwd等命令是对Shell端工作目录进行操作,通过chdir、getcwd等命令是对系统工作目录进行操作,两个工作目录相互之间没有联系。当文件系统操作命令入参是相对路径时要格外注意。 - >![](../public_sys-resources/icon-notice.gif) **须知:** - >Shell功能仅供调试使用,在Debug版本中开启(使用时通过menuconfig在配置项中开启"LOSCFG\_DEBUG\_VERSION"编译开关进行相关控制),商用产品中禁止包含该功能。 +- 在使用网络Shell指令前,需要先调用tcpip_init函数完成网络初始化并完成telnet连接后才能起作用,内核默认不初始化tcpip_init。 +- 不建议使用Shell命令对/dev目录下的设备文件进行操作,这可能会引起不可预知的结果。 +- Shell功能不符合POSIX标准,仅供调试使用。 + > ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** + > Shell功能仅供调试使用,在Debug版本中开启(使用时通过menuconfig在配置项中开启"LOSCFG_DEBUG_VERSION"编译开关进行相关控制),商用产品中禁止包含该功能。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-shell.md b/zh-cn/device-dev/kernel/kernel-small-debug-shell.md index 49338fd8b1..f07325ca67 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-shell.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-shell.md @@ -1,15 +1,14 @@ -# Shell +# Shell -- **[Shell介绍](kernel-small-debug-shell-overview.md)** -- **[Shell命令开发指导](kernel-small-debug-shell-guide.md)** +- **[Shell介绍](kernel-small-debug-shell-overview.md)** -- **[Shell命令编程实例](kernel-small-debug-shell-build.md)** +- **[Shell命令开发指导](kernel-small-debug-shell-guide.md)** -- **[Shell命令使用详解](kernel-small-debug-shell-details.md)** +- **[Shell命令编程实例](kernel-small-debug-shell-build.md)** -- **[魔法键使用方法](kernel-small-debug-shell-magickey.md)** - -- **[用户态异常信息说明](kernel-small-debug-shell-error.md)** +- **[Shell命令使用详解](kernel-small-debug-shell-details.md)** +- **[魔法键使用方法](kernel-small-debug-shell-magickey.md)** +- **[用户态异常信息说明](kernel-small-debug-shell-error.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-faqs.md b/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-faqs.md index bc36a03cff..c78cd368ba 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-faqs.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-faqs.md @@ -1,16 +1,15 @@ -# 常见问题定位方法 +# 常见问题定位方法 -- [通过异常信息定位问题](#section695838161711) -- [内存池完整性验证](#section362917569179) -- [全局变量踩内存定位方法](#section18971311121816) +- [通过异常信息定位问题](#通过异常信息定位问题) +- [内存池完整性验证](#内存池完整性验证) +- [全局变量踩内存定位方法](#全局变量踩内存定位方法) -## 通过异常信息定位问题 +## 通过异常信息定位问题 系统异常被挂起后,会在串口看到一些关键寄存器的信息,如图1所示。可通过这些信息定位到异常所在函数和其调用栈关系,为原因分析提供第一手资料。 -图1 异常信息 - -![](figure/zh-cn_image_0000001173429547.png) +**图1** 异常信息 +![zh-cn_image_0000001153823524](figures/zh-cn_image_0000001153823524.png) 上图中的异常信息主要解释4个标签: @@ -22,15 +21,16 @@ **标签4**:lr 的值依次标识正常情况下PC要依次执行的指令的位置。 -对于内核异常打印信息,确定PC和LR的具体位置的指令需要结合out目录下OHOS\_Image.asm(跟烧写的系统镜像OHOS\_Image.bin对应的汇编文件)查看,根据指令所在的位置可确认使用该指令的函数,依次确定LR位置所在的函数,即得到异常发生时的函数调用关系。 +对于内核异常打印信息,确定PC和LR的具体位置的指令需要结合out目录下OHOS_Image.asm(跟烧写的系统镜像OHOS_Image.bin对应的汇编文件)查看,根据指令所在的位置可确认使用该指令的函数,依次确定LR位置所在的函数,即得到异常发生时的函数调用关系。 + -## 内存池完整性验证 +## 内存池完整性验证 -仅凭上节异常信息定位的基本方法,常常无法直接定位问题所在。并且常常会因为异常的寄存器值而无法对问题进行定位。若怀疑是堆内存越界导致的问题,可以调用内存池完整性检测函数LOS\_MemIntegrityCheck进行检查。函数LOS\_MemIntegrityCheck将会对系统动态内存池所有的节点进行遍历,如果所有节点正常则函数返回0,不会有任何打印,否则将打印相关的错误信息。该函数的入参使用\(VOID \*\)OS\_SYS\_MEM\_ADDR。 +仅凭上节异常信息定位的基本方法,常常无法直接定位问题所在。并且常常会因为异常的寄存器值而无法对问题进行定位。若怀疑是堆内存越界导致的问题,可以调用内存池完整性检测函数LOS_MemIntegrityCheck进行检查。函数LOS_MemIntegrityCheck将会对系统动态内存池所有的节点进行遍历,如果所有节点正常则函数返回0,不会有任何打印,否则将打印相关的错误信息。该函数的入参使用(VOID \*)OS_SYS_MEM_ADDR。 -定位堆内存越界踩的问题,一般是在可能存在问题的业务逻辑代码前后使用LOS\_MemIntegrityCheck,如果该业务代码不存在问题,则前后两次LOS\_MemIntegrityCheck调用不会失败,按前述方式逐步缩小问题定位范围。 +定位堆内存越界踩的问题,一般是在可能存在问题的业务逻辑代码前后使用LOS_MemIntegrityCheck,如果该业务代码不存在问题,则前后两次LOS_MemIntegrityCheck调用不会失败,按前述方式逐步缩小问题定位范围。 -## 全局变量踩内存定位方法 -如果已知一个全局变量内存域被踩,可在OHOS\_Image.map文件中找到该全局变量所在的地址,并且特别注意该地址之前最近被使用的变量,有极大概率是前面的变量(尤其数组类型的或会被强转成其他类型的变量)在使用的过程中内存越界,破坏了这个全局变量。 +## 全局变量踩内存定位方法 +如果已知一个全局变量内存域被踩,可在OHOS_Image.map文件中找到该全局变量所在的地址,并且特别注意该地址之前最近被使用的变量,有极大概率是前面的变量(尤其数组类型的或会被强转成其他类型的变量)在使用的过程中内存越界,破坏了这个全局变量。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md b/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md index 538a2190f0..c74d2a8661 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-trace-other-lastwords.md @@ -1,17 +1,19 @@ -# 临终遗言 +# 临终遗言 -- [使用场景](#section158501652121514) -- [功能说明](#section1186411122215) -- [参数说明](#section1083765723015) -- [开发流程](#section783435801510) +- [使用场景](#使用场景) +- [功能说明](#功能说明) +- [参数说明](#参数说明) +- [开发流程](#开发流程) -## 使用场景 +## 使用场景 在无串口的设备上,将系统异常时打印的信息保存到不丢失的存储介质上,方便对运行时问题进行定位。 -## 功能说明 -该调测功能提供了一种用于保存系统异常时打印信息到不丢失存储介质中的机制,用户可自行注册读写异常时打印信息的钩子函数,实现在不同存储介质上保存异常信息的能力,这样方便无串口的设备的问题定位。接口名为LOS\_ExcInfoRegHook,该函数声明在los\_config.h中,函数原型: +## 功能说明 + +该调测功能提供了一种用于保存系统异常时打印信息到不丢失存储介质中的机制,用户可自行注册读写异常时打印信息的钩子函数,实现在不同存储介质上保存异常信息的能力,这样方便无串口的设备的问题定位。接口名为LOS_ExcInfoRegHook,该函数声明在los_config.h中,函数原型: + ``` typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf); @@ -19,78 +21,36 @@ typedef VOID (*log_read_write_fn)(UINT32 startAddr, UINT32 space, UINT32 rwFlag, VOID LOS_ExcInfoRegHook(UINT32 startAddr, UINT32 space, CHAR *buf, log_read_write_fn hook); ``` -## 参数说明 - -**表 1** LOS\_ExcInfoRegHook 参数说明 - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

startAddr

-

存取异常信息的物理介质起始地址

-

space

-

存取的空间大小

-

buf

-

存取异常信息的内存缓冲区

-

log_read_write_fn

-

存取异常信息的函数

-
- -**表 2** log\_read\_write\_fn 参数说明 - - - - - - - - - - - - - - - - - - - -

参数

-

参数说明

-

startAddr

-

存取异常信息的物理介质起始地址

-

space

-

存取的空间大小

-

rwFlag

-

读写标记,0为写,1为读

-

buf

-

存取异常信息的内存缓冲区

-
- -## 开发流程 - -该功能依赖于宏LOSCFG\_SAVE\_EXCINFO,使用临终遗言功能时,在配置项中开启“ Enable Saving Exception Information ”:Debug-\> Enable Saving Exception Information ;若关闭该选项,则该功能失效。功能开启后,可在SystemInit中调用LOS\_ExcInfoRegHook来注册存取异常信息的位置、大小、内存缓冲区以及存取函数。当系统进入异常时,会将异常时系统各类信息先保存在注册时传入的内存缓冲区中,最后调用注册的存取函数,将异常信息写入到物理存储介质中。 - ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 注册的存取位置不要跟其他存储重叠。 ->- 注册的内存缓冲区不能太小,建议不低于16KiB,否则异常信息会存储不完整。 ->- 注册的读写函数对应的具体存储介质的驱动功能正常,才能保证存取功能正常。 +## 参数说明 + +**表1** LOS_ExcInfoRegHook 参数说明 + +| 参数 | 参数说明 | +| -------- | -------- | +| startAddr | 存取异常信息的物理介质起始地址 | +| space | 存取的空间大小 | +| buf | 存取异常信息的内存缓冲区 | +| log_read_write_fn | 存取异常信息的函数 | + +**表2** log_read_write_fn 参数说明 + +| 参数 | 参数说明 | +| -------- | -------- | +| startAddr | 存取异常信息的物理介质起始地址 | +| space | 存取的空间大小 | +| rwFlag | 读写标记,0为写,1为读 | +| buf | 存取异常信息的内存缓冲区 | + + +## 开发流程 + +该功能依赖于宏LOSCFG_SAVE_EXCINFO,使用临终遗言功能时,在配置项中开启“ Enable Saving Exception Information ”:Debug-> Enable Saving Exception Information ;若关闭该选项,则该功能失效。功能开启后,可在SystemInit中调用LOS_ExcInfoRegHook来注册存取异常信息的位置、大小、内存缓冲区以及存取函数。当系统进入异常时,会将异常时系统各类信息先保存在注册时传入的内存缓冲区中,最后调用注册的存取函数,将异常信息写入到物理存储介质中。 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 注册的存取位置不要跟其他存储重叠。 +> +> - 注册的内存缓冲区不能太小,建议不低于16KiB,否则异常信息会存储不完整。 +> +> - 注册的读写函数对应的具体存储介质的驱动功能正常,才能保证存取功能正常。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-trace.md b/zh-cn/device-dev/kernel/kernel-small-debug-trace.md index 072048df10..07e975b0d0 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-trace.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-trace.md @@ -1,37 +1,23 @@ -# Trace调测 +# Trace -- [基本概念](#section1) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) + - [内核态](#内核态) + - [用户态](#用户态) +- [开发指导](#开发指导) + - [内核态开发流程](#内核态开发流程) +- [内核态编程实例](#内核态编程实例) +- [内核态示例代码](#内核态示例代码) +- [结果验证](#结果验证) -- [运行机制](#section2) +## 基本概念 -- [接口说明](#section3) - - - [内核态](#section3.1) - - - [用户态](#section3.2) - -- [开发指导](#section4) - - - [内核态开发流程](#section4.1.1) - - - [内核态编程实例](#section4.1.2) - - - [内核态实例代码](#section4.1.3) - - - [内核态结果验证](#section4.1.4) - - - [用户态开发流程](#section4.2.1) - - - [用户态编程实例](#section4.2.2) - - - [用户态实例代码](#section4.2.3) +Trace调测旨在帮助开发者获取内核的运行流程,各个模块、任务的执行顺序,从而可以辅助开发者定位一些时序问题或者了解内核的代码运行过程。 - - [用户态结果验证](#section4.2.4) -## 基本概念 -Trace调测旨在帮助开发者获取内核的运行流程,各个模块、任务的执行顺序,从而可以辅助开发者定位一些时序问题或者了解内核的代码运行过程。 +## 运行机制 -## 运行机制 内核提供一套Hook框架,将Hook点预埋在各个模块的主要流程中, 在内核启动初期完成Trace功能的初始化,并注册Trace的处理函数到Hook中。 当系统触发到一个Hook点时,Trace模块会对输入信息进行封装,添加Trace帧头信息,包含事件类型、运行的cpuid、运行的任务id、运行的相对时间戳等信息; @@ -40,174 +26,117 @@ Trace提供2种工作模式,离线模式和在线模式。 离线模式会将trace frame记录到预先申请好的循环buffer中。如果循环buffer记录的frame过多则可能出现翻转,会覆盖之前的记录,故保持记录的信息始终是最新的信息。Trace循环buffer的数据可以通过shell命令导出进行详细分析,导出信息已按照时间戳信息完成排序。 -![](figure/zh-cn_image_0000001127390512.png) +![zh-cn_image_0000001214329013](figures/zh-cn_image_0000001214329013.png) 在线模式需要配合IDE使用,实时将trace frame记录发送给IDE,IDE端进行解析并可视化展示。 -## 接口说明 - -### 内核态 - -OpenHarmony LiteOS-A内核的Trace模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h)参考。 - -**表 1** Trace模块接口说明 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

启停控制

-

LOS_TraceStart

-

启动Trace

-

LOS_TraceStop

-

停止Trace

-

操作Trace记录的数据

-

LOS_TraceRecordDump

-

输出Trace缓冲区数据

-

LOS_TraceRecordGet

-

获取Trace缓冲区的首地址

-

LOS_TraceReset

-

清除Trace缓冲区中的事件

-

过滤Trace记录的数据

-

LOS_TraceEventMaskSet

-

设置事件掩码,仅记录某些模块的事件

-

屏蔽某些中断号事件

-

LOS_TraceHwiFilterHookReg

-

注册过滤特定中断号事件的钩子函数

-

插桩函数

-

LOS_TRACE_EASY

-

简易插桩

-

LOS_TRACE

-

标准插桩

-
- - -1. 当用户需要针对自定义事件进行追踪时,可按规则在目标源代码中进行插桩,系统提供如下2种插桩接口: - -+ LOS_TRACE_EASY(TYPE, IDENTITY, params...) 简易插桩。 - - - 一句话插桩,用户在目标源代码中插入该接口即可。 - - - TYPE有效取值范围为[0, 0xF],表示不同的事件类型,不同取值表示的含义由用户自定义。 - - - IDENTITY类型UINTPTR,表示事件操作的主体对象。 - - - Params类型UINTPTR,表示事件的参数。 - - - 示例: - - ``` - 假设需要新增对文件(fd1、fd2)读写操作的简易插桩, - 自定义读操作为type:1, 写操作为type:2,则 - 在读fd1文件的适当位置插入: - LOS_TRACE_EASY(1, fd1, flag, size); - 在读fd2文件的适当位置插入: - LOS_TRACE_EASY(1, fd2, flag, size); - 在写fd1文件的适当位置插入: - LOS_TRACE_EASY(2, fd1, flag, size); - 在写fd2文件的适当位置插入: - LOS_TRACE_EASY(2, fd2,flag, size); - ``` - -+ LOS_TRACE(TYPE, IDENTITY, params...) 标准插桩。 - - - 相比简易插桩,支持动态过滤事件和参数裁剪,但使用上需要用户按规则来扩展。 - - - TYPE用于设置具体的事件类型,可以在头文件los_trace.h中的enum LOS_TRACE_TYPE中自定义事件类型。定义方法和规则可以参考其他事件类型。 - - - IDENTITY和Params的类型及含义同简易插桩。 - - - 示例: -``` - 1.在enum LOS_TRACE_MASK中定义事件掩码,即模块级别的事件类型。 - 定义规范为TRACE_#MOD#_FLAG,#MOD#表示模块名,例如: - TRACE_FS_FLAG = 0x4000 - 2.在enum LOS_TRACE_TYPE中定义具体事件类型。定义规范为#TYPE# = TRACE_#MOD#_FLAG | NUMBER,例如: - FS_READ = TRACE_FS_FLAG | 0; // 读文件 - FS_WRITE = TRACE_FS_FLAG | 1; // 写文件 - 3.定义事件参数。定义规范为#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ... - 其中的#TYPE#就是上面2中的#TYPE#,例如: - #define FS_READ_PARAMS(fp, fd, flag, size) fp, fd, flag, size - 宏定义的参数对应于Trace缓冲区中记录的事件参数,用户可对任意参数字段进行裁剪: - 当定义为空时,表示不追踪该类型事件: - #define FS_READ_PARAMS(fp, fd, flag, size) // 不追踪文件读事件 - 4.在适当位置插入代码桩。定义规范为LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...)) - LOS_TRACE(FS_READ, fp, fd, flag, size); // 读文件的代码桩, - #TYPE#之后的入参就是上面3中的FS_READ_PARAMS函数的入参 -``` -2. 预置的Trace事件及参数均可以通过上述方式进行裁剪,参数详见kernel\include\los_trace.h。 - -3. Trace Mask事件过滤接口LOS_TraceEventMaskSet(UINT32 mask),其入参mask仅高28位生效(对应LOS_TRACE_MASK中某模块的使能位),仅用于模块的过滤,暂不支持针对某个特定事件的细粒度过滤。例如:LOS_TraceEventMaskSet(0x202),则实际设置生效的mask为0x200(TRACE_QUE_FLAG),QUE模块的所有事件均会被采集。一般建议使用的方法为: - LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG); -4. 如果仅需要过滤简易插桩事件,通过设置Trace Mask为TRACE_MAX_FLAG即可。 +## 接口说明 + + +### 内核态 + +LiteOS-A内核的Trace模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_trace.h)参考。 + +**表1** Trace模块接口说明 + +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 启停控制 | LOS_TraceStart | 启动Trace | +| | LOS_TraceStop |停止Trace| +| 操作Trace记录的数据 | LOS_TraceRecordDump | 输出Trace缓冲区数据 | +| | LOS_TraceRecordGet |获取Trace缓冲区的首地址| +| | LOS_TraceReset |清除Trace缓冲区中的事件| +| 过滤Trace记录的数据 | LOS_TraceEventMaskSet | 设置事件掩码,仅记录某些模块的事件 | +| 屏蔽某些中断号事件 | LOS_TraceHwiFilterHookReg | 注册过滤特定中断号事件的钩子函数 | +| 插桩函数 | LOS_TRACE_EASY | 简易插桩 | +| | LOS_TRACE |标准插桩| + +- 当用户需要针对自定义事件进行追踪时,可按规则在目标源代码中进行插桩,系统提供如下2种插桩接口: + - LOS_TRACE_EASY(TYPE, IDENTITY, params...) 简易插桩。 + - 用户在目标源代码中插入该接口即可。 + - TYPE有效取值范围为[0, 0xF],表示不同的事件类型,不同取值表示的含义由用户自定义。 + - IDENTITY类型UINTPTR,表示事件操作的主体对象。 + - Params类型UINTPTR,表示事件的参数。 + 示例: + ``` + 假设需要新增对文件(fd1、fd2)读写操作的简易插桩, + 自定义读操作为type:1, 写操作为type:2,则 + 在读fd1文件的适当位置插入: + LOS_TRACE_EASY(1, fd1, flag, size); + 在读fd2文件的适当位置插入: + LOS_TRACE_EASY(1, fd2, flag, size); + 在写fd1文件的适当位置插入: + LOS_TRACE_EASY(2, fd1, flag, size); + 在写fd2文件的适当位置插入: + LOS_TRACE_EASY(2, fd2,flag, size); + ``` + - LOS_TRACE(TYPE, IDENTITY, params...) 标准插桩。 + - 相比简易插桩,支持动态过滤事件和参数裁剪,但使用上需要用户按规则来扩展。 + - TYPE用于设置具体的事件类型,可以在头文件los_trace.h中的enum LOS_TRACE_TYPE中自定义事件类型。定义方法和规则可以参考其他事件类型。 + - IDENTITY和Params的类型及含义同简易插桩。 + 示例: + ``` + 1.在enum LOS_TRACE_MASK中定义事件掩码,即模块级别的事件类型。 + 定义规范为TRACE_#MOD#_FLAG,#MOD#表示模块名。 + 例如: + TRACE_FS_FLAG = 0x4000 + 2.在enum LOS_TRACE_TYPE中定义具体事件类型。 + 定义规范为#TYPE# = TRACE_#MOD#_FLAG | NUMBER, + 例如: + FS_READ = TRACE_FS_FLAG | 0; // 读文件 + FS_WRITE = TRACE_FS_FLAG | 1; // 写文件 + 3.定义事件参数。定义规范为#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ... + 其中的#TYPE#就是上面2中的#TYPE#, + 例如: + #define FS_READ_PARAMS(fp, fd, flag, size) fp, fd, flag, size + 宏定义的参数对应于Trace缓冲区中记录的事件参数,用户可对任意参数字段进行裁剪: + 当定义为空时,表示不追踪该类型事件: + #define FS_READ_PARAMS(fp, fd, flag, size) // 不追踪文件读事件 + 4.在适当位置插入代码桩。 + 定义规范为LOS_TRACE(#TYPE#, #TYPE#_PARAMS(IDENTITY, parma1...)) + LOS_TRACE(FS_READ, fp, fd, flag, size); // 读文件的代码桩, + #TYPE#之后的入参就是上面3中的FS_READ_PARAMS函数的入参 + ``` + + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** + > 预置的Trace事件及参数均可以通过上述方式进行裁剪,参数详见kernel\include\los_trace.h。 + +- Trace Mask事件过滤接口LOS_TraceEventMaskSet(UINT32 mask),其入参mask仅高28位生效(对应LOS_TRACE_MASK中某模块的使能位),仅用于模块的过滤,暂不支持针对某个特定事件的细粒度过滤。例如:LOS_TraceEventMaskSet(0x202),则实际设置生效的mask为0x200(TRACE_QUE_FLAG),QUE模块的所有事件均会被采集。一般建议使用的方法为: LOS_TraceEventMaskSet(TRACE_EVENT_FLAG | TRACE_MUX_FLAG | TRACE_SEM_FLAG | TRACE_QUE_FLAG); + +- 如果仅需要使能简易插桩事件,通过设置Trace Mask为TRACE_MAX_FLAG即可。 + +- Trace缓冲区有限,事件写满之后会覆盖写,用户可通过LOS_TraceRecordDump中打印的CurEvtIndex识别最新记录。 + +- Trace的典型操作流程为:LOS_TraceStart、 LOS_TraceStop、 LOS_TraceRecordDump. + +- 针对中断事件的Trace, 提供中断号过滤,用于解决某些场景下特定中断号频繁触发导致其他事件被覆盖的情况,用户可自定义中断过滤的规则, + 示例如下: + ``` + BOOL Example_HwiNumFilter(UINT32 hwiNum) + { + if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { + return TRUE; + } + return FALSE; + } + LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); + ``` -5. Trace缓冲区有限,事件写满之后会覆盖写,用户可通过LOS_TraceRecordDump中打印的CurEvtIndex识别最新记录。 - -6. Trace的典型操作流程为:LOS_TraceStart、 LOS_TraceStop、 LOS_TraceRecordDump. - -7. 针对中断事件的Trace, 提供中断号过滤,用于解决某些场景下特定中断号频繁触发导致其他事件被覆盖的情况,用户可自定义中断过滤的规则, - - 示例如下: -``` -BOOL Example_HwiNumFilter(UINT32 hwiNum) -{ - if ((hwiNum == TIMER_INT) || (hwiNum == DMA_INT)) { - return TRUE; - } - return FALSE; -} -LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); -``` 则当中断号为TIMER_INT 或者DMA_INT时,不记录中断事件。 -### 用户态 -新增trace字符设备,位于"/dev/trace",通过对设备节点的read\write\ioctl,实现用户态trace的读写和控制: +### 用户态 + +新增trace字符设备,位于"/dev/trace",通过对设备节点的read、write、ioctl,实现用户态trace的读写和控制: - read: 用户态读取Trace记录数据 - write: 用户态事件写入 - ioctl: 用户态Trace控制操作,包括 -```C + +``` #define TRACE_IOC_MAGIC 'T' #define TRACE_START _IO(TRACE_IOC_MAGIC, 1) #define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) @@ -215,32 +144,32 @@ LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); #define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) #define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) ``` + 分别对应Trace启动(LOS_TraceStart)、停止(LOS_TraceStop)、清除记录(LOS_TraceReset)、dump记录(LOS_TraceRecordDump)、设置事件过滤掩码(LOS_TraceEventMaskSet) -具体的使用方法参见[用户态编程实例](#section4.2.2) +具体的使用方法参见[用户态编程实例](https://gitee.com/openharmony/docs/blob/70744e1e0e34d66e11108a00c8db494eea49dd02/zh-cn/device-dev/kernel/kernel-small-debug-trace.md#section4.2.2)。 +## 开发指导 -## 开发指导 -### 内核态开发流程 +### 内核态开发流程 开启Trace调测的典型流程如下: 1. 配置Trace模块相关宏。 - -配置Trace控制宏LOSCFG_KERNEL_TRACE,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Hook Feature->Enable Trace Feature"中打开: - -| 配置项 | menuconfig选项 | 含义 | 设置值 | -| ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | -| LOSCFG_KERNEL_TRACE | Enable Trace Feature | Trace模块的裁剪开关 | YES/NO | -| LOSCFG_RECORDER_MODE_OFFLINE | Trace work mode ->Offline mode | Trace工作模式为离线模式 | YES/NO | -| LOSCFG_RECORDER_MODE_ONLINE | Trace work mode ->Online mode | Trace工作模式为在线模式 | YES/NO | -| LOSCFG_TRACE_CLIENT_INTERACT | Enable Trace Client Visualization and Control | 使能与Trace IDE (dev tools)的交互,包括数据可视化和流程控制 | YES/NO | -| LOSCFG_TRACE_FRAME_CORE_MSG | Enable Record more extended content ->Record cpuid, hardware interrupt status, task lock status | 记录CPUID、中断状态、锁任务状态 | YES/NO | -| LOSCFG_TRACE_FRAME_EVENT_COUNT | Enable Record more extended content ->Record event count, which indicate the sequence of happened events | 记录事件的次序编号 | YES/NO | -| LOSCFG_TRACE_FRAME_MAX_PARAMS | Record max params | 配置记录事件的最大参数个数 | INT | -| LOSCFG_TRACE_BUFFER_SIZE | Trace record buffer size | 配置Trace的缓冲区大小 | INT | + 配置Trace控制宏LOSCFG_KERNEL_TRACE,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Hook Feature->Enable Trace Feature"中打开: + + | 配置项 | menuconfig选项 | 含义 | 设置值 | + | -------- | -------- | -------- | -------- | + | LOSCFG_KERNEL_TRACE | Enable Trace Feature | Trace模块的裁剪开关 | YES/NO | + | LOSCFG_RECORDER_MODE_OFFLINE | Trace work mode ->Offline mode | Trace工作模式为离线模式 | YES/NO | + | LOSCFG_RECORDER_MODE_ONLINE | Trace work mode ->Online mode | Trace工作模式为在线模式 | YES/NO | + | LOSCFG_TRACE_CLIENT_INTERACT | Enable Trace Client Visualization and Control | 使能与Trace IDE (dev tools)的交互,包括数据可视化和流程控制 | YES/NO | + | LOSCFG_TRACE_FRAME_CORE_MSG | Enable Record more extended content ->Record cpuid, hardware interrupt status, task lock status | 记录CPUID、中断状态、锁任务状态 | YES/NO | + | LOSCFG_TRACE_FRAME_EVENT_COUNT | Enable Record more extended content ->Record event count, which indicate the sequence of happend events | 记录事件的次序编号 | YES/NO | + | LOSCFG_TRACE_FRAME_MAX_PARAMS | Record max params | 配置记录事件的最大参数个数 | INT | + | LOSCFG_TRACE_BUFFER_SIZE | Trace record buffer size | 配置Trace的缓冲区大小 | INT | 2. (可选)预置事件参数和事件桩(或使用系统默认的事件参数配置和事件桩)。 @@ -254,7 +183,6 @@ LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); 7. 调用LOS_TraceRecordDump输出缓冲区数据(函数的入参为布尔型,FALSE表示格式化输出,TRUE表示输出到Trace IDE)。 - 上述第3-7步中的接口,均封装有对应的shell命令,开启shell后可执行相应的命令,对应关系如下: - LOS_TraceReset —— trace_reset @@ -267,25 +195,27 @@ LOS_TraceHwiFilterHookReg(Example_HwiNumFilter); - LOS_TraceRecordDump —— trace_dump -### 内核态编程实例 - 本实例实现如下功能: +## 内核态编程实例 + +本实例实现如下功能: - 1. 创建一个用于Trace测试的任务。 +1. 创建一个用于Trace测试的任务。 - 2. 设置事件掩码。 +2. 设置事件掩码。 - 3. 启动trace。 +3. 启动trace。 - 4. 停止trace。 +4. 停止trace。 - 5. 格式化输出trace数据。 +5. 格式化输出trace数据。 -### 内核态示例代码 + +## 内核态示例代码 实例代码如下: -```C +``` #include "los_trace.h" UINT32 g_traceTestTaskId; VOID Example_Trace(VOID) @@ -306,7 +236,6 @@ VOID Example_Trace(VOID) LOS_TraceStop(); LOS_TraceRecordDump(FALSE); } - UINT32 Example_Trace_test(VOID){ UINT32 ret; TSK_INIT_PARAM_S traceTestTask; @@ -332,12 +261,13 @@ UINT32 Example_Trace_test(VOID){ LOS_MODULE_INIT(Example_Trace_test, LOS_INIT_LEVEL_KMOD_EXTENDED); ``` -### 内核态结果验证 + +## 结果验证 输出结果如下: -```c -*******TraceInfo begin******* +``` +***TraceInfo begin*** clockFreq = 50000000 CurEvtIndex = 7 Index Time(cycles) EventType CurTask Identity params @@ -349,7 +279,7 @@ Index Time(cycles) EventType CurTask Identity params 5 0x36eec810 0x45 0xc 0x1 0x9 0x8 0x1f 6 0x3706f804 0x45 0x1 0x0 0x1f 0x4 0x0 7 0x37070e59 0x45 0x0 0x1 0x0 0x8 0x1f -*******TraceInfo end******* +***TraceInfo end*** ``` 输出的事件信息包括:发生时间、事件类型、事件发生在哪个任务中、事件操作的主体对象、事件的其他参数。 @@ -358,9 +288,9 @@ Index Time(cycles) EventType CurTask Identity params - CurrentTask:表示当前运行在哪个任务中,值为taskid。 -- Identity:表示事件操作的主体对象,可查阅头文件los_trace.h中的#TYPE#_PARAMS。 +- Identity:表示事件操作的主体对象,可查阅头文件los_trace.h中的\#TYPE\#_PARAMS。 -- params:表示的事件参数可查阅头文件los_trace.h中的#TYPE#_PARAMS。 +- params:表示的事件参数可查阅头文件los_trace.h中的\#TYPE\#_PARAMS。 下面以序号为0的输出项为例,进行说明。 @@ -375,139 +305,14 @@ Index Time(cycles) EventType CurTask Identity params - Identity和params的含义需要查看TASK_SWITCH_PARAMS宏定义: -```c +``` #define TASK_SWITCH_PARAMS(taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus) \ taskId, oldPriority, oldTaskStatus, newPriority, newTaskStatus ``` -因为#TYPE#_PARAMS(IDENTITY, parma1...) IDENTITY, ...,所以Identity为taskId(0x0),第一个参数为oldPriority(0x1f) - -> ![](../public_sys-resources/icon-note.gif)**说明** - - > params的个数由menuconfig中Enable Trace Feature --> Record max params配置,默认为3,超出的参数不会被记录,用户应自行合理配置该值。 - - 综上所述,任务由0x1切换到0x0,0x1任务的优先级为0x1f,状态为0x4,0x0任务的优先级为0x0。 +因为\#TYPE\#_PARAMS(IDENTITY, parma1...) IDENTITY, ...,所以Identity为taskId(0x0),第一个参数为oldPriority(0x1f) -### 用户态开发流程 -通过在menuconfig配置"Driver->Enable TRACE DRIVER",开启Trace驱动。该配置仅在内核Enable Trace Feature后,才可在Driver的选项中可见。 -1. 打开“/dev/trace”字符文件,进行读写和IOCTL操作; -2. 系统提供用户态的trace命令,该命令位于/bin目录下,cd bin 后可执行如下命令: -- ./trace reset 清除Trace记录 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> params的个数由LOSCFG_TRACE_FRAME_MAX_PARAMS配置,默认为3,超出的参数不会被记录,用户应自行合理配置该值。 -- ./trace mask num 设置Trace事件过滤掩码 - -- ./trace start 启动Trace - -- ./trace stop 停止Trace - -- ./trace dump 0/1 格式化输出Trace记录 - -- ./trace read nBytes 读取Trace记录 - -- ./trace write type id params... 写用户态事件 - 如:./trace write 0x1 0x1001 0x2 0x3 则写入一条用户态事件,其事件类型为0x1, id为0x1001,参数有2个,分别是0x2和0x3. - - 用户态命令行的典型使用方法如下: - - ./trace start - - ./trace write 0x1 0x1001 0x2 0x3 - - ./trace stop - - ./trace dump 0 - -### 用户态编程实例 - - 本实例实现如下功能: - - 1. 打开trace字符设备。 - - 2. 设置事件掩码。 - - 3. 启动trace。 - - 4. 写trace事件。 - - 5. 停止trace。 - - 6. 格式化输出trace数据。 - -### 用户态示例代码 -实例代码如下 -```c -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TRACE_IOC_MAGIC 'T' -#define TRACE_START _IO(TRACE_IOC_MAGIC, 1) -#define TRACE_STOP _IO(TRACE_IOC_MAGIC, 2) -#define TRACE_RESET _IO(TRACE_IOC_MAGIC, 3) -#define TRACE_DUMP _IO(TRACE_IOC_MAGIC, 4) -#define TRACE_SET_MASK _IO(TRACE_IOC_MAGIC, 5) -#define TRACE_USR_MAX_PARAMS 3 - -typedef struct { - unsigned int eventType; - uintptr_t identity; - uintptr_t params[TRACE_USR_MAX_PARAMS]; -} UsrEventInfo; - -int main(int argc, char **argv) -{ - size_t mask; - - int fd = open("/dev/trace", O_RDWR); - if (fd == -1) { - printf("Trace open failed.\n"); - exit(EXIT_FAILURE); - } - - ioctl(fd, TRACE_STOP, NULL); - ioctl(fd, TRACE_RESET, NULL); /* clear all events */ - - mask = 0x10000; /* filter kernel events */ - ioctl(fd, TRACE_SET_MASK, mask); - - ioctl(fd, TRACE_START, NULL); /* start trace */ - sleep(1); - - UsrEventInfo info = { - .eventType = 0x1, - .identity = 0x0001, - .params = {1, 2, 3}, - }; - (void)write(fd, &info, sizeof(UsrEventInfo)); - - info.eventType = 0x2; - info.identity = 0x0002; - (void)write(fd, &info, sizeof(UsrEventInfo)); - - ioctl(fd, TRACE_STOP, NULL); - ioctl(fd, TRACE_DUMP, 0); - - close(fd); - return 0; -} -``` -### 用户态结果验证 -输出结果如下: - -```c -*******TraceInfo begin******* -clockFreq = 50000000 -CurEvtIndex = 2 -Index Time(cycles) EventType CurTask Identity params -0 0x366d5e88 0xfffffff1 0x1 0x1 0x1 0x2 0x3 -1 0x366d74ae 0xfffffff2 0x1 0x2 0x1 0x2 0x3 -*******TraceInfo end******* -``` -示例代码中调用了2次write,对应产生2条Trace记录; -用户层事件的EventType高28位固定均为1(即0xfffffff0),仅低4位表示具体的事件类型。 \ No newline at end of file +综上所述,任务由0x1切换到0x0,0x1任务的优先级为0x1f,状态为0x4,0x0任务的优先级为0x0。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-concept.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-concept.md index 5266e039bf..e77727e14b 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-concept.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-concept.md @@ -1,6 +1,6 @@ -# 基本概念 +# 基本概念 Debug版本的musl-libc库为用户提供内存泄漏检测、堆内存统计、踩内存分析以及backtrace功能等维测手段,可以提高用户态内存相关问题的定位效率。 -采用了对malloc/free接口进行插桩,保存关键节点信息,然后程序在申请和释放内存时进行内存节点完整性校验,最后在程序结束时通过统计节点信息得到内存统计信息并根据统计信息判断内存是否泄漏的设计思想。 +采用了对malloc/free接口进行插桩,保存关键节点信息,然后程序在申请和释放内存时进行内存节点完整性校验,最后在程序结束时通过统计节点信息得到内存统计信息并根据统计信息判断内存是否泄漏的设计思想。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-faqs.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-faqs.md index 064b627e16..d6d754fcaf 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-faqs.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-faqs.md @@ -1,52 +1,43 @@ -# 常见问题场景 +# 常见问题场景 -- [UAF\(Use after free\)](#section4427132815445) -- [Double free](#section827194818458) -- [堆内存节点被踩](#section1763741216461) +## UAF(Use after free) -## UAF\(Use after free\) +- 申请小块内存(不大于0x1c000字节) + free之后: -- 申请小块内存(不大于0x1c000字节) + 读操作:读取free之后的内存大概率是魔术数字(0xFEFEFEFE) - free之后: + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** + > free之后的堆内存不会立即释放进堆内存池,会先放至固定长度的队列中,并置魔术数字0xFE,队列满后会将先放至队列中的内存块释放进堆内存池 - 读操作:读取free之后的内存大概率是魔术数字\(0xFEFEFEFE\) + 写操作:无法校验。 - >![](../public_sys-resources/icon-note.gif) **说明:** - >free之后的堆内存不会立即释放进堆内存池,会先放至固定长度的队列中,并置魔术数字0xFE,队列满后会将先放至队列中的内存块释放进堆内存池 - 写操作:无法校验。 +- 申请大块内存(大于0x1c000) + 堆内存由malloc通过调用mmap接口申请,free之后若仍访问该内存,则用户程序异常(该内存区间已被unmap)。 -- 申请大块内存(大于0x1c000) - - 堆内存由malloc通过调用mmap接口申请,free之后若仍访问该内存,则用户程序异常(该内存区间已被unmap)。 - - -## Double free +## Double free Double free时,用户程序将会异常退出。 -## 堆内存节点被踩 - -- 申请小块内存(不大于0x1c000) - - 堆内存节点被踩时,用户程序将会异常退出,并输出破坏被踩节点的可能的堆内存申请调用栈,对于野指针踩内存情况无法校验出来。例如用户程序mem\_check中存在堆内存越界踩的情况,利用命令行方式可以获得踩内存的可能的具体位置。 - - ``` - OHOS # ./mem_check --mwatch - OHOS # - ==PID:6== Memory integrity information: - [TID:28 allocated addr: 0x272e1ea0, size: 0x120] The possible attacker was allocated from: - #00: [0x640e8] -> /lib/libc.so - #01: [0x21d0] -> mem_check - ``` - 可以通过调用栈解析脚本对调用栈信息进行解析。 +## 堆内存节点被踩 +- 申请小块内存(不大于0x1c000) + 堆内存节点被踩时,用户程序将会异常退出,并输出破坏被踩节点的可能的堆内存申请调用栈,对于野指针踩内存情况无法校验出来。例如用户程序mem_check中存在堆内存越界踩的情况,利用命令行方式可以获得踩内存的可能的具体位置。 -- 申请大块内存(大于0x1c000) + ``` + OHOS # ./mem_check --mwatch + OHOS # + ==PID:6== Memory integrity information: + [TID:28 allocated addr: 0x272e1ea0, size: 0x120] The possible attacker was allocated from: + #00: [0x640e8] -> /lib/libc.so + #01: [0x21d0] -> mem_check + ``` - 堆内存由malloc通过mmap接口申请,申请得到的堆内存块前后各置一个size为PAGE\_SIZE大小的区间,设置无读写权限,读写操作会触发用户程序异常。 + 可以通过调用栈解析脚本对调用栈信息进行解析。 +- 申请大块内存(大于0x1c000) + 堆内存由malloc通过mmap接口申请,申请得到的堆内存块前后各置一个size为PAGE_SIZE大小的区间,设置无读写权限,读写操作会触发用户程序异常。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-function.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-function.md index 96783b0069..3955e8ae22 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-function.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-function.md @@ -1,10 +1,10 @@ -# 运行机制 +# 运行机制 -- [内存泄漏检查](#section142061581018) -- [堆内存统计](#section136902041337) -- [内存完整性检查](#section196491231761) +- [内存泄漏检查](#内存泄漏检查) +- [堆内存统计](#堆内存统计) +- [内存完整性检查](#内存完整性检查) -## 内存泄漏检查 +## 内存泄漏检查 对于每个进程,内存调测模块维护了128个链表(当前系统的线程最大数量为128个),每个链表的索引为线程ID。 @@ -12,47 +12,44 @@ 释放内存时:根据需要释放的内存地址匹配内存节点控制块并将该控制块删除。 -**图 1** 堆内存节点信息链表 -![](figure/堆内存节点信息链表.png "堆内存节点信息链表") +**图1** 堆内存节点信息链表 +![zh-cn_image_0000001165890158](figures/zh-cn_image_0000001165890158.png) 申请内存时,返回地址会被保存到LR寄存器中。进程运行过程中,系统会在内存节点控制块中添加疑似泄漏点对应的lr等信息。如下图所示: -**图 2** 堆内存节点信息 -![](figure/堆内存节点信息.png "堆内存节点信息") +**图2** 堆内存节点信息 +![zh-cn_image_0000001165890518](figures/zh-cn_image_0000001165890518.png) -其中,TID表示线程ID;PID表示进程ID;ptr表示申请的内存地址;size表示申请的内存大小;lr\[n\]表示函数调用栈地址,变量n可以根据具体场景的需要进行配置。 +其中,TID表示线程ID;PID表示进程ID;ptr表示申请的内存地址;size表示申请的内存大小;lr[n]表示函数调用栈地址,变量n可以根据具体场景的需要进行配置。 释放内存时,将free等接口的入参指针与node的ptr字段进行匹配,如果相同则删除该内存节点控制块信息。 用户通过串口或文件等方式,将各个进程内存调测信息导出,利用addr2line工具将导出的信息转换成导致内存泄漏的代码行,便可以解决内存泄露问题。 -**图 3** 泄漏点代码行定位流程 -![](figure/泄漏点代码行定位流程.png "泄漏点代码行定位流程") +**图3** 泄漏点代码行定位流程 +![zh-cn_image_0000001165730464](figures/zh-cn_image_0000001165730464.png) -## 堆内存统计 -用户态线程堆内存使用统计具有一定的实际意义,统计线程申请的堆内存占比,为用户程序的内存使用优化提供数据支持。用户态堆内存统计模块主要涉及的接口为malloc和free。如[图1](#fig4294145810543),每个进程维护128个链表,链表索引即线程ID,申请内存时系统将ptr和size信息记录在内存节点控制块中并将节点控制块挂在以线程ID为头信息的链表上,堆内存释放时根据ptr从对应的链表上移除相应的堆内存块信息;同时计算出当前线程所持有的堆内存总的使用量,并更新当前进程的堆内存使用量和堆内存使用峰值。 +## 堆内存统计 -## 内存完整性检查 +用户态线程堆内存使用统计具有一定的实际意义,统计线程申请的堆内存占比,为用户程序的内存使用优化提供数据支持。用户态堆内存统计模块主要涉及的接口为malloc和free。如图1所示,每个进程维护128个链表,链表索引即线程ID,申请内存时系统将ptr和size信息记录在内存节点控制块中并将节点控制块挂在以线程ID为头信息的链表上,堆内存释放时根据ptr从对应的链表上移除相应的堆内存块信息;同时计算出当前线程所持有的堆内存总的使用量,并更新当前进程的堆内存使用量和堆内存使用峰值。 -- 使用malloc申请内存(小于等于0x1c000bytes时通过堆分配算法分配) - 用户程序申请堆内存时,在堆内存节点处添加校验值等信息,如果校验值异常,则很有可能是前一块堆内存使用越界导致的(目前无法识别校验值被野指针破坏的场景)。在内存申请、释放时校验内存节点校验值的正确性,若内存节点被破坏,校验失败时则输出tid、pid及当前被踩节点前一块堆内存申请时保存的调用栈信息,通过addr2line工具可获得具体的代码行信息,辅助用户解决问题。 +## 内存完整性检查 - **图 4** node节点头信息添加校验值 - ![](figure/node节点头信息添加校验值.png "node节点头信息添加校验值") +- 使用malloc申请内存(小于等于0x1c000bytes时通过堆分配算法分配) + 用户程序申请堆内存时,在堆内存节点处添加校验值等信息,如果校验值异常,则很有可能是前一块堆内存使用越界导致的(目前无法识别校验值被野指针破坏的场景)。在内存申请、释放时校验内存节点校验值的正确性,若内存节点被破坏,校验失败时则输出tid、pid及当前被踩节点前一块堆内存申请时保存的调用栈信息,通过addr2line工具可获得具体的代码行信息,辅助用户解决问题。 - free堆内存时,不会立即把该内存块释放掉,而是在内存中写入魔术数字0xFE,并放到free队列中\(保证在一定时间内不会再被malloc函数分配\),当有野指针或use-after-free的情况对该内存进行读取的操作时,能够发现数据异常,但是对于写操作则无法判断出来。 + **图4** node节点头信息添加校验值 + ![zh-cn_image_0000001211449151](figures/zh-cn_image_0000001211449151.png) - **图 5** free流程图 - ![](figure/free流程图.png "free流程图") + free堆内存时,不会立即把该内存块释放掉,而是在内存中写入魔术数字0xFE,并放到free队列中(保证在一定时间内不会再被malloc函数分配),当有野指针或use-after-free的情况对该内存进行读取的操作时,能够发现数据异常,但是对于写操作则无法判断出来。 + **图5** free流程图 + ![zh-cn_image_0000001165890904](figures/zh-cn_image_0000001165890904.png) -- 使用malloc申请内存(大于0x1c000bytes时通过mmap申请) - - 当malloc通过mmap申请大块内存时,在返回给用户使用的内存区间头和尾分别多申请一个页,一个页PAGE\_SIZE当前为0x1000,这两个页分别通过mprotect接口设置权限为PROT\_NONE(无可读可写权限),可以有效防止内存越界读写问题:越界读写数据时由于无读写权限而导致用户程序异常,根据异常调用栈信息可找到相应的代码逻辑。 - - **图 6** malloc通过mmap机制申请内存的内存布局 - ![](figure/malloc通过mmap机制申请内存的内存布局.png "malloc通过mmap机制申请内存的内存布局") - +- 使用malloc申请内存(大于0x1c000bytes时通过mmap申请) + 当malloc通过mmap申请大块内存时,在返回给用户使用的内存区间头和尾分别多申请一个页,一个页PAGE_SIZE当前为0x1000,这两个页分别通过mprotect接口设置权限为PROT_NONE(无可读可写权限),可以有效防止内存越界读写问题:越界读写数据时由于无读写权限而导致用户程序异常,根据异常调用栈信息可找到相应的代码逻辑。 + **图6** malloc通过mmap机制申请内存的内存布局 + ![zh-cn_image_0000001211130993](figures/zh-cn_image_0000001211130993.png) diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-api.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-api.md index d87b20aeba..8b1e87c408 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-api.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-api.md @@ -1,55 +1,13 @@ -# 接口说明 +# 接口说明 -**表 1** 内存调测模块接口 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

内存调测功能

-

mem_check_init

-

初始化内存检测模块。

-

watch_mem

-

获取线程级堆内存使用信息。

-

check_leak

-

检查是否有堆内存泄漏。

-

check_heap_integrity

-

检查堆内存的完整性。

-

调用栈回溯功能

-

backtrace

-

获取调用栈地址信息。

-

backtrace_symbols

-

根据地址信息获取符号信息。

-

print_trace

-

输出函数调用栈信息。

-
+**表1** 内存调测模块接口 +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 内存调测功能 | mem_check_init | 初始化内存检测模块。 | +| | watch_mem |获取线程级堆内存使用信息。| +| | check_leak |检查是否有堆内存泄漏。| +| | check_heap_integrity |检查堆内存的完整性。| +| 调用栈回溯功能 | backtrace | 获取调用栈地址信息。 | +| | backtrace_symbols |根据地址信息获取符号信息。| +| | print_trace |输出函数调用栈信息。| diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-api.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-api.md index d5b8010de2..850590180c 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-api.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-api.md @@ -1,11 +1,11 @@ -# 接口调用方式 +# 接口调用方式 -- [示例代码](#section5490173592518) -- [编译](#section534302242515) -- [调测信息](#section1017419992515) -- [调用栈解析](#section1485163282417) +- [示例代码](#示例代码) +- [编译](#编译) +- [调测信息](#调测信息) +- [调用栈解析](#调用栈解析) -## 示例代码 +## 示例代码 代码功能:显式调用调测模块的相关接口对用户代码进行内存校验。 @@ -37,21 +37,29 @@ int main() } ``` -## 编译 + +## 编译 ``` $ clang -o mem_check mem_check.c -funwind-tables -rdynamic -g -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos --sysroot=/home//harmony/out/hispark_taurus/ipcamera_hispark_taurus/sysroot $(clang -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos -print-file-name=libunwind.a) ``` ->![](../public_sys-resources/icon-note.gif) **说明:** ->- 本编译示例基于将编译器的路径写入环境变量中,即.bashrc文件中。 ->- 编译用户程序及所需的lib库时,需要添加编译选项-funwind-tables,-rdynamic,-g,用于栈回溯。 ->- -mfloat-abi=softfp,-mcpu=cortex-a7,-mfpu=neon-vfpv4编译选项用于指定具体的芯片架构、浮点数计算优化、fpu,与具体的libc库使用的编译选项保持一致,否则链接时可能出现找不到libc库文件。 ->- -target arm-liteos用于指定编译器相关库文件路径。 ->- --sysroot=/home//harmony/out/hispark\_taurus/ipcamera\_hispark\_taurus/sysroot用于指定编译器库文件搜索根目录,假设OpenHarmony工程代码存放路径为/home//harmony。其中out/hispark\_taurus/ipcamera\_hispark\_taurus路径为在编译时,hb set命令指定的具体产品,本示例选择的是ipcamera\_hispark\_taurus产品。 ->- $\(clang -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos -print-file-name=libunwind.a\)用于指定相应的unwind库的路径。 -## 调测信息 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> - 本编译示例基于将编译器的路径写入环境变量中,即.bashrc文件中。 +> +> - 编译用户程序及所需的lib库时,需要添加编译选项-funwind-tables,-rdynamic,-g,用于栈回溯。 +> +> - -mfloat-abi=softfp,-mcpu=cortex-a7,-mfpu=neon-vfpv4编译选项用于指定具体的芯片架构、浮点数计算优化、fpu,与具体的libc库使用的编译选项保持一致,否则链接时可能出现找不到libc库文件。 +> +> - -target arm-liteos用于指定编译器相关库文件路径。 +> +> - --sysroot=/home/<user-name>/harmony/out/hispark_taurus/ipcamera_hispark_taurus/sysroot用于指定编译器库文件搜索根目录,假设OpenHarmony工程代码存放路径为/home/<user-name>/harmony。其中out/hispark_taurus/ipcamera_hispark_taurus路径为在编译时,hb set命令指定的具体产品,本示例选择的是ipcamera_hispark_taurus产品。 +> +> - $(clang -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 -target arm-liteos -print-file-name=libunwind.a)用于指定相应的unwind库的路径。 + + +## 调测信息 ``` OHOS # ./mem_check @@ -102,9 +110,10 @@ Check heap integrity ok! // 堆内存完整性检查 Check heap integrity ok! ``` -## 调用栈解析 -提供parse\_mem\_info.sh脚本可以对调用栈进行解析,解析脚本存放的路径:kernel/liteos\_a/tools/scripts/parse\_memory/parse\_mem\_info.sh。利用脚本可以将相应的调测信息转换成具体的源码行号,如下命令所示,mem\_debug.txt保存的是内存调测信息,elf1、elf2等文件是需要解析的elf文件。 +## 调用栈解析 + +提供parse_mem_info.sh脚本可以对调用栈进行解析,解析脚本存放的路径:kernel/liteos_a/tools/scripts/parse_memory/parse_mem_info.sh。利用脚本可以将相应的调测信息转换成具体的源码行号,如下命令所示,mem_debug.txt保存的是内存调测信息,elf1、elf2等文件是需要解析的elf文件。 ``` $ ./parse_mem_info.sh mem_debug.txt elf1 elf2 elf3 ... @@ -144,4 +153,3 @@ Check heap integrity ok! ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). ``` - diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md index 129757a1fa..8c3ef15472 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use-cli.md @@ -1,27 +1,31 @@ -# 命令行参数方式 +# 命令行参数方式 -- [示例代码](#section13793104782316) -- [编译](#section1676431122320) -- [使用mwatch参数命令](#section1703415132311) -- [调用栈解析](#section1880675510221) -- [使用mrecord参数命令](#section071022822210) +- [示例代码](#示例代码) +- [编译](#编译) +- [使用mwatch参数命令](#使用mwatch参数命令) +- [调用栈解析](#调用栈解析) +- [使用mrecord参数命令](#使用mrecord参数命令) 对用户态进程进行内存相关的检查时,除了接口调用方式还可以通过命令行方式进行内存统计、内存泄漏或内存完整性检查。 + ``` --mwatch:初始化内存调测功能,注册信号。内存调测信息将从串口输出; --mrecord :初始化内存调测功能,注册信号。内存调测信息将保存至f_path文件,若f_path创建失败,则内存调测信息将从串口输出 ``` + 在待调测的进程未退出时可使用信号机制获取对应信息: + ``` kill -35 # 查看线程级堆内存占用 kill -36 # 检查是否存在堆内存泄漏 kill -37 # 检查堆内存头节点是否完整 ``` -## 示例代码 + +## 示例代码 代码功能:构造内存问题利用命令行方式进行内存调测。 @@ -46,11 +50,13 @@ int main() } ``` -## 编译 -参考[接口调用一节](kernel-small-debug-user-guide-use-api.md#section534302242515)。 +## 编译 -## 使用mwatch参数命令 +参考[接口调用一节](../kernel/kernel-small-debug-user-guide-use-api.md#编译)。 + + +## 使用mwatch参数命令 ``` OHOS # ./mem_check --mwatch // 利用task命令可以查到mem_check进程的pid为4 @@ -88,7 +94,8 @@ OHOS # Check heap integrity ok! ``` -## 调用栈解析 + +## 调用栈解析 将调测信息保存至test.txt文件中,利用脚本进行解析,获取内存泄漏的具体行号。 @@ -114,116 +121,111 @@ Now using addr2line ... ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). ``` -## 使用mrecord参数命令 - -1. 执行用户程序并指定记录内存调测信息的文件路径 - - ``` - OHOS # ./mem_check --mrecord /storage/check.txt - ``` - -2. 利用kill -35 统计内存信息,该信息将会输出到文件中,使用cat命令查看 - - ``` - OHOS # kill -35 4 - OHOS # Memory statistics information saved in /storage/pid(4)_check.txt - - OHOS # cat /storage/pid(4)_check.txt - - ==PID:4== Heap memory statistics(bytes): - [Check point]: - #00: [0x5973c] -> /lib/libc.so - - [TID: 18, Used: 0x640] - - ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s) - ``` - -3. 利用kill -36 校验内存完整性,该信息将会输出到文件中,使用cat命令查看 - - ``` - OHOS # kill -36 4 - OHOS # Leak check information saved in /storage/pid(4)_check.txt - - OHOS # cat /storage/pid(4)_check.txt - - ==PID:4== Heap memory statistics(bytes): - [Check point]: - #00: [0x5973c] -> /lib/libc.so - - [TID: 18, Used: 0x640] - - ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s) - - ==PID:4== Detected memory leak(s): - [Check point]: - #00: [0x2e38c] -> /lib/libc.so - #01: [0x5973c] -> /lib/libc.so - - [TID:18 Leak:0x320 byte(s)] Allocated from: - #00: [0x724] -> mem_check - #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so - - [TID:18 Leak:0x320 byte(s)] Allocated from: - #00: [0x6ec] -> mem_check - #01: [0x740] -> mem_check - #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so - - ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). - ``` - -4. 利用kill -9 杀掉当前进程,进程退出后会默认校验内存完整性,该信息将会输出到文件中,使用cat命令查看 - - ``` - OHOS # kill -9 4 - OHOS # Leak check information saved in /storage/pid(4)_check.txt - - Check heap integrity ok! - - OHOS # cat /storage/pid(4)_check.txt - OHOS # - ==PID:4== Heap memory statistics(bytes): - [Check point]: - #00: [0x5973c] -> /lib/libc.so - - [TID: 18, Used: 0x640] - - ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s) - - ==PID:4== Detected memory leak(s): - [Check point]: - #00: [0x2e38c] -> /lib/libc.so - #01: [0x5973c] -> /lib/libc.so - - [TID:18 Leak:0x320 byte(s)] Allocated from: - #00: [0x724] -> mem_check - #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so - - [TID:18 Leak:0x320 byte(s)] Allocated from: - #00: [0x6ec] -> mem_check - #01: [0x740] -> mem_check - #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so - - ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). - - ==PID:4== Detected memory leak(s): - [Check point]: - #00: [0x2e38c] -> /lib/libc.so - #01: [0x11b2c] -> /lib/libc.so - - [TID:18 Leak:0x320 byte(s)] Allocated from: - #00: [0x724] -> mem_check - #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so - - [TID:18 Leak:0x320 byte(s)] Allocated from: - #00: [0x6ec] -> mem_check - #01: [0x740] -> mem_check - #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so - - ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). - ``` - - ->![](../public_sys-resources/icon-note.gif) **说明:** ->上述连续记录的信息会逐步追加到初始化时所指定的文件中,故最后cat文件时,文件中还包含历史记录的信息内容。 +## 使用mrecord参数命令 + +1. 执行用户程序并指定记录内存调测信息的文件路径 + ``` + OHOS # ./mem_check --mrecord /storage/check.txt + ``` + +2. 利用kill -35 <pid>统计内存信息,该信息将会输出到文件中,使用cat命令查看 + ``` + OHOS # kill -35 4 + OHOS # Memory statistics information saved in /storage/pid(4)_check.txt + + OHOS # cat /storage/pid(4)_check.txt + + ==PID:4== Heap memory statistics(bytes): + [Check point]: + #00: [0x5973c] -> /lib/libc.so + + [TID: 18, Used: 0x640] + + ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s) + ``` + +3. 利用kill -36 <pid>校验内存完整性,该信息将会输出到文件中,使用cat命令查看 + ``` + OHOS # kill -36 4 + OHOS # Leak check information saved in /storage/pid(4)_check.txt + + OHOS # cat /storage/pid(4)_check.txt + + ==PID:4== Heap memory statistics(bytes): + [Check point]: + #00: [0x5973c] -> /lib/libc.so + + [TID: 18, Used: 0x640] + + ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s) + + ==PID:4== Detected memory leak(s): + [Check point]: + #00: [0x2e38c] -> /lib/libc.so + #01: [0x5973c] -> /lib/libc.so + + [TID:18 Leak:0x320 byte(s)] Allocated from: + #00: [0x724] -> mem_check + #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so + + [TID:18 Leak:0x320 byte(s)] Allocated from: + #00: [0x6ec] -> mem_check + #01: [0x740] -> mem_check + #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so + + ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). + ``` + +4. 利用kill -9 <pid>杀掉当前进程,进程退出后会默认校验内存完整性,该信息将会输出到文件中,使用cat命令查看 + ``` + OHOS # kill -9 4 + OHOS # Leak check information saved in /storage/pid(4)_check.txt + + Check heap integrity ok! + + OHOS # cat /storage/pid(4)_check.txt + OHOS # + ==PID:4== Heap memory statistics(bytes): + [Check point]: + #00: [0x5973c] -> /lib/libc.so + + [TID: 18, Used: 0x640] + + ==PID:4== Total heap: 0x640 byte(s), Peak: 0x640 byte(s) + + ==PID:4== Detected memory leak(s): + [Check point]: + #00: [0x2e38c] -> /lib/libc.so + #01: [0x5973c] -> /lib/libc.so + + [TID:18 Leak:0x320 byte(s)] Allocated from: + #00: [0x724] -> mem_check + #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so + + [TID:18 Leak:0x320 byte(s)] Allocated from: + #00: [0x6ec] -> mem_check + #01: [0x740] -> mem_check + #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so + + ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). + + ==PID:4== Detected memory leak(s): + [Check point]: + #00: [0x2e38c] -> /lib/libc.so + #01: [0x11b2c] -> /lib/libc.so + + [TID:18 Leak:0x320 byte(s)] Allocated from: + #00: [0x724] -> mem_check + #01: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so + + [TID:18 Leak:0x320 byte(s)] Allocated from: + #00: [0x6ec] -> mem_check + #01: [0x740] -> mem_check + #02: <(null)+0x1fdd231c>[0x2231c] -> /lib/libc.so + + ==PID:4== SUMMARY: 0x640 byte(s) leaked in 2 allocation(s). + ``` + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 上述连续记录的信息会逐步追加到初始化时所指定的文件中,故最后cat文件时,文件中还包含历史记录的信息内容。 diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use.md index 693255e5ed..b479e7a9c3 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide-use.md @@ -1,17 +1,21 @@ -# 使用说明 +# 使用说明 编译OpenHarmony工程时默认编译的是debug版本,即libc库已经集成内存调测相关的接口实现,用户可以根据具体需要决定是否使能内存调测功能。 + 堆内存调测功能提供两种方式供用户使用:接口调用及命令行参数。 -- 接口调用:优点是可以较精确的检查某一段代码逻辑的堆内存相关信息,缺点是需要修改用户代码。 -- 命令行参数:优点是无需修改用户代码,缺点是无法精确的校验某一段逻辑的堆内存信息。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->内存调测功能使能后,进程退出时会默认进行一次堆内存泄漏和堆内存完整性检查。内存调测功能未使能时,堆内存统计、堆内存泄漏检查、堆内存完整性校验功能不会开启,调用相关调测接口无响应。 +- 接口调用:优点是可以较精确的检查某一段代码逻辑的堆内存相关信息,缺点是需要修改用户代码。 + +- 命令行参数:优点是无需修改用户代码,缺点是无法精确的校验某一段逻辑的堆内存信息。 + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 内存调测功能使能后,进程退出时会默认进行一次堆内存泄漏和堆内存完整性检查。内存调测功能未使能时,堆内存统计、堆内存泄漏检查、堆内存完整性校验功能不会开启,调用相关调测接口无响应。 -- **[接口调用方式](kernel-small-debug-user-guide-use-api.md)** -- **[命令行参数方式](kernel-small-debug-user-guide-use-cli.md)** +- **[接口调用方式](kernel-small-debug-user-guide-use-api.md)** +- **[命令行参数方式](kernel-small-debug-user-guide-use-cli.md)** diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide.md b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide.md index cd541f2cfd..2a0508628a 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user-guide.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user-guide.md @@ -1,7 +1,6 @@ -# 使用指导 +# 使用指导 -- **[接口说明](kernel-small-debug-user-guide-api.md)** - -- **[使用说明](kernel-small-debug-user-guide-use.md)** +- **[接口说明](kernel-small-debug-user-guide-api.md)** +- **[使用说明](kernel-small-debug-user-guide-use.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-user.md b/zh-cn/device-dev/kernel/kernel-small-debug-user.md index e36276326b..00f600d1e7 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-user.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug-user.md @@ -1,17 +1,10 @@ -# 用户态内存调测 +# 用户态内存调测 -- **[基本概念](kernel-small-debug-user-concept.md)** -- **[运行机制](kernel-small-debug-user-function.md)** +- **[基本概念](kernel-small-debug-user-concept.md)** -- **[使用指导](kernel-small-debug-user-guide.md)** - -- **[常见问题场景](kernel-small-debug-user-faqs.md)** - -- **[Linux内核概述](kernel-standard-overview.md)** - -- **[OpenHarmony开发板Patch使用指导](kernel-standard-patch.md)** - -- **[Linux内核编译与构建指导](kernel-standard-build.md)** +- **[运行机制](kernel-small-debug-user-function.md)** +- **[使用指导](kernel-small-debug-user-guide.md)** +- **[常见问题场景](kernel-small-debug-user-faqs.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug.md b/zh-cn/device-dev/kernel/kernel-small-debug.md index 42650fda0d..6b615e508e 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug.md +++ b/zh-cn/device-dev/kernel/kernel-small-debug.md @@ -1,13 +1,18 @@ -# 调测与工具 +# 调测与工具 -- **[Shell](kernel-small-debug-shell.md)** -- **[Trace](kernel-small-debug-trace.md)** +- **[Shell](kernel-small-debug-shell.md)** -- **[进程调测](kernel-small-debug-process.md)** +- **[Trace](kernel-small-debug-trace.md)** -- **[内存调测](kernel-small-debug-memory.md)** +- **[Perf调测](kernel-mini-memory-perf.md)** -- **[其他内核调测手段](kernel-small-debug-other.md)** +- **[LMS调测](kernel-small-memory-lms.md)** +- **[进程调测](kernel-small-debug-process.md)** +- **[内核态内存调测](kernel-small-debug-memory.md)** + +- **[用户态内存调测](kernel-small-debug-user.md)** + +- **[其他内核调测手段](kernel-small-debug-other.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small-debug-lms.md b/zh-cn/device-dev/kernel/kernel-small-memory-lms.md similarity index 59% rename from zh-cn/device-dev/kernel/kernel-small-debug-lms.md rename to zh-cn/device-dev/kernel/kernel-small-memory-lms.md index 708a386da7..63f4e9c69d 100644 --- a/zh-cn/device-dev/kernel/kernel-small-debug-lms.md +++ b/zh-cn/device-dev/kernel/kernel-small-memory-lms.md @@ -1,37 +1,37 @@ # LMS调测 -- [基本概念](#section1) +- [基本概念](#基本概念) +- [运行机制](#运行机制) +- [接口说明](#接口说明) + - [内核态](#内核态) + - [用户态](#用户态) +- [开发指导](#开发指导) + - [内核态开发流程](#内核态开发流程) +- [内核态编程实例](#内核态编程实例) +- [内核态示例代码](#内核态示例代码) + - [内核态结果验证](#内核态结果验证) + - [用户态开发流程](#用户态开发流程) + - [用户态编程实例](#用户态编程实例) + - [用户态示例代码](#用户态示例代码) + - [用户态结果验证](#用户态结果验证) + +## 基本概念 -- [运行机制](#section2) - -- [接口说明](#section3) - - - [内核态](#section3.1) - - - [用户态](#section3.2) - -- [开发指导](#section4) - - - [内核态开发流程](#section4.1.1) - - - [内核态编程实例](#section4.1.2) +LMS全称为Lite Memory Sanitizer,是一种实时检测内存操作合法性的调测工具。LMS能够实时检测缓冲区溢出(buffer overflow),释放后使用(use after free) 和重复释放(double Free), 在异常发生的第一时间通知操作系统,结合backtrace等定位手段,能准确定位到产生内存问题的代码行,极大提升内存问题定位效率。 - - [内核态实例代码](#section4.1.3) +OpenHarmony LiteOS-A内核的LMS模块提供下面几种功能: - - [内核态结果验证](#section4.1.4) +- 支持多内存池检测; - - [用户态开发流程](#section4.2.1) +- 支持LOS_MemAlloc、LOS_MemAllocAlign、LOS_MemRealloc申请出的内存检测; - - [用户态编程实例](#section4.2.2) +- 支持安全函数的访问检测(默认开启); - - [用户态实例代码](#section4.2.3) +- 支持libc 高频函数的访问检测,包括:memset、memcpy、memmove、strcat、strcpy、strncat、strncpy。 - - [用户态结果验证](#section4.2.4) -## 基本概念 -LMS全称为Lite Memory Sanitizer,是一种实时检测内存操作合法性的调测工具。LMS能够实时检测缓冲区溢出(buffer overflow),释放后使用(use after free) 和重复释放(double Free), 在异常发生的第一时间通知操作系统,结合backtrace等定位手段,能准确定位到产生内存问题的代码行,极大提升内存问题定位效率。 +## 运行机制 -## 运行机制 LMS使用影子内存映射标记系统内存的状态,一共可标记为三个状态:可读写,不可读写,已释放。影子内存存放在内存池的尾部。 - 内存从堆上申请后,会将数据区的影子内存设置为“可读写”状态,并将头结点区的影子内存设置为“不可读写”状态。 @@ -42,134 +42,93 @@ LMS使用影子内存映射标记系统内存的状态,一共可标记为三 - 在内存释放时,会检测被释放地址的影子内存状态值,若检测到影子内存非可读写,则会报重复释放错误。 -## 接口说明 -### 内核态 +## 接口说明 + + +### 内核态 OpenHarmony LiteOS-A内核的LMS模块提供下面几种功能,接口详细信息可以查看[API](https://gitee.com/openharmony/kernel_liteos_a/blob/master/kernel/include/los_lms.h)参考。 +**表1** LMS模块接口说明 -1. 支持多内存池检测; - -2. 支持LOS_MemAlloc、LOS_MemAllocAlign、LOS_MemRealloc申请出的内存检测; - -3. 支持安全函数的访问检测(默认开启); - -4. 支持libc 高频函数的访问检测,包括:memset、memcpy、memmove、strcat、strcpy、strncat、strncpy。 - -5. 可动态设置的功能如下: - -**表 1** LMS模块接口说明 - - - - - - - - - - - - - - - - - - - - - -

功能分类

-

接口名

-

描述

-

添加指定内存池被检测

-

LOS_LmsCheckPoolAdd

-

将指定内存池的地址范围添加到LMS的内存检测链表上,当访问的地址在链表范围内时,LMS才进行合法性校验;且LOS_MemInit接口会调用该接口,默认将初始化的内存池挂入到检测链表中。

-

删除指定内存池不被检测

-

LOS_LmsCheckPoolDel

-

不检测指定内存池地址范围内的合法性校验。

-

使能指定内存段锁保护

-

LOS_LmsAddrProtect

-

为某段内存地址上锁,设置为不可读写,一旦访问则报错。

-

去能指定内存段锁保护

-

LOS_LmsAddrDisableProtect

-

为某段内存地址解锁,设置为可读写。

-
- - -### 用户态 +| 功能分类 | 接口名 | 描述 | +| -------- | -------- | -------- | +| 添加指定内存池被检测 | LOS_LmsCheckPoolAdd | 将指定内存池的地址范围添加到LMS的内存检测链表上,当访问的地址在链表范围内时,LMS才进行合法性校验;且LOS_MemInit接口会调用该接口,默认将初始化的内存池挂入到检测链表中。 | +| 删除指定内存池不被检测 | LOS_LmsCheckPoolDel | 不检测指定内存池地址范围内的合法性校验。 | +| 使能指定内存段锁保护 | LOS_LmsAddrProtect | 为某段内存地址上锁,设置为不可读写,一旦访问则报错。 | +| 去能指定内存段锁保护 | LOS_LmsAddrDisableProtect | 为某段内存地址解锁,设置为可读写。 | + + +### 用户态 用户态仅提供LMS检测库,不提供对外接口。 -## 开发指导 -### 内核态开发流程 +## 开发指导 + + +### 内核态开发流程 开启LMS调测的典型流程如下: 1. 配置LMS模块相关宏。 + 配置LMS控制宏LOSCFG_KERNEL_LMS,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Lite Memory Sanitizer"中打开YES: - 配置LMS控制宏LOSCFG_KERNEL_LMS,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Lite Memory Sanitizer"中打开: + | 宏 | menuconfig选项 | 含义 | 取值 | + | -------- | -------- | -------- | -------- | + | LOSCFG_KERNEL_LMS | Enable Lms Feature | Lms模块的裁剪开关 | YES/NO | + | LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms check pool max num | LMS支持的检测内存池最大个数 | INT | + | LOSCFG_LMS_LOAD_CHECK | Enable lms read check | LMS内存读检测的裁剪开关 | YES/NO | + | LOSCFG_LMS_STORE_CHECK | Enable lms write check | LMS内存写检测的裁剪开关 | YES/NO | + | LOSCFG_LMS_CHECK_STRICT | Enable lms strict check, byte-by-byte | LMS内存逐字节严格检测的裁剪开关 | YES/NO | - | 配置项 | menuconfig选项 | 含义 | 设置值 | - | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------ | - | LOSCFG_KERNEL_LMS | Enable Lms Feature | Lms模块的裁剪开关 | YES/NO | - | LOSCFG_LMS_MAX_RECORD_POOL_NUM | Lms check pool max num | LMS支持的检测内存池最大个数 | INT | - | LOSCFG_LMS_LOAD_CHECK | Enable lms read check | LMS内存读检测的裁剪开关 | YES/NO | - | LOSCFG_LMS_STORE_CHECK | Enable lms write check | LMS内存写检测的裁剪开关 | YES/NO | - | LOSCFG_LMS_CHECK_STRICT | Enable lms strict check, byte-by-byte | LMS内存逐字节严格检测的裁剪开关 | YES/NO | +2. 在被检测模块的编译脚本中,修改编译选项。 + 增加LMS检测编译选项-fsanitize=kernel-address。为避免编译器优化,增加-O0编译选项。 -2. 在被检测模块的编译脚本中,增加LMS检测编译选项-fsanitize=kernel-address。 + gcc与clang编译选项存在差异,参照如下示例: + ``` + if ("$ohos_build_compiler_specified" == "gcc") { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + ] + } else { + cflags_c = [ + "-O0", + "-fsanitize=kernel-address", + "-mllvm", + "-asan-instrumentation-with-call-threshold=0", + "-mllvm", + "-asan-stack=0", + "-mllvm", + "-asan-globals=0", + ] + } + ``` -3. 为避免编译器优化,增加-O0编译选项。 +3. 重新编译,查看串口输出。如果检测到内存问题,会输出检测结果。 -4. gcc与clang编译选项存在差异,参照如下示例: - ``` - if ("$ohos_build_compiler_specified" == "gcc") { - cflags_c = [ - "-O0", - "-fsanitize=kernel-address", - ] - } else { - cflags_c = [ - "-O0", - "-fsanitize=kernel-address", - "-mllvm", - "-asan-instrumentation-with-call-threshold=0", - "-mllvm", - "-asan-stack=0", - "-mllvm", - "-asan-globals=0", - ] - } - ``` +## 内核态编程实例 -5. 重新编译,查看串口输出。如果检测到内存问题,会输出检测结果。 +本实例实现如下功能: -### 内核态编程实例 +1. 创建一个用于Lms测试的任务。 - 本实例实现如下功能: +2. 构造内存溢出错误和释放后使用错误。 - 1. 创建一个用于Lms测试的任务。 +3. 添加-fsanitize=kernel-address后编译执行,观察输出结果 - 2. 构造内存溢出错误和释放后使用错误。 - - 3. 添加-fsanitize=kernel-address后编译执行,观察输出结果 -### 内核态示例代码 +## 内核态示例代码 实例代码如下: - -```C +``` #define PAGE_SIZE (0x1000U) #define INDEX_MAX 20 - UINT32 g_lmsTestTaskId; char g_testLmsPool[2 * PAGE_SIZE]; - STATIC VOID testPoolInit(void) { UINT32 ret = LOS_MemInit(g_testLmsPool, 2 * PAGE_SIZE); @@ -178,7 +137,6 @@ STATIC VOID testPoolInit(void) return; } } - static VOID LmsTestOsmallocOverflow(VOID) { PRINTK("\n######%s start ######\n", __FUNCTION__); @@ -187,7 +145,6 @@ static VOID LmsTestOsmallocOverflow(VOID) PRINTK("str[%2d]=0x%2x ", INDEX_MAX, str[INDEX_MAX]); /* trigger heap overflow at str[INDEX_MAX] */ PRINTK("\n######%s stop ######\n", __FUNCTION__); } - static VOID LmsTestUseAfterFree(VOID) { PRINTK("\n######%s start ######\n", __FUNCTION__); @@ -197,14 +154,12 @@ static VOID LmsTestUseAfterFree(VOID) PRINTK("str[%2d]=0x%2x ", 0, str[0]); /* trigger use after free at str[0] */ PRINTK("\n######%s stop ######\n", __FUNCTION__); } - VOID LmsTestCaseTask(VOID) { testPoolInit(); LmsTestOsmallocOverflow(); LmsTestUseAfterFree(); } - UINT32 Example_Lms_test(VOID){ UINT32 ret; TSK_INIT_PARAM_S lmsTestTask; @@ -225,28 +180,26 @@ UINT32 Example_Lms_test(VOID){ LOS_MODULE_INIT(Example_Lms_test, LOS_INIT_LEVEL_KMOD_EXTENDED); ``` -### 内核态结果验证 -输出结果如下: +### 内核态结果验证 -```c +输出结果如下: +``` ######LmsTestOsmallocOverflow start ###### -[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected Start ***** +[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected Start * [ERR][KProcess:LmsTestCaseTask]Heap buffer overflow error detected [ERR][KProcess:LmsTestCaseTask]Illegal READ address at: [0x4157a3c8] [ERR][KProcess:LmsTestCaseTask]Shadow memory address: [0x4157be3c : 4] Shadow memory value: [2] OsBackTrace fp = 0x402c0f88 runTask->taskName = LmsTestCaseTask runTask->taskID = 2 -*******backtrace begin******* +***backtrace begin*** traceback fp fixed, trace using fp = 0x402c0fd0 traceback 0 -- lr = 0x400655a4 fp = 0x402c0ff8 traceback 1 -- lr = 0x40065754 fp = 0x402c1010 traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca - [LMS] Dump info around address [0x4157a3c8]: - [0x4157a3a0]: 00 00 00 00 00 00 00 00 | [0x4157be3a | 0]: 1 1 [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 @@ -258,27 +211,24 @@ traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca [0x4157a3e0]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 0]: 3 3 [0x4157a3e8]: 00 00 00 00 00 00 00 00 | [0x4157be3e | 4]: 3 3 [0x4157a3f0]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 0]: 3 3 -[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected End ***** +[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected End * str[20]=0xffffffba ######LmsTestOsmallocOverflow stop ###### - ###### LmsTestUseAfterFree start ###### -[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected Start ***** +[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected Start * [ERR][KProcess:LmsTestCaseTask]Use after free error detected [ERR][KProcess:LmsTestCaseTask]Illegal READ address at: [0x4157a3d4] [ERR][KProcess:LmsTestCaseTask]Shadow memory address: [0x4157be3d : 2] Shadow memory value: [3] OsBackTrace fp = 0x402c0f90 runTask->taskName = LmsTestCaseTask runTask->taskID = 2 -*******backtrace begin******* +***backtrace begin*** traceback fp fixed, trace using fp = 0x402c0fd8 traceback 0 -- lr = 0x40065680 fp = 0x402c0ff8 traceback 1 -- lr = 0x40065758 fp = 0x402c1010 traceback 2 -- lr = 0x40044bd0 fp = 0x402c1038 traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca - [LMS] Dump info around address [0x4157a3d4]: - [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 [0x4157a3b8]: 00 00 00 00 00 00 00 00 | [0x4157be3b | 4]: 0 0 @@ -290,29 +240,36 @@ traceback 3 -- lr = 0x40004e14 fp = 0xcacacaca [0x4157a3e8]: ba dc cd ab c8 a3 57 41 | [0x4157be3e | 4]: 2 2 [0x4157a3f0]: 0c 1a 00 00 00 00 00 00 | [0x4157be3f | 0]: 2 3 [0x4157a3f8]: 00 00 00 00 00 00 00 00 | [0x4157be3f | 4]: 3 3 -[ERR][KProcess:LmsTestCaseTask]***** Kernel Address Sanitizer Error Detected End ***** +[ERR][KProcess:LmsTestCaseTask]* Kernel Address Sanitizer Error Detected End * str[ 0]=0x 0 ######LmsTestUseAfterFree stop ###### ``` + 输出的关键信息包括: -- 错误类型: - - Heap buffer overflow堆内存越界 - - Use after free 释放后使用 -- 错误操作: - - Illegal Read非法读 - - Illegal Write非法写 - - Illegal Double free重复释放 + +- 错误类型: + - Heap buffer overflow堆内存越界 + - Use after free 释放后使用 + +- 错误操作: + - Illegal Read非法读 + - Illegal Write非法写 + - Illegal Double free重复释放 + - 上下文: - - 当前任务信息(taskName, taskId) - - 回溯栈(backtrace) + - 当前任务信息(taskName, taskId) + - 回溯栈(backtrace) + - 出错地址的内存信息: - - 内存的值、及对应影子内存的值 - - 内存地址:内存值| [影子内存地址 | 影子内存字节内偏移]:影子内存值 - - 影子内存值:0(可读可写)、3(已释放)、2(红区)、1(填充值)。 + - 内存的值、及对应影子内存的值 + - 内存地址:内存值| [影子内存地址 | 影子内存字节内偏移]:影子内存值 + - 影子内存值:0(可读可写)、3(已释放)、2(红区)、1(填充值)。 + +### 用户态开发流程 + +在待检测的app编译脚本中,添加如下参数即可, 完整示例可参见/kernel/liteos_a/apps/lms/BUILD.gn。 -### 用户态开发流程 -在待检测的app编译脚本中,添加如下参数即可, 完整示例可参见/kernel/liteos_a/apps/lms/BUILD.gn ``` if ("$ohos_build_compiler_specified" == "gcc") { cflags_c = [ @@ -352,26 +309,28 @@ if ("$ohos_build_compiler_specified" == "gcc") { "-Wl,--wrap=strcat", ] deps = [ "//kernel/liteos_a/kernel/extended/lms/usr:usrlmslib" ] - ``` +``` -### 用户态编程实例 - 本实例实现如下功能: +### 用户态编程实例 - 1. 构造内存溢出错误和释放后使用错误。 - - 2. 添加对应编译选项后,重新编译执行 +本实例实现如下功能: -### 用户态示例代码 -实例代码如下 -```c +1. 构造内存溢出错误和释放后使用错误。 + +2. 添加对应编译选项后,重新编译执行 + + +### 用户态示例代码 + +实例代码如下: +``` static void BufWriteTest(void *buf, int start, int end) { for (int i = start; i <= end; i++) { ((char *)buf)[i] = 'a'; } } - static void BufReadTest(void *buf, int start, int end) { char tmp; @@ -379,7 +338,6 @@ static void BufReadTest(void *buf, int start, int end) tmp = ((char *)buf)[i]; } } - static void LmsMallocTest(void) { printf("\n-------- LmsMallocTest Start --------\n"); @@ -388,7 +346,6 @@ static void LmsMallocTest(void) free(buf); printf("\n-------- LmsMallocTest End --------\n"); } - static void LmsFreeTest(void) { printf("\n-------- LmsFreeTest Start --------\n"); @@ -398,7 +355,6 @@ static void LmsFreeTest(void) free(buf); printf("\n-------- LmsFreeTest End --------\n"); } - int main(int argc, char * const * argv) { printf("\n############### Lms Test start ###############\n"); @@ -408,21 +364,20 @@ int main(int argc, char * const * argv) printf("\n############### Lms Test End ###############\n"); } ``` -### 用户态结果验证 -输出结果如下: -```c -***** Lite Memory Sanitizer Error Detected ***** + +### 用户态结果验证 + +输出结果如下: +``` +* Lite Memory Sanitizer Error Detected * Heap buffer overflow error detected! Illegal READ address at: [0x1f8b3edf] Shadow memory address: [0x3d34d3ed : 6] Shadow memory value: [2] - Accessable heap addr 0 Heap red zone 2 Heap freed buffer 3 - Dump info around address [0x1f8b3edf]: - [0x1f8b3eb8]: 74 55 8b 1f 74 55 8b 1f | [0x3d34d3eb | 4]: 0 0 [0x1f8b3ec0]: f8 9c 8b 1f 00 00 00 00 | [0x3d34d3ec | 0]: 0 0 [0x1f8b3ec8]: 00 00 00 00 9c fc fc fc | [0x3d34d3ec | 4]: 0 0 @@ -432,8 +387,7 @@ Dump info around address [0x1f8b3edf]: [0x1f8b3ee8]: 09 00 00 00 00 00 00 00 | [0x3d34d3ee | 4]: 0 0 [0x1f8b3ef0]: 00 00 00 00 08 03 09 00 | [0x3d34d3ef | 0]: 2 2 [0x1f8b3ef8]: 00 00 00 00 00 00 00 00 | [0x3d34d3ef | 4]: 2 2 -***** Lite Memory Sanitizer Error Detected End ***** - +* Lite Memory Sanitizer Error Detected End * Backtrace() returned 5 addresses #01: [0x4d6c] -> ./sample_usr_lms #02: <(null)+0x2004074>[0x4074] -> ./sample_usr_lms @@ -441,19 +395,14 @@ Backtrace() returned 5 addresses #04: [0x363c] -> ./sample_usr_lms #05: <(null)+0x1f856f30>[0x56f30] -> /lib/libc.so -------- LMS_malloc_test End -------- - -***** Lite Memory Sanitizer Error Detected ***** +* Lite Memory Sanitizer Error Detected * Use after free error detected! Illegal Double free address at: [0x1f8b3ee0] Shadow memory address: [0x3d34d3ee : 0] Shadow memory value: [3] - Accessable heap addr 0 Heap red zone 2 Heap freed buffer 3 - - Dump info around address [0x1f8b3ee0]: - [0x1f8b3ec0]: f8 9c 8b 1f 00 00 00 00 | [0x3d34d3ec | 0]: 0 0 [0x1f8b3ec8]: 00 00 00 00 fc fd fc fc | [0x3d34d3ec | 4]: 0 0 [0x1f8b3ed0]: 21 00 00 00 20 01 00 00 | [0x3d34d3ed | 0]: 0 0 @@ -463,15 +412,14 @@ Dump info around address [0x1f8b3ee0]: [0x1f8b3ef0]: 20 40 8b 1f 20 20 8b 1f | [0x3d34d3ef | 0]: 3 3 [0x1f8b3ef8]: 00 00 00 00 00 00 00 00 | [0x3d34d3ef | 4]: 3 3 [0x1f8b3f00]: 00 00 00 00 00 00 00 00 | [0x3d34d3f0 | 0]: 3 3 -***** Lite Memory Sanitizer Error Detected End ***** - +* Lite Memory Sanitizer Error Detected End * Backtrace() returned 5 addresses #01: [0x4d6c] -> ./sample_usr_lms #02: [0x5548] -> ./sample_usr_lms #03: <(null)+0x2003fc4>[0x3fc4] -> ./sample_usr_lms #04: [0x3664] -> ./sample_usr_lms #05: <(null)+0x1f856f30>[0x56f30] -> /lib/libc.so - -------- LMS_free_test End -------- ``` + 输出的Backtrace中包含地址所在的文件名,用户需查找对应文件中地址对应的代码行号。 diff --git a/zh-cn/device-dev/kernel/kernel-small-overview.md b/zh-cn/device-dev/kernel/kernel-small-overview.md index 8852458ea0..9071dd20c8 100644 --- a/zh-cn/device-dev/kernel/kernel-small-overview.md +++ b/zh-cn/device-dev/kernel/kernel-small-overview.md @@ -1,55 +1,60 @@ -# 内核概述 +# 内核概述 -- [简介](#section6614133913129) -- [内核架构](#section827143517385) +- [简介](#简介) +- [内核架构](#内核架构) -## 简介 +## 简介 -OpenHarmony 轻量级内核是基于IoT领域轻量级物联网操作系统Huawei LiteOS内核演进发展的新一代内核,包含LiteOS-M和LiteOS-A两类内核。LiteOS-M内核主要应用于轻量系统,面向的MCU一般是百K级内存,可支持MPU隔离,业界类似的内核有FreeRTOS或ThreadX等;LiteOS-A内核主要应用于小型系统,面向设备一般是M级内存,可支持MMU隔离,业界类似的内核有Zircon或Darwin等。本开发指南适用于LiteOS-A内核。 +OpenHarmony 轻量级内核是基于IoT领域轻量级物联网操作系统Huawei LiteOS内核演进发展的新一代内核,包含LiteOS-M和LiteOS-A两类内核。LiteOS-M内核主要应用于轻量系统,面向的MCU一般是百K级内存,可支持MPU隔离,业界类似的内核有FreeRTOS或ThreadX等;LiteOS-A内核主要应用于小型系统,面向设备一般是M级内存,可支持MMU隔离,业界类似的内核有Zircon或Darwin等。 + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> OpenHarmony针对不同量级的系统,分别使用了不同形态的内核,小型系统支持LiteOS和Linux,本开发指南适用于LiteOS-A内核,linux内核的相关操作请参考[Linux内核概述](../kernel/kernel-standard-overview.md)。 为适应IoT产业的高速发展,OpenHarmony 轻量级内核不断优化和扩展,能够带给应用开发者友好的开发体验和统一开放的生态系统能力。轻量级内核LiteOS-A重要的新特性如下: -- 新增了丰富的内核机制 +- 新增了丰富的内核机制 + 新增虚拟内存、系统调用、多核、轻量级IPC(Inter-Process Communication,进程间通信)、DAC(Discretionary Access Control,自主访问控制)等机制,丰富了内核能力;为了更好的兼容软件和开发者体验,新增支持多进程,使得应用之间内存隔离、相互不影响,提升系统的健壮性。 - 新增虚拟内存、系统调用、多核、轻量级IPC(Inter-Process Communication,进程间通信)、DAC(Discretionary Access Control,自主访问控制)等机制,丰富了内核能力;为了更好的兼容软件和开发者体验,新增支持多进程,使得应用之间内存隔离、相互不影响,提升系统的健壮性。 +- 引入统一驱动框架HDF(Hardware Driver Foundation) + 引入统一驱动框架HDF,统一驱动标准,为设备厂商提供了更统一的接入方式,使驱动更加容易移植,力求做到一次开发,多系统部署。 -- 引入统一驱动框架HDF(Hardware Driver Foundation) +- 支持1200+标准POSIX接口 + 更加全面的支持POSIX标准接口,使得应用软件易于开发和移植,给应用开发者提供了更友好的开发体验。 - 引入统一驱动框架HDF,统一驱动标准,为设备厂商提供了更统一的接入方式,使驱动更加容易移植,力求做到一次开发,多系统部署。 +- 内核和硬件高解耦 + 轻量级内核与硬件高度解耦,新增单板,内核代码不用修改。 -- 支持1200+标准POSIX接口 - 更加全面的支持POSIX标准接口,使得应用软件易于开发和移植,给应用开发者提供了更友好的开发体验。 +## 内核架构 -- 内核和硬件高解耦 +轻量级内核主要由基础内核、扩展组件、HDF框架、POSIX接口组成。轻量级内核的文件系统、网络协议等扩展功能(没有像微内核那样运行在用户态)运行在内核地址空间,主要考虑组件之间直接函数调用比进程间通信或远程过程调用要快得多。 - 轻量级内核与硬件高度解耦,新增单板,内核代码不用修改。 +**图1** OpenHarmony LiteOS-A内核架构图 +![zh-cn_image_0000001160018656](figures/zh-cn_image_0000001160018656.png) +- 基础内核主要包括内核的基础机制,如调度、内存管理、中断异常等 -## 内核架构 +- 扩展组件主要包括文件系统、网络协议和安全等扩展功能 -轻量级内核主要由基础内核、扩展组件、HDF框架、POSIX接口组成。轻量级内核的文件系统、网络协议等扩展功能(没有像微内核那样运行在用户态)运行在内核地址空间,主要考虑组件之间直接函数调用比进程间通信或远程过程调用要快得多。 +- HDF框架是外设驱动统一标准框架 -**图 1** OpenHarmony LiteOS-A内核架构图 +- POSIX接口是为兼容POSIX标准的应用方便移植到OpenHarmony +**基础内核** -![](figure/zh-cn_image_0000001191018697.png) +基础内核组件实现精简,主要包括内核的基础机制,如调度、内存管理、中断异常、内核通信等; -- 基础内核主要包括内核的基础机制,如调度、内存管理、中断异常等 -- 扩展组件主要包括文件系统、网络协议和安全等扩展功能 -- HDF框架是外设驱动统一标准框架 -- POSIX接口是为兼容POSIX标准的应用方便移植到OpenHarmony +- 进程管理:支持进程和线程,基于Task实现进程,进程独立4GiB地址空间 -**基础内核** +- 多核调度:支持任务和中断亲核性设置,支持绑核运行 -基础内核组件实现精简,主要包括内核的基础机制,如调度、内存管理、中断异常、内核通信等; +- 实时调度:支持高优先级抢占,同优先级时间片轮转 -- 进程管理:支持进程和线程,基于Task实现进程,进程独立4GiB地址空间 -- 多核调度:支持任务和中断亲核性设置,支持绑核运行 -- 实时调度:支持高优先级抢占,同优先级时间片轮转 -- 虚拟内存:支持缺页异常,内核空间静态映射到0-1GiB地址,用户空间映射到1-4GiB地址 -- 内核通信:事件、信号量、互斥锁、队列 -- 时间管理:软件定时器、系统时钟 +- 虚拟内存:内核空间静态映射到0-1GiB地址,用户空间映射到1-4GiB地址 + +- 内核通信:事件、信号量、互斥锁、队列 + +- 时间管理:软件定时器、系统时钟 **文件系统** @@ -57,41 +62,58 @@ OpenHarmony 轻量级内核是基于IoT领域轻量级物联网操作系统Huawe 主要特性有: -- 完整的POSIX接口支持 -- 文件级缓存\(pagecache) -- 磁盘级缓存(bcache) -- 目录缓存\(pathcache\) -- DAC能力 -- 支持嵌套挂载及文件系统堆叠等 -- 支持特性的裁剪和资源占用的灵活配置。 +- 完整的POSIX接口支持 + +- 文件级缓存(pagecache) + +- 磁盘级缓存(bcache) + +- 目录缓存(pathcache) + +- DAC能力 + +- 支持嵌套挂载及文件系统堆叠等 + +- 支持特性的裁剪和资源占用的灵活配置。 **网络协议** 轻量级内核网络协议基于开源LWIP构建,对LWIP的RAM占用进行优化,同时提高LWIP的传输性能。 -- 协议: IP、IPv6、 ICMP、 ND、MLD、 UDP、 TCP、IGMP、ARP、PPPoS、PPPoE -- API:socket API -- 扩展特性:多网络接口IP转发、TCP拥塞控制、RTT估计和快速恢复/快速重传 -- 应用程序:HTTP\(S\)服务、SNTP客户端、SMTP\(S\)客户端、ping工具、NetBIOS名称服务、mDNS响应程序、MQTT客户端、TFTP服务、DHCP客户端、DNS客户端、AutoIP/APIPA(零配置)、SNMP代理 +- 协议: IP、IPv6、 ICMP、 ND、MLD、 UDP、 TCP、IGMP、ARP、PPPoS、PPPoE + +- API:socket API + +- 扩展特性:多网络接口IP转发、TCP拥塞控制、RTT估计和快速恢复/快速重传 + +- 应用程序:HTTP(S)服务、SNTP客户端、SMTP(S)客户端、ping工具、NetBIOS名称服务、mDNS响应程序、MQTT客户端、TFTP服务、DHCP客户端、DNS客户端、AutoIP/APIPA(零配置)、SNMP代理 **HDF框架** 轻量级内核集成HDF框架,HDF框架旨在为开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。 -- 支持多内核平台 -- 支持用户态驱动 -- 可配置组件化驱动模型 -- 基于消息的驱动接口模型 -- 基于对象的驱动、设备管理 -- HDI(Hardware Driver Interface)统一硬件接口 -- 支持电源管理、PnP +- 支持多内核平台 + +- 支持用户态驱动 + +- 可配置组件化驱动模型 + +- 基于消息的驱动接口模型 + +- 基于对象的驱动、设备管理 + +- HDI(Hardware Driver Interface)统一硬件接口 + +- 支持电源管理、PnP **扩展组件** 对内核功能进行扩展,可选但很重要的机制。 -- 动态链接:支持标准ELF链接执行、加载地址随机化 -- 进程通信:支持轻量级LiteIPC,同时也支持标准的Mqueue、Pipe、Fifo、Signal等机制 -- 系统调用:支持170+系统调用,同时有支持VDSO机制 -- 权限管理:支持进程粒度的特权划分和管控,UGO三种权限配置 +- 动态链接:支持标准ELF链接执行、加载地址随机化 + +- 进程通信:支持轻量级LiteIPC,同时也支持标准的Mqueue、Pipe、Fifo、Signal等机制 + +- 系统调用:支持170+系统调用,同时有支持VDSO机制 +- 权限管理:支持进程粒度的特权划分和管控,UGO三种权限配置 diff --git a/zh-cn/device-dev/kernel/kernel-small-start-kernel.md b/zh-cn/device-dev/kernel/kernel-small-start-kernel.md index 484ecce12e..9a104780cb 100644 --- a/zh-cn/device-dev/kernel/kernel-small-start-kernel.md +++ b/zh-cn/device-dev/kernel/kernel-small-start-kernel.md @@ -1,106 +1,45 @@ -# 内核态启动 +# 内核态启动 -- [内核启动流程](#section9882154318299) -- [编程样例](#section19145114703217) - - [实例描述](#section1045483642518) +- [内核启动流程](#内核启动流程) +- [编程样例](#编程样例) + - [实例描述](#实例描述) - -## 内核启动流程 +## 内核启动流程 内核启动流程包含汇编启动阶段和C语言启动阶段2部分,如图1所示。汇编启动阶段完成CPU初始设置,关闭dcache/icache,使能FPU及neon,设置MMU建立虚实地址映射,设置系统栈,清理bss段,调用C语言main函数等。C语言启动阶段包含OsMain函数及开始调度等,其中如上图所示,OsMain函数用于内核基础初始化和架构、板级初始化等,其整体由内核启动框架主导初始化流程,图中右边区域为启动框架中可接受外部模块注册启动的阶段,各个阶段的说明如下表1所示。 -**图 1** 内核启动流程图 - - -![](figure/zh-cn_image_0000001178856385.png) - -**表 1** 启动框架层级 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

层级

-

说明

-

LOS_INIT_LEVEL_EARLIEST

-

最早期初始化

-

说明:不依赖架构,单板以及后续模块会对其有依赖的纯软件模块初始化

-

例如:Trace模块

-

LOS_INIT_LEVEL_ARCH_EARLY

-

架构早期初始化

-

说明:架构相关,后续模块会对其有依赖的模块初始化,如启动过程中非必需的功能,建议放到LOS_INIT_LEVEL_ARCH层

-

LOS_INIT_LEVEL_PLATFORM_EARLY

-

平台早期初始化

-

说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化,如启动过程中必需的功能,建议放到LOS_INIT_LEVEL_PLATFORM层

-

例如:uart模块

-

LOS_INIT_LEVEL_KMOD_PREVM

-

内存初始化前的内核模块初始化

-

说明:在内存初始化之前需要使能的模块初始化

-

LOS_INIT_LEVEL_VM_COMPLETE

-

基础内存就绪后的初始化

-

说明:此时内存初始化完毕,需要进行使能且不依赖进程间通讯机制与系统进程的模块初始化

-

例如:共享内存功能

-

LOS_INIT_LEVEL_ARCH

-

架构后期初始化

-

说明:架构拓展功能相关,后续模块会对其有依赖的模块初始化

-

LOS_INIT_LEVEL_PLATFORM

-

平台后期初始化

-

说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化

-

例如:驱动内核抽象层初始化(mmc、mtd)

-

LOS_INIT_LEVEL_KMOD_BASIC

-

内核基础模块初始化

-

说明:内核可拆卸的基础模块初始化

-

例如:VFS初始化

-

LOS_INIT_LEVEL_KMOD_EXTENDED

-

内核扩展模块初始化

-

说明:内核可拆卸的扩展模块初始化

-

例如:系统调用初始化、ProcFS初始化、Futex初始化、HiLog初始化、HiEvent初始化、LiteIPC初始化

-

LOS_INIT_LEVEL_KMOD_TASK

-

内核任务创建

-

说明:进行内核任务的创建(内核任务,软件定时器任务)

-

例如:资源回收系统常驻任务的创建、SystemInit任务创建、CPU占用率统计任务创建

-
- -## 编程样例 - -### 实例描述 + +**图1** 内核启动流程图 +![zh-cn_image_0000001153832492](figures/zh-cn_image_0000001153832492.png) + + +**表1** 启动框架层级 + +| 层级 | 说明 | +| -------- | -------- | +| LOS_INIT_LEVEL_EARLIEST | 最早期初始化
说明:不依赖架构,单板以及后续模块会对其有依赖的纯软件模块初始化
例如:Trace模块 | +| LOS_INIT_LEVEL_ARCH_EARLY | 架构早期初始化
说明:架构相关,后续模块会对其有依赖的模块初始化,如启动过程中非必需的功能,建议放到LOS_INIT_LEVEL_ARCH层 | +| LOS_INIT_LEVEL_PLATFORM_EARLY | 平台早期初始化
说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化,如启动过程中必需的功能,建议放到LOS_INIT_LEVEL_PLATFORM层
例如:uart模块 | +| LOS_INIT_LEVEL_KMOD_PREVM | 内存初始化前的内核模块初始化
说明:在内存初始化之前需要使能的模块初始化 | +| LOS_INIT_LEVEL_VM_COMPLETE | 基础内存就绪后的初始化
说明:此时内存初始化完毕,需要进行使能且不依赖进程间通讯机制与系统进程的模块初始化
例如:共享内存功能 | +| LOS_INIT_LEVEL_ARCH | 架构后期初始化
说明:架构拓展功能相关,后续模块会对其有依赖的模块初始化 | +| LOS_INIT_LEVEL_PLATFORM | 平台后期初始化
说明:单板平台、驱动相关,后续模块会对其有依赖的模块初始化
例如:驱动内核抽象层初始化(mmc、mtd) | +| LOS_INIT_LEVEL_KMOD_BASIC | 内核基础模块初始化
说明:内核可拆卸的基础模块初始化
例如:VFS初始化 | +| LOS_INIT_LEVEL_KMOD_EXTENDED | 内核扩展模块初始化
说明:内核可拆卸的扩展模块初始化
例如:系统调用初始化、ProcFS初始化、Futex初始化、HiLog初始化、HiEvent初始化、LiteIPC初始化 | +| LOS_INIT_LEVEL_KMOD_TASK | 内核任务创建
说明:进行内核任务的创建(内核任务,软件定时器任务)
例如:资源回收系统常驻任务的创建、SystemInit任务创建、CPU占用率统计任务创建 | + + +## 编程样例 + + +### 实例描述 新增一个内核模块,需要在内核初始化时进行该模块的初始化,则通过内核启动框架将该模块的初始化函数注册进内核启动流程中。 + **示例代码** + ``` /* 内核启动框架头文件 */ #include "los_init.h" @@ -117,8 +56,10 @@ unsigned int OsSampleModInit(void) LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED); ``` + **结果验证** + ``` main core booting up... OsSampleModInit SUCCESS! @@ -127,9 +68,11 @@ cpu 1 entering scheduler cpu 0 entering scheduler ``` + 根据上述系统启动阶段的打印可知,内核在启动时进行了该注册模块的初始化函数调用,完成该模块的初始化操作。 ->![](../public_sys-resources/icon-note.gif) **说明:** ->启动框架中同一层级内的注册模块不能有依赖关系,建议新增模块按照上述启动阶段进行模块初始化的拆分,按需注册启动。 ->可通过查看系统编译生成文件OHOS\_Image.map中.rodata.init.kernel.\*段内的符号表来了解当前已注册进内核启动框架中的各个模块初始化入口,以及检查新注册的模块初始化入口是否生效。 +> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** +> 启动框架中同一层级内的注册模块不能有依赖关系,建议新增模块按照上述启动阶段进行模块初始化的拆分,按需注册启动。 +> +> 可通过查看系统编译生成文件OHOS_Image.map中.rodata.init.kernel.\*段内的符号表来了解当前已注册进内核启动框架中的各个模块初始化入口,以及检查新注册的模块初始化入口是否生效。 diff --git a/zh-cn/device-dev/kernel/kernel-small-start-user.md b/zh-cn/device-dev/kernel/kernel-small-start-user.md index 70b9e4d536..589d026666 100644 --- a/zh-cn/device-dev/kernel/kernel-small-start-user.md +++ b/zh-cn/device-dev/kernel/kernel-small-start-user.md @@ -1,19 +1,19 @@ -# 用户态启动 +# 用户态启动 -- [用户态根进程启动](#section79911135647) - - [根进程的启动过程](#section1184317581349) - - [根进程的职责](#section1590220321759) +- [用户态根进程启动](#用户态根进程启动) + - [根进程的启动过程](#根进程的启动过程) + - [根进程的职责](#根进程的职责) +- [用户态程序运行](#用户态程序运行) -- [用户态程序运行](#section194576310611) - -## 用户态根进程启动 +## 用户态根进程启动 根进程是系统第一个用户态进程,进程ID为1,它是所有用户态进程的祖先。 -**图 1** 进程树示意图 -![](figure/进程树示意图.png "进程树示意图") +**图1** 进程树示意图 +![zh-cn_image_0000001178108019](figures/zh-cn_image_0000001178108019.png) + -### 根进程的启动过程 +### 根进程的启动过程 使用链接脚本将如下init启动代码放置到系统镜像指定位置。 @@ -31,52 +31,44 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) 系统启动阶段,OsUserInitProcess启动init进程。具体过程如下: -1. 由内核OsLoadUserInit加载上述代码。 -2. 创建新的进程空间,启动/bin/init进程。 +1. 由内核OsLoadUserInit加载上述代码。 -### 根进程的职责 +2. 创建新的进程空间,启动/bin/init进程。 -- 启动关键系统程序或服务,如交互进程shell。 - >![](../public_sys-resources/icon-note.gif) **说明:** - >在OpenHarmony 中**init**进程通过读取/etc/init.cfg,根据配置执行指定命令,或启动指定进程(详见:[init启动引导](../subsystems/subsys-boot-init.md))。 +### 根进程的职责 +- 启动关键系统程序或服务,如交互进程shell。 + > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** + > 在OpenHarmony 中**init**进程通过读取/etc/init.cfg,根据配置执行指定命令,或启动指定进程(详见:[init启动引导](../subsystems/subsys-boot.md) 。 -- 监控回收孤儿进程,清理子进程中的僵尸进程。 +- 监控回收孤儿进程,清理子进程中的僵尸进程。 -## 用户态程序运行 +## 用户态程序运行 用户态程序常见编译方式有如下两种: +1. [利用框架编译用户态进程](../quick-start/quickstart-standard-running-rk3568-create.md)。 -1. [利用框架编译用户态进程](../quick-start/quickstart-standard-running-hi3516-create.md)。 -2. 手动编译 - - 实例: - - ``` - clang --target=arm-liteos --sysroot=prebuilts/lite/sysroot -o helloworld helloworld.c - ``` - - **clang**:参考[LLVM安装指导](../quick-start/quickstart-lite-package-environment.md)安装LLVM编译器。 +2. 手动编译 + 实例: + ``` + clang --target=arm-liteos --sysroot=prebuilts/lite/sysroot -o helloworld helloworld.c + ``` - **--target**:--target=arm-liteos,指定编译平台为arm-liteos。 + **clang**:参考[LLVM安装指导](../quick-start/quickstart-lite-package-environment.md#安装llvm-仅openharmony_v1-x分支-标签需要-)安装LLVM编译器。 - **--sysroot**:--sysroot=$\{YOUR\_ROOT\_PATH\}/prebuilts/lite/sysroot,指定头文件以及依赖标准库搜索路径为prebuilts下的指定路径。 + **--target**:--target=arm-liteos,指定编译平台为arm-liteos。 + **--sysroot**:--sysroot=${YOUR_ROOT_PATH}/prebuilts/lite/sysroot,指定头文件以及依赖标准库搜索路径为prebuilts下的指定路径。 用户态程序启动有如下常见方式: -- shell命令启动进程。 - - ``` - OHOS $ exec helloworld - OHOS $ ./helloworld - OHOS $ /bin/helloworld - ``` - - -- 通过POSIX接口启动新进程。 - - Fork方法创建一个新的进程,exec类接口执行一个全新的进程。 - +- shell命令启动进程。 + ``` + OHOS $ exec helloworld + OHOS $ ./helloworld + OHOS $ /bin/helloworld + ``` +- 通过POSIX接口启动新进程。 + Fork方法创建一个新的进程,exec类接口执行一个全新的进程。 diff --git a/zh-cn/device-dev/kernel/kernel-small-start.md b/zh-cn/device-dev/kernel/kernel-small-start.md index ec3766d391..486973ced4 100644 --- a/zh-cn/device-dev/kernel/kernel-small-start.md +++ b/zh-cn/device-dev/kernel/kernel-small-start.md @@ -1,7 +1,6 @@ -# 内核启动 +# 内核启动 -- **[内核态启动](kernel-small-start-kernel.md)** - -- **[用户态启动](kernel-small-start-user.md)** +- **[内核态启动](kernel-small-start-kernel.md)** +- **[用户态启动](kernel-small-start-user.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-small.md b/zh-cn/device-dev/kernel/kernel-small.md index ae83891e29..de47769b00 100644 --- a/zh-cn/device-dev/kernel/kernel-small.md +++ b/zh-cn/device-dev/kernel/kernel-small.md @@ -1,15 +1,14 @@ -# 小型系统内核 +# 小型系统内核 -- **[内核概述](kernel-small-overview.md)** -- **[内核启动](kernel-small-start.md)** +- **[内核概述](kernel-small-overview.md)** -- **[基础内核](kernel-small-basics.md)** +- **[内核启动](kernel-small-start.md)** -- **[扩展组件](kernel-small-bundles.md)** +- **[基础内核](kernel-small-basics.md)** -- **[调测与工具](kernel-small-debug.md)** - -- **[附录](kernel-small-apx.md)** +- **[扩展组件](kernel-small-bundles.md)** +- **[调测与工具](kernel-small-debug.md)** +- **[附录](kernel-small-apx.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/kernel-standard-build.md b/zh-cn/device-dev/kernel/kernel-standard-build.md index f83572008e..84a64a60f8 100644 --- a/zh-cn/device-dev/kernel/kernel-standard-build.md +++ b/zh-cn/device-dev/kernel/kernel-standard-build.md @@ -1,12 +1,17 @@ -# Linux内核编译与构建指导 +# Linux内核编译与构建指导 + +- [开发示例1](#开发示例1) + +## 开发示例1 + +以hi3516dv300开源开发板+ubuntu x86主机开发环境为例。 -以hi3516dv300开源开发板+ubuntu x86主机开发环境为例 使用工程的全量编译命令,编译生成uImage内核镜像 + ``` ./build.sh --product-name Hi3516DV300 # 编译hi3516dv300镜像 --build-target build_kernel # 编译hi3516dv300的uImage内核镜像 --gn-args linux_kernel_version=\"linux-5.10\" # 编译指定内核版本 ``` - diff --git a/zh-cn/device-dev/kernel/kernel-standard-overview.md b/zh-cn/device-dev/kernel/kernel-standard-overview.md index 7df3f0bfb5..50361707d3 100644 --- a/zh-cn/device-dev/kernel/kernel-standard-overview.md +++ b/zh-cn/device-dev/kernel/kernel-standard-overview.md @@ -1,18 +1,18 @@ -# Linux内核概述 +# Linux内核概述 -- [Linux内核版本](#section152847516485) -- [OpenHarmony内核版本选择](#section2716416191715) +标准系统类设备(参考内存≥128MiB),OpenHarmony选择Linux内核作为基础内核,可以对不同资源受限的设备产品配置出适合的OS内核,为上层提供基础的操作系统能力。 -面向标准系统类设备(参考内存≥128MiB),OpenHarmony选择Linux内核作为基础内核,可以对不同资源受限的设备产品配置出适合的OS内核,为上层提供基础的操作系统能力。 -## Linux内核版本 +## Linux内核版本 -Linux内核版本分为稳定版本以及长期支持LTS\(long term support\)版本。 +Linux内核版本分为稳定版本以及长期支持LTS(long term support)版本。 稳定版本大约每三个月发布一个新版本,包含最新硬件支持、性能改进以及bug修复等。其缺点是整体维护生命周期较短,产品软件不能得到长期稳定的支持。 + LTS为长期支持版本,“长期支持”体现在对该版本内核的长期维护(对bug和安全方面的修复),一般维护周期达到6年之久。相较于维护周期从6个月到2年不等非LTS内核版本,对一款商用产品来说并不能覆盖其产品完整的生命周期,很有可能会使产品暴露于安全漏洞的风险之中。且LTS版本更新不会包含新的特性升级,保证了版本的稳定,这对追求稳定以及安全的商用产品来说LTS版本更为适合。 -## OpenHarmony内核版本选择 -OpenHarmony中Linux内核从LTS版本中选择合适的版本作为内核的基础版本,目前已完成对Linux-4.19及Linux-5.10的适配及支持。 +## OpenHarmony内核版本选择 + +OpenHarmony 中Linux内核从LTS版本中选择合适的版本作为内核的基础版本,目前已完成对Linux-4.19及Linux-5.10的适配及支持。 diff --git a/zh-cn/device-dev/kernel/kernel-standard-patch.md b/zh-cn/device-dev/kernel/kernel-standard-patch.md index 4ec8244dcb..8f9e30ec2f 100644 --- a/zh-cn/device-dev/kernel/kernel-standard-patch.md +++ b/zh-cn/device-dev/kernel/kernel-standard-patch.md @@ -1,35 +1,28 @@ -# OpenHarmony开发板Patch使用指导 +# OpenHarmony开发板Patch使用指导 1. 合入HDF补丁 - - 在kernel/linux/build仓中,按照kernel.mk中HDF的补丁合入方法,合入不同内核版本对应的HDF内核补丁: - - ``` - $(OHOS_BUILD_HOME)/drivers/adapter/khdf/linux/patch_hdf.sh $(OHOS_BUILD_HOME) $(KERNEL_SRC_TMP_PATH) $(HDF_PATCH_FILE) - ``` + 在kernel/linux/build仓中,按照kernel.mk中HDF的补丁合入方法,合入不同内核版本对应的HDF内核补丁: + ``` + $(OHOS_BUILD_HOME)/drivers/adapter/khdf/linux/patch_hdf.sh $(OHOS_BUILD_HOME) $(KERNEL_SRC_TMP_PATH) $(HDF_PATCH_FILE) + ``` 2. 合入芯片平台驱动补丁 + 以Hi3516DV300为例: - 以Hi3516DV300为例: - - 在kernel/linux/build仓中,按照kernel.mk中的芯片组件所对应的patch路径规则及命名规则,将对应的芯片组件patch放到对应路径下: - - ``` - DEVICE_PATCH_DIR := $(OHOS_BUILD_HOME)/kernel/linux/patches/${KERNEL_VERSION}/$(DEVICE_NAME)_patch - DEVICE_PATCH_FILE := $(DEVICE_PATCH_DIR)/$(DEVICE_NAME).patch - ``` + 在kernel/linux/build仓中,按照kernel.mk中的芯片组件所对应的patch路径规则及命名规则,将对应的芯片组件patch放到对应路径下: + ``` + DEVICE_PATCH_DIR := $(OHOS_BUILD_HOME)/kernel/linux/patches/${KERNEL_VERSION}/$(DEVICE_NAME)_patch + DEVICE_PATCH_FILE := $(DEVICE_PATCH_DIR)/$(DEVICE_NAME).patch + ``` 3. 修改自己所需要编译的config + 在kernel/linux/build仓中,按照kernel.mk中的芯片组件所对应的patch路径规则及命名规则,将对应的芯片组件config放到对应路径下: + ``` + KERNEL_CONFIG_PATH := $(OHOS_BUILD_HOME)/kernel/linux/config/${KERNEL_VERSION} + DEFCONFIG_FILE := $(DEVICE_NAME)_$(BUILD_TYPE)_defconfig + ``` - 在kernel/linux/build仓中,按照kernel.mk中的芯片组件所对应的patch路径规则及命名规则,将对应的芯片组件config放到对应路径下: - - ``` - KERNEL_CONFIG_PATH := $(OHOS_BUILD_HOME)/kernel/linux/config/${KERNEL_VERSION} - DEFCONFIG_FILE := $(DEVICE_NAME)_$(BUILD_TYPE)_defconfig - ``` - - > **须知:** - > - >由于OpenHarmony工程的编译构建流程中会拷贝kernel/linux/linux-\*\.\*的代码环境后进行打补丁动作,在使用OpenHarmony的版本级编译命令前,需要kernel/linux/linux-\*\.\*原代码环境。 - > - >根据不同系统工程,编译完成后会在out目录下的kernel目录中生成对应实际编译的内核,基于此目录的内核,进行对应的config修改,将最后生成的\.config文件cp到config仓对应的路径文件里,即可生效。 + > ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** + > 由于OpenHarmony工程的编译构建流程中会拷贝kernel/linux/linux-\*.\*的代码环境后进行打补丁动作,在使用OpenHarmony的版本级编译命令前,需要kernel/linux/linux-\*.\*原代码环境。 + > + > 根据不同系统工程,编译完成后会在out目录下的kernel目录中生成对应实际编译的内核,基于此目录的内核,进行对应的config修改,将最后生成的.config文件cp到config仓对应的路径文件里,即可生效。 diff --git a/zh-cn/device-dev/kernel/kernel-standard.md b/zh-cn/device-dev/kernel/kernel-standard.md index abe3b66da4..d642451274 100644 --- a/zh-cn/device-dev/kernel/kernel-standard.md +++ b/zh-cn/device-dev/kernel/kernel-standard.md @@ -1,9 +1,9 @@ -# 标准系统内核 +# 标准系统内核 -- **[Linux内核概述](kernel-standard-overview.md)** -- **[OpenHarmony开发板Patch使用指导](kernel-standard-patch.md)** +- **[Linux内核概述](kernel-standard-overview.md)** -- **[Linux内核编译与构建指导](kernel-standard-build.md)** +- **[开发板Patch使用指导](kernel-standard-patch.md)** +- **[Linux内核编译与构建指导](kernel-standard-build.md)** diff --git a/zh-cn/device-dev/kernel/kernel.md b/zh-cn/device-dev/kernel/kernel.md index 46e7da1143..17047169bf 100644 --- a/zh-cn/device-dev/kernel/kernel.md +++ b/zh-cn/device-dev/kernel/kernel.md @@ -1,9 +1,8 @@ -# 内核 +# 内核 -- **[轻量系统内核](kernel-mini.md)** -- **[小型系统内核](kernel-small.md)** - -- **[标准系统内核](kernel-standard.md)** +- **[轻量系统内核](kernel-mini.md)** +- **[小型系统内核](kernel-small.md)** +- **[标准系统内核](kernel-standard.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-caution.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-danger.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 GIT binary patch literal 580 zcmV-K0=xZ3Nk%w1VIu$?0Hp~4{QBgqmQ+MG9K51r{QB&)np^||1PlfQ%(86!{`~yv zv{XhUWKt}AZaiE{EOcHp{O-j3`t;<+eEiycJT4p@77X;(jQsMfB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-note.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda GIT binary patch literal 394 zcmZ?wbhEHblx7fPSjxcg=ii?@_wH=jwxy=7CMGH-B`L+l$wfv=#>UF#$gv|VY%C^b zCQFtrnKN(Bo_%|sJbO}7RAORe!otL&qo<>yq_Sq+8Xqqo5h0P3w3Lvb5E(g{p01vl zxR@)KuDH0l^z`+-dH3eaw=XqSH7aTIx{kzVBN;X&hha0dQSgWuiw0NWUvMRmkD|> literal 0 HcmV?d00001 diff --git a/zh-cn/device-dev/kernel/public_sys-resources/icon-notice.gif b/zh-cn/device-dev/kernel/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 GIT binary patch literal 406 zcmV;H0crk6Nk%w1VIu$@0J8u9|NsB@_xJDb@8;&_*4Ea}&d#;9wWXz{jEszHYim+c zQaU<1At50E0000000000A^8Le000gEEC2ui03!e%000R7038S%NU)&51O^i-Tu6`s z0)`MFE@;3YqD6xSC^kTNu_J>91{PH8XfZ(p1pp2-SU@u3#{mEUC}_}tg3+I#{z}{Ok@D_ZUDg- zt0stin4;pC8M{WLSlRH*1pzqEw1}3oOskyNN?j;7HD{BBZ*OEcv4HK!6Bk6beR+04 z&8}k>SkTusVTDmkyOz#5fCA$JTPGJVQvr3uZ?QzzPQFvD0rGf_PdrcF`pMs}p^BcF zKtKTd`0wipR%nKN&Wj+V}pX;WC3SdJV!a_8Qi zE7z`U*|Y^H0^}fB$R?oG%6hQ z+MMLZbQBH@)Vg&1^3?qHb(5!%>3r0+`eq=&V&E}0Dypi0000000000 z00000A^8LW000R9EC2ui03!e$000L5z=Uu}ED8YtqjJd<+B}(9bIOb$3-31_h|V>=0A{ z1Hh0#H30>fNT})^fRU_83uewx9oRr{f{Sx1Ml`t)EQ zGkHZ67&~y{W5Jpq4H_WfuLxp*3<7O}GEl;1ESe36fLNs=B0&LQM1Buf(R)qg(BRd`t1OPjI1m_q4 literal 0 HcmV?d00001 -- GitLab

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 EALft9X#fBK diff --git a/en/device-dev/kernel/figure/kernel-architecture.png b/en/device-dev/kernel/figure/kernel-architecture.png deleted file mode 100644 index 22880de59d064ae9ce1451c0475dd950280ea087..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26242 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 YDpV|HjDGiFAG0tuvb;$)`0bDX3)(GcRR910 diff --git a/en/device-dev/kernel/figure/no-out-of-bounds-memory-access.png b/en/device-dev/kernel/figure/no-out-of-bounds-memory-access.png deleted file mode 100644 index ea030c6de270bdc55c4d6e43c8ce332dd5a9231b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2156 zcmV-y2$T1TP)$$+9ec zwgsqN*L6n!)CTGU>H`%YP~%jLqX4Rti28sA$Pa*IKbm=&%_pcy0%=JRwm=5ld==acz3c-q^^Ui&^CoI(9>b9w^ZoxFZ>Cx6#T6(oMw{?G0o&#zx+Iu2r38N46e zsv-pB#S~W(0zb=I`S%*df|Ub?kJH7(E1Am5!tdFqX*SC;n`xvR!D5zWf_;2%21}>w ziH}w(30{ydn7 zAc69^O+4o42ol${k8=5(`DeGCnRo@mbUj`Z5PI*{Uml;6*aR`>Fq#6Llc?dzNZ4{T zCN42ZAvoieL}dnU;!jp0XlUf;>!3$xR|=K(8&?wcJqePVu8O!#Jt_d~^MN0DxE+XCw3*{0mdd&MLx_4)V2$5>k)DiouQn9MlKY2dX|$CB8ZWs{T5Qs}J1n0}2v4i>ME%4^(}iN>miS z9fj3~YQtCe0R@SN&m#DAS*09a9`r_bNWWD3?5C>iAXtG96|8H|NPCc%fhF zP=bMOp9K^oZnxn*z*QOtiGB|qo<+vff&?k{$O=u*G61O_k9IyQUsn<$*h}Le(bI8# z<=+L6z!wC;o^`cjH)2fW>*OWB>F3ZLaO^7km#}20o7a>+$YoyP3SAd#l#;D zxwrcGT9w}#pZ9!locwFgwgc%Kh1b?|sDPahBCRJ;u@SwcS*oXz`F6za^IONyJE)zd zrqN7u@B#K8n6=shK6UzjNc4w#8+@+>0ur6&q({#;j-g&iRF8!27xb&f59Lj&@k!%a zi65))0Ct}Z>B?V2qwOmz3ID0``t=|+I7T%IHck<(3S@q(NW>F6to`2LhI$Uz(apIB z39Tm)+Z^o_*`FL5>uE%v)jNkIItF;eUwAFt-a{XsMH5h2C)7_mAI1sf65z%4IxN2g z0unt12mWpOpdLxiepUUX_>t)8w?Et0@}u$b`t1M-DzY+|KB|@k1DF_)8+C(6oe=oR zphb}IM!>dlIfQM)b<%;0##Eh10Ho{_)5o(NO&s5(9g-92NA|15PYeA@|B2cU`q`pI zz7P|{l)s^;W#H_~t5JzJ+-}f4h)x-&5cw-0VT~M?pleNsoKr&Q?gkRKwl6tXjt>2B z&fD1koTIY-d+SL^`q?(am~U2<+6oNa>N8ka}vHPbYfA;AHIpFsB^(qrP z32iq!oydP{`yqf(a2Ns8^V>qz?3 z_6KBV^cO)OH%=}3SUzbcZ_v-TRgAwPUGU#bPAOi=h-2UolxipNr^jU_-Cz((N6UOd zxfcGMF@49$0dJ}2kPS{AU>tmK9t4?N+qeAHdJhQ*f*z!MwSA^n6>Cb(P{D#K|j(c=pw`-hJEAF`&OiDo^(F=UmzrcSt_9MBJi}C!a zep38MboP%mr&p*)!t}KL#QvEva*FqmnWak3rT+$H2Qf42xARjaXTP+rX2(NO*=PoU z;38cz9olBc8$e>49lo~xG`kGhb!?vp1p48Ec+0=mv#>l{`U(P8egKJhYglk>)?+=^ zo^G%VKS@O6#^}B=&QZB-(j0ld%7X% zm(tVtljv3d_5MT2W*2+Ao^C*gb4Gw`oBb%zT4pT0r`^_n&sIBU^56Es+$8YZI^DPZ zYn=8)2l2iJ+pbhp{(Wph!ImZ)U%|Et5)MS%HpBhzh`%?(T?3?g@1OGz1qpTfKj-wX iFngKp6QDOyDjTZM*HT~6tU=UI%HQ4Cm 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