不干净的网站做性/商品关键词优化的方法
【ASOC全解析(三)】machine原理和实战
- 一、machine概述与原理
- 1.1 machine的主要职责
- 1.2 本文的主要内容
- 二、machine程序示例
- 完整的machine驱动代码示例
- 扩展知识:SND_SOC_DAILINK_DEFS
- 使用方法说明
- 总结与其它说明
/*****************************************************************************************************************/
声明: 本博客内容均由https://blog.csdn.net/weixin_47702410原创,转载or引用请注明出处,谢谢!
创作不易,如果文章对你有帮助,麻烦点赞 收藏支持~感谢
/*****************************************************************************************************************/
一、machine概述与原理
在ASOC中,Machine层,也称为“机器层”或“板级层”,是ASoC架构中负责将Codec和Platform层连接起来的部分。它是ASoC中与硬件平台相关的部分,通常包含了特定于机器(如开发板或产品)的音频路由和控制逻辑。
1.1 machine的主要职责
Machine层的主要职责包括:
-
定义音频路径:Machine层定义了音频数据在系统中的流动路径。这包括输入(如麦克风)和输出(如扬声器)设备的连接方式,以及它们如何与Codec设备进行交互。
-
控制音频接口:Machine层负责管理和配置音频接口,例如I2S、PCM、AC97等,这些接口用于在Codec和SoC之间传输音频数据。
-
音频路由和混音:Machine层定义了音频信号的路由,例如将哪个音频输入路由到哪个输出,以及如何混合不同的音频源。
-
DAPM(Dynamic Audio Power Management)配置:Machine层配置DAPM策略,以便在不使用某些音频组件时关闭它们的电源,从而节省能源。
-
板级初始化代码:Machine层包含了特定于机器的初始化代码,这些代码在系统启动时执行,用于初始化音频硬件和ASoC组件。
-
提供用户空间接口:Machine层通过ALSA提供了用户空间接口,允许应用程序控制音频硬件,例如调整音量、改变音频路由等。
Machine层通常是由设备制造商或社区开发者针对特定硬件平台编写的,因为它需要详细了解硬件的音频架构和功能。在Linux内核源代码中,Machine层的代码通常位于sound/soc/目录下的与特定板相关的子目录中。
Machine层的实现通常涉及到编写一个Machine驱动,这个驱动会注册一个snd_soc_card结构,该结构描述了音频卡的各种属性,包括DAI(Digital Audio Interface)链接、Codec信息、平台信息以及DAPM路由等。这个驱动还会处理与音频相关的平台特定事件,比如耳机插入检测或按钮控制等。
1.2 本文的主要内容
本文针对DAI的连接为主,进行相关的实践。即将所有组件驱动程序(例如Codec端、platform端和 DAI)粘合在一起的代码。
其它功能会关联ALSA Core层或者DAPM或者指定硬件相关的知识,后续有时间再另作文章介绍。
二、machine程序示例
针对DAI的连接,主要是有三个步骤:
- 1、定义DAI_Link连接codec和platform
- 2、定义声卡,需要定义snd_soc_card
- 3、注册声卡
上面的这三点,主要是调用API函数snd_soc_register_card完成(这个函数很重要,但内容较多,后续有时间再出一版文章详细说明)
完整的machine驱动代码示例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>SND_SOC_DAILINK_DEFS(mycodec,DAILINK_COMP_ARRAY(COMP_CPU("myplat.0")),DAILINK_COMP_ARRAY(COMP_CODEC("my_codec.0", "my_codec_dai")),DAILINK_COMP_ARRAY(COMP_PLATFORM("myplat.0")));static int my_card_init(struct snd_soc_pcm_runtime *rtd)
{printk("%s,line:%d\n",__func__,__LINE__);return 0;
}static int my_card_hw_params(struct snd_pcm_substream *substream,struct snd_pcm_hw_params *params) {struct snd_soc_pcm_runtime *rtd = substream->private_data;//struct snd_soc_dai *codec_dai = rtd->codec_dai;struct snd_soc_card *card = rtd->card;unsigned int freq;//int ret;int stream_flag;printk("%s,line:%d\n",__func__,__LINE__);switch (params_rate(params)) {case 8000:case 12000:case 16000:case 24000:case 32000:case 48000:case 96000:case 192000:freq = 24576000;break;case 11025:case 22050:case 44100:freq = 22579200;break;default:dev_err(card->dev, "invalid rate setting\n");return -EINVAL;}/* the substream type: 0->playback, 1->capture */stream_flag = substream->stream;return 0;
}static struct snd_soc_ops my_card_ops = {.hw_params = my_card_hw_params,
};static struct snd_soc_dai_link my_card_dai_link[] = {{.name = "my-codec",.stream_name = "MY-CODEC",SND_SOC_DAILINK_REG(mycodec),
/*SND_SOC_DAILINK_REG(mycodec)等效于.codec_name = "my_codec.0",.codec_dai_name = "my_codec_dai",.cpu_dai_name = "myplat.0",.platform_name = "myplat.0",
*/.init = my_card_init,.ops = &my_card_ops,},
};static struct snd_soc_card snd_soc_my_card = {.name = "my-codec",.owner = THIS_MODULE,.dai_link = my_card_dai_link,.num_links = ARRAY_SIZE(my_card_dai_link),
};static int mymachine_probe(struct platform_device *pdev) {int ret = 0;struct snd_soc_card *card = &snd_soc_my_card;printk("-----%s----\n",__func__);/* register the soc card */card->dev = &pdev->dev;ret = snd_soc_register_card(card);if (ret < 0) {dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);return -1;}return ret;
}static int mymachine_remove(struct platform_device *pdev){printk("-----%s----\n",__func__);return 0;
}static void mymachine_pdev_release(struct device *dev){printk("-----%s----\n",__func__);
}static struct platform_device mymachine_pdev = {.name = "mymachine",.dev.release = mymachine_pdev_release,
};static struct platform_driver mymachine_pdrv = {.probe = mymachine_probe,.remove = mymachine_remove,.driver = {.name = "mymachine",},
};static int __init mymachine_init(void)
{int ret;ret = platform_device_register(&mymachine_pdev);if (ret)return ret;ret = platform_driver_register(&mymachine_pdrv);if (ret)platform_device_unregister(&mymachine_pdev);return ret;
}static void __exit mymachine_exit(void)
{platform_driver_unregister(&mymachine_pdrv);platform_device_unregister(&mymachine_pdev);
}module_init(mymachine_init);
module_exit(mymachine_exit);
MODULE_LICENSE("GPL");
扩展知识:SND_SOC_DAILINK_DEFS
从Linux 5.x开始,Linux使用宏SND_SOC_DAILINK_REG快捷定义DAI_LINK中的有关codec和platform连接关系。
其本质和5.x之前的版本并无实质的变化,仅是在形式上采用了一种更加便捷的定义方法。相关源码主要参考“linux/v5.10.177/source/include/sound/soc.h“
本小节主要扩展解释一下下面的语句:
SND_SOC_DAILINK_DEFS(mycodec,DAILINK_COMP_ARRAY(COMP_CPU("myplat.0")),DAILINK_COMP_ARRAY(COMP_CODEC("my_codec.0", "my_codec_dai")),DAILINK_COMP_ARRAY(COMP_PLATFORM("myplat.0")));SND_SOC_DAILINK_REG(mycodec),
SND_SOC_DAILINK_DEFS的定义如下:
#define SND_SOC_DAILINK_DEFS(name, cpu, codec, platform...) \SND_SOC_DAILINK_DEF(name##_cpus, cpu); \SND_SOC_DAILINK_DEF(name##_codecs, codec); \SND_SOC_DAILINK_DEF(name##_platforms, platform)
代入得到:
#define SND_SOC_DAILINK_DEFS(mycodec, COMP_CPU("myplat.0"), COMP_CODEC("my_codec.0", "my_codec_dai"), COMP_PLATFORM("myplat.0")) \
//...
再展开上面的三个宏可以得到:
#define SND_SOC_DAILINK_DEFS(mycodec, { .dai_name = "myplat.0", }, { .name = "my_codec.0", .dai_name = "my_codec_dai", }, { .name = "myplat.0" }) \
//...
将上面的结果完整代入SND_SOC_DAILINK_DEF,即可以得到完整的SND_SOC_DAILINK_DEFS展开结果:
SND_SOC_DAILINK_DEF(mycodec_cpus, { .dai_name = "myplat.0", }); \SND_SOC_DAILINK_DEF(mycodec_codecs, { .name = "my_codec.0", .dai_name = "my_codec_dai", }); \SND_SOC_DAILINK_DEF(mycodec_platforms, { .name = "myplat.0" })
进一步代入SND_SOC_DAILINK_DEF可以得到:
static struct snd_soc_dai_link_component mycodec_cpus[] = { .dai_name = "myplat.0", };static struct snd_soc_dai_link_component mycodec_codecs[] = {.name = "my_codec.0", .dai_name = "my_codec_dai", };static struct snd_soc_dai_link_component mycodec_platforms[] = {.name = "myplat.0" };
使用方法说明
使用方法
SND_SOC_DAILINK_REG(name),
这个宏展开后如下:
.cpus = mycodec_cpus,.num_cpus = ARRAY_SIZE(mycoded_cpus),.codecs = mycodec_codecs,.num_codecs = ARRAY_SIZE(mycodec_codecs),.platforms = mycodec_platforms,.num_platforms = ARRAY_SIZE(mycodec_platforms),
总结与其它说明
SND_SOC_DAILINK_DEFS(mycodec,DAILINK_COMP_ARRAY(COMP_CPU("myplat.0")),DAILINK_COMP_ARRAY(COMP_CODEC("my_codec.0", "my_codec_dai")),DAILINK_COMP_ARRAY(COMP_PLATFORM("myplat.0")));static struct snd_soc_dai_link my_card_dai_link[] = {{.name = "my-codec",.stream_name = "MY-CODEC",SND_SOC_DAILINK_REG(mycodec),.init = my_card_init,.ops = &my_card_ops,},
};//***************************************************************
//最终展开是:
static struct snd_soc_dai_link_component mycodec_cpus[] = { .dai_name = "myplat.0",
};static struct snd_soc_dai_link_component mycodec_codecs[] = {.name = "my_codec.0", .dai_name = "my_codec_dai",
};static struct snd_soc_dai_link_component mycodec_platforms[] = {.name = "myplat.0"
};static struct snd_soc_dai_link my_card_dai_link[] = {{.name = "my-codec",.stream_name = "MY-CODEC",.cpus = mycodec_cpus,.num_cpus = ARRAY_SIZE(mycodec_cpus),.codecs = mycodec_codecs,.num_codecs = ARRAY_SIZE(mycodec_codecs),.platforms = mycodec_platforms,.num_platforms = ARRAY_SIZE(mycodec_platforms),.init = my_card_init,.ops = &my_card_ops,},
};
其它说明
Linux源码中也另外提供了三种DAI_Link的定义方式,下面直接分析其内容的含义,先看Linux官方的说明:
//include/sound/soc.h
/** Sample 1 : Single CPU/Codec/Platform** SND_SOC_DAILINK_DEFS(test,* DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai")),* DAILINK_COMP_ARRAY(COMP_CODEC("codec", "codec_dai")),* DAILINK_COMP_ARRAY(COMP_PLATFORM("platform")));** struct snd_soc_dai_link link = {* ...* SND_SOC_DAILINK_REG(test),* };** Sample 2 : Multi CPU/Codec, no Platform** SND_SOC_DAILINK_DEFS(test,* DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai1"),* COMP_CPU("cpu_dai2")),* DAILINK_COMP_ARRAY(COMP_CODEC("codec1", "codec_dai1"),* COMP_CODEC("codec2", "codec_dai2")));** struct snd_soc_dai_link link = {* ...* SND_SOC_DAILINK_REG(test),* };** Sample 3 : Define each CPU/Codec/Platform manually** SND_SOC_DAILINK_DEF(test_cpu,* DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai1"),* COMP_CPU("cpu_dai2")));* SND_SOC_DAILINK_DEF(test_codec,* DAILINK_COMP_ARRAY(COMP_CODEC("codec1", "codec_dai1"),* COMP_CODEC("codec2", "codec_dai2")));* SND_SOC_DAILINK_DEF(test_platform,* DAILINK_COMP_ARRAY(COMP_PLATFORM("platform")));** struct snd_soc_dai_link link = {* ...* SND_SOC_DAILINK_REG(test_cpu,* test_codec,* test_platform),* };** Sample 4 : Sample3 without platform** struct snd_soc_dai_link link = {* ...* SND_SOC_DAILINK_REG(test_cpu,* test_codec);* };*/
这段注释提供了几个示例来说明如何使用SND_SOC_DAILINK_DEFS和SND_SOC_DAILINK_REG宏来定义和注册SoC音频dailink。一个dailink通常包含一个CPU(DMA引擎),一个或多个编解码器,以及一个平台(音频控制器硬件)。
下面是每个示例的解释:
- 示例 1:单个CPU/Codec/Platform
SND_SOC_DAILINK_DEFS(test,DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai")),DAILINK_COMP_ARRAY(COMP_CODEC("codec", "codec_dai")),DAILINK_COMP_ARRAY(COMP_PLATFORM("platform")));
这个示例展示了如何定义一个包含单个CPU、Codec和Platform的dailink。SND_SOC_DAILINK_DEFS宏用于创建三个数组:test_cpus、test_codecs和test_platforms,每个数组包含一个组件。
struct snd_soc_dai_link link = {...SND_SOC_DAILINK_REG(test),
};
然后,SND_SOC_DAILINK_REG宏用于在snd_soc_dai_link结构体中注册这些组件。
- 示例 2:多个CPU/Codec,没有Platform
SND_SOC_DAILINK_DEFS(test,DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai1"),COMP_CPU("cpu_dai2")),DAILINK_COMP_ARRAY(COMP_CODEC("codec1", "codec_dai1"),COMP_CODEC("codec2", "codec_dai2")));
这个示例展示了如何定义一个包含多个CPU和Codec,但没有Platform的dailink。SND_SOC_DAILINK_DEFS宏创建了两个数组:test_cpus和test_codecs,每个数组包含两个组件。
struct snd_soc_dai_link link = {...SND_SOC_DAILINK_REG(test),
};
SND_SOC_DAILINK_REG宏在这里假定Platform是空的,并在snd_soc_dai_link结构体中注册CPU和Codec组件。
- 示例 3:手动定义每个CPU/Codec/Platform
SND_SOC_DAILINK_DEF(test_cpu,DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai1"),COMP_CPU("cpu_dai2")));
SND_SOC_DAILINK_DEF(test_codec,DAILINK_COMP_ARRAY(COMP_CODEC("codec1", "codec_dai1"),COMP_CODEC("codec2", "codec_dai2")));
SND_SOC_DAILINK_DEF(test_platform,DAILINK_COMP_ARRAY(COMP_PLATFORM("platform")));
这个示例展示了如何手动定义每个CPU、Codec和Platform组件。SND_SOC_DAILINK_DEF宏用于创建三个独立的数组。
struct snd_soc_dai_link link = {...SND_SOC_DAILINK_REG(test_cpu,test_codec,test_platform),
};
然后,SND_SOC_DAILINK_REG宏用于在snd_soc_dai_link结构体中注册这些组件。
- 示例 4:没有Platform的示例3
struct snd_soc_dai_link link = {...SND_SOC_DAILINK_REG(test_cpu,test_codec);
};
这个示例与示例3类似,但它省略了Platform组件。SND_SOC_DAILINK_REG宏在这里只注册CPU和Codec组件。
这些示例展示了如何灵活地使用宏来定义和注册不同配置的dailinks,这对于SoC音频驱动的开发非常重要。
相关文章:

【ASOC全解析(三)】machine原理和实战
【ASOC全解析(三)】machine原理和实战 一、machine概述与原理1.1 machine的主要职责1.2 本文的主要内容 二、machine程序示例完整的machine驱动代码示例扩展知识:SND_SOC_DAILINK_DEFS使用方法说明总结与其它说明 /*************************…...

matlab appdesigner系列-常用15-滑块、微调器
滑块,以左右拖动的方式在一定范围内改变数值 此示例,滑块显示微调器的数值,微调器也可以显示滑块的数值 操作步骤为: 1)将滑块和微调器拖拽到画布上 2)分别设置这两个组件的回调函数 回调函数有两个选项…...

google翻译相机报错 请安装最新的Google应用,以便使用相机翻译功能
修复:google翻译相机报错 背景:解决方法 背景: 国内手机使用google翻译的相机时报错: 请安装最新的Google应用,以便使用相机翻译功能点击报错的“确定”后转到了国内空白的软件商店页面 解决方法 Google Play搜索 …...

openssl3.2/test/certs - 015 - Primary intermediate ca: ca-cert
文章目录 openssl3.2/test/certs - 015 - Primary intermediate ca: ca-cert概述笔记END openssl3.2/test/certs - 015 - Primary intermediate ca: ca-cert 概述 openssl3.2 - 官方demo学习 - test - certs 笔记 这个例子有不同的地方, 发证书时, 指定了CA. 看实验注释, 是…...

linux中用户及用户组信息
1,linux通过用户名和口令来验证用户的身份。 2,几个用户可以组成一个用户组。 3,useradd工具添加用户,groupadd命令添加用户组。 4,history 命令查看用户在Shell中执行命令的历史记录。 5,userdel命令删…...

用Go plan9汇编实现斐波那契数列计算
斐波那契数列是一个满足递推关系的数列,如:1 1 2 3 5 8 ... 其前两项为1,第3项开始,每一项都是其前两项之和。 用Go实现一个简单的斐波那契计算逻辑 func fib(n int) int {if n 1 || n 2 {return 1}return fib(n-1) fib(n-2) …...

Message queue 消息队列--RabbitMQ 【基础入门】
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是平顶山大师,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《Message queue 消息队列--RabbitMQ 【基础入门…...

【汇编】 13.3 对int iret和栈的深入理解
书中示例 assume cs:codecode segment start:mov ax,csmov ds,axmov si,offset lpmov ax,0mov es,axmov di,200hmov cx,offset end0-offset lpcldrep movsb ;lp到end0的指令传送到0:200处mov ax,0mov es,axmov word ptr es:[7ch*4],200hmov word ptr es:[7ch*42],0 ;设置7c表项…...

Git提交大文件报错“remote: Please remove the file from history and try again. ”
如在使用Git过程中不小心将较大的二进制文件加入仓库,那么仓库大小很快就会超过规定的配额,在Push的时候会报下面的错误: remote: Powered by GITEE.COM [GNK-6.4] remote: error: File: c91e5de4f55bedd0669db01036fc131ea8e516ce 130.66 MB…...

接口测试 03 -- 接口自动化思维 Requests库应用
1. 接口自动化思维梳理 1.1接口自动化的优点 接口测试自动化,简单来讲就是功能测试用例脚本化然后执行脚本,产生一份可视化测试报告。不管什么样的测试方式,都是为了验证功能与发现 BUG。那为什么要做接口测试自动化呢?一句话概括…...

SpringBoot:Bean生命周期自定义初始化和销毁
🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java项目分享》 《RabbitMQ》《Spring》《SpringMVC》 🛸学无止境,不骄不躁,知行合一 文章目录 前言一、Bean注解指…...

Git--基本操作介绍(2)
Git 常用的是以下 6 个命令:git clone、git push、git add 、git commit、git checkout、git pull. 说明: workspace:工作区staging area:暂存区/缓存区local repository:版本库或本地仓库remote repository…...

第08章_面向对象编程(高级)(static,单例设计模式,理解mian方法,代码块,final,抽象类与抽象方法,接口,内部类,枚举类,注解,包装类)
文章目录 第08章_面向对象编程(高级)本章专题与脉络1. 关键字:static1.1 类属性、类方法的设计思想1.2 static关键字1.3 静态变量1.3.1 语法格式1.3.2 静态变量的特点1.3.3 举例1.3.4 内存解析 1.4 静态方法1.4.1 语法格式1.4.2 静态方法的特点1.4.3 举例 1.5 练习 …...

Java中Map接口常用的方法
java.util.Map接口中常用的方法: 1.Map和Collection没有继承关系 2.Map集合以key和value的方式存储数据:键值对 key和value都是引用数据类型 key和value都是存储对象的内存地址 key起到主导的地位,value是key的一个附属品 3.Map接口中常用的方…...

Linux软件包管理器yum
文章目录 前言概述Linux下载软件的三种方式源代码安装rpm安装yum安装 关于yum的相关操作查看软件包软件安装卸载软件 yum源问题 前言 在Windows系统中,如果我们要去下载软件,我们可以在该软件的官网中进行下载,或者在微软的额软件商店进行下…...

Linux中NFS服务器的搭建和安装
1.介绍: 网络文件系统即将本地系统放在网络上某一个位置的系统,基于UDP/IP使用nfs能够在不同计算机之间通过网络进行文件共享,能使使用者访问网络上其他计算机中的文件就像在访问自己的计算机一样,也就是说放在一个开发板上&#…...

c递归算法模型
使用递归算法模型可以较为自然地解决许多问题,尤其是对于那些数据结构层次比较清晰的问题,递归算法模型往往能够提供一种简单清晰的解法。 递归算法模型的核心思想是将一个大问题通过递归的方式拆分为若干个较小的问题,并不断递归下去直到问…...

力扣740. 删除并获得点数
动态规划 思路: 选择元素 x,获得其点数,删除 x 1 和 x - 1,则其他的 x 的点数也会被获得;可以将数组转换成一个有序 map,key 为 x, value 为对应所有 x 的和;则问题转换成了不能同…...

spring和springboot的区别
在当今的软件开发领域,Spring和Spring Boot无疑是Java开发者最常用的框架之一。尽管它们都源于Spring项目,但它们在设计和使用上有很大的不同。本文将深入探讨Spring和Spring Boot之间的主要区别,以及为什么有时候选择其中一个而不是另一个是…...

imgaug库图像增强指南(35):【iaa.Fog】——轻松创建自然雾气场景
引言 在深度学习和计算机视觉的世界里,数据是模型训练的基石,其质量与数量直接影响着模型的性能。然而,获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此,数据增强技术应运而生,成为了解决这一问题的…...

网络安全--防御保护02
第二天重要的一个点是区域这个概念 防火墙的主要职责在于控制和防护---安全策略---防火墙可以根据安全策略来抓取流量之后做出对应的动作 防火墙的分类: 单一主机防火墙:专门有设备作为防火墙 路由集成:核心设备,可流量转发 分…...

UE5 C++学习笔记 常用宏的再次理解
1.随意创建一个类,他都有UCLASS()。GENERATED_BODY()这样的默认的宏。 UCLASS() 告知虚幻引擎生成类的反射数据。类必须派生自UObject. (告诉引擎我是从远古大帝UObject中,继承而来,我们是一家人,只是我进化了其他功能…...

SpringBoot整合SSE
目录 1.SseController2. SseServiceSseServiceSseServiceImpl 3.SendMessageTask4.将定时任务加入启动类5.参考资料 1.SseController Slf4j RestController RequestMapping("sse") public class SseController {Autowiredprivate SseService sseService;RequestMappi…...

mysql-进阶篇
文章目录 存储引擎MySQL体系结构相关操作 存储引擎特点InnoDBInnoDB 逻辑存储结构 MyISAMMemory三个存储引擎之间的区别存储引擎的选择 索引1. 索引结构B-TreeB-Tree (多路平衡查找树)B-Tree演变过程 BTree与 B-Tree 的区别BTree演变过程 Hash 2.索引分类3.索引语法演示 4.SQL性…...

Js中的构造函数
在JavaScript中,构造函数是一种特殊类型的方法,用于创建并初始化一个新的对象。它通常使用 new 关键字来调用,并且通常以大写字母开头,以与其他非构造函数区分开来。 一个简单的构造函数示例: function Person(name,…...

[小程序]页面事件
一、下拉刷新 1.开启和配置 小程序中开启下拉刷新的方式有两种: ①全局开启下来刷新 在app.json的window节点中,设置enablePullDownRefresh设为ture。 ②局部开启下来刷新 在页面对应的json文件的的window节点中,设置enablePullDownRefresh设…...

vue echarts地图
下载地图文件: DataV.GeoAtlas地理小工具系列 范围选择器右侧行政区划范围中输入需要选择的省份或地市,选择自己想要的数据格式,这里选择了geojson格式,点右侧的蓝色按钮复制到浏览器地址栏中,打开的geojson文件内容…...

v38.Switch语句
1.Switch语句可以替代if-else语句 2.具体使用 Switch(expression) { case label:...... } ①将x与case后的label 进行比较; ②注意后面有冒号; ③从上往下开始检查case; ④如果…...

如何进行产品的人机交互设计?
产品的人机交互设计是指通过用户界面和用户体验设计来优化产品与用户之间的交互过程,从而提高产品的易用性、可用性和用户满意度。人机交互设计需要考虑用户的需求、行为模式、心理感受以及技术实现,下面我将介绍如何进行产品的人机交互设计。 首先&…...

【ARMv8M Cortex-M33 系列 7.3 -- EXC_RETURN 与 LR 及 PC 的关系详细介绍】
请阅读【嵌入式开发学习必备专栏 之 ARM Cortex-Mx专栏】 文章目录 背景EXC_RETURN 与 LR 及 PCcortex-m33 从异常返回后 各个寄存器出战顺序ARM 栈增长方式 背景 接着上篇文章:【ARMv8M Cortex-M33 系列 7.2 – HardFault 问题定位 1】,后面定位到是在…...