
# 开发指导
#### 使用场景
在多任务系统中，信号量是一种非常灵活的同步方式，可以运用在多种场合中，实现锁、同步、资源计数等功能，也能方便的用于任务与任务，中断与任务的同步中。信号量常用于协助一组相互竞争的任务访问共享资源。
#### 功能
Huawei LiteOS 的信号量模块为用户提供下面几种功能，接口详细信息可以查看API参考。
| 功能分类     | 接口名                 | 描述               |
|:---|:---|:---|
| 创建/删除信号量 | LOS_SemCreate       | 创建信号量，返回信号量ID    |
| 创建/删除信号量 | LOS_BinarySemCreate | 创建二值信号量，其计数值最大为1 |
| 创建/删除信号量 | LOS_SemDelete       | 删除指定的信号量         |
| 申请/释放信号量 | LOS_SemPend         | 申请指定的信号量，并设置超时时间 |
| 申请/释放信号量 | LOS_SemPost         | 释放指定的信号量         |
   
![](https://support.huaweicloud.com/kernelmanual-LiteOS/public_sys-resources/note_3.0-zh-cn.png)
信号量有三种申请模式：无阻塞模式、永久阻塞模式、定时阻塞模式。
- 无阻塞模式：即任务申请信号量时，入参timeout等于0。若当前信号量计数值不为0，则申请成功，否则立即返回申请失败。
- 永久阻塞模式：即任务申请信号量时，入参timeout等于0xFFFFFFFF。若当前信号量计数值不为0，则申请成功。否则该任务进入阻塞态，系统切换到就绪任务中优先级最高者继续执行。任务进入阻塞态后，直到有其他任务释放该信号量，阻塞任务才会重新得以执行。
- 定时阻塞模式：即任务申请信号量时，0\<timeout\<0xFFFFFFFF。若当前信号量计数值不为0，则申请成功。否则，该任务进入阻塞态，系统切换到就绪任务中优先级最高者继续执行。任务进入阻塞态后，超时前如果有其他任务释放该信号量，则该任务可成功获取信号量继续执行，若超时前未获取到信号量，接口将返回超时错误码。
 
#### 信号量错误码
对存在失败可能性的操作返回对应的错误码，以便快速定位错误原因。
| 序号 | 定义                                | 实际数值       | 描述                       | 参考解决方案                                                                   |
|:---|:---|:---|:---|:---|
| 1  | LOS_ERRNO_SEM_NO_MEMORY           | 0x02000700 | 初始化信号量时，内存空间不足           | 调整OS_SYS_MEM_SIZE以确保有足够的内存供信号量使用，或减小系统支持的最大信号量数LOSCFG_BASE_IPC_SEM_LIMIT |
| 2  | LOS_ERRNO_SEM_INVALID             | 0x02000701 | 信号量ID不正确或信号量未创建          | 传入正确的信号量ID或创建信号量后再使用                                                     |
| 3  | LOS_ERRNO_SEM_PTR_NULL            | 0x02000702 | 传入空指针                    | 传入合法指针                                                                   |
| 4  | LOS_ERRNO_SEM_ALL_BUSY            | 0x02000703 | 创建信号量时，系统中已经没有未使用的信号量    | 及时删除无用的信号量或增加系统支持的最大信号量数LOSCFG_BASE_IPC_SEM_LIMIT                        |
| 5  | LOS_ERRNO_SEM_UNAVAILABLE         | 0x02000704 | 无阻塞模式下未获取到信号量            | 选择阻塞等待或根据该错误码适当处理                                                        |
| 6  | LOS_ERRNO_SEM_PEND_INTERR         | 0x02000705 | 中断期间非法调用LOS_SemPend申请信号量 | 中断期间禁止调用LOS_SemPend                                                      |
| 7  | LOS_ERRNO_SEM_PEND_IN_LOCK        | 0x02000706 | 任务被锁，无法获得信号量             | 在任务被锁时，不能调用LOS_SemPend申请信号量                                              |
| 8  | LOS_ERRNO_SEM_TIMEOUT             | 0x02000707 | 获取信号量超时                  | 将时间设置在合理范围内                                                              |
| 9  | LOS_ERRNO_SEM_OVERFLOW            | 0x02000708 | 信号量计数值已达到最大值，无法再继续释放该信号量 | 根据该错误码适当处理                                                               |
| 10 | LOS_ERRNO_SEM_PENDED              | 0x02000709 | 等待信号量的任务队列不为空            | 唤醒所有等待该信号量的任务后，再删除该信号量                                                   |
| 11 | LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK | 0x0200070a | 在系统任务中获取信号量，如idle和软件定时器  | 不要在系统任务中获取信号量                                                            |
   
![](https://support.huaweicloud.com/kernelmanual-LiteOS/public_sys-resources/notice_3.0-zh-cn.png)
错误码定义见[错误码简介](https://support.huaweicloud.com/kernelmanual-LiteOS/zh-cn_topic_0311018405.html#ZH-CN_TOPIC_0311018405__zh-cn_topic_0175230332_section29852515161)。8\~15位的所属模块为信号量模块，值为0x07。
#### 开发流程
信号量的开发典型流程：
1. 执行make menuconfig命令，进入Kernel ---\> Enable Sem菜单，完成信号量的配置。
   
   | 配置项                       | 含义          | 取值范围         | 默认值  | 依赖 |
   |:---|:---|:---|:---|:---|
   | LOSCFG_BASE_IPC_SEM       | 信号量模块裁剪开关   | YES/NO       | YES  | 无  |
   | LOSCFG_BASE_IPC_SEM_LIMIT | 系统支持的信号量最大数 | \[0, 65535\] | 1024 | 无  |
      
   
2. 创建信号量LOS_SemCreate，若要创建二值信号量则调用LOS_BinarySemCreate。
3. 申请信号量LOS_SemPend。
4. 释放信号量LOS_SemPost。
5. 删除信号量LOS_SemDelete。
 
#### 平台差异性
无。
