|
内核模块程序:
- /*
- * btn_drv_module.c
- *
- * Created on: 2017年8月9日
- * Author: zhengyi
- */
- #define __SYLIXOS_KERNEL
- #include <SylixOS.h>
- #include <module.h>
- #define __BTN_ON(pbtn) gpioSetValue(pbtn->BTN_uiGpio, pbtn->BTN_bIsOutPutHigh ? 1 : 0)
- #define __BTN_OFF(pbtn) gpioSetValue(pbtn->BTN_uiGpio, pbtn->BTN_bIsOutPutHigh ? 0 : 1)
- static INT BtnDrvNum = 0; /* BTN 主设备号 */
- /*设备结构*/
- typedef struct __btn_dev{
- LW_DEV_HDR BTN_devhdr;//设备头
- LW_LIST_LINE_HEADER BTN_fdNodeHeader;//线形表表头
- LW_OBJECT_HANDLE BTN_hthread;//线程
- LW_OBJECT_HANDLE BTN_hSemaphoreB;//信号量
- UINT BTN_uigpio;//gpio
- BOOL BTN_bIsOutPutHigh;//是否输出高电平为点亮
- BOOL BTN_bQuit;//线程退出标志
- time_t BTN_time;//设备创建时间
- }__BTN_DEV;
- typedef __BTN_DEV *__PBTN_DEV;
- /*中断程序
- *
- * 对led取反操作
- * */
- void test_irq(void)
- {
- API_GpioClearIrq(50);
- if(API_GpioGetValue(0)){
- API_GpioSetValue(0, 0);
- }
- else{
- API_GpioSetValue(0, 1);
- }
- return;
- }
- /*btn线程
- *
- * 实现btn等待功能
- * */
- static void __btnThread(__PBTN_DEV pbtn)
- {
- ULONG ulMsTime;
- int i_error, i_irq;
- i_error = API_GpioRequestOne(0, LW_GPIOF_OUT_INIT_LOW, "led");//设置GPIO输出并默认输出低电平
- if(i_error != 0){
- printk("led gpio request failed.\n");
- return;
- }
- for(;;){
- /*等待二进制型信号量*/
- if(API_SemaphoreBPendEx(pbtn->BTN_hSemaphoreB, LW_OPTION_WAIT_INFINITE,
- (PVOID)&ulMsTime) == 0){
- if (pbtn->BTN_bQuit) {
- break;
- }
- /*********************************待完成*****************************************/
- i_irq = API_GpioSetupIrq(50, 0, 0);
- if(i_irq == PX_ERROR){
- printk("gpio setup irq failed.\n");
- return;
- }
- i_error = API_InterVectorConnect(i_irq, (PINT_SVR_ROUTINE) test_irq, (PVOID) 50, "test_irq");
- if(i_error != 0){
- printk("connect irq failed.\n");
- return;
- }
- API_InterVectorEnable(i_irq);
- API_TimeSSleep(20);
- /*解除系统指定向量中断服务*/
- API_InterVectorDisconnect((ULONG)i_irq, (PINT_SVR_ROUTINE)test_irq, (PVOID)50);
- API_GpioFree(0);
- API_GpioFree(50);
- }
- }
- }
- /*BTN打开
- *
- * PLW_FD_NODE:文件节点
- * */
- static long __btnOpen(__PBTN_DEV pbtn, char *pcName, int iFlags, int iMode)
- {
- LW_CLASS_THREADATTR threadattr;
- PLW_FD_NODE pfdnode;
- BOOL bIsNew;
- if(pcName == NULL){
- _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);//没有设备名
- return -1;
- }else{
- pfdnode = API_IosFdNodeAdd(&pbtn->BTN_fdNodeHeader, (dev_t) pbtn, 0, iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
- if(pfdnode == NULL){
- printk("__btnOpen(): failed to add fd node!\n");
- return -1;
- }
- if(LW_DEV_INC_USE_COUNT(&pbtn->BTN_devhdr) == 1){
- if(gpioRequestOne(pbtn->BTN_uigpio,
- (LW_GPIOF_OUT_INIT_HIGH), "btn")){
- LW_DEV_DEC_USE_COUNT(&pbtn->BTN_devhdr);
- API_IosFdNodeDec(&pbtn->BTN_fdNodeHeader, pfdnode, NULL);
- return PX_ERROR;
- }
- pbtn->BTN_bQuit = LW_FALSE;
- threadattr = API_ThreadAttrGetDefault();
- threadattr.THREADATTR_pvArg = (void *)pbtn;
- threadattr.THREADATTR_ucPriority = LW_PRIO_HIGH;
- threadattr.THREADATTR_ulOption |= LW_OPTION_OBJECT_GLOBAL;
- pbtn->BTN_hSemaphoreB = API_SemaphoreBCreate("semaphore_btn", 0, 0, NULL);
- pbtn->BTN_hthread = API_ThreadCreate("t_btn", (PTHREAD_START_ROUTINE) __btnThread,
- &threadattr, NULL);
- }
- return ((long) pfdnode);
- }
- }
- /*btn关闭
- *
- * PLW_FD_ENTRY:文件结构(文件表)
- * */
- static int __btnClose(PLW_FD_ENTRY pfdentry)
- {
- __PBTN_DEV pbtn = (__PBTN_DEV)pfdentry->FDENTRY_pdevhdrHdr;
- PLW_FD_NODE pfdnode = (PLW_FD_NODE)pfdentry->FDENTRY_pfdnode;
- if(pfdentry && pfdnode){//若文件结构和文件节点都存在
- API_IosFdNodeDec(&pbtn->BTN_fdNodeHeader, pfdnode, NULL);//删除一个 fd_node
- if(LW_DEV_DEC_USE_COUNT(&pbtn->BTN_devhdr) == 0){
- pbtn->BTN_bQuit = 1;
- API_SemaphoreBPostEx(pbtn->BTN_hSemaphoreB, NULL);//释放信号量
- API_ThreadJoin(pbtn->BTN_hthread, NULL);//确保线程完全执行
- pbtn->BTN_hthread = 0;//删除线程
- API_SemaphoreBDelete(&pbtn->BTN_hSemaphoreB);
- pbtn->BTN_hSemaphoreB = 0;//删除信号量
- API_GpioFree(pbtn->BTN_uigpio);//释放gpio
- }
- }
- return 0;
- }
- /*ioctl
- *
- * btn控制
- * */
- static int __btnIoctl(PLW_FD_ENTRY pfdentry, int iCmd, long lArg)
- {
- __PBTN_DEV pbtn = (__PBTN_DEV)pfdentry->FDENTRY_pdevhdrHdr;
- switch(iCmd){
- case 0:
- API_SemaphoreBPostEx(pbtn->BTN_hSemaphoreB, (VOID *)lArg);
- return 0;
- case 1:
- API_ThreadSetPriority(pbtn->BTN_hthread, (UINT8)lArg);
- return 0;
- }
- return -1;
- }
- /*创建BTN驱动程序*/
- int btnDrv(void)
- {
- struct file_operations fileop;
- if(BtnDrvNum){
- return ERROR_NONE;
- }
- lib_memset(&fileop, 0, sizeof(struct file_operations));
- fileop.owner = LW_NULL;
- fileop.fo_create = __btnOpen;
- fileop.fo_open = __btnOpen;
- fileop.fo_close = __btnClose;
- fileop.fo_ioctl = __btnIoctl;
- //fileop.fo_lstat = __btnLstat;
- /*安装驱动程序,NEW_1型设备驱动程序*/
- BtnDrvNum = API_IosDrvInstallEx2(&fileop, LW_DRV_TYPE_NEW_1);
- API_IoSetDrvAuthor(BtnDrvNum, "Zheng.Yi");
- API_IoSetDrvDescription(BtnDrvNum, "btn driver.");
- API_IoSetDrvLicense(BtnDrvNum, "v1.00");
- return (BtnDrvNum > 0) ? ERROR_NONE : PX_ERROR;
- }
- INT btnDevCreate(CPCHAR cpcName, UINT gpio, BOOL bIsOutPutHigh)
- {
- __PBTN_DEV pbtn;
- /*从堆中申请字节池 (首次适应算法),返回分配的内存地址*/
- pbtn = (__PBTN_DEV)__SHEAP_ALLOC(sizeof(__BTN_DEV));
- if(!pbtn){
- _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\n");
- _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY);
- return -1;
- }
- lib_memset(pbtn, 0, sizeof(__BTN_DEV));
- pbtn->BTN_uigpio = gpio;
- pbtn->BTN_bIsOutPutHigh = bIsOutPutHigh;
- /*安装设备(指定设备 d_type),DT_CHR字符设备*/
- if(API_IosDevAddEx(&pbtn->BTN_devhdr, cpcName, BtnDrvNum, DT_CHR) != 0){
- __SHEAP_FREE(pbtn);
- _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY);
- return -1;
- }
- _ErrorHandle(ERROR_NONE);
- return (ERROR_NONE);
- }
- void module_init(void)
- {
- btnDrv();
- btnDevCreate("/dev/btn", 50, LW_FALSE);
- }
- void module_exit(void)
- {
- PLW_DEV_HDR pdevHdr;
- pdevHdr = API_IosDevFind("/dev/btn", LW_NULL);
- if (pdevHdr) {
- API_IosDevDelete(pdevHdr);
- }
- }
复制代码 应用程序:
- /*
- * btn_drv_module.c
- *
- * Created on: 2017年8月9日
- * Author: zhengyi
- *
- *********************************************************************************************************/
- #include <stdio.h>
- /*********************************************************************************************************
- ** 函数名称: main
- ** 功能描述: 程序主函数
- ** 输 入 : 无
- ** 输 出 : 无
- ** 全局变量:
- ** 调用模块:
- *********************************************************************************************************/
- int main (int argc, char *argv[])
- {
- int fb;
- long time_ms;
- fb = open("/dev/btn", O_RDWR, 0666);
- if (fb < 0) {
- printf("failed to open /dev/led\n");
- return (-1);
- }
- /*
- * LED 灯闪烁 10 次,每次亮 100ms,1s 后重新点亮。
- */
- time_ms = 1000000;
- ioctl(fb, 0, time_ms);
- sleep(10);
- close(fb);
- return (0);
- }
- /*********************************************************************************************************
- END
- *********************************************************************************************************/
复制代码
|
|