Melis4.0[D1s]:1.启动流程(与adc按键初始化相关部分)跟踪笔记

news/2024/5/17 9:20:19/文章来源:https://blog.csdn.net/hwd00001/article/details/129117492

文章目录

  • 1.启动流程
    • 1.1 最先进入的文件:head_s.S
    • 1.2 start_kernel()函数所在的文件:init.c
    • 1.3 input_init()函数所在文件:sys_input.c
    • 1.4 INPUT_LKeyDevInit()所在文件:keyboarddev.c
    • 1.5 esINPUT_RegLdev()所在文件:input.c
      • 1.5.1 来到这里,无法与后面的硬件初始化搭上关系。
  • 2.从底层操作硬件的函数往前面跟踪
    • 2.1 实现对adc按键硬件初始化的函数 sunxi_keyboard_init()
      • 2.1.1 本函数是被do_initcalls()调用的
      • 2.1.2 本函数注册了中断函数keyboard_irq_callback(),直接产生按键消息
  • 3.根据分压电阻的实际阻值修改代码
    • 3.1 关键代码分析
    • 3.1 根据硬件不同,重新计算参数
  • 4. mq-r(F133)按键接法

本文是自己为了厘清Melis4.0[D1s]启动时加载输入按键驱动流程而做的笔记。

1.启动流程

Melis4.0的RTOS内核有2种选择,我们选的是RT-Thread:
在这里插入图片描述
关于RT-Thread启动流程的详细资料可以参考官方文档:RT-Thread Nano 移植原理。
但是Melis的启动流程似乎与RT-Thread关系不大,参考全志官方文档《Melis4.0 RTOS系统开发指南》。
下面做部分摘录,稍作整理:

1.1 最先进入的文件:head_s.S

该文件路径为 《D1s-Melis\ekernel\arch\riscv\rv64gc\head_s.S》,完成以下功能:

• bss 段的清零;
• sp 栈指针的初始化;
• mmu 初始化和页表基地址赋值;
• 异常统一入口赋值;
• 跳转至 start_kernel 函数;

1.2 start_kernel()函数所在的文件:init.c

该文件路径为 《D1s-Melis\ekernel\arch\riscv\sunxi\init.c》start_kernel()函数间接调用input_init()函数完成输入设备初始化函数的调用。
在这里插入图片描述
这里的awos_init_thread()函数还调用do_initcalls(),而do_initcalls()调用了sunxi_keyboard_init()。下面摘录官方文章介绍do_initcalls()的内容:

do_initcalls()函数通过层层调用,调用了initcall_levels数组定义的函数地址标识,这些地址标识在riscv/lds/kernel.lds中定义,表示代码段名称为initcallxx.init类的代码,c 文件通过__attribute__((section(“text”))),指定函数或变量在链接时存放的代码段段名称。这个由source/include/melis/init.h文 件 中 的 宏 定 义___define_initcall(fn, id, .initcall##id)来 声 明 实现。
例 如:subsys_initcall(drv_dma_init);将 函 数 指 定 到 代 码 段.initcall4.init, 将 会 在 调用__initcall4_start时,把__initcall4_start到__initcall5_start代码段地址区间的函数接口执行一遍。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 input_init()函数所在文件:sys_input.c

该文件路径为 《D1s-Melis\ekernel\legacy\input\sys_input.c》,按键初始化是默认有的,触摸则根据配置参数决定是否初始化,鼠标则默认没有。按键设备的初始化函数为INPUT_LKeyDevInit(),继续跟踪。

int32_t input_init(void)
{__inf("input system initialize....");if (INPUT_CoreInit() != EPDK_OK){__wrn("INPUT_CoreInit failed");return EPDK_FAIL;}if (INPUT_LKeyDevInit() != EPDK_OK){__wrn("INPUT_LkeyDevInit failed");INPUT_CoreExit();return EPDK_FAIL;}
#if 0if (INPUT_LMouseDevInit() != EPDK_OK){__wrn("INPUT_LMouseDevInit failed");INPUT_LKeyDevExit();INPUT_CoreExit();return EPDK_FAIL;}
#endif#if CONFIG_SUPPORT_TOUCHPANELif (INPUT_LTSDevInit() != EPDK_OK){__wrn("INPUT_LTPDevInit failed");//INPUT_LMouseDevExit();INPUT_LKeyDevExit();INPUT_CoreExit();return EPDK_FAIL;}
#endifreturn EPDK_OK;
}

1.4 INPUT_LKeyDevInit()所在文件:keyboarddev.c

该文件路径为 《D1s-Melis\ekernel\legacy\input\keyboard\keyboarddev.c》,调用了esINPUT_RegLdev()

1.5 esINPUT_RegLdev()所在文件:input.c

该文件路径为 《D1s-Melis\ekernel\legacy\input\input\input.c》

1.5.1 来到这里,无法与后面的硬件初始化搭上关系。

上面是从开始往后面跟踪调用子函数,下面是从子函数跟踪被哪个上级函数调用,来到这里失联了。

2.从底层操作硬件的函数往前面跟踪

根据本节的分析,adc按键的功能是默认的,不用使用 make menuconfig 进行配置。

2.1 实现对adc按键硬件初始化的函数 sunxi_keyboard_init()

该文件路径为 《D1s-Melis\ekernel\drivers\drv\source\input\keyboard\sunxi_keyboard.c》

2.1.1 本函数是被do_initcalls()调用的

在文件sunxi_keyboard.c有下面的语句:

late_initcall(sunxi_keyboard_init);

对应的宏定义在文件 《D1s-Melis\include\melis\init.h》

#define late_initcall(fn)		__define_initcall(fn, 7)

于是变成了指针数组 initcall_levels 的一员:

static initcall_entry_t *initcall_levels[] =
{__initcall0_start,__initcall1_start,__initcall2_start,__initcall3_start,__initcall4_start,__initcall5_start,__initcall6_start,__initcall7_start,__initcall_end,
};

最终在do_initcalls()被调用,do_initcalls()所在的文件为 《D1s-Melis\ekernel\arch\common\initcall.c》

2.1.2 本函数注册了中断函数keyboard_irq_callback(),直接产生按键消息

int sunxi_keyboard_init(void)
{.......hal_gpadc_init();hal_gpadc_channel_init(GP_CH_0);hal_gpadc_register_callback(GP_CH_0, keyboard_irq_callback);return 0;
}

keyboard_irq_callback()可以直接发送系统消息:

int keyboard_irq_callback(uint32_t data_type, uint32_t data)
{......if (key_data->key_code  < key_config.key_num){if (key_flag == 0){console_LKeyDevEvent(NULL,  EV_KEY,  key_data->scankeycodes[key_data->key_code],  1);console_LKeyDevEvent(NULL,  EV_SYN,  0,  0);key_flag = 1;}......
}

3.根据分压电阻的实际阻值修改代码

官方的adc按键部分电路:
在这里插入图片描述
我用万能板焊接的电路板,使用了手头已有的电阻4.7k,10k,20k,30k:
在这里插入图片描述

3.1 关键代码分析

计算键值的关键代码:

struct sunxikbd_config key_config =
{.measure = 1800,.key_num = 5,.key_vol = {210, 410, 590, 750, 880},.scankeycodes = {KPAD_UP, KPAD_DOWN, KPAD_ENTER, KPAD_MENU, KPAD_RETURN},.name = "sunxi-keyboard"
};static unsigned char keypad_mapindex[128] =
{0, 0, 0, 0, 0, 0, 0, 0, 0,      /* key 1, 0-8 */1, 1, 1, 1, 1,                  /* key 2, 9-13 */2, 2, 2, 2, 2, 2,               /* key 3, 14-19 */3, 3, 3, 3, 3, 3,               /* key 4, 20-25 */4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,    /* key 5, 26-36 */5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,    /* key 6, 37-39 */6, 6, 6, 6, 6, 6, 6, 6, 6,      /* key 7, 40-49 */7, 7, 7, 7, 7, 7, 7             /* key 8, 50-63 */
};

大概思路是将AD值处理后(大约是除以32),在keypad_mapindex[]里面查表,得到一个在0-4(共5个按键)范围内的值,再从key_config. scankeycodes[]里面查表得到最终的键值。以key1为例,key1按下时的AD值(理论值) 经过处理,应该是4,这样可以使允许误差最大化。

3.1 根据硬件不同,重新计算参数

K0对应的AD理论值为183,除以32得 5.7,约等于6,那么可以取:

static unsigned char keypad_mapindex[128] =
{0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0,     /* key 1, 0-10 */

K1对应的AD理论值为524,除以32得 16.3,约等于16,那么可以取:

static unsigned char keypad_mapindex[128] =
{0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0,     /* key 1, 0-10 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1,         /* key 2, 11-20 */

K2对应的AD理论值为1055,除以32得 33,那么可以取:

static unsigned char keypad_mapindex[128] =
{0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0,     /* key 1, 0-10 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1,         /* key 2, 11-20 */2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,					  /* key 3, 21-36 */

K3对应的AD理论值为1448,除以32得 45.2,约等于45,那么可以取:

static unsigned char keypad_mapindex[128] =
{0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0,     /* key 1, 0-10 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1,         /* key 2, 11-20 */2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 			 /* key 3, 21-39 */3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3/* key 4, 40-50 */

K3对应的AD理论值为1878,除以32得 58.6,约等于58,那么可以取:

static unsigned char keypad_mapindex[128] =
{0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0,     /* key 1, 0-10 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1,         /* key 2, 11-20 */2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 			 /* key 3, 21-39 */3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3/* key 4, 40-50 */4, 4, 4, 4, 4, 4, 4, 4, 4, 4,4, 4, 4, 4, 4, 4, 4, 4, 4,          /* key 5, 51-69 */

其实,这个表是由下面的代码重新计算,并覆盖掉的:

static int sunxikbd_data_init(struct sunxikbd_drv_data *key_data, struct sunxikbd_config *sunxikbd_config)
{int i, j = 0;int key_num = 0;unsigned int resol;unsigned int key_vol[KEY_MAX_CNT];key_num = sunxikbd_config->key_num;if (key_num < 1 || key_num > KEY_MAX_CNT){return -1;}resol = sunxikbd_config->measure / MAXIMUM_SCALE;for (i = 0; i < key_num; i++){key_data->scankeycodes[i] = sunxikbd_config->scankeycodes[i];}for (i = 0; i < key_num; i++){key_vol[i] = sunxikbd_config->key_vol[i];}for (i = 0; i < (key_num - 1); i++){key_vol[i] += (key_vol[i + 1] - key_vol[i]) / 2;}
/*for (i = 0; i < MAXIMUM_SCALE; i++){if (i * resol > key_vol[j]){j++;}keypad_mapindex[i] = j;}
*/key_data->last_key_code = INITIAL_VALUE;return 0;
}

我因为还没看懂这个函数的逻辑,把其中覆盖keypad_mapindex[128]的代码屏蔽了。

4. mq-r(F133)按键接法

在这里插入图片描述

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

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

相关文章

【LeetCode】剑指 Offer 09. 用两个栈实现队列 p68 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/ 1. 题目介绍&#xff08;09. 用两个栈实现队列&#xff09; 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别…

如何运行YOLOv6的代码实现目标识别?

YOLOv6是由美团视觉团队开发的1.环境配置我们先把YOLOv6的代码clone下来git clone https://github.com/meituan/YOLOv6.git安装一些必要的包pip install pycocotools2.0作者要求pytorch的版本是1.8.0,我的环境是1.7.0&#xff0c;也是可以正常运行的pip install -r requirement…

【机器学习】决策树-C4.5算法

1.C4.5算法 C4.5算法与ID3相似&#xff0c;在ID3的基础上进行了改进&#xff0c;采用信息增益比来选择属性。ID3选择属性用的是子树的信息增益&#xff0c;ID3使用的是熵&#xff08;entropy&#xff0c; 熵是一种不纯度度量准则&#xff09;&#xff0c;也就是熵的变化值&…

Kaldi语音识别技术(六) ----- DTW和HMM-GMM

Kaldi语音识别技术(六) ----- DTW和HMM-GMM 文章目录Kaldi语音识别技术(六) ----- DTW和HMM-GMM前言一、语音识别概况二、语音识别基本原理三、DTW&#xff08;动态时间弯折&#xff09;算法四、GMM-HMM前言 前面的内容中我们完成了特征的提取,那么本章节我们主要进行理论部分…

2023爱分析· 云管理服务(MSP)市场厂商评估报告:华创方舟

目录 1. 研究范围定义 2. 云管理服务&#xff08;MSP&#xff09;市场定义 3. 厂商评估&#xff1a;华创方舟 4. 入选证书 1. 研究范围定义 数字化时代&#xff0c;应用成为企业开展各项业务的落脚点。随着业务的快速发展&#xff0c;应用的功能迭代变得越来越…

VSCode Remote-SSH配置免密登录踩坑

VSCode Remote-SSH配置免密登录踩坑1. 参考2. 基本流程2.1 机器A&#xff08;Windows客户端&#xff09;2.2 机器B&#xff08;Linux服务器&#xff09;2.3 机器A&#xff08;Windows客户端&#xff09;的VSCode设置3. 踩坑总结相关教程很多&#xff0c;但要么冗余&#xff0c;…

Elasticsearch:提升 Elasticsearch 性能

Elasticsearch 是为你的用户提供无缝搜索体验的不可或缺的工具。 在最近的 QCon 会议上&#xff0c;我遇到了很多的开发者。在他们的系统中&#xff0c;Elastic Stack 是不可缺少的工具&#xff0c;无论在搜索&#xff0c;可观测性或安全领域&#xff0c;Elastic Stack 都发挥着…

秒懂算法 | 莫队算法

01、基础莫队算法 莫队算法 = 离线 + 暴力 + 分块。 “离线”和“在线”的概念。在线是交互式的,一问一答;如果前面的答案用于后面的提问,称为“强制在线”。离线是非交互的,一次性读取所有问题,然后一起回答,"记录所有步,回头再做”。 基础的莫队算法是一种离线…

dubbo SPI之依赖注入、禁止依赖注入@DisableInject

本文基于dubbo2.7.7分析 dubbo SPI如何实现依赖注入如何禁用dubbo的依赖注入 使用标准Setter方法依赖注入 dubbo的SPI默认支持依赖注入功能, 在SPI的实现类中&#xff0c;只要写标准的Setter方法即可, 示例如下: public class CustomInterfaceImpl implements CustomInterf…

6 大经典机器学习数据集,3w+ 用户票选得出,建议收藏

内容一览&#xff1a;本期汇总了超神经下载排名众多的 6 个数据集&#xff0c;涵盖图像识别、机器翻译、遥感影像等领域。这些数据集质量高、数据量大&#xff0c;经历人气认证值得收藏码住。 关键词&#xff1a;数据集 机器翻译 机器视觉 数据集是机器学习模型训练的基础&…

LeetCode——51. N 皇后

一、题目 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案…

为什么会有跨域问题,代理是怎么解决的?

&#x1f4d6; 文章导航关于跨域问题同源策略跨域资源共享解决方案前端代理后端服务端代理关于跨域问题 同源策略 同源策略&#xff08;Same-origin policy&#xff09;是浏览器中一个重要的安全策略&#xff0c;它用于限制不同源之间的资源交互。其目的是为了帮助阻隔恶意文…

系列五、docker常见报错

一、运行mysql服务报错 1.1、查看3306端口被哪个服务监听 netstat -nap | grep 3306 1.2、杀死进程 kill 1851 1.3、关闭容器 docker stop 3185bc93893e 1.4、再次运行mysql服务 docker run --name mysql8.0.26 -v /root/mysql/data:/var/lib/mysql -v /root/mysql/conf/m…

业内人士告诉你,买流量卡时一定要问的几个问题?

互联网时代&#xff0c;流量当然是至关重要&#xff0c;但是&#xff0c;在网上搜索流量卡时&#xff0c;广告可谓是铺天盖地&#xff0c;五花八门&#xff0c;所以&#xff0c;小编提醒大家&#xff0c;为了选择性价比较高的卡&#xff0c;在购买流量卡时一定要关注几个问题。…

怎么配置最流行的智能聊天工具

注册OpenAI账号 1.打开https://beta.openai.com/signup 页面进行相应的注册。 2.此处需要输入邮箱进行注册并且提示到邮箱验证 3.注册没有问题的话&#xff0c;会提示你已经发送到对应邮箱&#xff0c;进行邮箱验证 此处需要注意下&#xff1a;邮箱验证需要进行翻墙进行验证…

100种思维模型之九屏幕分析思维模型-016

一、认识九屏幕分析思维模型 1.九屏幕分析思维模型定义 九屏幕法是TRIZ理论中的创新思维方法五大方法之一。它是把问题当成一个系统来研究&#xff0c; 关注系统的整体性、 层级性、目的性&#xff0c;即各要素之间的结构。 九屏幕法是按照时间和系统层次两个维度进行思考。 包…

windows版Rsync服务端和客户端cwRsync_4.1.0安装测试

下载地址&#xff1a;https://download.csdn.net/download/qq_32421489/87463506 服务端安装&#xff1a; cwRsyncServer&#xff08;服务端&#xff09;配置步骤 1.双击运行wRsyncServer_4.1.0_Installer.exe。 2.这里创建的账户是操作系统的&#xff0c;创建的这个账户是专…

使用Fabric.js实现贝塞尔曲线波浪特效

一、前言 本文是在此基础上收到启发然后进行的变化&#xff0c;当然&#xff0c;观看与否不会影响接下来的阅读体验。 二、实现思路 其实整个波浪动画其实可以看成&#xff1a;在相对坐标系静止的视角下&#xff0c;一个正弦函数在直角坐标系上匀速平移时我们所观察到的效果…

【基础语法】JavaScript 全栈体系(三)

JavaScript 基础 第三章 常量 一、常量的基本使用 概念&#xff1a;使用 const 声明的变量称为“常量”。使用场景&#xff1a;当某个变量永远不会改变的时候&#xff0c;就可以使用 const 来声明&#xff0c;而不是let。命名规范&#xff1a;和变量一致常量使用 // 声明一…

面试官:你是怎样理解Fiber的

hello&#xff0c;这里是潇晨&#xff0c;今天我们来聊一聊Fiber。不知道大家面试的时候有没有遇到过和react Fiber相关的问题呢&#xff0c;这一类问题比较开放&#xff0c;但也是考察对react源码理解深度的问题&#xff0c;如果面试高级前端岗&#xff0c;恰巧你平时用的是re…