蚂蚁S9矿板PS并发和竞争驱动 ---信号量
参考蚂蚁S9矿板引脚定义.csdn蚂蚁S9矿板PS并发和竞争驱动 —目录.csdn蚂蚁S9矿板PS并发和竞争驱动 —原子操作.csdn蚂蚁S9矿板PS并发和竞争驱动 —自旋锁.csdn蚂蚁S9矿板PS并发和竞争驱动 —信号量.csdn蚂蚁S9矿板PS并发和竞争驱动 —互斥体.csdn驱动 semaphore.kosemaphore.c#includelinux/types.h#includelinux/kernel.h#includelinux/delay.h#includelinux/ide.h#includelinux/init.h#includelinux/module.h#includelinux/errno.h#includelinux/gpio.h#includeasm/mach/map.h#includeasm/uaccess.h#includeasm/io.h#includelinux/cdev.h#includelinux/of.h#includelinux/of_address.h#includelinux/of_gpio.h#includelinux/semaphore.h#defineGPIOLED_CNT1/* 设备号个数 */#defineGPIOLED_NAMEgpioled/* 名字 *//* dtsled设备结构体 */structgpioled_dev{dev_tdevid;/* 设备号 */structcdevcdev;/* cdev */structclass*class;/* 类 */structdevice*device;/* 设备 */intmajor;/* 主设备号 */intminor;/* 次设备号 */structdevice_node*nd;/* 设备节点 */intled_gpio;/* LED所使用的GPIO编号 */structsemaphoresem;/* 信号量 */};staticstructgpioled_devgpioled;/* led设备 *//* * description : 打开设备 * param – inode : 传递给驱动的inode * param - filp : 设备文件file结构体有个叫做private_data的成员变量 * 一般在open的时候将private_data指向设备结构体。 * return : 0 成功;其他 失败 */staticintled_open(structinode*inode,structfile*filp){/* 获取信号量,如果获取不到则会进入休眠状态 */if(down_interruptible(gpioled.sem))return-ERESTARTSYS;#if0down(gpioled.sem);#endifreturn0;}/* * description : 从设备读取数据 * param - filp : 要打开的设备文件(文件描述符) * param - buf : 返回给用户空间的数据缓冲区 * param - cnt : 要读取的数据长度 * param - offt : 相对于文件首地址的偏移 * return : 读取的字节数如果为负值表示读取失败 */staticssize_tled_read(structfile*filp,char__user*buf,size_tcnt,loff_t*offt){return0;}/* * description : 向设备写数据 * param - filp : 设备文件表示打开的文件描述符 * param - buf : 要写给设备写入的数据 * param - cnt : 要写入的数据长度 * param - offt : 相对于文件首地址的偏移 * return : 写入的字节数如果为负值表示写入失败 */staticssize_tled_write(structfile*filp,constchar__user*buf,size_tcnt,loff_t*offt){intret;charkern_buf[1];retcopy_from_user(kern_buf,buf,cnt);// 得到应用层传递过来的数据if(0ret){printk(KERN_ERRkernel write failed!\r\n);return-EFAULT;}if(0kern_buf[0])gpio_set_value(gpioled.led_gpio,0);// 如果传递过来的数据是0则关闭ledelseif(1kern_buf[0])gpio_set_value(gpioled.led_gpio,1);// 如果传递过来的数据是1则点亮ledreturn0;}/* * description : 关闭/释放设备 * param – filp : 要关闭的设备文件(文件描述符) * return : 0 成功;其他 失败 */staticintled_release(structinode*inode,structfile*filp){/* 释放信号量信号量值加1 */up(gpioled.sem);return0;}/* 设备操作函数 */staticstructfile_operationsgpioled_fops{.ownerTHIS_MODULE,.openled_open,.readled_read,.writeled_write,.releaseled_release,};staticint__initled_init(void){constchar*str;intret;/* 1.获取led设备节点 */gpioled.ndof_find_node_by_path(/led);if(NULLgpioled.nd){printk(KERN_ERRgpioled: Failed to get /led node\n);return-EINVAL;}/* 2.读取status属性 */retof_property_read_string(gpioled.nd,status,str);if(!ret){if(strcmp(str,okay))return-EINVAL;}/* 2、获取compatible属性值并进行匹配 */retof_property_read_string(gpioled.nd,compatible,str);if(0ret){printk(KERN_ERRgpioled: Failed to get compatible property\n);returnret;}if(strcmp(str,ming,led)){printk(KERN_ERRgpioled: Compatible match failed\n);return-EINVAL;}printk(KERN_INFOgpioled: device matching successful!\r\n);/* 4.获取设备树中的led-gpio属性得到LED所使用的GPIO编号 */gpioled.led_gpioof_get_named_gpio(gpioled.nd,led-gpio,0);if(!gpio_is_valid(gpioled.led_gpio)){printk(KERN_ERRgpioled: Failed to get led-gpio\n);return-EINVAL;}printk(KERN_INFOgpioled: led-gpio num %d\r\n,gpioled.led_gpio);/* 5.向gpio子系统申请使用GPIO */retgpio_request(gpioled.led_gpio,LED-GPIO);if(ret){printk(KERN_ERRgpioled: Failed to request led-gpio\n);returnret;}/* 6.将led gpio管脚设置为输出模式 */gpio_direction_output(gpioled.led_gpio,0);/* 7.初始化LED的默认状态 */retof_property_read_string(gpioled.nd,default-state,str);if(!ret){if(!strcmp(str,on))gpio_set_value(gpioled.led_gpio,1);elsegpio_set_value(gpioled.led_gpio,0);}elsegpio_set_value(gpioled.led_gpio,0);/* 8.注册字符设备驱动 *//* 创建设备号 */if(gpioled.major){gpioled.devidMKDEV(gpioled.major,0);retregister_chrdev_region(gpioled.devid,GPIOLED_CNT,GPIOLED_NAME);if(ret)gotoout1;}else{retalloc_chrdev_region(gpioled.devid,0,GPIOLED_CNT,GPIOLED_NAME);if(ret)gotoout1;gpioled.majorMAJOR(gpioled.devid);gpioled.minorMINOR(gpioled.devid);}printk(gpioled: major%d,minor%d\r\n,gpioled.major,gpioled.minor);/* 初始化cdev */gpioled.cdev.ownerTHIS_MODULE;cdev_init(gpioled.cdev,gpioled_fops);/* 添加一个cdev */retcdev_add(gpioled.cdev,gpioled.devid,GPIOLED_CNT);if(ret)gotoout2;/* 创建类 */gpioled.classclass_create(THIS_MODULE,GPIOLED_NAME);if(IS_ERR(gpioled.class)){retPTR_ERR(gpioled.class);gotoout3;}/* 创建设备 */gpioled.devicedevice_create(gpioled.class,NULL,gpioled.devid,NULL,GPIOLED_NAME);if(IS_ERR(gpioled.device)){retPTR_ERR(gpioled.device);gotoout4;}/* 初始化信号量 */sema_init(gpioled.sem,1);return0;out4:class_destroy(gpioled.class);out3:cdev_del(gpioled.cdev);out2:unregister_chrdev_region(gpioled.devid,GPIOLED_CNT);out1:gpio_free(gpioled.led_gpio);returnret;}staticvoid__exitled_exit(void){/* 注销设备 */device_destroy(gpioled.class,gpioled.devid);/* 注销类 */class_destroy(gpioled.class);/* 删除cdev */cdev_del(gpioled.cdev);/* 注销设备号 */unregister_chrdev_region(gpioled.devid,GPIOLED_CNT);/* 释放GPIO */gpio_free(gpioled.led_gpio);}/* 驱动模块入口和出口函数注册 */module_init(led_init);module_exit(led_exit);MODULE_AUTHOR(DengTao 773904075qq.com);MODULE_DESCRIPTION(ming ZYNQ GPIO LED Driver);MODULE_LICENSE(GPL);spinlockApp.c#includestdio.h#includeunistd.h#includesys/types.h#includesys/stat.h#includefcntl.h#includestdlib.h#includestring.h/* * description : main主程序 * param - argc : argv数组元素个数 * param - argv : 具体参数 * return : 0 成功;其他 失败 */intmain(intargc,char*argv[]){intfd,ret;intcnt0;unsignedcharbuf[1];if(3!argc){printf(Usage:\n\t./semaphoreApp /dev/gpioled 1 close led\n\t./semaphoreApp /dev/gpioled 0 open led\n);return-1;}/* 打开设备 */fdopen(argv[1],O_RDWR);if(0fd){printf(ERROR: file %s open failed!\r\n,argv[1]);return-1;}/* 将字符串转换为int型数据 */buf[0]atoi(argv[2]);/* 向驱动写入数据 */retwrite(fd,buf,sizeof(buf));if(0ret){printf(ERROR: LED Control Failed!\r\n);close(fd);return-1;}/* 模拟占用25秒LED设备 */for(;;){sleep(5);cnt;printf(App running times:%d\r\n,cnt);if(cnt5)break;}printf(App running finished!\n);/* 关闭设备 */close(fd);return0;}编译驱动和app$CC-o semaphoreApp semaphoreApp.c测试rootant:~# insmod semaphore.kogpioled: device matching successful!gpioled: led-gpio num943gpioled:major244,minor0rootant:~# chmod 777 semaphoreApprootant:~# ./semaphoreApp /dev/gpioled 0^C rootant:~# ./semaphoreApp /dev/gpioled 1^C rootant:~# ./semaphoreApp /dev/gpioled 1 [1]520# ./semaphoreApp /dev/gpioled 1 执行1会自动关闭rootant:~# ./semaphoreApp /dev/gpioled 0App running times:1 App running times:2 App running times:3 App running times:4 App running times:5 App running finished!

相关新闻

内网环境下Python依赖安装全攻略与解决方案

内网环境下Python依赖安装全攻略与解决方案

1. 内网环境下的Python依赖安装挑战在企业级开发环境中,内网服务器通常与互联网物理隔离,这种安全策略虽然保障了系统安全,却给Python依赖管理带来了独特挑战。我经历过数十次从零搭建内网Python环境的完整流程,深刻理解其中的技术…

2026/9/24 3:43:38 阅读更多 →
Unity TMP文字渲染:从SDF原理到性能优化的完整指南

Unity TMP文字渲染:从SDF原理到性能优化的完整指南

1. 项目概述:为什么Unity开发者绕不开TMP?如果你在Unity里做过UI,尤其是处理过文字,那你大概率经历过原生UI Text带来的“痛苦”:字体模糊、性能开销大、特效支持弱。几年前,Unity官方推出了TextMeshPro&am…

2026/9/20 12:37:26 阅读更多 →
MVC、MVP与MVVM架构演进解析与应用场景

MVC、MVP与MVVM架构演进解析与应用场景

1. 软件架构演进全景图第一次接触MVC是在2013年维护一个遗留Java EE项目时,当时被各种交织的业务逻辑和视图代码折磨得苦不堪言。后来在Android开发中尝试MVP,再到WPF项目全面采用MVVM,我深刻体会到架构演进背后的驱动力始终是"解耦&quo…

2026/9/23 1:50:21 阅读更多 →

最新新闻

目前靠谱的IP驱动产业新场景新工具哪家靠谱

目前靠谱的IP驱动产业新场景新工具哪家靠谱

现在不管是实体门店、康养机构还是个人副业者,都想靠IP数字化落地拓展新营收,但市面上的工具要么抽成高锁数据,要么场景适配性差,投入几万块最后只落个空壳小程序。我们实测了全息生态、腾讯智慧零售、阿里1688新批发3家业内主流的…

2026/9/24 8:05:24 阅读更多 →
IronClaw Google Sheets clear_values 工具深度解析:Agent 清除单元格范围的参数契约、WASM 实现与权限模型

IronClaw Google Sheets clear_values 工具深度解析:Agent 清除单元格范围的参数契约、WASM 实现与权限模型

人工智能AI 应用交互助手AI Agent 【免费下载链接】ironclaw IronClaw is an Agent OS focused on privacy, security and extensibility 项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw 点击查看 免费下载 本文围绕 IronClaw 扩展包 google-sheets 中的 …

2026/9/24 8:05:24 阅读更多 →
Phoenix 多轮会话错误分析:定位上下文型失败的完整方法论

Phoenix 多轮会话错误分析:定位上下文型失败的完整方法论

可观测性AI 评测LLMOpsAI 应用人工智能 【免费下载链接】phoenix AI Observability & Evaluation 项目地址: https://gitcode.com/gh_mirrors/phoenix13/phoenix 点击查看 免费下载 多轮对话(Multi-Turn Conversation)是客服、AI 助教、…

2026/9/24 8:05:24 阅读更多 →
EmDash 插件开发实战:深入 Block Kit 声明式 UI 体系

EmDash 插件开发实战:深入 Block Kit 声明式 UI 体系

CMS后端前端插件系统 【免费下载链接】emdash EmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress 项目地址: https://gitcode.com/gh_mirrors/emdas/emdash 点击查看 免费下载 Block Kit 是 EmDash CMS(基于…

2026/9/24 8:05:24 阅读更多 →
网络排障必备:10个命令的实战技巧与避坑指南

网络排障必备:10个命令的实战技巧与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 8:05:24 阅读更多 →
行波测距高速数据采集:LKAD9653QF四通道ADC与FPGA同步设计

行波测距高速数据采集:LKAD9653QF四通道ADC与FPGA同步设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 8:04:24 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →