1.ubuntuå¦ä½è¿è¡ç¨åº
2.make 的源码执行过程与条件判断
3.开源ESP32 Quad-Terminal四足机器人操控终端
4.printf系列教程04_SWO打印输出配置,基于IAR『Terminal IO』
5.放弃 console.log 吧!源码用 Debugger 你能读懂各种源码
6.å¦ä½çå¾
Windows Terminal(Windows ç»ç«¯)?源码
ubuntuå¦ä½è¿è¡ç¨åº
åºç¨ç¨åº-ç³»ç»-ç»ç«¯ï¼terminalï¼ãç¹å¼åè¾å ¥ä¸é¢çæ令ï¼åæ¶ç³»ç»ä¼æ示è¾å ¥ç³»ç»å¯ç ï¼è¾å ¥åï¼wineèªå¨å®è£ ãå®è£ å®æåï¼è¿æ¯å¨åºç¨ç¨åº-ç³»ç»-wineéé¢å¯ä»¥æ¾å°wineï¼ç¶åæ¿windowsä¸çä¸äºexeï¼.comç¨åºå°±å¯ä»¥è¿è¡å®è£ äºï¼è³äºè£ çå¦ä½ï¼å¾çæ åµã
楼主ï¼ä¸è¬ubuntuä¸æ¯æç¸åºç软件æ¥ä»£æ¿windowsï¼è½è£ ï¼å°±ç¨ubuntuä¸ç好äºï¼å¦æè¦ç¨windowsä¸çç¨åºçè¯ï¼å¯è½ä¼éå°é®é¢ï¼ä½ ä¸ä¸ççå»ä¹å¯ä»¥ï¼å°±æçè§è¿çï¼photoshop éå ½é½å¯ä»¥è£ çï¼è¿ é·æ¯è£ ä¸äºçã
make 的执行过程与条件判断
通过在 Terminal 中输入以下命令可以将本课程所涉及的所有源代码下载到Linux环境中,作为参照对比进行学习。源码
命令执行后 WebIDE 的源码工作区中将会出现一个名为make_example-master 的文件夹。
本章节的源码大数据分析网站源码源代码位于/home/project/make_example-master/chapter3 目录下,请在 Terminal 中通过 cd 命令切换至该目录后再进行实验学习。源码
编写 makefile 文件内容如下:
在 makefile 文件中我们定义了两个变量vari_a 与 vari_b,源码同时我们在执行规则 all 时将他们的源码值打印输出,现在执行 make 命令,源码观察输出结果。源码
新增一个文件inc_a,源码在文件中声明一个变量 vari_b 值为 「vari b from inc_a」。源码 提供的源码源代码中已有此文件,内容如下:
修改 makefile 文件,源码在文件的最后一行通过 include 将 inc_a 包含到 makefile 中。
执行make 命令观察输出结果。
可以发现vari_b 的值被修改了。
我们知道make 是按照顺序一行行读入 makefile。 前面介绍make 的第一阶段是读入所有 makefile 文件,include导入的文件以及环境变量指定的文件。所以解析新修改的 makefile 时,inc_a 应该在第一阶段被解析完毕,所以 vari_b 变量就被 inc_a 修改掉了。
由此说明文件的处理顺序与include 指示符在 makefile 中的位置无关。
到目前为止,我们已经知道 makefile 中的指令都是 shell 指令,那么make 是怎样执行目标对应指令呢? 答案还是 shell。make 会调用 shell 去执行每一条指令。需要注意的是,即便在同一个目标下,每一条指令都是相互独立的。 也就是说 make 会分别调用 shell 去执行每一条指令,而非使用一个 shell 进程按顺序执行所有的命令。
使用cd 命令和 pwd 命令查看两条相邻的命令能否相互产生影响,由此来验证说法的密码登录源码正确性。 在提供的源文件代码中已经有 cd_test.mk 文件,内容如下:
从内容中我们可以知道all 规则是由三条命令构成的,其中 @pwd 表示打印当前绝对路径,但不要显示 pwd 命令,cd .. 表示回到上一层目录。 因此,若三条指令是在一个 shell 进程中顺序执行,那么命令的执行顺序是先打印当前目录的绝对路径,再返回上一层目录并打印上一层目录的绝对路径。若是三条指令是在三个不同的 shell 中执行的,则两次 @pwd 命令的执行结果将会是相同的。
现在执行下面的命令并观察输出结果。
Terminal 的输出结果如图:
说明三条命令是在三个不同的 shell 中执行的。
打印进程id确认指令会被不同的进程执行。 提供的源代码中已有用来测试的代码文件cmd_test.mk, 内容如下:
其中“$$$$”代表的是当前进程id。 所以cmd_test.mk的命令执行过程就是分别打印all目标下两条命令的进程id。 执行make -f cmd_test.mk进行测试:
可以看出两条命令输出的进程 id 是不同的
目标下的每一条命令都是通过不同的shell执行的。
有些状况下,用户希望能够使用cd 命令来控制命令执行时所在的路径,比如 cd 到某个目录下,编译其中的源代码,要实现该操作就必须在一行中写入多条指令。
先修改cd_test.mk文件,将三条指令都放在一行,并用“;”隔开。 请注意第三条“@pwd”的指令中,“@”符号要删掉,此符号只用于每一行的开头。 修改后的cd_test.mk内容如下:
执行以下命令:
Terminal 的输出结果如图所示:
说明这三条命令是在同一个进程中被执行的。
在同一行中书写多条指令是一件比较麻烦的事情,尤其是指令较长时,非常不方便阅读和修改。makefile 中可以使用反斜线“\”来将一行的内容分割成多行。 源文件中有一个multi_test.mk脚本,轮回ol源码用于测试反斜线的作用,内容如下:
此文件将一条指令分割成 3 行,其中第 1 行和第 2 行组成一条完整的指令,内容与第 3 行指令相似。两条指令的作用也是打印当前执行进程的 id 号。 使用make -f multi_test.mk 命令执行此文件。
Terminal 的输出结果如图:
可以看出执行效果与修改后的cmd_test.mk 文件执行效果一致,说明反斜杠的确能起到连接多行指令的作用。
makefile 中的条件判断语句条件判断语句的基本格式如下:
其中TEXT-IF-TRUE 可以为若干任何文本行,当条件为真时它被 make 作为需要执行的一部分。
makefile 中有else 分支的条件判断语句格式如下:
其中make 在条件为真时执行 TEXT-IF-TRUE,否则执行TEXT-IF-FALSE。
ifeq 用于判断条件是否相等,可以支持以下几种格式:
❗ 注意:ifeq/ifneq 等关键字后面一定要接一个空格,否则 make 会因为无法识别关键字而报错!
提供的代码文件中已有eq.mk 文件,内容如下:
依次执行下面的命令:
Terminal 输出结果如图:
ifneq 支持的格式与 ifeq 相同,同样提供的代码文件中已有 neq.mk 文件,内容如下:
neq.mk 中的条件判断语句使用了 ifneq ... else ... endif 结构。 当 a 不为空时,b 的值与 a 相同,否则 b 为默认值 null。
依次执行下面的make 命令,打印输出 b 在各种情况下的值:
Terminal 输出结果如图:
ifdef 语句的语法格式如下:
它只会判断变量是否有值,而不关心其值是否为空。
现在我们测试ifdef 的用法,以及要怎样理解变量值为空和变量未定义的差别。 提供的源代码文件中已有测试需要的代码文件def.mk,内容如下:
def.mk 文件中先声明了一个变量 a,但并未给其赋值,即变量 a 未定义。 变量 a 又被赋给了变量 b,由于 a 是未定义变量,因此 b 为空值。 make 执行此文件时分别打印变量 a、android 自带源码b、c、d 的值。
现在执行下面的make 命令,观察输出结果。
Terminal 的输出结果如图:
可见对make 来说,它认为 a 属于未定义变量,b 则属于已定义变量。
ifndef语句的格式与 ifeq 相同,逻辑上与 ifeq 相反。 提供的源代码中包含了测试需要用到的代码文件 ndef.mk 文件,它的内容与 def.mk 相似:
现在执行下面的make 命令并查看输出结果。
Terminal 中的输出结果如图所示:
本章学习了make 执行的两个阶段,目标指令的执行细节以及 makefile 中条件执行语句的编写。
开源ESP Quad-Terminal四足机器人操控终端
ESP四足机器人低成本操控终端开源项目,以Arduino平台为基础,专为仿生机器人设计。其核心功能包括:利用Wi-Fi UDP通信技术,实现与机器人的双向数据传输,配置文件支持SD卡存储和在线修改。
实时显示机器人关节反馈数据,以及波形绘制功能,便于监测和分析机器人的运行状态。
集成按键控制,支持电机标定和状态标定,便于远程操作和调整。
通过按键实现简单遥控,用户可以直观地控制机器人的行动。
安装教程推荐使用Arduino 2.0 IDE或Vscode,需从Seeed Github下载以下库:Seeed_Arduino_FS, Seeed_Arduino_LIS3DHTR, Seeed_Arduino_mbedtls-dev, Seeed_Arduino_rpcUnified, Seeed_Arduino_rpcWiFi, Seeed_Arduino_SFUD。 该项目支持Wio Terminal主板,但也可移植到其他ESP平台。Wio Terminal需更新至Wi-Fi固件,并参考相关wiki文档进行操作,如getiot.tech/wifi相关内容。天罗地网指标源码 针对遥控精度和供电问题,底板在年8月进行了升级,采用Wio外扩排针串口1与IO板通信,并扩展了电池和按键功能,兼容USB通讯与充电。 使用操作指南如下:首次开机后,可从sd_card目录复制文件至G TF卡,或直接修改代码固定连接Wi-Fi。Wio作为客户端,与机器人主控制器进行通信。主界面分为RC和WIN模式,通过按键切换,RC模式用于摇杆控制,WIN模式则通过摇杆选择功能按键。 源代码中的WiFiUDPClient文件是核心控制部分,开发者可以根据需求进行定制和扩展。这款低成本操控终端为四足机器人操控提供了一个灵活且易于使用的平台。printf系列教程_SWO打印输出配置,基于IAR『Terminal IO』
本文由『strongerHuang』原创首发于微信公众号『嵌入式专栏』,并同步发布在他的个人网站 EmbeddedDevelop。本文主要讲解如何在基于IAR的『Terminal IO』中配置SWO打印输出,适用于Cortex-M3/M4/M7的STM开发。
SWD、SWO、SWV和ITM是一组用于调试的串行接口,其中SWO(串行线输出)是单线异步通信方式,通过Cortex-M系列的内核ITM模块实现。要使用SWO,首先确保你的STM MCU有相应的引脚,如Cortex-M3/M4/M7,而M0系列如STMF0、STML0和STMG0则不支持。
在STMCubeMX中,只需在Debug选项中配置SWO引脚。要实现在IAR EWARM的『Terminal IO』中输出,首先在Project选项中选择调试工具(ST-Link或J-Link),并配置相应的CPU时钟。进入调试模式后,进入SWO配置,设置时钟和使能ITM端口,以及PC采样。重定义代码时,将UART发送字符替换为ITM_SendChar函数,根据需要修改ITM端口号并确保相关刺激端口启用。
为了帮助理解,文章提供了两个示例源码工程:STMF(HAL)_SWO和STMF(HAL)_SWO,链接在百度网盘,提取码nbd3。请注意,链接可能需要关注公众号获取最新链接,源码仅供参考,可能不适用于所有项目。
最后,本文版权属于作者,仅供学习使用。作者在strongerhuang.com和github.com/EmbeddedDeve...分享更多信息,关注微信公众号『strongerHuang』,随时获取更多嵌入式教程内容。
放弃 console.log 吧!用 Debugger 你能读懂各种源码
很多同学不清楚为什么要使用debugger进行调试,难道console.log不行吗?
即使学会了使用debugger,还是有很多代码看不懂,如何调试复杂的源码呢?
这篇文章将为你讲解为什么要使用这些调试工具:console.log vs Debugger。
相信绝大多数同学都会使用console.log进行调试,将想查看的变量值打印在控制台。
这种方法可以满足基本需求,但遇到对象打印时就无法胜任了。
比如,我想查看webpack源码中的compilation对象的值,我尝试打印了一下:
但你会发现,当对象的值也是对象时,它不会展开,而是打印一个[Object] [Array]这样的字符串。
更严重的是,打印的内容过长会超过缓冲区的大小,在terminal中显示不全:
而使用debugger来运行,在这里设置一个断点查看,就没有这些问题了:
有些同学可能会说,那打印一个简单的值时使用console.log还是很方便的。
比如这样:
真的吗?
那还不如使用logpoint:
代码执行到这里就会打印:
而且没有污染代码,使用console.log的话,调试完成后这个console也不得不删除掉。
而logpoint不需要,它就是一个断点的设置,不在代码中。
当然,最重要的是debugger调试可以看到调用栈和作用域!
首先是调用栈,它就是代码的执行路线。
比如这个App的函数组件,你可以看到渲染这个函数组件会经历workLoop、beginWork、renderWithHooks等流程:
你可以点击调用栈的每一帧,查看都执行了什么逻辑,用到了什么数据。比如可以看到这个函数组件的fiber节点:
再就是作用域,点击每一个栈帧就可以看到每个函数的作用域中的变量:
使用debugger可以看到代码的执行路径,每一步的作用域信息。而你使用console.log呢?
只能看到那个变量的值而已。
得到的信息量差距不是一点半点,调试时间长了,别人会对代码的运行流程越来越清晰,而你使用console.log呢?还是老样子,因为你看不到代码执行路径。
所以,不管是调试库的源码还是业务代码,不管是调试Node.js还是网页,都推荐使用debugger打断点,别再用console.log了,即使想打印日志,也可以使用LogPoint。
而且在排查问题的时候,使用debugger的话可以加一个异常断点,代码跑到抛异常的地方就会断住:
可以看到调用栈来理清出错前都走了哪些代码,可以通过作用域来看到每一个变量的值。
有了这些,排查错误就变得轻松多了!
而你使用console.log呢?
什么也没有,只能自己猜。
Performance
前面说debugger调试可以看到一条代码的执行路径,但是代码的执行路径往往比较曲折。
比如那个React会对每个fiber节点做处理,每个节点都会调用beginWork。处理完之后又会处理下一个节点,再次调用beginWork:
就像你走了一条小路,然后回到大路之后又走了另一条小路,使用debugger只能看到当前这条小路的执行路径,看不到其他小路的路径:
这时候就可以结合Performance工具了,使用Performance工具看到代码执行的全貌,然后用debugger来深入每一条代码执行路径的细节。
SourceMap
sourcemap非常重要,因为我们执行的都是编译打包后的代码,基本是不可读的,调试这种代码也没有什么意义,而sourcemap就可以让我们直接调试最初的源码。
比如vue,关联了sourcemap之后,我们能直接调试ts源码:
nest.js也是:
不使用sourcemap的话,想搞懂源码,但你调试的是编译后的代码,怎么读懂呢?
读懂一行
前面说的debugger、Performance、SourceMap只是调试代码的工具,那会了调试工具,依然读不懂代码怎么办呢?
我觉得这是不可能的。
为什么这么说呢?
就拿react源码来说:
switch case能读懂吧。三目运算符能读懂吧。函数调用能读懂吧。
每一行代码都能读懂,而全部的代码不就是由这一行行代码组成的么?
加上我们可以单步执行来知道代码执行路径。
为啥每行代码都能读懂,连起来就读不懂了呢?
那应该是代码太多了,而你花的时间不够而已。
先要读懂一行,一个函数,读懂一个小功能的实现流程,慢慢积累,之后了解的越来越多之后,你能读懂的代码就会越多。
总结
这篇文章讲了为什么要使用调试工具,如何读懂复杂代码。
console.log的弊端太多了,大对象打印不全,会超过terminal缓冲区,对象属性不能展开等等,不建议大家使用。即使要打印也可以使用LogPoint。
使用debugger可以看到调用栈,也就是代码的执行路径,每个栈帧的作用域,可以知道代码从开始运行到现在都经历了什么,而console.log只能知道某个变量的值。
此外,报错的时候也可以通过异常断点来梳理代码执行路径来排查报错原因。
但debugger只能看到一条执行路径,可以使用Performance录制代码执行的全流程,然后再结合debugger来深入其中一条路径的执行细节。
此外,只有调试最初的源码才有意义,不然调试编译后的代码会少很多信息。可以通过SourceMap来关联到源码,不管是Vue、React的源码还是Nest.js、Babel等的源码。
会了调试之后,就能调试各种代码了,不存在看不懂的源码,因为每一行代码都是基础的语法,都是能看懂的,如果看不懂,只可能是代码太多了,你需要更多的耐心去读一行行代码、一个个函数、理清一个个功能的实现,慢慢积累就好了。
掌握基于debugger、Performance、SourceMap等调试代码之后,各种网页和Node.js代码都能调试,各种源码都能读懂!
å¦ä½çå¾ Windows Terminal(Windows ç»ç«¯)?
ä½éªå¥½å¾ä¸å¡ç³æ¶ï¼å¾å¼ºå¾é ·ç«ãå¦å¤åæå¦ä¸ä¼å¿ï¼ 主é¢å¯èªå®ä¹ ãå è´¹å¼æ¾æºä»£ç ãæ©å±æ§è¶ 强 ã
UIç¾è§çè¦æ±ï¼å¯ä»¥éè¿èªå®ä¹ä¸»é¢æ¥è§£å³ï¼so easyã
æ©å±æ§ä»ä¹ç6å¾ä¸ç¬ï¼Windows terminalåæ¶å¯ä»¥å¼ CMD/PowerShell/Ubuntu/OpenSUSE/äºå¹³å°ççççªå£ã
æç»å¥½ä¸å¥½çï¼å®å ¨çä½ DIYæ°´å¹³çé«ä½äºã
Windows ç»ç«¯æ¯ä¸ä¸ªé¢åå½ä»¤è¡å·¥å ·å shellï¼å¦å½ä»¤æ示符ãPowerShell åéç¨äº Linux ç Windows åç³»ç» (WSL)ï¼ç¨æ·çæ°å¼ç»ç«¯åºç¨ç¨åºã
å®ç主è¦åè½å æ¬å¤ä¸ªé项å¡ãçªæ ¼ãUnicode å UTF-8 å符æ¯æãGPU å éææ¬åç°å¼æï¼ä½ è¿å¯ç¨å®æ¥åå»ºä½ èªå·±ç主é¢å¹¶èªå®ä¹ææ¬ãé¢è²ãèæ¯åå¿«æ·æ¹å¼ã