赞
踩
从本篇开始往后的文章主要介绍下SylixOS常用的编程接口,比如同步互斥接口、动态内存相关类接口、Cache操作接口等等,主要聚焦于驱动开发中经常使用到的内核接口。
1. 基本作用
互斥锁在SylixOS中也被叫做互斥信号量,它的主要作用就是保护一段“共享资源”避免被同时访问,从而达到互斥的效果。比如在一般的网卡或者SD卡驱动中,硬件模块的数据收发都是通过描述符来进行设置的,当一个线程或者进程在更新或者准备这些描述符数据时,这些描述符是不可以再被别的线程来访问的,不然的话你前面一个线程设置好的描述符还没开始用立马又被别的线程给更改了,这就造成描述符的混乱从而导致收发数据异常。在这个案例中,描述符数据就是“共享资源”,访问这些数据可以使用互斥锁进行保护。
当一个线程成功获取到互斥锁后,就可以正常去访问“共享资源”,如果这时候另外的线程也来获取互斥锁,一般会被阻塞住,直到获取到锁的线程访问完“共享资源”,然后释放锁的时候会唤醒这些阻塞住的线程,从中选择一个优先级最高的调度运行。
互斥锁的详细使用方法在《SylixOS应用开发手册》的7.3.3章节有介绍,这里只介绍基本用法和使用过程中的一些注意事项或者比较重要的东西。
2. 互斥锁相关接口
2.1 创建互斥锁
互斥锁在使用之前需要进行创建,创建成功后会获得一个互斥锁句柄,后续的操作都是基于这个句柄来进行的。互斥锁创建使用接口API_SemaphoreMCreate 来实现,这个接口可以在应用层使用也可以在内核和驱动中使用,其函数原型如下:
- LW_API LW_OBJECT_HANDLE API_SemaphoreMCreate(CPCHAR pcName,
- UINT8 ucCeilingPriority,
- ULONG ulOption,
- LW_OBJECT_ID *pulId); /* 建立互斥信号量 */
此接口成功创建返回互斥锁句柄,失败返回LW_OBJECT_HANDLE_INVALID 。另外有个比较重要的地方需要注意,就是ulOption中有一个LW_OPTION_OBJECT_GLOBAL 标志,当在驱动中使用此接口创建互斥锁时,一定要加上这个属性标志,在应用层使用此接口时则使用的是LW_OPTION_OBJECT_LOCAL 这个标志,一定要铭记!!!
GLOBAL那个标志控制着当进程结束时是否自动销毁此互斥锁资源。在SylixOS下,互斥锁、二进制信号量等其他内核对象都属于资源,当互斥锁没有设置GLOBAL标志时,进程退出时如果没有回收这些资源,系统会帮忙自动回收这些资源。这种机制对于应用层来说没有啥问题,因为即使你在应用中不手动销毁互斥锁,系统会帮你销毁以回收资源,但是在驱动中就有问题了。比如在某些驱动中,当初次被某个进程使用时会动态创建一些互斥锁等资源以用于驱动功能管理,当再次被别的进程使用时是不会再次去创建这些资源,这些资源只有在驱动卸载时才会被销毁回收。也就是说这些资源虽然是在第一个进程使用的过程中创建的,却不能在第一个进程结束时被系统来回收,这就是通过在创建时加上GLOBAL标志来实现的。所以在驱动中创建这些资源时都需要加上这个GLOBAL标志。
2.2 获取互斥锁
创建好互斥锁之后,在访问“共享资源”之前需要申请互斥锁或者叫获取互斥锁,在SylixOS下这是通过API_SemaphoreMPend 接口实现的,如下所示。
- LW_API ULONG API_SemaphoreMPend(LW_OBJECT_HANDLE ulId,
- ULONG ulTimeout);/* 等待互斥信号量 */
此接口成功返回0,失败返回错误码,比如等待超时会返回ERROR_THREAD_WAIT_TIMEOUT。
2.3 释放互斥锁
当访问完“共享资源”后,需要释放互斥锁以让别的线程或者进程来访问“共享资源”,在SylixOS下这是通过API_SemaphoreMPost 接口实现的,如下所示。
LW_API ULONG API_SemaphoreMPost(LW_OBJECT_HANDLE ulId); /* 释放互斥信号量 */
此接口会检查是否有别的线程在等待获取此互斥锁,如果有则将所有等待线程中优先级最高的线程加入调度就绪表。成功则返回0,失败返回错误码。
2.5 销毁互斥锁
由于互斥锁是占用系统资源的,如果确认使用完毕的话需要进行销毁以回收系统资源,在SylixOS下这是通过API_SemaphoreMDelete 接口实现的,如下所示。
LW_API ULONG API_SemaphoreMDelete(LW_OBJECT_HANDLE *pulId); /* 删除互斥信号量 */
成功返回0,失败返回错误码。
3. 接口使用示例
这里用伪代码来说明上述接口的基本使用方法,详细的使用请参考应用开发手册。
- LW_OBJECT_HANDLE mutex;
-
- 1. 创建互斥锁
- mutex = Lw_SemaphoreM_Create("lock",
- LW_PRIO_HIGH,
- LW_OPTION_WAIT_FIFO | LW_OPTION_OBJECT_GLOBAL| LW_OPTION_INHERIT_PRIORITY,
- LW_NULL);
-
- 2. 获取互斥锁,如果获取不到则一直等待
- API_SemaphoreMPend(mutex, LW_OPTION_WAIT_INFINITE);
-
- 3. 访问共享资源
-
- 4. 释放互斥锁
- API_SemaphoreMPost(mutex);
-
- 5. 删除互斥锁
- API_SemaphoreMDelete(&mutex);
为了简洁,上述代码没有进行函数调用返回值检查,在实际的使用中一定要记得检查函数调用的返回值。
关于互斥锁还有其他一些接口,具体可以参见内核源码SylixOS/kernel/include/k_api.h。
4.注意事项
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。