# æ ‡å‡†åº“æ”¯æŒ ## CMSISæ”¯æŒ ### 基本概念 [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** å†…æ ¸ä¿¡æ¯ä¸ŽæŽ§åˆ¶ | 接å£å | 接å£æè¿° | | -------- | -------- | | 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å†…æ ¸æ»´ç”频率。 | **表2** çº¿ç¨‹ç®¡ç† | 接å£å | 接å£æè¿° | | -------- | -------- | | osThreadDetach | 分离线程(线程终æ¢æ—¶å¯ä»¥å›žæ”¶çº¿ç¨‹å˜å‚¨ï¼‰ã€‚(暂未实现) | | osThreadEnumerate | 枚举活动线程。(暂未实现) | | osThreadExit | 终æ¢å½“å‰æ£åœ¨è¿è¡Œçš„线程的执行。 | | osThreadGetCount | 获å–活动线程的数é‡ã€‚ | | osThreadGetId | 返回当å‰æ£åœ¨è¿è¡Œçš„线程的线程ID。 | | osThreadGetName | 获å–线程的å称。 | | osThreadGetPriority | 获å–线程的当å‰ä¼˜å…ˆçº§ã€‚ | | osThreadGetStackSize | 获å–çº¿ç¨‹çš„å †æ ˆå¤§å°ã€‚ | | osThreadGetStackSpace | æ ¹æ®æ‰§è¡ŒæœŸé—´çš„å †æ ˆæ°´å°è®°å½•èŽ·å–线程的å¯ç”¨å †æ ˆç©ºé—´ã€‚ | | osThreadGetState | 获å–线程的当å‰çº¿ç¨‹çŠ¶æ€ã€‚ | | osThreadJoin | ç‰å¾…指定线程终æ¢ã€‚(暂未实现) | | osThreadNew | åˆ›å»ºä¸€ä¸ªçº¿ç¨‹å¹¶å°†å…¶æ·»åŠ åˆ°æ´»åŠ¨çº¿ç¨‹ä¸ã€‚ | | osThreadResume | æ¢å¤çº¿ç¨‹çš„执行。 | | osThreadSetPriority | 更改线程的优先级。 | | osThreadSuspend | æš‚åœæ‰§è¡Œçº¿ç¨‹ã€‚ | | osThreadTerminate | 终æ¢çº¿ç¨‹çš„执行。 | | osThreadYield | 将控制æƒä¼ 递给处于就绪状æ€çš„下一个线程。 | **表3** çº¿ç¨‹æ ‡å¿— | 接å£å | 接å£æè¿° | | -------- | -------- | | osThreadFlagsSet | è®¾ç½®çº¿ç¨‹çš„æŒ‡å®šçº¿ç¨‹æ ‡å¿—ã€‚ï¼ˆæš‚æœªå®žçŽ°ï¼‰ | | osThreadFlagsClear | 清除当å‰æ£åœ¨è¿è¡Œçš„çº¿ç¨‹çš„æŒ‡å®šçº¿ç¨‹æ ‡å¿—ã€‚ï¼ˆæš‚æœªå®žçŽ°ï¼‰ | | osThreadFlagsGet | 获å–当å‰æ£åœ¨è¿è¡Œçš„线程的当å‰çº¿ç¨‹æ ‡å¿—。(暂未实现) | | osThreadFlagsWait | ç‰å¾…当å‰æ£åœ¨è¿è¡Œçš„çº¿ç¨‹çš„ä¸€ä¸ªæˆ–å¤šä¸ªçº¿ç¨‹æ ‡å¿—å‘出信å·ã€‚(暂未实现) | **表4** äº‹ä»¶æ ‡å¿— | 接å£å | 接å£æè¿° | | -------- | -------- | | osEventFlagsGetName | 获å–äº‹ä»¶æ ‡å¿—å¯¹è±¡çš„å称。(暂未实现) | | osEventFlagsNew | 创建并åˆå§‹åŒ–äº‹ä»¶æ ‡å¿—å¯¹è±¡ã€‚ | | osEventFlagsDelete | åˆ é™¤äº‹ä»¶æ ‡å¿—å¯¹è±¡ã€‚ | | osEventFlagsSet | è®¾ç½®æŒ‡å®šçš„äº‹ä»¶æ ‡å¿—ã€‚ | | osEventFlagsClear | æ¸…é™¤æŒ‡å®šçš„äº‹ä»¶æ ‡å¿—ã€‚ | | osEventFlagsGet | 获å–当å‰äº‹ä»¶æ ‡å¿—。 | | osEventFlagsWait | ç‰å¾…ä¸€ä¸ªæˆ–å¤šä¸ªäº‹ä»¶æ ‡å¿—è¢«å‘出信å·ã€‚ | **表5** 通用ç‰å¾…函数 | 接å£å | 接å£æè¿° | | -------- | -------- | | osDelay | ç‰å¾…超时(时间延迟)。 | | osDelayUntil | ç‰åˆ°æŒ‡å®šæ—¶é—´ã€‚ | **表6** è®¡æ—¶å™¨ç®¡ç† | 接å£å | 接å£æè¿° | | -------- | -------- | | osTimerDelete | åˆ é™¤è®¡æ—¶å™¨ã€‚ | | osTimerGetName | 获å–计时器的å称。(暂未实现) | | osTimerIsRunning | 检查计时器是å¦æ£åœ¨è¿è¡Œã€‚ | | osTimerNew | 创建和åˆå§‹åŒ–计时器。 | | osTimerStart | å¯åŠ¨æˆ–é‡æ–°å¯åŠ¨è®¡æ—¶å™¨ã€‚ | | osTimerStop | åœæ¢è®¡æ—¶å™¨ã€‚ | **表7** äº’æ–¥ç®¡ç† | 接å£å | 接å£æè¿° | | -------- | -------- | | osMutexAcquire | 获å–互斥或超时(如果已é”定)。 | | osMutexDelete | åˆ é™¤äº’æ–¥å¯¹è±¡ã€‚ | | osMutexGetName | 获å–互斥对象的å称。(暂未实现) | | osMutexGetOwner | 获å–拥有互斥对象的线程。 | | osMutexNew | 创建并åˆå§‹åŒ–Mutex对象。 | | osMutexRelease | 释放由osMutexAcquire获å–çš„Mutex。 | **表8** ä¿¡å·é‡ | 接å£å | 接å£æè¿° | | -------- | -------- | | osSemaphoreAcquire | 获å–ä¿¡å·é‡ä»¤ç‰Œæˆ–超时(如果没有å¯ç”¨çš„令牌)。 | | osSemaphoreDelete | åˆ é™¤ä¸€ä¸ªä¿¡å·é‡å¯¹è±¡ã€‚ | | osSemaphoreGetCount | 获å–当å‰ä¿¡å·é‡ä»¤ç‰Œè®¡æ•°ã€‚ | | osSemaphoreGetName | 获å–ä¿¡å·é‡å¯¹è±¡çš„å称。(暂未实现) | | osSemaphoreNew | 创建并åˆå§‹åŒ–一个信å·é‡å¯¹è±¡ã€‚ | | osSemaphoreRelease | 释放信å·é‡ä»¤ç‰Œï¼Œç›´åˆ°åˆå§‹æœ€å¤§è®¡æ•°ã€‚ | **表9** 内å˜æ± | 接å£å | 接å£æè¿° | | -------- | -------- | | osMemoryPoolAlloc | 从内å˜æ± 分é…一个内å˜å—。 | | osMemoryPoolDelete | åˆ é™¤å†…å˜æ± 对象。 | | osMemoryPoolFree | 将分é…的内å˜å—返回到内å˜æ± 。 | | osMemoryPoolGetBlockSize | 获å–内å˜æ± ä¸çš„内å˜å—大å°ã€‚ | | osMemoryPoolGetCapacity | 获å–内å˜æ± ä¸æœ€å¤§çš„内å˜å—数。 | | osMemoryPoolGetCount | 获å–内å˜æ± ä¸ä½¿ç”¨çš„内å˜å—数。 | | osMemoryPoolGetName | 获å–内å˜æ± 对象的å称。 | | osMemoryPoolGetSpace | 获å–内å˜æ± ä¸å¯ç”¨çš„内å˜å—数。 | | osMemoryPoolNew | 创建并åˆå§‹åŒ–一个内å˜æ± 对象。 | **表10** 消æ¯é˜Ÿåˆ— | 接å£å | 接å£æè¿° | | -------- | -------- | | 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å†…æ ¸çš„è¿™äº›å®šä¹‰ã€‚  #### 编程实例 ``` #include ... #include "cmsis_os2.h" /*---------------------------------------------------------------------------- * 应用程åºä¸»çº¿ç¨‹ *---------------------------------------------------------------------------*/ void app_main (void *argument) { // ... for (;;) {} } int main (void) { // 系统åˆå§‹åŒ– MySystemInit(); // ... osKernelInitialize(); // åˆå§‹åŒ–CMSIS-RTOS osThreadNew(app_main, NULL, NULL); // 创建应用程åºä¸»çº¿ç¨‹ osKernelStart(); // 开始执行线程 for (;;) {} } ``` ## POSIXæ”¯æŒ ### 基本概念 OpenHarmonyå†…æ ¸ä½¿ç”¨**musl libc**库以åŠè‡ªç ”接å£ï¼Œæ”¯æŒéƒ¨åˆ†æ ‡å‡†POSIX接å£ï¼Œå¼€å‘者å¯åŸºäºŽPOSIXæ ‡å‡†æŽ¥å£å¼€å‘å†…æ ¸ä¹‹ä¸Šçš„ç»„ä»¶åŠåº”用。 ### å¼€å‘指导 #### 接å£è¯´æ˜Ž **表1** 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 co<br/>nd, const pthread_condattr_t \*restrict attr); | åˆå§‹åŒ–æ¡ä»¶å˜é‡ | | \#include <pthread.h> | int pthread_cond_timedwait(pthread_cond_t \*restr<br/>ict 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_<br/>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 \*<br/>policy, struct sched_param \*param); | 获å–线程的调度ç–略和å‚æ•° | | \#include <pthread.h> | int pthread_setschedparam(pthread_t thread, int<br/>policy, const struct sched_param \*param); | 设置线程的调度ç–略和å‚æ•° | | \#include <pthread.h> | int pthread_mutex_init(pthread_mutex_t \*__restrict m<br/>, 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<br/>_t \*attr, size_t \*stacksize); | 获å–çº¿ç¨‹å±žæ€§å¯¹è±¡çš„å †æ ˆå¤§å° | | \#include <pthread.h> | int pthread_attr_setstacksize(pthread_attr_t \*attr<br/>, size_t stacksize); | è®¾ç½®çº¿ç¨‹å±žæ€§å¯¹è±¡çš„å †æ ˆå¤§å° | | \#include <pthread.h> | int pthread_attr_getschedparam(const pthread_<br/>attr_t \*attr, struct sched_param \*param); | 获å–线程属性对象的调度å‚数属性 | | \#include <pthread.h> | int pthread_attr_setschedparam(pthread_attr_t \*<br/>attr, const struct sched_param \*param); | 设置线程属性对象的调度å‚数属性 | | \#include <pthread.h> | int pthread_getname_np(pthread_t pthread, char<br/>\*name, size_t len); | 获å–线程å称 | | \#include <pthread.h> | int pthread_setname_np(pthread_t pthread, const<br/>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<br/>c, pthread_mutex_t \*__restrict m); | ç‰å¾…æ¡ä»¶ | **表2** 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, con<br/>st char \*filesystemtype, unsigned long mountflags, c<br/>onst 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); | 获å–æŒ‡å®šè·¯å¾„ä¸‹æ–‡ä»¶çš„æ–‡ä»¶ç³»ç»Ÿä¿¡æ¯ | **表3** 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 \*<br/>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<br/>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 \*__<br/>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<br/>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结构 | **表4** 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<br/>\*\*endptr, int base); | å°†å—符串转æ¢ä¸ºunsigned longåž‹æ•´æ•° | | \#include <stdlib.h> | unsigned long long int strtoull(const char \*nptr,<br/>char \*\*endptr,int base); | å°†å—符串转æ¢ä¸ºunsigned long longåž‹æ•´æ•° | | \#include <regex.h> | int regcomp(regex_t \*preg, const char \*regex,<br/>int cflags); | 编译æ£åˆ™è¡¨è¾¾å¼ | | \#include <regex.h> | int regexec(const regex_t \*preg, const char \*<br/>string, size_t nmatch,regmatch_t pmatch[], int eflags); | 匹é…æ£åˆ™è¡¨è¾¾å¼ | | \#include <regex.h> | void regfree(regex_t \*preg); | 释放æ£åˆ™è¡¨è¾¾å¼ | | \#include <string.h> | char \*strerror(int errnum); | 返回æ述错误å·çš„å—符串 | **表5** 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); | å¹³æ–¹æ ¹ | **表6** 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,<br/>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<br/>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); | 读文件内容 | **表7** net | 需è¦åŒ…å«çš„头文件 | 接å£å | æè¿° | | -------- | -------- | -------- | | \#include <sys/socket.h> | void freeaddrinfo(struct addrinfo \*res); | 释放调用getaddrinfo所分é…的动æ€å†…å˜ | | \#include <sys/socket.h> | int getaddrinfo(const char \*restrict nodename,const<br/>char \*restrict servname,const struct addrinfo \*restrict<br/>hints,struct addrinfo \*\*restrict res); | 网络地å€å’ŒæœåŠ¡è½¬æ¢ | | \#include <sys/socket.h> | int getnameinfo(const struct sockaddr \*restrict sa,<br/>socklen_t salen,char \*restrict node, socklen_t nodelen<br/>, 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,<br/>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<br/>flags,const struct sockaddr \*dest_addr, socklen_t addrlen); | 从socketå‘é€æ¶ˆæ¯ | | \#include <sys/socket.h> | int setsockopt(int sockfd, int level, int optname,const<br/>void \*optval, socklen_t optlen); | 设置与套接å—å…³è”的选项 | **表8** 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所指å‘的内å˜ç©ºé—´ | **表9** IPC | 需è¦åŒ…å«çš„头文件 | 接å£å | æè¿° | | -------- | -------- | -------- | | \#include <semaphore.h> | int sem_timedwait(sem_t \*sem, const struct<br/> timespec \*abs_timeout); | 计时é”定信å·é‡ | | \#include <semaphore.h> | int sem_destroy(sem_t \*sem); | 销æ¯æŒ‡å®šçš„æ— åä¿¡å·é‡ | | \#include <semaphore.h> | int sem_init(sem_t \*sem, int pshared<br/>, 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,<br/> 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<br/> char \*msg,size_t msgLen, unsigned int msgPrio); | æ¤API用于将具有指定内容和长度的消æ¯æ”¾å…¥å…·æœ‰æŒ‡å®šæ述符的消æ¯é˜Ÿåˆ—ä¸ | | \#include <mqueue.h> | ssize_t mq_receive(mqd_t personal, char \*msg,<br/>size_t msgLen, unsigned int \*msgPrio); | æ¤API用于从具有指定æ述符的消æ¯é˜Ÿåˆ—ä¸åˆ 除最è€çš„消æ¯ï¼Œå¹¶å°†å…¶æ”¾å…¥msg_ptr所指å‘çš„ç¼“å†²åŒºä¸ | | \#include <mqueue.h> | int mq_timedsend(mqd_t personal, const char<br/>\*msg, size_t msgLen, unsigned int msgPrio, c<br/>onst struct timespec \*absTimeout) | æ¤API用于在预定时间将具有指定内容和长度的消æ¯æ”¾å…¥å…·æœ‰æ述符的消æ¯é˜Ÿåˆ—ä¸ | | \#include <mqueue.h> | ssize_t mq_timedreceive(mqd_t personal, char<br/>\*msg, size_t msgLen, unsigned int \*msgPrio,<br/>const struct timespec \*absTimeout); | æ¤API用于从具有指定æ述符的消æ¯é˜Ÿåˆ—消æ¯ä¸èŽ·å–具有指定消æ¯å†…å®¹å’Œé•¿åº¦çš„æ¶ˆæ¯ | | \#include <mqueue.h> | int mq_setattr(mqd_t mqdes, const struct mq_<br/>attr \*__restrict newattr, struct mq_attr \*__restrict oldattr); | 设置æ述符指定的消æ¯é˜Ÿåˆ—属性 | | \#include <libc.h> | const char \*libc_get_version_string(void); | 获å–libc版本å—符串 | | \#include <libc.h> | int libc_get_version(void); | 获å–libcç‰ˆæœ¬å· | #### 注æ„事项 常用错误ç 对照表: | 错误ç | 值 | æè¿° | å«ä¹‰ | | -------- | -------- | -------- | -------- | | 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功能: 创建一个线程并将父线程ä¸çš„ä¿¡æ¯ä¼ 递给å线程,在å线程ä¸æ‰“å°ä¼ 递过æ¥çš„ä¿¡æ¯å’Œè‡ªèº«çº¿ç¨‹id值。 本演示代ç 在 ./kernel/liteos_m/testsuites/src/osTest.c ä¸ç¼–译验è¯ï¼Œåœ¨TestTaskEntryä¸è°ƒç”¨éªŒè¯å…¥å£å‡½æ•°DemoForTest。 ``` #include <stdio.h> #include <pthread.h> pthread_t ntid; void *ThreadFn(void *arg) { pthread_t tid; while(1) { tid = pthread_self(); printf("\n++++++++++++++ %s %s tid = %d ++++++++++++++\n", (char*)arg, __FUNCTION__, tid); } return ((void *)0); } void DemoForTest() { int err; char* str = "Hello world"; err = pthread_create(&ntid, NULL, ThreadFn, (void*)str); if(err != 0) { printf("can't create thread\n"); } } ``` 执行DemoForTestè¿è¡Œç»“果如下: ``` ++++++++++++++ Hello world ThreadFn tid = 48 ++++++++++++++ ++++++++++++++ Hello world ThreadFn tid = 48 ++++++++++++++ ++++++++++++++ Hello world ThreadFn tid = 48 ++++++++++++++ ```