【ARM Linux驱动开发】嵌入式ARM Linux驱动开发基本步骤

news2024/11/26 14:48:55

【ARM Linux驱动开发】嵌入式ARM Linux驱动开发基本步骤

文章目录

  • 开发环境
  • 驱动开发(以字符设备为例)
  • 安装驱动
  • 应用程序开发
  • 附录:压缩字符串、大小端格式转换
    • 压缩字符串
      • 浮点数
      • 压缩Packed-ASCII字符串

开发环境

首先需要交叉编译器和Linux环境
这里采用编译器:

arm-none-linux-gnueabihf-gcc

同时需要目标ARM板子的Linux系统内核环境
并编译内核:

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- stm32mp1_atk_defconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- uImage vmlinux dtbs LOADADDR=0xC2000040 -j4
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- stm32mp1_atk_defconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- modules -j4

如果是第一次编译 则可能有所不同 需要根据实际手册来

以下是我编译好 打包好的虚拟机

通过百度网盘分享的文件:适用于STM32MP135开发板的开发环境虚拟机
链接:https://pan.baidu.com/s/1Sf_wk2gEPj0JlQ7X_rpQcg 
提取码:d9sj

驱动开发(以字符设备为例)

通过开发字符驱动等设备 编译成驱动*.ko文件

编译前要配置环境变量:

source /etc/profile

需要先在此文件中 指定环境所在目录
Makefile

KERNELDIR := /home/alientek/linux/atk-mp135/linux/my_linux/linux-5.15.24
CURRENT_PATH := $(shell pwd)

obj-m := test.o

build: kernel_modules

kernel_modules:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

clean:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean


执行编译

make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf-

安装驱动

将编译好的驱动推荐放置到ARM板子的/lib/modules/<kernel-version>目录下

加载驱动:
insmod test.komodprobe test
建议用modprobe 原因是可以解决依赖关系
在这里插入图片描述

查看已安装的模块:
使用lsmodcat /proc/devices查看 其中 还能看到已安装的驱动设备号(新安装的不能重复)

创建设备节点文件:

mknod /dev/test c 200 0

查看节点文件:

ls /dev/test -l

在这里插入图片描述
最后如果不需要了 则卸载
卸载模块:
rmmod testmodprobe -r test

应用程序开发

应用程序可以对/dev/下的驱动进行读写等操作 前提是已经安装了驱动
开发后 使用一条简单的命令即可编译

arm-none-linux-gnueabihf-gcc test_app.c -o test_app

最后进行测试即可

附录:压缩字符串、大小端格式转换

压缩字符串

首先HART数据格式如下:
在这里插入图片描述
在这里插入图片描述
重点就是浮点数和字符串类型
Latin-1就不说了 基本用不到

浮点数

浮点数里面 如 0x40 80 00 00表示4.0f

在HART协议里面 浮点数是按大端格式发送的 就是高位先发送 低位后发送

发送出来的数组为:40,80,00,00

但在C语言对浮点数的存储中 是按小端格式来存储的 也就是40在高位 00在低位
浮点数:4.0f
地址0x1000对应00
地址0x1001对应00
地址0x1002对应80
地址0x1003对应40

若直接使用memcpy函数 则需要进行大小端转换 否则会存储为:
地址0x1000对应40
地址0x1001对应80
地址0x1002对应00
地址0x1003对应00

大小端转换:

void swap32(void * p)
{
   uint32_t *ptr=p;
   uint32_t x = *ptr;
   x = (x << 16) | (x >> 16);
   x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);

   *ptr=x;
}

压缩Packed-ASCII字符串

本质上是将原本的ASCII的最高2位去掉 然后拼接起来 比如空格(0x20)
四个空格拼接后就成了
1000 0010 0000 1000 0010 0000
十六进制:82 08 20
对了一下表 0x20之前的识别不了
也就是只能识别0x20-0x5F的ASCII表
在这里插入图片描述

压缩/解压函数后面再写:

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_ASCII_to_Pack(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
   if(str_len%4)
   {
      return 0;
   }
	 
   uint8_t i=0;
   memset(buf,0,str_len/4*3);	  
   for(i=0;i<str_len;i++)
   {
      if(str[i]==0x00)
      {
         str[i]=0x20;
      }
   }

   for(i=0;i<str_len/4;i++)
   {
      buf[3*i]=(str[4*i]<<2)|((str[4*i+1]>>4)&0x03);
      buf[3*i+1]=(str[4*i+1]<<4)|((str[4*i+2]>>2)&0x0F);
      buf[3*i+2]=(str[4*i+2]<<6)|(str[4*i+3]&0x3F);
   }

   return 1;
}

//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_Pack_to_ASCII(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
   if(str_len%4)
   {
      return 0;
   }

   uint8_t i=0;

   memset(str,0,str_len);

   for(i=0;i<str_len/4;i++)
   {
      str[4*i]=(buf[3*i]>>2)&0x3F;
      str[4*i+1]=((buf[3*i]<<4)&0x30)|(buf[3*i+1]>>4);
      str[4*i+2]=((buf[3*i+1]<<2)&0x3C)|(buf[3*i+2]>>6);
      str[4*i+3]=buf[3*i+2]&0x3F;
   }

   return 1;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2207312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

豆包PixelDance指南:字节跳动推出的AI视频生成大模型,突破多主体互动难关

豆包PixelDance是由字节跳动旗下火山引擎发布的AI视频生成大模型。它是业界首个突破多主体互动难关的视频生成模型&#xff0c;支持多风格多比例的一致性多镜头生成。PixelDance基于DiT架构&#xff0c;具备高效的DiT融合计算单元&#xff0c;能够实现复杂的多主体运动交互和多…

【高等数学】 一元函数积分学

1. 不定积分的计算 1.1. 基本积分表 知识点 例题 1.2. 凑微分&#xff08;第一类换元法&#xff09; 知识点 本质&#xff1a;利用复合函数求导法则的逆运算 第一步&#xff0c;识别或者凑出来复合函数的导函数 如果被积函数具备以下特点&#xff1a; 1.它由两项相乘来表…

《案例》—— OpenCV 实现2B铅笔填涂的答题卡答案识别

文章目录 一、案例介绍二、代码解析 一、案例介绍 下面是一张使用2B铅笔填涂选项后的答题卡 使用OpenCV 中的各种方法进行真确答案识别&#xff0c;最终将正确填涂的答案用绿色圈出&#xff0c;错误的答案不圈出&#xff0c;用红色圈出错误题目的正确答案最终统计正确的题目数…

PCL用KDtree,给搜索到的邻近点上色

用KDtree&#xff0c;给搜索到的邻近点上色。 #include <pcl/io/pcd_io.h> #include <pcl/point_types.h>#include <pcl/search/kdtree.h> // 包含kdtree头文件 #include <pcl/visualization/pcl_visualizer.h> #include <boost/thread/thread.hpp&…

【MATLAB】基于RSSI的蓝牙定位程序,4个锚点、二维平面

目录 ​编辑 商品描述 主要功能 技术细节 适用场景 下载链接 商品描述 这款基于接收信号强度指示&#xff08;RSSI&#xff09;原理的蓝牙定位程序&#xff0c;专为需要高效、可靠定位解决方案的开发者和研究人员设计。它能够在二维平面内&#xff0c;通过4个锚点实现对未…

ESNP静态路由进阶

0x01 前言 前一篇文章说了一个简单的ESNP静态路由实验&#xff0c;那么后面给了一个进阶拓扑&#xff1a;https://blog.csdn.net/Moxin1044/article/details/142850946 现在我们来解决一下 0x02 拓扑图 在上一个拓扑图基础上&#xff0c;规划了一个新的7.0网段&#xff0c;那…

DGX平台

NVIDIA DGX 平台 文章目录 前言一、优势经过验证的企业 AI 标准体验 DGX 平台的优势1. 先进的 AI 开发平台2. 融入了 NVIDIA AI 专业技术和服务3. 性能卓越、成本可预测二、用例DGX 助力 AI 走向各行各业1. 壳牌推动能源领域不断取得突破2. 宝马借助 AI 重新定义工厂物流3. 索尼…

【Linux】段错误(核心已转储)

原因:linux在安装docker 安装完之后再添加用户就报错了。。。。 各种查原因: 内存问题:系统可能存在内存损坏或不足的问题。磁盘空间不足:系统分区可能没有足够的空间来创建新用户。文件系统错误:文件系统可能存在错误。SELinux或AppArmor:安全模块可能阻止了 useradd 命…

el-table表头加红色星标

代码&#xff1a; <el-table-column prop"name" label"姓名" width"auto"><template #header><span style"color: red; margin-right: 4px">*</span><span>姓名</span></template></el…

Java idea中项目在maven执行install命令后出现Java heap space错误

Java idea中项目在maven执行install命令后出现Java heap space错误 这代表着你的maven需要足够的内存来编译和打包你的项目&#xff0c;而你分配的堆内存却不够用。 解决办法&#xff1a; idea左上角File —> Settings Build —> Build Tools —> Maven —> Run…

【GPT提问技巧】如何高效提问GPT:掌握核心技巧,获取高质量回答的终极指南!

人工智能&#xff08;AI&#xff09;已经成为我们获取知识和信息的重要工具。尤其是GPT&#xff08;Generative Pre-trained Transformer&#xff09;等语言模型&#xff0c;凭借其强大的自然语言处理能力&#xff0c;能够为我们提供丰富的回答。然而&#xff0c;如何向GPT提问…

【论文分享】ShEF: Shielded Enclaves for Cloud FPGAs 22‘ASPLOS

目录 ABSTRACTINTRODUCTIONBACKGROUND AND MOTIVATIONTrusted Execution Environments (TEEs)Conventional FPGA Security MechanismsRemote FPGAs-as-a-ServiceChallenges for Secure and Customized ComputingA lack of asymmetric keys.Presence of an untrusted ShellLack …

【Vue3】 h()函数的用法

目录 介绍 参数 使用案例 1.创建虚拟 DOM 元素 2. 组件的动态渲染 3. 创建功能组件 4.渲染动态属性 5. 使用插槽 6. 创建动态标签 介绍 h() 函数用于辅助创建虚拟 DOM 节点&#xff0c;它是 hypescript 的简称——能生成 HTML (超文本标记语言) 的 JavaScript&#x…

开发实时美颜系统:视频美颜SDK与直播平台的集成方案详解

本文将详细介绍如何开发一个实时美颜系统&#xff0c;并探讨视频美颜SDK与直播平台的集成方案&#xff0c;帮助开发者实现流畅的美颜功能。 一、视频美颜SDK的核心功能 视频美颜SDK主要提供了一系列实时处理视频图像的算法&#xff0c;常见的功能包括&#xff1a; 1.美白、磨…

Vue3教程 - 3 HelloWorld

更好的阅读体验&#xff1a;点这里 &#xff08; www.foooor.com &#xff09; 3 HelloWorld 下面来正式进入 Vue3 的学习。先写一个 HelloWorld。 3.1 关于Vite Vite 是一个新型前端构建工具。 在 Vue2 中&#xff0c;我们主要使用 vue-cli 来构建我们的前端项目&#x…

进程的优先级详解(1)(在Linux中观察进程优先级,优先级的概念,优先级范围,进程的切换和切换的过程和理解)

文章目录 进程的优先级什么是进程的优先级&#xff1f;进程的优先级的划分1. 优先级的级别划分2. 动态与静态优先级 那么为什么要有优先级呢&#xff1f;区分 那么是怎么确定优先级的呢&#xff1f; Linux中的优先级Linux中的进程优先级补充 Linux优先级的范围进程的切换切换过…

四款pdf转图片在线转换免费工具推荐:

大家好&#xff01;今天我来给大家推荐几款PDF转图片的在线转换工具&#xff0c;让你轻松将PDF文件转换成图片&#xff0c;无论是工作还是学习&#xff0c;都能派上大用场。下面&#xff0c;让我们来看看这几款工具吧&#xff01; 一、福昕转换器 直通车&#xff08;粘贴到浏览…

多线程(二):创建线程关键属性终止线程

目录 1、run & start 2、Thread类常见的属性和方法 2.1 构造方法 2.2 属性 3、后台进程 & 前台进程 4、后台线程的判断和设定——isDaemon & setDaemon 5、线程是否存活——isAlive 6、终止一个线程 6.1 lambda变量捕获 6.2 currentThread & isInterr…

atomic physics

​​​​​​​ https://www.youtube.com/watch?v6F8Wjblb0vE&listPLX2gX-ftPVXVqAS_q3OfJDmPn8-EQld_r&index18

Python 工具库每日推荐 【logging】

文章目录 引言Python日志记录的重要性今日推荐:logging模块主要功能:使用场景:快速上手基本使用代码解释实际应用案例案例:文件日志记录器案例分析高级特性日志过滤器上下文管理器扩展阅读与资源优缺点分析优点:缺点:总结【 已更新完 TypeScript 设计模式 专栏,感兴趣可…