I.MX6ULL模仿 STM32 驱动开发格式实验

系列文章目录

I.MX6ULL模仿 STM32 驱动开发格式实验


I.MX6ULL模仿 STM32 驱动开发格式实验

  • 系列文章目录
  • 一、前言
  • 二、模仿 STM32 寄存器定义
    • 2.1 STM32 寄存器定义简介
    • 2.2 I.MX6Ul 寄存器定义
    • 2.3硬件原理图
    • 2.4实验程序编写
  • 三、编译下载验证


一、前言

使用 C 语言编写 LED 灯驱动的时候,每个寄存器的地址我们都需要写宏定义,使用起来非常的不方便。我们在学习 STM32 的时候,可以使用“GPIOB->ODR”这种方式来给
GPIOB 的寄存器 ODR 赋值,因为在 STM32 中同属于一个外设的所有寄存器地址基本是相邻的(有些会有保留寄存器)。因此我们可以借助 C 语言里面的结构体成员地址递增的特点来将某个外设的所有寄存器写入到一个结构体里面,然后定义一个结构体指针指向这个外设的寄存器基地址,这样我们就可以通过这个结构体指针来访问这个外设的所有寄存器。同理,I.MX6U 也可以使用这种方法来定义外设寄存器,本章我们就模仿 STM32 里面的寄存器定义方式来编写I.MX6ULL的驱动,通过本章的学习也可以对 STM32 的寄存器定义方式有一个深入的认识。


二、模仿 STM32 寄存器定义

2.1 STM32 寄存器定义简介

为了开发方便,ST 官方为 STM32F103 编写了一个叫做 stm32f10x.h 的文件,在这个文件里面定义了 STM32F103 所有外设寄存器,我们可以使用其定义的寄存器来进行开发,比如我们可以用如下代码来初始化一个 GPIO:

GPIOE->CRL&=0XFF0FFFFF;
GPIOE->CRL|=0X00300000; //PE5 推挽输出
GPIOE->ODR|=1<<5; //PE5 输出高

上述代码是初始化 STM32 的 PE5 这个 GPIO 为推挽输出,需要配置的就是 GPIOE 的寄存器 CRL 和 ODR, “GPIOE”的定义:

#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)

可以看出“GPIOE”是个宏定义,是一个指向地址 GPIOE_BASE 的结构体指针,结构体为
GPIO_TypeDef,GPIO_TypeDef 和 GPIOE_BASE 的定义如下:

typedef struct
{
 __IO uint32_t CRL;
 __IO uint32_t CRH;
 __IO uint32_t IDR;
 __IO uint32_t ODR;
 __IO uint32_t BSRR;
 __IO uint32_t BRR;
 __IO uint32_t LCKR;
} GPIO_TypeDef;
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define PERIPH_BASE ((uint32_t)0x40000000)

上述定义中 GPIO_TypeDef 是个结构体,结构体里面的成员变量有 CRL、CRH、IDR、ODR、BSRR、BRR 和 LCKR,这些都是 GPIO 的寄存器,每个成员变量都是 32 位(4 字节),这些寄存器在结构体中的位置都是按照其地址值从小到大排序的。GPIOE_BASE 就是 GPIOE 的基地址,其为:

GPIOE_BASE=APB2PERIPH_BASE+0x1800
= PERIPH_BASE + 0x10000 + 0x1800
=0x40000000 + 0x10000 + 0x1800
=0x40011800

GPIOE_BASE 的基地址为 0x40011800,宏 GPIOE 指向这个地址,因此 GPIOE 的寄存器CRL 的地址就是 0X40011800,寄存器 CRH 的地址为0X40011800+4=0X40011804,其他寄存器地址以此类推。我们要操作 GPIOE 的 ODR 寄存器的话就可以通过“GPIOE->ODR”来实现,这个方法是借助了结构体成员地址连续递增的原理。
了解了 STM32 的寄存器定义以后,我们就可以参考其原理来编写 I.MX6ULL 的外设寄存器定义了。NXP 官方并没有为 I.MX6UL 编写类似 stm32f10x.h 这样的文件,NXP 只为 I.MX6ULL提供了类似 stm32f10x.h 这样的文件,名为 MCIMX6Y2.h,但是 I.MX6UL 和 I.MX6ULL 几乎一模一样,所以文件 MCIMX6Y2.h 也可以用在 I.MX6UL 上。
参考 stm32f10x.h 来编写一个简单的 MCIMX6Y2.h 文件


2.2 I.MX6Ul 寄存器定义

参考 STM32 的官方文件来编写 I.MX6Ul 的寄存器定义,比如 IO 复用寄存器组
“IOMUX_SW_MUX_CTL_PAD_XX”,步骤如下:
1、编写外设结构体
先将同属于一个外设的所有寄存器编写到一个结构体里面,如 IO 复用寄存器组的结构体
如下:

/* 
 * IOMUX 寄存器组
 */
1 typedef struct
2 {
3 volatile unsigned int BOOT_MODE0;
4 volatile unsigned int BOOT_MODE1;
5 volatile unsigned int SNVS_TAMPER0;
6 volatile unsigned int SNVS_TAMPER1;
………
107 volatile unsigned int CSI_DATA00;
108 volatile unsigned int CSI_DATA01;
109 volatile unsigned int CSI_DATA02;
110 volatile unsigned int CSI_DATA03;
111 volatile unsigned int CSI_DATA04;
112 volatile unsigned int CSI_DATA05;
113 volatile unsigned int CSI_DATA06;
114 volatile unsigned int CSI_DATA07;
/* 为了缩短代码,其余 IO 复用寄存器省略 */
115}IOMUX_SW_MUX_Tpye;

上述结构体 IOMUX_SW_MUX_Type 就是 IO 复用寄存器组,成员变量是每个 IO 对应的复用寄存器,每个寄存器的地址是 32 位,每个成员都使用“volatile”进行了修饰,目的是防止编译器优化。

2、定义 IO 复用寄存器组的基地址
根据结构体 IOMUX_SW_MUX_Type 的定义,其第一个成员变量为 BOOT_MODE0,也就是 BOOT_MODE0 这个 IO 的 IO 复用寄存器,查找 I.MX6UL的参考手册可以得知其地址为0X020E0014,所以 IO 复用寄存器组的基地址就是 0X020E0014,定义如下:

#define IOMUX_SW_MUX_BASE (0X020E0014)

3、定义访问指针
访问指针定义如下:

#define IOMUX_SW_MUX ((IOMUX_SW_MUX_Type *)IOMUX_SW_MUX_BASE)

通过上面三步我们就可以通过“IOMUX_SW_MUX->GPIO1_IO03”来访问 GPIO1_IO03 的
IO 复用寄存器了。同样的,其他的外设寄存器都可以通过这三步来定义。同理I.MX6ULL一样配置


2.3硬件原理图

I.MX6UALPHA 开发板上有一个 LED 灯,原理图如下图所示;
在这里插入图片描述

从图可以看出,LED0 接到了 GPIO_3 上,GPIO_3 就是 GPIO1_IO03,当 GPIO1_IO03输出低电平(0)的时候发光二极管 LED0 就会导通点亮,当 GPIO1_IO03 输出高电平(1)的时候发光二极管 LED0 不会导通,因此 LED0 也就不会点亮。所以 LED0 的亮灭取决于 GPIO1_IO03的输出电平,输出 0 就亮,输出 1 就灭。


2.4实验程序编写

创建 VSCode 工程,工作区名字为“ledc_stm32”,新建三个文件:start.S、main.c 和 imx6ul.h。其中 start.S 是汇编文件,start.S 文件的内容参考,直接复制过来就可以。main.c 和 imx6ull.h 是 C 文件
文件 imx6ul.h 用来存放外设寄存器定义,在 imx6ull.h 中输入如下代码:
CCM基地址为:0X020C4000,同理依次找这些寄存器的基地址
在这里插入图片描述

/* 
* 外设寄存器组的基地址
*/
1 #define CCM_BASE (0X020C4000)
2 #define CCM_ANALOG_BASE (0X020C8000)
3 #define IOMUX_SW_MUX_BASE (0X020E0014)
4 #define IOMUX_SW_PAD_BASE (0X020E0204)
5 #define GPIO1_BASE (0x0209C000)
6 #define GPIO2_BASE (0x020A0000)
7 #define GPIO3_BASE (0x020A4000)
8 #define GPIO4_BASE (0x020A8000)
9 #define GPIO5_BASE (0x020AC000)
10 
11 /* 
12 * CCM 寄存器结构体定义,分为 CCM 和 CCM_ANALOG 
13 */
14 typedef struct
15 {
16 volatile unsigned int CCR;
17 volatile unsigned int CCDR;
18 volatile unsigned int CSR;
……
46 volatile unsigned int CCGR6;
47 volatile unsigned int RESERVED_3[1];
48 volatile unsigned int CMEOR; 
49 } CCM_Type;
50 
51 typedef struct
52 {
53 volatile unsigned int PLL_ARM;
54 volatile unsigned int PLL_ARM_SET;
55 volatile unsigned int PLL_ARM_CLR;
56 volatile unsigned int PLL_ARM_TOG;
……
110 volatile unsigned int MISC2;
111 volatile unsigned int MISC2_SET;
112 volatile unsigned int MISC2_CLR;
113 volatile unsigned int MISC2_TOG;
114 } CCM_ANALOG_Type;
115
116 /* 
117 * IOMUX 寄存器组
118 */
119 typedef struct
120 {
121 volatile unsigned int BOOT_MODE0;
122 volatile unsigned int BOOT_MODE1;
123 volatile unsigned int SNVS_TAMPER0;
……
241 volatile unsigned int CSI_DATA04;
242 volatile unsigned int CSI_DATA05;
243 volatile unsigned int CSI_DATA06;
244 volatile unsigned int CSI_DATA07;
245 }IOMUX_SW_MUX_Type;
246
247 typedef struct
248 {
249 volatile unsigned int DRAM_ADDR00;
250 volatile unsigned int DRAM_ADDR01;
.................
419 volatile unsigned int GRP_DDRPKE;
420 volatile unsigned int GRP_DDRMODE;
421 volatile unsigned int GRP_DDR_TYPE;
422 }IOMUX_SW_PAD_Type;
423
424 /* 
425 * GPIO 寄存器结构体
426 */
427 typedef struct
428 {
429 volatile unsigned int DR; 
430 volatile unsigned int GDIR; 
431 volatile unsigned int PSR; 
432 volatile unsigned int ICR1; 
433 volatile unsigned int ICR2; 
434 volatile unsigned int IMR; 
435 volatile unsigned int ISR; 
436 volatile unsigned int EDGE_SEL; 
437 }GPIO_Type;
438
439
440 /* 
441 * 外设指针
442 */
443 #define CCM ((CCM_Type *)CCM_BASE)
444 #define CCM_ANALOG ((CCM_ANALOG_Type *)CCM_ANALOG_BASE)
445 #define IOMUX_SW_MUX ((IOMUX_SW_MUX_Type *)IOMUX_SW_MUX_BASE)
446 #define IOMUX_SW_PAD ((IOMUX_SW_PAD_Type *)IOMUX_SW_PAD_BASE)
447 #define GPIO1 ((GPIO_Type *)GPIO1_BASE)
448 #define GPIO2 ((GPIO_Type *)GPIO2_BASE)
449 #define GPIO3 ((GPIO_Type *)GPIO3_BASE)
450 #define GPIO4 ((GPIO_Type *)GPIO4_BASE)
451 #define GPIO5 ((GPIO_Type *)GPIO5_BASE)

在编写寄存器组结构体的时候注意寄存器的地址是否连续,有些外设的寄存器地址可能不
是连续的,会有一些保留地址,因此我们需要在结构体中留出这些保留的寄存器。比如 CCM 的CCGR6 寄存器地址为 0X020C4080,而寄存器 CMEOR 的地址为 0X020C4088。按照地址顺序递增的原理,寄存器 CMEOR 的地址应该是 0X020C4084,但是实际上 CMEOR 的地址是0X020C4088,相当于中间跳过了 0X020C4088-0X020C4080=8 个字节,如果寄存器地址连续的话应该只差 4 个字节(32 位),但是现在差了 8 个字节,所以需要在寄存器 CCGR6 和 CMEOR直接加入一个保留寄存器,这个就是代码第 47 行 RESERVED_3[1]的来源。如果不添加保留位来占位的话就会导致寄存器地址错位!
main.c 文件中输入如下所示内容:
相对于I.MX6ULL Linux C语言开发环境搭建(点灯实验),已经简便了,可以直接使用指针操作寄存器了

1 #include "imx6ul.h"
2 
3 /*
4 * @description : 使能 I.MX6U 所有外设时钟
5 * @param : 无
6 * @return : 无
7 */
8 void clk_enable(void)
9 {
10 CCM->CCGR0 = 0XFFFFFFFF;
11 CCM->CCGR1 = 0XFFFFFFFF;
12 CCM->CCGR2 = 0XFFFFFFFF;
13 CCM->CCGR3 = 0XFFFFFFFF;
14 CCM->CCGR4 = 0XFFFFFFFF;
15 CCM->CCGR5 = 0XFFFFFFFF;
16 CCM->CCGR6 = 0XFFFFFFFF;
17 }
18 
19 /*
20 * @description : 初始化 LED 对应的 GPIO
21 * @param : 无
22 * @return : 无
23 */
24 void led_init(void)
25 {
26 /* 1、初始化 IO 复用 */
27 IOMUX_SW_MUX->GPIO1_IO03 = 0X5; /* 复用为 GPIO1_IO03 */
28 
29 
30 /* 2、配置 GPIO1_IO03 的 IO 属性 
31 *bit 16:0 HYS 关闭
32 *bit [15:14]: 00 默认下拉
33 *bit [13]: 0 kepper 功能
34 *bit [12]: 1 pull/keeper 使能
35 *bit [11]: 0 关闭开路输出
36 *bit [7:6]: 10 速度 100Mhz
37 *bit [5:3]: 110 R0/6 驱动能力
38 *bit [0]: 0 低转换率
39 */
40 IOMUX_SW_PAD->GPIO1_IO03 = 0X10B0;
41 
42
43 /* 3、初始化 GPIO */
44 GPIO1->GDIR = 0X0000008; /* GPIO1_IO03 设置为输出 */
45 
46 /* 4、设置 GPIO1_IO03 输出低电平,打开 LED0 */ 
47 GPIO1->DR &= ~(1 << 3);
48 
49 }
50 
51 /*
52 * @description : 打开 LED 灯
53 * @param : 无
54 * @return : 无
55 */
56 void led_on(void)
57 {
58 /* 将 GPIO1_DR 的 bit3 清零 */
59 GPIO1->DR &= ~(1<<3);
60 }
61 
62 /*
63 * @description : 关闭 LED 灯
64 * @param : 无
65 * @return : 无
66 */
67 void led_off(void)
68 {
69 /* 将 GPIO1_DR 的 bit3 置 1 */
70 GPIO1->DR |= (1<<3);
71 }
72 
73 /*
74 * @description : 短时间延时函数
75 * @param - n : 要延时循环次数(空操作循环次数,模式延时)
76 * @return : 无
77 */
78 void delay_short(volatile unsigned int n)
79 {
80 while(n--){}
81 }
82 
83 /*
84 * @description : 延时函数,在 396Mhz 的主频下
85 * 延时时间大约为 1ms
86 * @param - n : 要延时的 ms 数
87 * @return : 无
88 */
89 void delay(volatile unsigned int n)
90 {
91 while(n--)
92 {
93 delay_short(0x7ff);
94 }
95 }
96 
97 /*
98 * @description : main 函数
99 * @param : 无
100 * @return : 无
101 */
102 int main(void)
103 {
104 clk_enable(); /* 使能所有的时钟 */
105 led_init(); /* 初始化 led */
106
107 while(1) /* 死循环 */
108 { 
109 led_off(); /* 关闭 LED */
110 delay(500); /* 延时 500ms */
111
112 led_on(); /* 打开 LED */
113 delay(500); /* 延时 500ms */
114 }
115
116 return 0;
117 }

main.c 中 7 个函数,这 7 个函数的含义和I.MX6ULL Linux C语言开发环境搭建(点灯实验)main.c 文件一样,只是函数体写法变了,寄存器的访问采用 imx6ul.h 中定义的外设指针。比如第 27 行设置 GPIO1_IO03 的复用功能就可以通过“IOMUX_SW_MUX->GPIO1_IO03”来给寄存 SW_MUX_CTL_PAD_GPIO1_IO03赋值。


三、编译下载验证

编写 Makefile 和链接脚本
Makefile 文件的内容基本I.MX6ULL Linux C语言开发环境搭建(点灯实验)的 Makefile 一样

1 objs := start.o main.o
2 
3 ledc.bin:$(objs)
4 arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf $^
5 arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@
6 arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis
7 
8 %.o:%.s
9 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
10 
11 %.o:%.S
12 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
13 
14 %.o:%.c
15 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<
16 
17 clean:
18 rm -rf *.o ledc.bin ledc.elf ledc.dis

链接脚本 imx6ul.lds 的内容和I.MX6ULL Linux C语言开发环境搭建(点灯实验)一样,可以直接使用该链接脚本文件。

编译下载
使用 Make 命令编译代码,编译成功以后使用软件 imxdownload 将编译完成的 ledc.bin 文件下载到 SD 卡中,命令如下:

chmod 777 imxdownload //给予 imxdownload 可执行权限,一次即可
./imxdownload ledc.bin /dev/sdd //烧写到 SD 卡中,不能烧写到/dev/sda 或 sda1 设备里面!

烧写成功以后将 SD 卡插到开发板的 SD 卡槽中,然后复位开发板,如果代码运行正常的
话 LED0 就会以 500ms 的时间间隔亮灭。


END
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习——自己的训练集——图像分类(CNN)

图像分类 1.导入必要的库2.指定图像和标签文件夹路径3.获取文件夹内的所有图像文件名4.获取classes.txt文件中的所有标签5.初始化一个字典来存储图片名和对应的标签6.遍历每个图片名的.txt文件7.随机选择一张图片进行展示8.构建图像的完整路径9.加载图像10.检查图像是否为空 随…

消息队列实战应用

适用场景 耗时长&#xff0c;非核心业务&#xff0c;生产者不会用到消息处理结果的情况下&#xff0c;可以将消息交给异步服务去缓存与消费 部署MQ服务 version: "3.0" services:rabbitmq:container_name: rabbitmq-15672-1image: rabbitmq:3-managementports:- &…

短视频再度重逢:四川京之华锦信息技术公司

短视频再度重逢 在数字化时代的浪潮中&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为现代人生活中不可或缺的一部分。而当我们谈论起短视频&#xff0c;我们不仅仅是在谈论一种娱乐方式&#xff0c;更是在谈论一种情感的载体&#xff0c;一种回忆的媒介。今天&…

【ai】LiveKit Agent 的example及python本地开发模式工程实例

title: ‘LiveKit Agent Playground’ playgroundLiveKit Community playground的环境变量&#xff1a;LiveKit API # LiveKit API Configuration LIVEKIT_API_KEYYOUR_API_KEY LIVEKIT_API_SECRETYOUR_API_SECRET# Public configuration NEXT_PUBLIC_LIVEKIT_URLwss://YOUR_…

pytorch比较操作

文章目录 常用的比较操作1.torch.allclose()2.torch.argsort()3.torch.eq()4.torch.equal()5.torch.greater_equal()6.torch.gt()7.torch.isclose()8.torch.isfinite()9.torch.isif()10.torch.isposinf()11.torch.isneginf()12.torch.isnan()13.torch.kthvalue()14.torch.less_…

【从零开始学习RabbitMQ | 第二篇】如何确保MQ的可靠性和消费者可靠性

目录 前言&#xff1a; MQ可靠性&#xff1a; 数据持久化&#xff1a; Lazy Queue&#xff1a; 消费者可靠性&#xff1a; 消费者确认机制&#xff1a; 消费失败处理&#xff1a; MQ保证幂等性&#xff1a; 方法一&#xff1a; 总结&#xff1a; 前言&#xff1a; …

以梦为马,不负韶华(3)-AGI在企业服务的应用

AGI在企业服务中&#xff0c;各应⽤已覆盖企业全流程&#xff0c;包含⼈⼒、法务、财税、流程⾃动化、知识管理和软件开发各领域。 由于⼤语⾔模型对⽂本处理类场景有着天然且直接的适配性&#xff0c;⽂本总结、⽂本内容⽣成、服务指引等发展起步早且应⽤成熟度更⾼。 在数据…

Captura完全免费的电脑录屏软件

一、简介 1、Captura 是一款免费开源的电脑录屏软件&#xff0c;允许用户捕捉电脑屏幕上的任意区域、窗口、甚至是全屏画面&#xff0c;并将这些画面录制为视频文件。这款软件具有多种功能&#xff0c;例如可以设置是否显示鼠标、记录鼠标点击、键盘按键、计时器以及声音等。此…

LeetCode题练习与总结:有序链表转换二叉搜索树--109

一、题目描述 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为平衡二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0&#xff0c;-3,9&#xff0c;-10,null,5]&#xff0c;它表…

医疗图像处理2023:Transformers in medical imaging: A survey

医学成像中的transformer:综述 目录 一、介绍 贡献与安排 二、CNN和Transformer 1.CNN 2.ViT 三、Transformer应用于各个领域 1.图像分割 1&#xff09;器官特异性 ①2D ②3D 2&#xff09;多器官类别 ①纯transformer ②混合架构 单尺度 多尺度 3&#xff09;…

Kubernetes——监听机制与调度约束

目录 前言 一、监听机制 1.Pod启动创建过程 2.调度过程 1.指定调度节点 1.1强制匹配 1.2强制约束 二、硬策略和软策略 1.键值运算关系 1.硬策略——requiredDuringSchedulingIgnoredDuringExecution 2.软策略——preferredDuringSchedulingIgnoredDuringExecution …

Varjo XR-4功能详解:由凝视驱动的XR自动对焦相机系统

Varjo是XR市场中拥有领先技术的虚拟现实设备供应商&#xff0c;其将可变焦距摄像机直通系统带入到虚拟和混合现实场景中。在本篇文章中&#xff0c;Varjo的技术工程师维尔蒂莫宁详细介绍了这项在Varjo XR-4焦点版中投入应用的技术。 对可变焦距光学系统的需求 目前所有其他XR头…

基于STM32实现智能饮水机控制系统

目录 引言环境准备智能饮水机控制系统基础代码示例&#xff1a;实现智能饮水机控制系统 温度传感器数据读取水泵和加热器控制水位传感器数据读取用户界面与显示应用场景&#xff1a;家庭和办公室的智能饮水管理问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在S…

自适应感兴趣区域的级联多尺度残差注意力CNN用于自动脑肿瘤分割| 文献速递-深度学习肿瘤自动分割

Title 题目 Cascade multiscale residual attention CNNs with adaptive ROI for automatic brain tumor segmentation 自适应感兴趣区域的级联多尺度残差注意力CNN用于自动脑肿瘤分割 01 文献速递介绍 脑肿瘤是大脑细胞异常和不受控制的增长&#xff0c;被认为是神经系统…

第二证券炒股知识:股票破发后怎么办?

当一只新股的价格跌破其发行价时&#xff0c;往往会受到商场出资者的关注。关于股票破发后怎么办&#xff0c;第二证券下面就为我们具体介绍一下。 股票破发是指股票的商场价格低于其发行价格或最近一次增发价格&#xff0c;股票破发往往是由于多种要素共同作用的结果&#xf…

强化学习——学习笔记2

在上一篇文章中对强化学习进行了基本的概述&#xff0c;在此篇文章中将继续深入强化学习的相关知识。 一、什么是DP、MC、TD&#xff1f; 动态规划法&#xff08;DP&#xff09;&#xff1a;动态规划法离不开一个关键词&#xff0c;拆分 &#xff0c;就是把求解的问题分解成若…

亡羊补牢,一文讲清各种场景下GIT如何回退

系列文章目录 手把手教你安装Git&#xff0c;萌新迈向专业的必备一步 GIT命令只会抄却不理解&#xff1f;看完原理才能事半功倍&#xff01; 常用GIT命令详解&#xff0c;手把手让你登堂入室 GIT实战篇&#xff0c;教你如何使用GIT可视化工具 GIT使用需知&#xff0c;哪些操作…

Meta 推出新型多模态 AI 模型“变色龙”(Chameleon),挑战 GPT-4o,引领多模态革命

在人工智能领域&#xff0c;Meta 近日发布了一款名为“变色龙”&#xff08;Chameleon&#xff09;的新型多模态 AI 模型&#xff0c;旨在挑战 OpenAI 的 GPT-4o&#xff0c;并刷新了当前的技术标准&#xff08;SOTA&#xff09;。这款拥有 34B 参数的模型通过 10 万亿 token 的…

2-EMMC启动及各分区文件生成过程

EMMC的使用比nand flash还是复杂一些&#xff0c;有其特有的分区和电器性能 1、启动过程介绍 跟普通nand或spi flash不同&#xff0c;uboot前面还有好几级 在vendor某些厂商的设计中&#xff0c;ATF并不是BOOTROM加载后的第一个启动镜像&#xff0c;可能是这样的&#xff1a; …

微信小程序多端应用Donut Android生成签名

一、生成签名的作用 确保应用的完整性&#xff1a;签名可以确保应用在发布后没有被修改。如果应用被修改&#xff0c;签名就会改变&#xff0c;Android系统就会拒绝安装。确定应用的唯一身份&#xff1a;签名是应用的唯一标识&#xff0c;Android系统通过签名来区分不同的应用…