I.MX6U 裸机开发3. GPIO操作控制LED灯

I.MX6U 裸机开发3. GPIO操作控制LED灯

  • 一、创建项目目录及源文件
    • 1. 新建目录
    • 2. 远程开发环境
    • 3. 创建源文件
  • 二、代码编写
    • 1. 打开时钟
    • 2. 配置端口复用功能为GPIO
    • 3. 配置端口电气属性
    • 4. 设置GPIO方向(GDIR寄存器)
    • 5. 输出
    • 6. 死循环等待
  • 三、编译程序
    • 1. 整体过程
    • 2. 编译,使用命令 arm-linux-gnueabihf-gcc
    • 3. 链接,使用命令 arm-linux-gnueabihf-ld
      • 3.3.1 起始地址
      • 3.3.2 DDR初始化
      • 3.3.3 链接命令:
    • 4. 格式转换 arm-linux-gnueabihf-objcopy
    • 5. 反汇编
  • 四、烧写测试
    • 1. 准备工具
    • 2. 将SD卡通过读卡器连接到虚拟机
    • 3. 烧写
  • 五、执行
    • 1. SD卡插到开发板
    • 2. 引导方式拨码开关调到SD卡模式
  • 六、创建 makefile

在这里插入图片描述

一、创建项目目录及源文件

1. 新建目录

~/linux/IMX6ULL/Board_Drivers/1_leds

2. 远程开发环境

为了方便远程开发,可在本地的vscode安装 Remote Development 插件:
在这里插入图片描述
设置方法:
点View-Command Palette,输入Remote,选择 Remote-SSH:Add New SSH Host…
在这里插入图片描述
按提示格式输入:
ssh root:123456@192.168.222.129
账号密码按自己真实情况填写,

点击
在这里插入图片描述
点击自己Ubuntu设备后的连接:
在这里插入图片描述
接下来的提示窗口按提示选择即可:
在这里插入图片描述
接下来点击 Open Folder,选择ubuntu上的开发目录 :
在这里插入图片描述

3. 创建源文件

leds.s
在这里插入图片描述

二、代码编写

1. 打开时钟

I.MX6U的时钟寄存器,首先到IMX6ULL参考手册找到 CCGR0~CCGR6地址,通过设置为0xFFFFFFFF把时钟全部使能。
在这里插入图片描述
初始化代码:

.global _start @全局标号_start:/* 使能CCGR0的全部时钟 */LDR R0, =0x020C4068     @ 把 CCGR0 的内存地址赋值给R0LDR R1, =0xFFFFFFFF      @ R1 里赋值STR R1, [R0]            @ 把 CCGR0 全部设置为高/* 使能CCGR1的全部时钟 */LDR R0, =0x020C406CSTR R1, [R0]/* 使能CCGR2的全部时钟 */LDR R0, =0x020C4070STR R1, [R0]/* 使能CCGR3的全部时钟 */LDR R0, =0x020C4074STR R1, [R0]/* 使能CCGR4的全部时钟 */LDR R0, =0x020C4078STR R1, [R0]/* 使能CCGR5的全部时钟 */LDR R0, =0x020C407CSTR R1, [R0]/* 使能CCGR6的全部时钟 */LDR R0, =0x020C4080STR R1, [R0]

2. 配置端口复用功能为GPIO

在手册找到 1571 页,
在这里插入图片描述

代码:

@ 配置 GPIO1_IO03的复用功能@ IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 5LDR R0, =0x020E0068LDR R1, =0x00000005STR R1, [R0]

3. 配置端口电气属性

在手册第1793页:
在这里插入图片描述
在这里插入图片描述

设置:

  • bit0: SRE压摆率,设置为0低速率
  • bit5~3:DSE驱动能力,设置为110 (R0/6)
  • bit7~6:设置为10(100Mhz)
  • bit11:设置为0,关闭开漏输出
  • bit12:PKE设置为1,使能pull/keeper
  • bit13:PUE设置为0,保持
  • bit15~14:PUS设置为00, 等效100欧下拉
  • bit16:HYS设置为0关闭
    代码:
    LDR R0, =0x020E02F4LDR R1, =0x10b0STR R1, [R0]

4. 设置GPIO方向(GDIR寄存器)

手册第 1357 页:
在这里插入图片描述

    LDR R0, =0x0209C004LDR R1, =0x8STR R1, [R0]

5. 输出

在这里插入图片描述

    /* 设置GPIO1_IO03输出低电平 */LDR R0, =0x0209C000LDR R1, =0x0STR R1, [R0]

6. 死循环等待

B .

三、编译程序

1. 整体过程

  1. 编译:将.c .s文件编译为 .o 目标文件
  2. 链接:将所有的.o 文件链接为 elf 格式可执行文件
  3. 将 elf 转成.bin 文件。

2. 编译,使用命令 arm-linux-gnueabihf-gcc

命令:

arm-linux-gnueabihf-gcc -g -c leds.s -o led.o

3. 链接,使用命令 arm-linux-gnueabihf-ld

3.3.1 起始地址

为了确定程序在内存中的加载位置,链接器通过链接脚本或命令行参数要指定起始地址。指定起始地址有以下作用:

  1. 内存布局控制:指定起始地址可以确保程序的各个部分(如代码段、数据段、堆栈等)在内存中有序排列,避免冲突。
  2. 硬件要求:某些嵌入式系统或硬件平台的特定要求。
  3. 调试和诊断:指定起始地址有助于调试和诊断,因为开发人员可以明确知道程序在内存中的位置。

使用 I.MX6ULL时,链接起始地址应指向RAM地址。而RAM分为内部RAM和外部RAM,根据文档可查询到,其RAM范围:

  • 内部RAM的范围是 0x900000~0x91FFFF,
  • 外部RAM的范围,需要视开发板而定。

我这里使用的正点原子I.MX6U-MINI开发板,512M字节的DDR范围是 :
0x80000000~0x9FFFFFFF
对于256M字节的DDR的范围是:
0x80000000~0x8FFFFFFF

本系列博文,链接地址使用了0x87800000,这是以后要学到的Uboot的链接地址就是0x87800000,这里沿用其设置。

3.3.2 DDR初始化

DDR内存模块,在上电后处于未定义状态,要使用需要先初始化。
这里我们要添加一个头部,在这个头部实现 从指定存储中读取头部、初始化DDR,并将bin拷贝到指定地方。
Bin的运行地址要和链接地址保持一致。

3.3.3 链接命令:

arm-linux-gnueabihf-ld  -Ttext 0x87800000 led.o -o led.elf

4. 格式转换 arm-linux-gnueabihf-objcopy

本步骤有以下作用:

  1. 格式转换:将目标文件从一种格式转换为另一种格式。例如,从 ELF 格式转换为二进制格式。
  2. 去除符号表:可以去除目标文件中的符号表和调试信息,以减小文件大小。
  3. 提取部分内容:可以从目标文件中提取特定的部分,如只提取代码段或数据段。
  4. 合并文件:可以将多个目标文件合并为一个文件。
  5. 修改段属性:可以修改目标文件中段的属性,如段的起始地址、大小等。

命令:

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

5. 反汇编

这一步不是为了烧写,而是为了方便以后调试代码。
命令:

arm-linux-gnueabihf-objdump -D led.elf > led.dis

反汇编生成的文件示例:
在这里插入图片描述

四、烧写测试

I.MX6U 支持 SD卡、EMMC、NAND、NOR、SPI Flash,本例程使用烧写到SD卡。
烧写工具使用: imxdownload。

1. 准备工具

将 imxdownload 其拷到ubuntu的tools目录下:
在这里插入图片描述
使用 chmod +x imxdownload 给文件可执行权限。
在这里插入图片描述
imxdownload 工具会向led.bin添加一个头部。

2. 将SD卡通过读卡器连接到虚拟机

先在ubuntu上执行命令:

ls /dev/sd* -l

输出如下内容:
在这里插入图片描述
将U盘连接到Ubuntu虚拟机,再次执行:

ls /dev/sd* -l

输出如下:
在这里插入图片描述
其中 /dev/sdb有一个/dev/sdb1备用设备,这个/dev/sdb 就是目标SD卡。

3. 烧写

命令:

../tools/imxdownload led.bin /dev/sdb

在这里插入图片描述
其中的load.imx就是最终烧写到SD卡的文件。

五、执行

1. SD卡插到开发板

在这里插入图片描述

2. 引导方式拨码开关调到SD卡模式

默认是 EMMC启动方式,按丝印所示调整为SD卡模式:
在这里插入图片描述
通过 USB_TTL 上电,
执行效果,启动后等1-2秒,LED1亮。
在这里插入图片描述

六、创建 makefile

led.bin : leds.sarm-linux-gnueabihf-gcc -g -c leds.s -o led.oarm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led_elfarm-linux-gnueabihf-objcopy -O binary -S -g led_elf led.binarm-linux-gnueabihf-objdump -D led_elf > led.dis
clean:rm -f *.bin *.o *.dis *.elf
download:../tools/imxdownload led.bin ${DEV}
.PHONY: clean

以后可以下面命令来代码前面的编译、链接、格式转换等工作:

make clean
make
# 烧录
make download DEV=/dev/sdb

如果提示make没有安装,可以使用:

sudo apt install make -y

安装 make 。

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

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

相关文章

java ssm 公司内部员工管理系统 员工信息管理 企业员工 源码 jsp

一、项目简介 本项目是一套基于SSM的公司内部员工管理系统,主要针对计算机相关专业的和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本、软件工具等。 项目都经过严格调试,确保可以运行! 二、技术实现 ​后端技术&am…

数据分析:宏基因组DESeq2差异分析筛选差异物种

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍原理:计算步骤:结果:加载R包准备画图主题数据链接导入数据Differential abundance (No BP vs 2BP TA)构建`countData`矩阵过滤低丰度物种构建DESeq数据对象DESeq2差异分析画图Di…

Spark的yarn集群环境搭建

一.为什么要搭建yarn集群 为什么要将Spark的程序运行在YARN上,不运行在自带的 Standalone集群上? 1、统一化资源管理 Standalone是Spark专用的资源管理集群,只能用于运行 Spark程序 YARN是功能的分布式资源管理平台,可以运行各种分…

51单片机教程(六)- LED流水灯

1 项目分析 基于点亮LED灯、LED灯闪烁,扩展到构成最简单、花样流水灯。 2 技术准备 1 流水灯硬件及原理图 流水灯是由多个LED灯组成的 2 C语言知识点 数组 数组声明:长度不可变 数据类型 数组名称[长度n] // 整数型默认为0,小数型默认…

PyQt5实战——翻译的实现,第一次爬取微软翻译经验总结(八)

个人博客:苏三有春的博客 系类往期文章: PyQt5实战——多脚本集合包,前言与环境配置(一) PyQt5实战——多脚本集合包,UI以及工程布局(二) PyQt5实战——多脚本集合包,程序…

前端好用的网站分享——CSS(持续更新中)

1.CSS Scan 点击进入CSS Scan CSS盒子阴影大全 2.渐变背景 点击进入color.oulu 3.CSS简化压缩 点击进入toptal 4.CSS可视化 点击进入CSS可视化 这个强推,话不多说,看图! 5.Marko 点击进入Marko 有很多按钮样式 6.getwaves 点击进入getwaves 生…

理解Web登录机制:会话管理与跟踪技术解析(三)-过滤器Filter

在Java Web应用中,Filter(过滤器)是实现登录校验的常见方式。通过Filter,我们能够在请求到达实际的业务逻辑之前,对其进行拦截和处理,从而完成身份校验、权限验证等操作。本文将深入探讨登录校验的实现方法…

FreeBSD将操作系统支持时间从5年缩短为4年 继续与AMD合作

FreeBSD 项目今天发布了 2024 年第三季度进度报告,概述了该开源 BSD 操作系统在上一季度的改进情况。FreeBSD 开发人员仍然非常忙碌,他们在 2024 年第三季度取得的一些成就包括: FreeBSD 发布团队决定将支持时限从五年缩短为四年。 AMD 与 F…

kafka如何获取 topic 主题的列表?

大家好,我是锋哥。今天分享关于【kafka如何获取 topic 主题的列表?】面试题?希望对大家有帮助; kafka如何获取 topic 主题的列表? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在Kafka中,可以…

【网络-交换机】生成树协议、环路检测

路由优先级 路由优先级决定了在多种可达的路由类型中,哪种路由将被用来转发数据包。路由优先级值越低,对应路由的优先级越高,优先级值255表示对应的路由不可达。一般情况下,静态路由的优先级为1,OSPF路由优先级为110&a…

基于Spring Boot的在线装修管理系统的设计与实现,LW+源码+讲解

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱,出错率高,信息安全性差&#…

【数字图像处理】图像旋转中三种常见插值方法的效果比较:最近邻插值、双线性插值和双三次插值

引言 插值是一种数学方法,用于在已知的数据点之间估计新的数据点。在图像处理中,插值通常用于图像缩放、旋转和其他形态变换。 原始图像 最近邻插值(Nearest-neighbor interpolation) 这是最简单的插值方法,也是计算…

“方块兽神仙猿点石成金”游戏搭建开发

“方块兽神仙猿点石成金”是一款结合了策略和运气的休闲游戏。玩家需在规定时间内向不同的山头投入矿石,等待神仙猿降临并随机选择一座山进行“点石成金”。根据神仙猿的选择,玩家将获得不同的奖励。 游戏核心机制 矿石投入:玩家在游戏开始…

C/C++每日一练:实现选择排序

选择排序 选择排序是一种简单直观的排序算法,时间复杂度为,其中 n 是数组长度,不适合大数据集的排序,适合于元素较少且对性能要求不高的场景。 选择排序的基本思想是:每次从未排序部分选择最小的元素,将其放…

Java8新特性/java

1.lambda表达式 区别于js的箭头函数,python、cpp的lambda表达式,java8的lambda是一个匿名函数,java8运行把函数作为参数传递进方法中。 语法格式 (parameters) -> expression 或 (parameters...) ->{ statements; }实战 替代匿名内部类…

《现代网络技术》读书笔记:SDN数据平面和OpenFlow

本文部分内容来源于《现代网络技术:SDN,NFV,QoE、物联网和云计算:SDN,NFV,QoE,IoT,andcloud》 SDN数据平面 SDN 数据平面也称为基础设施层,而在ITU-T的Y3300标准中则称为资源层,它是网络转发设备根据 SDN控制平面的决策来执行数据…

linux centos 安装redis

安装 wget https://download.redis.io/releases/redis-7.4.0.tar.gz解压redis-7.4.0.tar.gz文件 tar -zxvf redis-7.4.0.tar.gz进入redis安装目录 cd redis-7.4.0make时报错,因为需要安装gcc,gcc安装需要联网安装 修改端口 编辑文件用vi。nano命令cen…

面向对象技术简述(含设计模式)

6.9.2 面向对象技术 面向对象 对象 分类 继承 通过消息的通信 面向对象 对象 分类 继承 通过消息的通信 面向对象对象分类继承通过消息的通信其中包括: 对象 运行的实体;既包含属性/数据,又包含方法/行为/操作数据的函数;…

yakit中的规则详细解释

官方文档 序列前置知识之高级配置 | Yak Program Language 本文章多以编写yaml模版的视角来解释 规则一览 匹配器 在编写yaml中会使用到这里两个东西 点击添加会在返回包的右下角出现匹配器 上面有三个过滤器模式,官方解释 丢弃:丢弃模式会在符合匹配…

算法每日双题精讲——双指针(移动零,复写零)

🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟 别再犹豫了!快来订阅我们的算法每日双题精讲专栏,一起踏上算法学习的精彩之旅吧!💪…