OpenHarmony设备开发轻量系统内核(LiteOSM)附录鸿蒙开发者社区

此规范基于业界通用的编程规范整理而成,请内核的开发人员遵守这样的编程风格。

总体原则:

在大部分情况下,开发人员应当遵从以下规范,但也有一些例外场景。如修改第三方开源代码或大量使用开源代码接口下,应当与开源代码保持一致。请依据总体原则,灵活处理。

建议按照功能模块划分子目录,子目录再定义头文件和源文件目录。

目录名和文件名如果没有特殊的需要,采用全小写的形式,可以使用下划线(“_”)分割。

推荐使用驼峰风格,具体规则如下:

类型

命名风格

形式

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

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

AaaBbb

XXX_AaaBbb

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

小驼峰

aaaBBB

全局变量

带“g_”前缀的小驼峰

g_aaaBBB

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

全大写,下划线分割

AAA_BBB

函数式宏

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

头文件防止重复的符号

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

_AAA_H

内核对外API建议采用LOS_ModuleFunc的形式,如果有宾语则建议采用前置的方式,比如:

LOS_TaskCreateLOS_MuxLockkernel目录下内部模块间的接口使用OsModuleFunc的形式,比如:

OsTaskScanOsMuxInit注释一般的,尽量通过清晰的软件架构,良好的符号命名来提高代码可读性;在需要的时候,辅以注释说明。

注释是为了帮助阅读者快速读懂代码,所以要从读者的角度出发,按需注释。

注释内容要简洁、明了、无歧义,信息全面且不冗余。

注释风格要统一,建议优先选择/**/的方式,注释符与注释内容之间要有1空格,单行、多行注释风格如下:

/*单行注释*///单行注释/**多行注释*第二行*///多行注释//另一行针对代码的注释,应该置于对应代码的上方或右方。

代码上方的注释,与代码行间无空行,保持与代码一样的缩进。

代码右边的注释,与代码之间,至少留1空格。

建议将多条连续的右侧注释对齐,比如:

#defineCONST_A100/*ConstA*/#defineCONST_B2000/*ConstB*/格式程序采用缩进风格编写,使用空格而不是制表符(’\t’)进行缩进,每级缩进为4个空格。

换行时,函数左大括号另起一行放行首,并独占一行;其他左大括号跟随语句放行末。右大括号独占一行,除非后面跟着同一语句的剩余部分,如do语句中的while,或者if语句的else/elseif,或者逗号、分号。

一行只写一条语句。

比如:

structMyType{//跟随语句放行末,前置1空格...};//右大括号后面紧跟分号intFoo(inta){//函数左大括号独占一行,放行首if(a>0){Foo();//一行只有一条语句Bar();}else{//右大括号、"else"、以及后续的左大括号均在同一行...}//右大括号独占一行...}每行字符数不要超过120个,代码过长时应当换行,换行时将操作符留在行末,新行缩进一层或进行同类对齐,并将表示未结束的操作符或连接符号留在行末。

while(condition){}//Good:即使循环体是空,也应使用大括号while(condition){continue;//Good:continue表示空逻辑,使用大括号}case/default语句相对switch缩进一层,风格如下:

switch(var){case0://Good:缩进DoSomething1();//Good:缩进break;case1:{//Good:带大括号格式DoSomething2();break;}default:break;}指针类型"*"跟随变量或者函数名,例如:

int*p1;//OKint*p2;//Bad:跟随类型int*p3;//Bad:两边都没空格int*p4;//Bad:两边都有空格structFoo*CreateFoo(void);//OK:"*"跟随函数名特例:char*constVERSION="V100";//OK:当有const修饰符时,"*"两边都有空格intFoo(constchar*restrictp);//OK:当有restrict修饰符时,"*"两边都有空格sz=sizeof(int*);//OK:右侧没有变量,"*"跟随类型宏定义函数式宏前,应考虑能否用函数替代。对于可替代场景,建议用函数替代宏。对于有性能需求的场景,可以使用内联函数。

定义宏时,要使用完备的括号,例如:

#defineSUM(a,b)((a)+(b))//符合本规范要求.#defineSOME_CONST100//Good:单独的数字无需括号#defineANOTHER_CONST(-1)//Good:负数需要使用括号#defineTHE_CONSTSOME_CONST//Good:单独的标识符无需括号以下情况需要注意:

//x不要加括号#defineMAKE_STR(x)#x//obj不要加括号#defineHELLO_STR(obj)"Hello,"obj//a,b需要括号;而value可以不加括号#defineUPDATE_VALUE(value,a,b)(value=(a)+(b))//a需要括号;而b可以不加括号#defineFOO(a,b)Bar((a)+1,b)包含多条语句的函数式宏的实现语句必须放在do-while(0)中。

禁止把带副作用的表达式作为参数传递给函数式宏,比如自加操作(“a++”)。

函数式宏定义中慎用return、goto、continue、break等改变程序流程的语句。

禁止宏调用参数中出现预编译指令,如#include,#dene和#ifdef,这样做会导致未定义的行为。

宏定义不以分号结尾。

头文件应当职责单一。

避免头文件循环依赖,如a.h包含b.h,b.h包含c.h,c.h包含a.h。

头文件应当自包含,即包含某个头文件,不需要引入其他头文件就可以编译。

头文件用#dene、#ifndef、#endif保护,防止重复包含;不要使用#pragmaonce。

建议按稳定度包含头文件,依次顺序为:源码对应的头文件,C标准库,操作系统库,平台库,项目公共库,自己其他的依赖。

基础数据类型建议使用los_compiler.h中定义的类型,比如无符号32位整数位定义为UINT32。

避免大量栈分配,如较大的局部数组。

谨慎使用全局变量,尽量不用或少用全局变量。

变量应当初始化后再使用。

指向资源句柄或描述符的变量,在资源释放后立即赋予新值(如果变量的作用域马上结束可以不赋予新值)。指向资源句柄或描述符的变量包括指针、文件描述符、socket描述符以及其它指向资源的变量。

断言必须使用宏定义,且只能在调试版本中生效。

断言应当看作设计约束,禁止用断言检测程序在运行期间可能导致的错误,可能发生的错误要用错误处理代码来处理。

禁止在断言内改变运行环境。

一个断言只用于检查一个错误。

由一个进程向另一个进程发送的数据、由应用向内核发送的数据等应当进行合法性校验,校验包括但不限于:

函数应避免使用全局变量、静态局部变量和直接的I/O操作,不可避免时,应当对读写操作进行封装。

CMSIS-RTOSv2提供下面几种功能,接口详细信息可以查看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

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

静态对象分配需要访问RTOS对象控制块定义。特定于实现的头文件(下图中的os_xx.h)提供对此类控制块定义的访问。对于OpenHarmonyLiteOS-M内核,由文件名以los_开头的头文件提供,这些文件包含OpenHarmonyLiteOS-M内核的这些定义。

#include...#include"cmsis_os2.h"/*----------------------------------------------------------------------------*应用程序主线程*---------------------------------------------------------------------------*/voidapp_main(void*argument){//...for(;;){}}intmain(void){//系统初始化MySystemInit();//...osKernelInitialize();//初始化CMSIS-RTOSosThreadNew(app_main,NULL,NULL);//创建应用程序主线程osKernelStart();//开始执行线程for(;;){}}POSIX支持基本概念OpenHarmony内核使用musllibc库以及自研接口,支持部分标准POSIX接口,开发者可基于POSIX标准接口开发内核之上的组件及应用。

表1process

需要包含的头文件

描述

#include

voidabort(void);

中止线程执行

#include

voidassert(scalarexpression);

断言为假终止线程

#include

intpthread_cond_destroy(pthread_cond_t*cond);

销毁条件变量

intpthread_cond_init(pthread_cond_t*restrictco

nd,constpthread_condattr_t*restrictattr);

初始化条件变量

intpthread_cond_timedwait(pthread_cond_t*restr

ictcond,pthread_mutex_t*restrictmutex,conststructtimespec*restrictabstime);

等待条件

intpthread_condattr_init(pthread_condattr_t*attr);

初始化条件变量属性对象

intpthread_mutex_unlock(pthread_mutex_t*mutex);

解锁互斥锁

intpthread_create(pthread_t*thread,constpthread_

attr_t*attr,void*(*start_routine)(void*),void*arg);

创建一个新的线程

intpthread_join(pthread_tthread,void**retval);

等待指定的线程结束

pthread_tpthread_self(void);

获取当前线程的ID

intpthread_getschedparam(pthread_tthread,int*

policy,structsched_param*param);

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

intpthread_setschedparam(pthread_tthread,int

policy,conststructsched_param*param);

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

intpthread_mutex_init(pthread_mutex_t*__restrictm

,constpthread_mutexattr_t*__restricta);

初始化互斥锁

intpthread_mutex_lock(pthread_mutex_t*m);

互斥锁加锁操作

intpthread_mutex_trylock(pthread_mutex_t*m);

互斥锁尝试加锁操作

intpthread_mutex_destroy(pthread_mutex_t*m);

销毁互斥锁

intpthread_attr_init(pthread_attr_t*attr);

初始化线程属性对象

intpthread_attr_destroy(pthread_attr_t*attr);

销毁线程属性对象

intpthread_attr_getstacksize(constpthread_attr

_t*attr,size_t*stacksize);

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

intpthread_attr_setstacksize(pthread_attr_t*attr

,size_tstacksize);

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

intpthread_attr_getschedparam(constpthread_

attr_t*attr,structsched_param*param);

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

intpthread_attr_setschedparam(pthread_attr_t*

attr,conststructsched_param*param);

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

intpthread_getname_np(pthread_tpthread,char

*name,size_tlen);

获取线程名称

intpthread_setname_np(pthread_tpthread,const

char*name);

设置线程名称

intpthread_cond_broadcast(pthread_cond_t*c);

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

intpthread_cond_signal(pthread_cond_t*c);

解除被阻塞的线程

intpthread_cond_wait(pthread_cond_t*__restrict

c,pthread_mutex_t*__restrictm);

表2fs

#include

char*dirname(char*path);

获取目录名

#include

structdirent*readdir(DIR*dirp);

读目录

#include

intstat(constchar*restrictpath,structstat*restrictbuf);

获取文件信息

#include

intunlink(constchar*pathname);

删除文件

#include

intopen(constchar*path,intoflags,…);

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

#include

intclose(intfd);

关闭文件

#include

intrename(constchar*oldpath,constchar*newpath);

重命名指定的文件

DIR*opendir(constchar*dirname);

打开指定目录

intclosedir(DIR*dir);

关闭指定目录

#include

intmount(constchar*source,constchar*target,con

stchar*filesystemtype,unsignedlongmountflags,c

onstvoid*data);

挂载文件系统

intumount(constchar*target);

卸载文件系统

intumount2(constchar*target,intflag);

intfsync(intfd);

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

intmkdir(constchar*pathname,mode_tmode);

创建目录

intrmdir(constchar*path);

删除目录

intfstat(intfd,structstat*buf);

获取文件状态信息

#include

intstatfs(constchar*path,structstatfs*buf);

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

表3time

#include

intgettimeofday(structtimeval*tv,structtimezone*tz);

#include

structtm*gmtime(consttime_t*timep);

structtm*localtime(consttime_t*timep);

structtm*localtime_r(consttime_t*timep,structtm*result);

time_tmktime(structtm*tm);

size_tstrftime(char*s,size_tmax,constchar*

format,conststructtm*tm);

time_ttime(time_t*tloc);

#include

clock_ttimes(structtms*buf);

intusleep(useconds_tusec);

休眠(微秒单位)

intnanosleep(conststructtimespec*tspec1,struct

timespec*tspec2);

intclock_gettime(clockid_tid,structtimespec*tspec);

inttimer_create(clockid_tid,structsigevent*__

restrictevp,timer_t*__restrictt);

为线程创建计时器

inttimer_delete(timer_tt);

为线程删除计时器

inttimer_settime(timer_tt,intflags,conststruct

itimerspec*__restrictval,structitimerspec*__restrictold);

为线程设置计时器

time_ttime(time_t*t);

char*strptime(constchar*s,constchar*format,structtm*tm);

表4util

intatoi(constchar*nptr);

字符串转换整型(int)

longatol(constchar*nptr);

字符串转换整型(long)

longlongatoll(constchar*nptr);

字符串转换整型(longlong)

#include

intisalnum(intc);

检查字母数字字符

intisascii(intc);

检查ASCII

intisdigit(intc);

检查数字字符

intislower(intc);

检查小写字符

intisprint(intc);

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

intisspace(intc);

检查空格字符

intisupper(intc);

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

intisxdigit(intc);

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

longintrandom(void);

生成伪随机数

voidsrandom(unsignedintseed);

初始化随机数生成器

inttolower(intc);

字母转换成小写

inttoupper(intc);

字母转换成大写

#include

typeva_arg(va_listap,type);

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

voidva_copy(va_listdest,va_listsrc);

复制参数

voidva_end(va_listap);

清空va_list可变参数列表

voidva_start(va_listap,last);

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

#include

char*strchr(constchar*s,intc);

在字符串中定位字符

intstrcmp(constchar*s1,constchar*s2);

比较字符串

size_tstrcspn(constchar*s,constchar*reject);

获取前缀子串的长度

char*strdup(constchar*s);

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

size_tstrlen(constchar*s);

计算字符串长度

#include

intstrncasecmp(constchar*s1,constchar*s2,size_tn);

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

intstrcasecmp(constchar*s1,constchar*s2);

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

intstrncmp(constchar*s1,constchar*s2,size_tn);

比较字符串(指定长度)

char*strrchr(constchar*s,intc);

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

寻找指定的子串

longintstrtol(constchar*nptr,char**endptr,intbase);

将字符串转换为long型整数

unsignedlongintstrtoul(constchar*nptr,char

**endptr,intbase);

将字符串转换为unsignedlong型整数

unsignedlonglongintstrtoull(constchar*nptr,

char**endptr,intbase);

将字符串转换为unsignedlonglong型整数

#include

intregcomp(regex_t*preg,constchar*regex,

intcflags);

编译正则表达式

intregexec(constregex_t*preg,constchar*

string,size_tnmatch,regmatch_tpmatch[],inteflags);

匹配正则表达式

voidregfree(regex_t*preg);

释放正则表达式

char*strerror(interrnum);

返回描述错误号的字符串

表5math

intabs(inti);

取绝对值

#include

doublelog(doublex);

自然对数函数

doublepow(doublex,doubley);

求x的指数y次幂

doubleround(doublex);

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

doublesqrt(doublex);

平方根

表6IO

voidclearerr(FILE*stream);

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

intfclose(FILE*stream);

关闭文件流

FILE*fdopen(intfd,constchar*mode);

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

intfeof(FILE*stream);

检测返回文件末尾指示位

intfflush(FILE*stream);

刷新流

char*fgets(char*s,intsize,FILE*stream);

读取流的下一行

intfileno(FILE*stream);

返回流的文件描述符

FILE*fopen(constchar*path,constchar*mode);

打开流

intfputs(constchar*s,FILE*stream);

向指定流写入一行

size_tfread(void*ptr,size_tsize,size_tnmemb,

FILE*stream);

读一个流

intfseek(FILE*stream,longoffset,intwhence);

设置流指针的位置

longftell(FILE*stream);

获取流指针的位置

size_tfwrite(constvoid*ptr,size_tsize,size_t

nmemb,FILE*stream);

向流写入

voidperror(constchar*s);

打印系统错误信息

voidrewind(FILE*stream);

重新定位流

ssize_twrite(intfd,constvoid*buf,size_tsize);

写文件内容

ssize_tread(intfd,void*buf,size_tsize);

读文件内容

表7net

#include

voidfreeaddrinfo(structaddrinfo*res);

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

intgetaddrinfo(constchar*restrictnodename,const

char*restrictservname,conststructaddrinfo*restrict

hints,structaddrinfo**restrictres);

网络地址和服务转换

intgetnameinfo(conststructsockaddr*restrictsa,

socklen_tsalen,char*restrictnode,socklen_tnodelen

,char*restrictservice,socklen_tservicelen,intflags);

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

#include

unsignedintif_nametoindex(constchar*ifname);

通过网络接口名得到索引

#include

in_addr_tinet_addr(constchar*cp);

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

char*inet_ntoa(structin_addrin);

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

constchar*inet_ntop(intaf,constvoid*src,char*dst,

socklen_tsize);

网络地址转换

intinet_pton(intaf,constchar*src,void*dst);

intlisten(intsockfd,intbacklog);

监听套接字

ssize_trecvmsg(intsockfd,structmsghdr*msg,intflags);

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

ssize_tsend(intsockfd,constvoid*buf,size_tlen,intflags);

从socket发送消息

ssize_tsendmsg(intsockfd,conststructmsghdr*msg,intflags);

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

ssize_tsendto(intsockfd,constvoid*buf,size_tlen,int

flags,conststructsockaddr*dest_addr,socklen_taddrlen);

intsetsockopt(intsockfd,intlevel,intoptname,const

void*optval,socklen_toptlen);

设置与套接字关联的选项

表8mem

intmemcmp(constvoid*s1,constvoid*s2,size_tn);

内存比较

void*memcpy(void*dest,constvoid*src,size_tn);

内存拷贝

void*memset(void*s,intc,size_tn);

内存初始化

void*realloc(void*ptr,size_tsize);

重分配内存

void*malloc(size_tsize);

动态分配内存块大小

voidfree(void*ptr);

释放ptr所指向的内存空间

表9IPC

#include

intsem_timedwait(sem_t*sem,conststruct

timespec*abs_timeout);

计时锁定信号量

intsem_destroy(sem_t*sem);

销毁指定的无名信号量

intsem_init(sem_t*sem,intpshared

,unsignedintvalue);

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

intsem_post(sem_t*sem);

增加信号量计数

intsem_wait(sem_t*sem);

获取信号量

#include

mqd_tmq_open(constchar*mqName,

intopenFlag,…);

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

intmq_close(mqd_tpersonal);

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

intmq_unlink(constchar*mqName);

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

intmq_send(mqd_tpersonal,const

char*msg,size_tmsgLen,unsignedintmsgPrio);

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

ssize_tmq_receive(mqd_tpersonal,char*msg,

size_tmsgLen,unsignedint*msgPrio);

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

intmq_timedsend(mqd_tpersonal,constchar

*msg,size_tmsgLen,unsignedintmsgPrio,c

onststructtimespec*absTimeout)

ssize_tmq_timedreceive(mqd_tpersonal,char

*msg,size_tmsgLen,unsignedint*msgPrio,

conststructtimespec*absTimeout);

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

intmq_setattr(mqd_tmqdes,conststructmq_

attr*__restrictnewattr,structmq_attr*__restrictoldattr);

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

#include

constchar*libc_get_version_string(void);

获取libc版本字符串

intlibc_get_version(void);

获取libc版本号

常用错误码对照表:

错误码

含义

ENOERR

0

Success

成功

EPERM

1

Operationnotpermitted

操作不允许

ENOENT

2

Nosuchfileordirectory

没有这样的文件或目录

ESRCH

3

Nosuchprocess

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

EINTR

4

Interruptedsystemcall

系统调用被中断

EIO

5

I/Oerror

I/O错误

ENXIO

6

Nosuchdeviceoraddress

没有这样的设备或地址

E2BIG

7

Arglisttoolong

参数列表太长

ENOEXEC

8

Execformaterror

执行格式错误

EBADF

9

Badfilenumber

坏的文件描述符

ECHILD

10

Nochildprocesses

没有子进程(暂不支持)

EAGAIN

11

Tryagain

资源暂时不可用

ENOMEM

12

Outofmemory

内存溢出

EACCES

13

Permissiondenied

拒绝许可

EFAULT

14

Badaddress

错误的地址

ENOTBLK

15

Blockdevicerequired

块设备请求

EBUSY

16

Deviceorresourcebusy

设备或资源忙

EEXIST

17

Fileexists

文件存在

EXDEV

18

Cross-devicelink

无效的交叉链接

ENODEV

19

Nosuchdevice

设备不存在

ENOTDIR

20

Notadirectory

不是一个目录

EISDIR

21

Isadirectory

是一个目录

EINVAL

22

Invalidargument

无效的参数

ENFILE*

23

Filetableoverflow

打开太多的文件系统

EMFILE

24

Toomanyopenfiles

打开的文件过多

EFBIG

27

Filetoolarge

文件太大

ENOSPC

28

Nospaceleftondevice

设备上没有空间

ESPIPE

29

Illegalseek

非法移位

EROFS

30

Read-onlyfilesystem

只读文件系统

EMLINK

31

Toomanylinks

太多的链接

EDOM

33

Mathargumentoutofdomain

数值结果超出范围

ERANGE

34

Mathresultnotrepresentable

数值结果不具代表性

EDEADLK

35

Resourcedeadlockwouldoccur

资源死锁错误

ENAMETOOLONG

36

Filenametoolong

文件名太长

ENOLCK

37

Norecordlocksavailable

没有可用锁

ENOSYS

38

Functionnotimplemented

功能没有实现

ENOTEMPTY

39

Directorynotempty

目录不空

ELOOP

40

Toomanysymboliclinksencountered

符号链接层次太多

ENOMSG

42

Nomessageofdesiredtype

没有期望类型的消息

EIDRM

43

Identifierremoved

标识符删除

ELNRNG

48

Linknumberoutofrange

链接数超出范围

EBADR

53

Invalidrequestdescriptor

请求描述符无效

EBADRQC

56

Invalidrequestcode

无效的请求代码

ENOSTR

60

Devicenotastream

设备不是字符流

ENODATA

61

Nodataavailable

无可用数据

ETIME

62

Timerexpired

计时器过期

EPROTO

71

Protocolerror

协议错误

74

Notadatamessage

非数据消息

EOVERFLOW

75

Valuetoolargefordefineddatatype

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

EMSGSIZE

90

Messagetoolong

消息太长

demo功能:

创建一个线程并将父线程中的信息传递给子线程,在子线程中打印传递过来的信息和自身线程id值。

本演示代码在./kernel/liteos_m/testsuites/src/osTest.c中编译验证,在TestTaskEntry中调用验证入口函数DemoForTest。

#include#includepthread_tntid;void*ThreadFn(void*arg){pthread_ttid;while(1){tid=pthread_self();printf("\n++++++++++++++%s%stid=%d++++++++++++++\n",(char*)arg,__FUNCTION__,tid);}return((void*)0);}voidDemoForTest(){interr;char*str="Helloworld";err=pthread_create(&ntid,NULL,ThreadFn,(void*)str);if(err!=0){printf("can'tcreatethread\n");}}执行DemoForTest运行结果如下:

++++++++++++++HelloworldThreadFntid=48++++++++++++++++++++++++++++HelloworldThreadFntid=48++++++++++++++++++++++++++++HelloworldThreadFntid=48++++++++++++++

THE END
1.Iottie是什么牌子Iottie品牌是什么档次?百强排行旗下店铺 查看全部 iottie旗舰店 直达链接 iottie京东旗舰店 直达链接 产品系列 查看全部 无线充电器 品牌榜排名NO.27 车载手机支架 品牌榜排名NO.96 车载充电器 未上榜 平板电脑 未上榜 充电器 未上榜 手机支架 未上榜 添加微信客服shuaiguo163 参加品牌秒杀或反馈您的宝贵意见 https://m.baiqiang.cn/pinpai/iottie/
2.探究:iPhone里的“I”究竟意味着什么?iphone史蒂夫·乔布斯但是,即使您有一个,您能自信地说您知道那个现在标志性的字母 I 代表什么吗? 您首先可能会猜是“互联网”,因为 iPhone 之所以出名,就在于它能够访问网络。或者您可能觉得它的意思是“我”,就跟人称代词“我”似的,因为您能通过自己选的应用程序和功能来个性化您的智能手机。但您会惊讶地发现,iPhone 中的“I”https://m.163.com/dy/article/JJGI5NVL05568E2R.html
3.applewatch上i的标志在哪硬件综合只要您所使用的iPhone手机达到以上的条件Apple Watch就会自动生成。 apple watch上i的标志在哪 第1步 1.在手表和手机未配对之前,打开苹果手表 第2步 2.在桌面上就能看到iwatch 图标,在手机和手表配对之后这个图标就不会在出现了!如果你取消了配对,想要重新配的话,只能将手表恢复出厂设置才会再看到i标志。https://m.jb51.net/hardware/zonghe/693276.html
4.各种格式的文件如何打开PDQ Patton&Patton Flowercharting PDQ Lite 文件 PDS 摄影图像文件(该文件格式的来源不清楚) PF Aladdin系统对私人文件进行加密的文件 PLT HPGL绘图仪绘图文件;AutoCAD plot绘图文件;Gerber标志制作软件 PM5 Pagemaker 5.0文件 PM6 Pagemaker 6.0文件 PNG 可移植的网络图形位图;Paint Shop Prohttp://www.360doc.com/content/11/1106/17/2582236_162273413.shtml
5.ComApInteliLiteNTInteliLite 4 AMF 25 高级单机发电机组控制器,可用于常用或备用机组应用 产品型号:IL4AMF25BAA、IL4AMF25BLA 询问更多信息现在 集备用电源和主电源应用为一体背光的符号标志 8 个二进制输出,8 + 1 个二进制输入, 4 个模拟量输入 (U/I/R) +5 VDC基准模拟量输出 https://chn.comap-control.com/products/controllers/single-gen-set-controllers/intelilite-nt/intelilite-4-amf-25
6.iscrolllite.js源码注释秋尘iscroll-lite.js源码注释 /*! iScroll v5.1.2 ~ (c) 2008-2014 Matteo Spinelli ~ http://cubiq.org/license*/(function(window, document, Math) {//请求动画帧varrAF = window.requestAnimationFrame ||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame|https://www.cnblogs.com/viccici/p/3904877.html
7.帝国大厦和iHeartMedia将向托尼班奈特90年来的标志性音乐致敬帝国大厦和iHeartMedia将利用灯光秀和艺术展,向托尼-班奈特90年来奉献的标志性音乐致敬 纽约2016年8月3日电 /美通社/ -- Empire State Realty Trust, Inc. (NYSE: ESRT)和iHeartMedia今天宣布达成庆祝活动合作,将于2016年8月3日(周三)向17座“格莱美奖?”(Grammy?)获得者、传奇人物托尼-班奈特(Tony Behttps://www.prnasia.com/story/155468-1.shtml
8.巡逻机器人CloudGingerLiteI系列成功部署,为城市公共安全带来近期,唐山这座以重工业为著称的城市正引 领科技与公共安全的新潮流。达闼机器人与唐山市公安局合作推出了云端室内安防巡逻机器人Cloud Ginger Lite I系列,成功部署在学校、商场、医院等人群聚集场所。这些机器人已经稳定运行两个多月,通过出色地完成巡逻安保任务,成功降低了犯罪率,有效威慑了潜在的犯罪嫌疑人,为市民的http://seagod.aichinaw.com/news/index.php?itemid=1945
9.转换Litecoin(LTC)与I0Coin(XIC):货币汇率转换计算器the Litecoin 是没有国家 的货币。 the I0Coin 是没有国家 的货币。 LTC 的标志可写作LTC 。 XIC 的标志可写作XIC 。 the Litecoin 的汇率最近在五月 26, 2024 从coinmarketcap.com 得到更新。 the I0Coin 的汇率最近在二月 5, 2019 从coinmarketcap.com 得到更新。 “ LTC 转换因子 15 有效数字位数https://zh.coinmill.com/XIC_LTC.html
10.MCIMX6G2CVM05AAdatasheet(14/132Pages)NXPi.MX6UltraLiteNXP Semiconductors MCIMX6G2AVM05AA 1Mb / 119P i.MX 6UltraLite Rev. 2.2, 05/2017 MCIMX6G2AVM05AB 1Mb / 119P i.MX 6UltraLite Rev. 2.2, 05/2017 MCIMX6G2AVM07AA 1Mb / 119P i.MX 6UltraLite Rev. 2.2, 05/2017 MCIMX6G2AVM07AB 1Mb / 119P i.MX 6UltraLite Rev. 2.2, https://html.alldatasheetcn.com/html-pdf/1054894/NXP/MCIMX6G2CVM05AA/1071/14/MCIMX6G2CVM05AA.html
11.I'mB!UE!PulsarXliteV2Wireless鼠标开箱&简评裙底角度。依旧是Xlite标志性的镂空大底,裸露的PCB上也不忘堆上设计元素。Xlite V2比起上代最大的https://www.chiphell.com/thread-2433578-1-1.html
12.iOS14.2越狱美化推荐23、iBlackList, 11.1 电话和信息的黑名单应用,秒杀安卓同类应用,最强的黑名单管理软件。选择苹果的理由。(应用,付费) //iOS12:不支持 24、Boxy 3, 3.4.1-1 定制图标排列,进入大屏时代,满屏密集的图标是苹果的标志性,可是我真的单手无法点击最左上角的图标。(终于媲美安卓,好!) 源:https://repo.packix.https://93665.xin/10808.html
13.形式化范文12篇(全文)1)allValuesFrom:限定了性质中涉及的两个类的取值必须来源于某个特定的类,等同于描述逻辑中的,在解释I下,或。 2)someValuesFrom:在功能上类似于allValuesFrom,等同于描述逻辑中的,在解释I下,或。 2.5 OWL Lite基数限制 OWL Lite基数限制指定了基数值只能为0或1,包括minCardinality,maxCardinality,cardinality三个https://www.99xueshu.com/w/ikeytpbxitnq.html
14.首发2023世界食品创新奖公布!21款获奖140+入围产品揭示了哪些Fermenti是一家来自英国的发酵食品品牌。Fermented Fruit Bites冻干食品由发酵椰子和新鲜水果制成,口感松脆,入口即化。其中富含有益健康的细菌和膳食纤维,有助于肠道健康。目前已推出的覆盆子口味,原料为60%覆盆子、发酵椰子、腰果脂、枫糖浆、椰子油和可可脂,采用了植物性的全天然成分,不含人造糖。该品牌未来将会推出https://www.foodtalks.cn/news/44792
15.116王子的一次非主流尝试,封面是他标志性的紫色带尾吉他。 06. Inspiral Carpets - Saturn 5 出自1994年专辑《Devil Hopping》。 Inspiral Carpets被认为是八十年代晚期至九十年代早期第三大受欢迎的乐队。他们依靠较少的当代舞蹈俱乐部节拍,成为曼城最早的吉他摇滚乐队之一。他们的狂热风格被大多数人所接受,不仅包括他们https://www.douban.com/note/222101277/
16.XilinxvivadoFFTIPv9.0详解vivadofftip核在线变换点数1. Radix-2 Lite Burst I/O 四种方式区别主要体现在运算速度和所占资源上: 本IP核可进行2^M(M=3~16)点的FFT、IFFT,同时支持在线更改变换点数和正负fft的功能。需要注意的是在线变更感换点数功能不支持PipelinedStreaming I/O、Radix-4Burst I/O这两种模式。 https://blog.csdn.net/qq_36375505/article/details/81742680
17.Lite建立标志(有条件的内容)可以用来标记内容,文件或目录的节点,以对同一项目创建多个版本的帮助系统(可能是'精简'和'专业'的版本)。 evget.com evget.com The portfolio of Zuken now includes a new version of "Board ModelerLite",which offers an even higher productivity in PCB layout design. http://cn.linguee.com/%E8%8B%B1%E8%AF%AD-%E4%B8%AD%E6%96%87/%E7%BF%BB%E8%AD%AF/lite.html
18.行泊一体研究:自研模式的份额逐年走低,供应商方案百花齐放其中,毫末基于时序Transformer模型在BEV环视空间上做了虚拟实时建图,让车道线的感知输出更加稳定和准确。此外,毫末还提出将 Transformer 引入到其数据智能体系 MANA 中,并逐步应用到实际的道路感知问题,如障碍物检测、车道线检测、可行驶区域分割、交通标志检测等。https://www.dongchedi.com/article/7259928483319792143
19.你就是锦鲤本鲤?2022虎年春节活动奖品一览活动in外设然后介绍一下为本次活动提供奖品赞助的品牌,包括凯华,佳达隆,TTC,雷柏,HyperX,Darmoshark,黑爵,腹灵,HEAVY SHELL,RK,珂芝,ROG,ZOMO,IQUNIX,杜伽,达尔优,多彩,指尖文创,黑峡谷,美加狮,美商海盗船,红龙,雷神(排名不分先后)。非常感谢以上品牌的大力支持,祝以上赞助商在虎年旗开得胜,马到功成! http://www.inwaishe.com/article-7200-1.html
20.GOOGLE11 公司业绩 12 公司荣誉 13 重组高层 14 Google眼镜 15 注册商标 16 I/O大会 Google公司简介 编辑 Google公司于1998年9月7日在美国加利福尼亚州山景城以私有股份公司的型式创立,以设计并管理一个互联网搜索引擎;Google网站于1999年下半年启动;2004年8月19日,Google公司的股票在纳斯达克(Nasdaq)上市,成为公有https://vibaike.com/4148/
21.魅族2011年,魅族M9上市,标志着魅族从WinCE系统2014魅族北京体育馆新品发布会成功进入Android系统。并成为当时最领先和成功的中国Android智能手机。 2012年1月1日,2018年10月15日,魅族在印尼发布了魅族16th、M6T, POP 和EP52 Lite四款产品[34]。 2021年3月3日,魅族正式推出了2021年度旗舰——魅族18 Pro手机[35]https://baike.sogou.com/v80183.htm
22.安卓网91门户(91.com)是百度旗下专注于移动互联网的智能手机互动媒体,是国内移动互联网第一平台。91门户致力于服务智能手机用户与软硬件厂商,同时横跨iOS及Android两大系统,是国内最大、最开放、最具影响力的智能手机应用分发平台,为开发者提供平台化、智能化的推广服务。http://www.hiapk.com/
23.产品文档:LiteTX2NX用户手册米文Lite TX2 NX 是一款专为智能图像分析设计的嵌入式人工智能计算机,能够为众多终端设备赋予高达1.33 I/O UART 1xRS2321xRS485 DB9 Terminal User Expansion M.2 1×M.2 M Key 2280 SIZE NVME 可以通过右上角的NVIDIA绿色标志设置进行调整。 米文设备的默认模式为3: MODE 10W 2CORE 图 设置图标https://doc.miivii.com/7474143.html
24.ebay标志在全球网络交易平台 eBay 享受买卖乐趣,从电子产品、汽车、时尚服饰、收藏品、体育用品、数码相机、婴儿用品到优惠券,应有尽有http://www.ebay.com/