SylixOS嵌入式操作系统|论坛

 找回密码
 注册
搜索
查看: 9661|回复: 1

使用内核模块创建字符设备,并实现按键控制led功能

[复制链接]

1

主题

1

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2017-8-11 15:39:57 | 显示全部楼层 |阅读模式
内核模块程序:
  1. /*
  2. * btn_drv_module.c
  3. *
  4. *  Created on: 2017年8月9日
  5. *      Author: zhengyi
  6. */

  7. #define __SYLIXOS_KERNEL
  8. #include <SylixOS.h>
  9. #include <module.h>

  10. #define __BTN_ON(pbtn)  gpioSetValue(pbtn->BTN_uiGpio, pbtn->BTN_bIsOutPutHigh ? 1 : 0)
  11. #define __BTN_OFF(pbtn) gpioSetValue(pbtn->BTN_uiGpio, pbtn->BTN_bIsOutPutHigh ? 0 : 1)
  12. static INT    BtnDrvNum = 0;                /*  BTN 主设备号          */


  13. /*设备结构*/
  14. typedef struct __btn_dev{
  15.         LW_DEV_HDR                                BTN_devhdr;//设备头
  16.         LW_LIST_LINE_HEADER                BTN_fdNodeHeader;//线形表表头
  17.         LW_OBJECT_HANDLE                BTN_hthread;//线程
  18.         LW_OBJECT_HANDLE                BTN_hSemaphoreB;//信号量
  19.         UINT                                        BTN_uigpio;//gpio
  20.         BOOL                                        BTN_bIsOutPutHigh;//是否输出高电平为点亮
  21.         BOOL                                        BTN_bQuit;//线程退出标志
  22.         time_t                                        BTN_time;//设备创建时间
  23. }__BTN_DEV;

  24. typedef __BTN_DEV                *__PBTN_DEV;

  25. /*中断程序
  26. *
  27. * 对led取反操作
  28. * */

  29. void test_irq(void)
  30. {
  31.         API_GpioClearIrq(50);
  32.         if(API_GpioGetValue(0)){
  33.                 API_GpioSetValue(0, 0);
  34.         }
  35.         else{
  36.                 API_GpioSetValue(0, 1);
  37.         }
  38.         return;
  39. }


  40. /*btn线程
  41. *
  42. * 实现btn等待功能
  43. * */
  44. static void __btnThread(__PBTN_DEV pbtn)
  45. {
  46.         ULONG ulMsTime;
  47.         int i_error, i_irq;
  48.         i_error = API_GpioRequestOne(0, LW_GPIOF_OUT_INIT_LOW, "led");//设置GPIO输出并默认输出低电平
  49.         if(i_error != 0){
  50.                 printk("led gpio request failed.\n");
  51.                 return;
  52.         }

  53.         for(;;){
  54.                 /*等待二进制型信号量*/
  55.                 if(API_SemaphoreBPendEx(pbtn->BTN_hSemaphoreB, LW_OPTION_WAIT_INFINITE,
  56.                                 (PVOID)&ulMsTime) == 0){
  57.                         if (pbtn->BTN_bQuit) {
  58.                                 break;
  59.                         }
  60. /*********************************待完成*****************************************/

  61.                         i_irq = API_GpioSetupIrq(50, 0, 0);
  62.                         if(i_irq == PX_ERROR){
  63.                                                     printk("gpio setup irq failed.\n");
  64.                                                     return;
  65.                         }

  66.                         i_error = API_InterVectorConnect(i_irq, (PINT_SVR_ROUTINE) test_irq, (PVOID) 50, "test_irq");
  67.                         if(i_error != 0){
  68.                         printk("connect irq failed.\n");
  69.                         return;
  70.                         }

  71.                         API_InterVectorEnable(i_irq);
  72.                         API_TimeSSleep(20);
  73.                         /*解除系统指定向量中断服务*/
  74.                         API_InterVectorDisconnect((ULONG)i_irq, (PINT_SVR_ROUTINE)test_irq, (PVOID)50);

  75.                         API_GpioFree(0);
  76.                         API_GpioFree(50);
  77.                 }
  78.         }

  79. }


  80. /*BTN打开
  81. *
  82. * PLW_FD_NODE:文件节点
  83. * */
  84. static long __btnOpen(__PBTN_DEV pbtn, char *pcName, int iFlags, int iMode)
  85. {
  86.         LW_CLASS_THREADATTR                threadattr;
  87.         PLW_FD_NODE                                pfdnode;
  88.         BOOL                                        bIsNew;
  89.         if(pcName == NULL){
  90.                 _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);//没有设备名
  91.                 return -1;
  92.         }else{
  93.                 pfdnode = API_IosFdNodeAdd(&pbtn->BTN_fdNodeHeader, (dev_t) pbtn, 0, iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
  94.                 if(pfdnode == NULL){
  95.                         printk("__btnOpen(): failed to add fd node!\n");
  96.                         return -1;
  97.                 }

  98.                 if(LW_DEV_INC_USE_COUNT(&pbtn->BTN_devhdr) == 1){
  99.                         if(gpioRequestOne(pbtn->BTN_uigpio,
  100.                                         (LW_GPIOF_OUT_INIT_HIGH), "btn")){
  101.                                 LW_DEV_DEC_USE_COUNT(&pbtn->BTN_devhdr);
  102.                                 API_IosFdNodeDec(&pbtn->BTN_fdNodeHeader, pfdnode, NULL);
  103.                                 return PX_ERROR;
  104.                         }
  105.                         pbtn->BTN_bQuit = LW_FALSE;
  106.                         threadattr = API_ThreadAttrGetDefault();
  107.                         threadattr.THREADATTR_pvArg = (void *)pbtn;
  108.                         threadattr.THREADATTR_ucPriority = LW_PRIO_HIGH;
  109.                         threadattr.THREADATTR_ulOption |= LW_OPTION_OBJECT_GLOBAL;
  110.                         pbtn->BTN_hSemaphoreB = API_SemaphoreBCreate("semaphore_btn", 0, 0, NULL);
  111.                         pbtn->BTN_hthread = API_ThreadCreate("t_btn", (PTHREAD_START_ROUTINE) __btnThread,
  112.                                         &threadattr, NULL);
  113.                 }
  114.                 return ((long) pfdnode);
  115.         }
  116. }

  117. /*btn关闭
  118. *
  119. * PLW_FD_ENTRY:文件结构(文件表)
  120. * */
  121. static int __btnClose(PLW_FD_ENTRY pfdentry)
  122. {
  123.         __PBTN_DEV pbtn = (__PBTN_DEV)pfdentry->FDENTRY_pdevhdrHdr;
  124.         PLW_FD_NODE pfdnode = (PLW_FD_NODE)pfdentry->FDENTRY_pfdnode;

  125.         if(pfdentry && pfdnode){//若文件结构和文件节点都存在
  126.                 API_IosFdNodeDec(&pbtn->BTN_fdNodeHeader, pfdnode, NULL);//删除一个 fd_node
  127.                 if(LW_DEV_DEC_USE_COUNT(&pbtn->BTN_devhdr) == 0){
  128.                         pbtn->BTN_bQuit = 1;
  129.                         API_SemaphoreBPostEx(pbtn->BTN_hSemaphoreB, NULL);//释放信号量

  130.                         API_ThreadJoin(pbtn->BTN_hthread, NULL);//确保线程完全执行
  131.                         pbtn->BTN_hthread = 0;//删除线程

  132.                         API_SemaphoreBDelete(&pbtn->BTN_hSemaphoreB);
  133.                         pbtn->BTN_hSemaphoreB = 0;//删除信号量

  134.                         API_GpioFree(pbtn->BTN_uigpio);//释放gpio
  135.                 }
  136.         }
  137.         return 0;
  138. }

  139. /*ioctl
  140. *
  141. * btn控制
  142. * */
  143. static int __btnIoctl(PLW_FD_ENTRY pfdentry, int iCmd, long lArg)
  144. {
  145.         __PBTN_DEV                pbtn = (__PBTN_DEV)pfdentry->FDENTRY_pdevhdrHdr;
  146.         switch(iCmd){
  147.         case 0:
  148.                 API_SemaphoreBPostEx(pbtn->BTN_hSemaphoreB, (VOID *)lArg);
  149.                 return 0;

  150.         case 1:
  151.                 API_ThreadSetPriority(pbtn->BTN_hthread, (UINT8)lArg);
  152.                 return 0;

  153.         }
  154.         return -1;
  155. }




  156. /*创建BTN驱动程序*/
  157. int btnDrv(void)
  158. {
  159.         struct file_operations fileop;

  160.         if(BtnDrvNum){
  161.                 return ERROR_NONE;
  162.         }

  163.         lib_memset(&fileop, 0, sizeof(struct file_operations));
  164.         fileop.owner                = LW_NULL;
  165.         fileop.fo_create        = __btnOpen;
  166.         fileop.fo_open                = __btnOpen;
  167.         fileop.fo_close                = __btnClose;
  168.         fileop.fo_ioctl                = __btnIoctl;
  169.         //fileop.fo_lstat                = __btnLstat;

  170.         /*安装驱动程序,NEW_1型设备驱动程序*/
  171.         BtnDrvNum = API_IosDrvInstallEx2(&fileop, LW_DRV_TYPE_NEW_1);

  172.         API_IoSetDrvAuthor(BtnDrvNum, "Zheng.Yi");
  173.         API_IoSetDrvDescription(BtnDrvNum, "btn driver.");
  174.         API_IoSetDrvLicense(BtnDrvNum, "v1.00");

  175.         return (BtnDrvNum > 0) ? ERROR_NONE : PX_ERROR;
  176. }

  177. INT btnDevCreate(CPCHAR cpcName, UINT gpio, BOOL bIsOutPutHigh)
  178. {
  179.         __PBTN_DEV pbtn;
  180.         /*从堆中申请字节池 (首次适应算法),返回分配的内存地址*/
  181.         pbtn = (__PBTN_DEV)__SHEAP_ALLOC(sizeof(__BTN_DEV));
  182.         if(!pbtn){
  183.                 _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\n");
  184.                 _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY);
  185.                 return -1;
  186.         }
  187.         lib_memset(pbtn, 0, sizeof(__BTN_DEV));
  188.         pbtn->BTN_uigpio = gpio;
  189.         pbtn->BTN_bIsOutPutHigh = bIsOutPutHigh;

  190.         /*安装设备(指定设备 d_type),DT_CHR字符设备*/
  191.         if(API_IosDevAddEx(&pbtn->BTN_devhdr, cpcName, BtnDrvNum, DT_CHR) != 0){
  192.                 __SHEAP_FREE(pbtn);
  193.                 _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY);
  194.                 return -1;
  195.         }
  196.         _ErrorHandle(ERROR_NONE);
  197.         return    (ERROR_NONE);
  198. }



  199. void module_init(void)
  200. {
  201.         btnDrv();
  202.         btnDevCreate("/dev/btn", 50, LW_FALSE);
  203. }

  204. void module_exit(void)
  205. {
  206.         PLW_DEV_HDR     pdevHdr;

  207.         pdevHdr = API_IosDevFind("/dev/btn", LW_NULL);
  208.         if (pdevHdr) {
  209.             API_IosDevDelete(pdevHdr);
  210.         }
  211. }

复制代码
应用程序:
  1. /*
  2. * btn_drv_module.c
  3. *
  4. *  Created on: 2017年8月9日
  5. *      Author: zhengyi
  6. *
  7. *********************************************************************************************************/
  8. #include <stdio.h>
  9. /*********************************************************************************************************
  10. ** 函数名称: main
  11. ** 功能描述: 程序主函数
  12. ** 输 入  : 无
  13. ** 输 出  : 无
  14. ** 全局变量:
  15. ** 调用模块:
  16. *********************************************************************************************************/
  17. int  main (int  argc, char  *argv[])
  18. {
  19.     int     fb;
  20.     long    time_ms;


  21.     fb = open("/dev/btn", O_RDWR, 0666);
  22.     if (fb < 0) {
  23.         printf("failed to open /dev/led\n");
  24.         return  (-1);
  25.     }

  26.     /*
  27.      * LED 灯闪烁 10 次,每次亮 100ms,1s 后重新点亮。
  28.      */
  29.     time_ms = 1000000;

  30.             ioctl(fb, 0, time_ms);
  31.             sleep(10);

  32.     close(fb);

  33.         return (0);
  34. }
  35. /*********************************************************************************************************
  36.   END
  37. *********************************************************************************************************/
复制代码


回复

使用道具 举报

6

主题

18

帖子

173

积分

版主

Rank: 7Rank: 7Rank: 7

积分
173
发表于 2017-8-12 10:12:38 | 显示全部楼层
666666666666666666666
SylixOS官方讨论群:32537017
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|Acoinfo Inc. All Rights Reserved. ( 京ICP备15059934号

GMT+8, 2024-3-29 20:40 , Processed in 0.021447 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表