打印 日志 内核打印
打印
学C语言第一个就是printf(“Hello World\n”);这个可以说基本就是所有程序员的开头了,若干年之后再次看到这句话,真的会有不同的感觉吧。回到正题,为什么是打印呢?因为在上古时代,那些机械和电脑非常非常打的时候,输出是没有屏幕的,但是人们想要一个记录和输出,此时就是打卡机了,就是在纸上打孔,这个孔就是数据输出啦,随着慢慢发展,也就沿用下来了。
打印操作
这个真的太多了,而且分平台,分语法,分架构,分系统等等,不过,现在是很少用打印机了,写代码还用打印机才是逆天啊。所以,一般都是屏幕直接现实或者命令行输出。
C语言就是fputc、printf等操作;linuxc就是printf、perror等操作;Qt就是qdebug咯;python就是print啦;自然还有mcu那些非windows,非控制台的环境了,他们就得重定向才能使用打印函数哦,就是把打印函数重写成串口发送等函数。这里要提一下啊了,为什么,嵌入式不能使用控制台。我当时学c语言的,都是devC++和gcc编译的,我觉得有控制台才对啊,为什么mcu就不能有控制台那些东西呢,还要费尽心思搞那些环境和芯片配置,后面懂得越来越多才知道,其实所有编译都可以算是交叉编译,因为都是为了满足一个平台和架构的特性,之所以在windows上面可以跑控制台是因为,他本来就是用自己的编译链,本来就是跑自己环境和架构,同理因为gcc是支持linux环境,所以linux才能用gcc编译,然后在命令行中打印出来,后面又要使用交叉编译才能烧录到特定的架构的芯片上,因为linux环境和架构是同目标的芯片又是不同的,所以还得要一次交叉编译才行。
花活,多颜色打印:
1 | 一个朋友 11:24:59 |
C语言中使用printf()打印漂亮的颜色字体_c语言printf颜色-CSDN博客
这里巧妙的使用字符串的自动拼接,而且不只是改变字体颜色那么简单哦,还可以改背景色,前景色等诸多操作,感兴趣去了解一下。给自己的枯燥无味的debug生活一点乐子咯。还有那种ai雌小鬼助手,打印出来的那些杂鱼啥的特殊颜色字体应该都是这样可以实现的哦。
日志
一开始,我看到那些神秘兮兮的log函数,我真的觉得有什么特别牛的东西,后面我才知道,他就是打印的一层封装,他本质还是打印函数,不过是会打印出操作、警告、操作者等属性,就是打印之前还会把其他属性也打印出来。这个在mcu中,因为空间的问题,所以都是直接打印出来没有保存的,如果使用文件系统就可以存放到文件系统,这样可以命令行去访问特定文件来知道干了什么,前提是空间要够啊。linux就不用说了,你敲的每一行指令,都有log历史记录的,用户是谁,干了什么,是否危险,什么权限都知道的。
内核打印
这个就是搞linux内核驱动的啦。Linux 内核共提供了八种不同的消息级别,分为级别 0~7。数值越大,表示级别越低,对应的消息越不重要。相应的宏定义在 include/linux/kern_levels.h
文件中。
KERN_EMERG 表示紧急事件,一般是系统崩溃之前提示的消息;
KERN_ALERT 表示必须立即采取行动的消息;
KERN_CRIT 表示临界状态,通常涉及严重的硬件或软件操作失败;
KERN_ERR 用于报告错误状态,设备驱动程序会经常使用该级别来报告来自硬件的问题;
KERN_WARNING 对可能出现问题的情况进行警告,这类情况通常不会对系统造成严重的问题;
KERN_NOTICE 表示有必要进行提示的正常情形,许多与安全相关的状况用这个级别进行汇报;
KERN_INFO 表示内核提示信息,很多驱动程序在启动的时候,用这个级别打印出它们找到的硬件信息;
KERN_DEBUG 用于调试信息。
1 | #define KERN_EMERG KERN_SOH "0" /* system is unusable */ |
注意:打印消息的级别大于控制台的打印级别时,才能出现在终端。并且:数字越大,级别越低
1 | $ cat /proc/sys/kernel/printk |
控制台打印级别 消息的默认打印级别 控制台最大打印级别 控制台最小级别
四个数值的含义如下:
- 控制台日志级别:优先级高于该值的消息将被打印至控制台;
- 默认的消息日志级别:将用该优先级来打印没有优先级的消息(即 printk 没有指定消息级别);
- 最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级);
- 默认的控制台日志级别:控制台日志级别的缺省值。
1 | printk("%s:%s:%d\n", __FILE__, __func__, __LINE__); //此时是没有设置打印等级的,就是默认4 |
Linux内核之 printk 打印_linux printk-CSDN博客
总结
打印是入门和快速测试的基础,日志是可以记录所有操作,可以保存到本地,这样其实是更加有利于bug复现的,还有调试交互,后续设计的,不过mcu和那些空间本来就少的设备是真的遭不住的。内核打印,就是写驱动的人才用得到的东西,因为此时打印函数都是无效的了,只能通过内核提供的打印函数才能实现打印效果哦。
TIM三大时基
定时器
MCU的经典外设之一了,这个确实有点新手噩梦的感觉了,尤其是当时学时钟树,我愣是横看竖看没看懂,现在是看懂也学会了,但是,我搞混了一个概念,也就是三大时基中的自动重装载了。
三大时基
预分频,计数器,自动重装载这三个就是大名鼎鼎的三大时基,可以说,只有配好他们才能保证定时器是稳稳当当的。此时就要看时钟树给此时定时器分了多少的频率,此时再通过我们的预分频就能设置为多少hz为一个节拍,计数器呢就是多少个节拍算完成任务,自动重装载我一般都是使能的,因为我一直以为是cnt到了计数器的时候,是自动重装载把cnt归位的,没想到还是计数器归位的。为什么我发现这个问题呢?直到有一天我发现没配置也能实现中断触发和回调的时候,我的世界观崩了!
自动重装载和影子寄存器
TIM触发一次
TIM中断
TIM的PWM输出
TIM相位编码
TIM刹车
总结
ADC异常
起因
我写好了协议层和应用层,但是我的同事也写了一个bootloader,但是他…所以,在我和他多次交流和协商下,他搞定了bootloader,但是出现问题了,就是adc不一样,他给的adc表格,不符合我实际读取的,所以就会出现偏差。
bug查找
我一开始以为是采样问题,看了周期,看了转换速度,看了分频,都是正常,代码cube一键生成,也是启动adc了,因为使用的F1的MCU,所以是不能修改分辨率的,统一是12,F4的那些高级一点才能自己选择分辨率哦。
最后,我让他把源码发给我了,我看了中断回调,看了函数处理,看了数据处理,都没问题,最后看到了,他没有校准ADC,这个我是早早的写了,我启动ADC就立刻校准了。
为什么要校准
我还记得高中和初中的时候,我还是物理科代表呢,但是做啥实验第一步都是清零校准,才能保证统一和实验性。放在我们现在的工作之中就是,使用万用表和示波器肯定要先校验才能保证数据和波形是正确的啊。所以,在处理传感器和adc,dac等方面都要注意校验的问题,不是说光初始init就能解决一切bug的。
那为什么会出现误差呢?
STM32 的 ADC 校准一般有 参考电压校准 和 增益校准。
参考电压校准:
先测量 ADC 参考电压的实际值,然后将该值与预设的参考电压进行比较,得到参考电压的偏差,最终通过校准将其校正的方式叫做 参考电压校准 ,其目的是为了准确测量 ADC 的输入信号。
叫做增益校准:
通过测量内部基准电压和 ADC 输入信号的幅值之间的比例关系,校准 ADC 增益的方式 叫做增益校准,其目的是确保 ADC 输出的数值与输入信号的幅值之间具有良好的线性关系,为了准确的转换 ADC 输入信号。
ADC 校准的目的是为了消除 ADC 的偏移误差和增益误差,从而提高测量精度。
原文链接:https://blog.csdn.net/weixin_42328389/article/details/129518720
这个就像芯片生产过程制造中的差异化一样,ADC部分也存在一些差异化(虽然很小),其参考电压、偏置电压、增益等参数可能存在一些不确定性和漂移,这些参数的变化会导致 ADC 的测量结果产生误差。
就想上面介绍什么是 ADC 校准最后说的,为了提高测量精度,消除 ADC 的偏移误差和增益误差,所以在使用 ADC 采样的时候都需要进行 ADC 校准。
只要不改变adc设置就不会变化哦,修改通道是没事的,前提是别改属性,也就是可以关闭,但是寄存器别动,下次继续使用是没问题的。如果工作环境一直发生变化,噪声环境比较恶劣,温度啊,干扰,那就得用一次校准一次了。
解决办法
就是启动ADC就立刻使用校准咯,这样就可以保证不同设备,或者同一个设备不同程序一样的adc啦。
FLASH操作
起因
还是经典的摸鱼?不是的,是我公司的一个工程师,让我帮他搞一下治具,突然发现,烧不了代码了,所以,我经过j-flash的测试,才知道加读保护了。而且用的还是APM32这个芯片,我没想到是APM32是直接照抄STM32的,甚至我的STM32的bin代码都可以直接跑哦,真合着寄存器,外设引脚,内部完全一模一样呗。所以,我想到做一期关于flash的博客。来巩固一下知识点。
FLASH是什么
FLASH就是一种掉电不丢失的储存单元,特性就是成本低,但是不能按位操作,空间大,结构简单。
为什么,不能按位呢?因为FLASH本身就是一个半导体一样的东西,我们看到刷新flash全是置为FF,为什么是FF,是因为此时单元束缚了一个电荷单元,旁边的高阻抗的传感器识别到,这个位置有电势差,所以就知道这个位bit里面有数据的。此时,就是把电子拿出来简单,放回去就难了,所以需要刷新才能重写。为什么拿出来和放回去难度不一样呢?因为上下结构不一样的。
上面是一个flash单元,因为flash下面的所有单元衬底其实是一整块的,所以,无法做到,按位进行操作,因为一操作就会导致所有数据都归零,所以,只能操作上面部分的电荷来实现放电操作。刷新过程,其实就是衬底清空,此时就会对上面的浮栅进行充电,然后,电压一走电荷就会被束缚在栅极之中。
还有那些颗粒类型什么的,我就不太了解了,因为我是一个臭写代码的,这个FLASH设计,要专业人士才能操作。当前存储颗粒主要分类:SLC、MLC、TLC、QLC
可以认为那些储存都是这些FLASH颗粒组成的哦。上面这个只是一个二维的设计,因为这个衬底可以设计成3维的,所以,3维的flash成本更低,同时擦除的块也变大了,这个是厂商设计的哦。
为什么设计简单,我们可以举例子,比如eemprom,这个其实就是内部类似矩阵一样,可以知道横纵就知道位置和操作了,因为没有采用统一衬底的设计,所以可以对任意位置操作,带来的布线、设计成本、生产成本,容量大小等诸多问题,都是限制它的原因。
还有就是速率啦,FLASH一般是SRAM或者SPI的,eemprom一般都是iic
FLASH类型
目前市面上常见的集成存储芯片类型:eMMC、UFS、SPI-Flash、QSPI-Flash、各尺寸的SD卡等。
我这里就分为2大类:第一个是NORFlash,第二个是NANOFlash
怎么理解呢?
NORFlash就是扩容的一个Flash,我们可以修改MCU的内存大小和BANK来使用外部的SRAM或者NORFlash,在外部上面跑代码就是指针直接指向,把外部的也当成SRAM跑,而且还是很可靠的,掉电不丢失,突发情况说不定还能查看内部bit来还原数据呢。读速度还行,写速度慢,每次使用都要刷新,擦写次数比NANOFlash少太多了。它的接口是SRAM的接口,同MCU的引脚连接。
NANOFlash就是纯纯的存储空间啦,一般都是有一个FLash芯片来实现对这写Flash单元的控制的,此时一般都是SPI,也有很多使用QSPI,一般是好的FLASH芯片都是有QSPI支持的,然后希望手册多一些有用的指令,便宜的FLash确实可以用,但是它的功能和指令都被阉割了。如果想要实现QSPI和文件系统等一些操作就比较麻烦了。读写速率都很快,但是不可靠,寿命高,可以擦写很多很多次。
内部FLASH
回到上面提到的读保护吧,确实一般在mcu中,只有写保护,就是想要修改FLASH,需要解除锁,才能刷新再写,读的话,一般是直接地址指过去了。那么读保护是干嘛的?我这内部完全没有限制我读取啊?
读保护是防外人的,那些狗东西最喜欢逆向和偷别人代码了,此时我开启读保护等级1,他们就不能通过调试来获取我的代码了。但是此时MCU是可以恢复到读保护等级0,只需要选择使用boot0 boot1都为1的SRAM启动,我们修改运行地址到SRAM中,修改映射,就可以在SRAM中把读保护等级修改了。但是如果读保护等级为2的时候,就把SRAM也禁用了,此时就gg了。
此时,不能更新了吗?不是的,我们此时是禁用了外部的操作啊,但是我们可以ota啊,我们程序还是可以通过内部的开锁关锁来实现对flash的更新,这个是内部的操作,不是来自外部的哦[doge]
SRAM FLASH ROM区别
SRAM和NORFlash都可以运行代码,他们的区别就是SRAM肯定更快啊,想都不用想的,而且不用担心丢失,掉电就没了,固态使用的DRAM,还需要定期充电呢维持呢,速度也快,成本贼低。
ROM和NANOFlash的区别呢?都想是存储的东西,但是,本质还是不一样的。ROM是一种只读的统称,可以认为是PROM(可编程ROM)、EPROM(可擦除可编程ROM,通过紫外线擦除)、EEPROM。ROM也是可以编程的,但是更少,Flash就擦除写入的多了,一般的固态SSD都是FLASH,因为便宜快速高效可以反复擦除。
感想
FLASH真的一个跨时代的发明。我想到了,最近要搞一个NAS玩玩,先玩黑群晖吧,刚好有一个闲置的垃圾笔记本,我看了一下群晖裸机也要1300呢,有点贵的,用的是机械盘,本质,是中间那个磁盘来着,怎么说呢。那个东西可以修复确实好,不过固态确实越来越好用。服务器还是机械吧,固态坏了真的修不了,都是电子和位,怎么恢复啊。FLASH带来的便利,也带来一些麻烦,比如固态涨价涨疯了,我都买不起了,呜呜呜。
Flash的底层驱动和上层调用策略
起因
我朋友发了一个sqi的flash芯片手册给我看了一下,那个是一个垃圾的国产芯片,只有简单的读取和写入功能,很多其他指令都没有,他说很难实现sfud的功能,sfud就是为了兼容不同型号的flash,我感觉确实挺不错的,有水平的,新出的flash一般都是支持SFDP标准的,而sfud也是支持的SFDP标准的,所以,只要满足就可以使用啦。想都想到flash就一个FLASH博客咯。
NANOFlash底层驱动
这个就是纯纯数据啦,现在固态都是NANOFLash的哦,(服务器的还是用机械盘,因为机械盘坏了可以修复,固态坏了是真的没救了)。是不能直接执行代码的,不过可以通过引导程序把代码下载到ram之中来运行哦。接口一般是看芯片的设计的,芯片有spi、m.2 、pcie、sata都是可以的,通信协议只是一个建立交互的手段罢了,速率和成本满足要求,怎么样都行。这个就没啥好操作的了,就是根据协议,写好收发,看着手册进行指令的发送,状态的判断,数据的获取和写入。封装成一个个api给上层调用咯。
NORFlash底层扩容操作
NORFlash一般不是用来存储东西的,更多是扩容和进行代码运行的,它是跟mcu的扩容引脚接在一起的,也就是说,mcu可以配置外部的bank之后,可以直接访问这个外部的Flash地址来进行操作,而且这个是非常可靠的,缺点肯定是有的,比如SRAM快和高效,掉电不丢失,重启要刷新等。
使用方法,一般都是抽象使用,也就是mmu来管理这块地址,因为flash刷新就会按照块来进行处理的,所以,里面最好不要又可变的变量,而是一个固定不变的数据和函数,当然可以用指针去直接使用它,没有mmu的管制,想干嘛都是可以的。实践中现代操作系统和环境通常会提供更高级别的抽象来管理内存和代码的执行,而不是直接由程序员操作指针去执行Flash中的代码。不过,在嵌入式系统或特定的低级编程场景中,这种直接操作更为常见。
QSPI
我们使用的SPI,一般都是sck,miso,mosi,css组成的,可以放弃一根线,只有mosi或者miso,也有使用qspi的,就是并行spi的,可以认为这种spi就是利用并发的操作来增加速率,每多一根并行,理论上是可以翻倍速率的,具体还是看QSPI硬件芯片的处理了。
文件管理系统
这个就是FLASH的底层调用啦,通过指令,知道空间大小,可以通过指令去处理和读写数据、文件等操作。
文件管理系统是操作系统的一个关键组成部分,负责组织、存储、检索用户和系统数据。它为用户提供了一个访问和管理文件的接口,使得用户能够创建、删除、修改、重命名文件以及目录(文件夹)。常见的文件管理系统有NTFS(Windows)、HFS+(macOS早期版本)、APFS(macOS新版本)、EXT4(Linux)等。它们通过各种数据结构(如inode、文件分配表等)来跟踪文件存储的位置、大小、权限等信息。
FLASH,通常指的是闪存技术,是一种非易失性存储器,意味着断电后存储的数据不会丢失。与传统的硬盘驱动器(HDD)使用磁性介质不同,闪存使用电子存储数据,在读写速度、功耗、抗震性方面具有优势。FLASH技术分为两类:NAND Flash和NOR Flash,其中NAND Flash因其高密度、低成本和较高速度的特点,广泛应用于USB闪存盘、固态硬盘(SSD)、移动设备的内部存储等场景。
虽然文件管理系统和FLASH技术分属不同层面,但它们紧密相关。现代的存储设备,特别是固态硬盘(SSD),大量采用FLASH技术作为存储介质。为了优化FLASH存储的性能和寿命(因为FLASH有擦写次数限制),文件管理系统需要针对FLASH特性进行特别设计或调整,比如引入TRIM指令来通知SSD哪些数据块已不再使用,可以提前擦除以提高写入效率;或者使用磨损均衡算法来均衡FLASH芯片中各区块的擦写次数,延长SSD寿命。
- 理解FLASH硬件特性:首先,深入了解您所使用的FLASH(NAND或NOR)的技术规格、命令集、读写速度、擦写寿命限制等,这对于设计高效且安全的接口至关重要。
- 开发驱动程序:对于嵌入式系统或特定应用,可能需要编写低级驱动程序来直接控制FLASH芯片。这包括初始化FLASH、发送读写命令、处理错误和状态返回等。
- 设计高级API:在驱动程序之上,设计一套易于使用的API,比如打开、关闭、读取、写入、 seek(定位)、truncate(截断)等操作,模仿文件I/O的方式,这样上层应用可以不关心底层硬件细节。
- 错误处理与磨损平衡:考虑到FLASH的擦写寿命,您的API设计应包含磨损平衡策略和错误处理机制,比如记录和报告坏块信息,使用损耗均衡算法等。
- 性能优化:根据FLASH的特性(如页大小、块大小)优化读写操作,比如批量读写以减少开销,利用缓存技术加速访问等。
- 测试与验证:彻底测试您的接口在各种条件下的表现,确保数据的完整性和可靠性。
现代文件系统通过维护元数据来跟踪文件的分配情况,通过多种机制确保数据一致性和空间的有效管理,同时提供给上层应用接口以实现并发访问控制和空间的精确计算。
其实就是一句话,文件系统给了需要接口,我们就得从底层提供api比如多大,读写操作api,空间使用等。然后文件系统就会自己去处理和判断空间剩余,空间使用,然后再封装api就可以进行文件io的操作了。
虚拟文件系统(Virtual File System, VFS)
现代操作系统内核中的一个重要组件,它提供了一个抽象层,使得操作系统和上层应用程序可以以统一的方式访问不同类型的文件系统,而无需关注底层文件系统的具体实现细节。VFS在处理并发访问和空间管理时,也遵循类似的原理,但其作用范围和方式更为通用和抽象。
并发访问控制
在VFS层面处理并发访问,主要是通过文件描述符、文件句柄以及与之相关的锁机制来实现的。当多个进程或线程试图访问同一个文件时,VFS会确保通过以下方式避免冲突:
- 文件描述符表:每个进程都有一个文件描述符表,其中包含了指向内核中打开文件结构的指针。这些结构包含了锁和其他同步机制,以保护文件的并发访问。
- 锁机制:VFS支持不同类型的锁,如读锁和写锁,来控制文件的访问权限。这些锁可以是进程间共享的,也可以是独占的,确保了读取和写入操作的原子性和一致性。
- 同步原语:操作系统提供的同步原语(如信号量、互斥锁等)同样可用于VFS层面的同步控制,尤其是在涉及更复杂的并发控制策略时。
空间管理
VFS不仅管理文件的逻辑表示,还间接参与空间的管理,尽管具体的磁盘块分配和空闲空间跟踪通常由下层的文件系统实现:
- 元数据抽象:VFS定义了统一的元数据接口,允许上层查询文件大小、链接数等信息,而底层文件系统负责实际的物理空间分配和释放。
- 空间分配策略:虽然具体的块分配算法(如位图、B树等)由具体文件系统实现,VFS确保了上层应用可以通过标准接口请求和释放空间,而不必关心底层细节。
- 跨文件系统操作:VFS使得不同文件系统可以挂载在同一目录树下,每个文件系统独立管理自己的空间,VFS提供了一个统一的视角,让上层可以透明地访问和管理这些不同文件系统中的文件。
总之,虚拟文件系统通过提供统一的接口和抽象,简化了对文件系统多样性的管理,同时也为并发访问控制和空间管理提供了一个基础框架,确保了操作的高效和一致性。
FLASH应用层
这个应用层是给到程序员的啊,一般都是在文件系统之上使用文件io去操作和处理很多事情,增删查改;还有使用数据库、日志等操作,这些操作都是看起来简答的api调用,实际上是底层驱动和文件系统做了很多处理的。写好应用层就可以给用户使用啦,这里要多注意判断的判断、纠错、校验、以及用户体验等问题。
FLAS用户层
就是用户看到的数据啦,我们使用文件管理系统就可以知道当前的状态了,此时可以使用上位机的办法或者指令的办法去固态进行处理和操作,其实就是对文件系统的那些io操作进行处理而已。比如打开我的电脑,就可以直接看到固态空间和使用情况,还可以直接进行修改,这个就是一个非常简单的使用了,已经是高度封装和抽象了。
总结
FLASH的原理和使用是简单的,如果直接为了实现通信和简单交互,其实是很简单的,但是现实是,用户是要体验的,要速率的,要稳定性,要可靠安全高效的,这个时候就要文件系统做非常大的校验和判断,还有底层的代码要不断优化,增加校验,增加纠错,增加速率,甚至修改通信协议等诸多问题,来给用户带来超棒的体验。
祛魅——技术的陷阱
祛魅
这篇博客,是一个自我认知和自我醒悟的过程和思考的记录。脱离技术包袱,逃离思想束缚。
首先,我们要知道祛魅是什么?我的理解就是将一个被神话的东西理解透彻。这个是什么意思呢?很多东西被大家吹的太夸张了,但是,如果愿意花上最多100+小时的学习,就能入门,而不是大家所说高不可攀。因为,对于这些事物的不断逃避,我们不断道听途说那些被神话的技术和知识,所以,就盲目以为那些非常难做,非常牛逼,觉得自己不行,觉得它好厉害,狂拽酷霸吊炸天。但是,一旦入行,我们就会明白,其实就是那样,没啥了不起的。
技术就是大家不断试错和大家统一的约定,比如协议,这个就是大家都是这样约定的,所以就有通信技术和通信协议;比如尺寸,也是大家经过不断试错,发现这个是最合适,所以就定这个了;比如开发流程,也是一样的,为什么要开发模型,为什么要架构,为什么要设备树,为什么要驱动平台,为什么要统一驱动写法,为什么要meunconfig?这些不都是大家一起约定俗称的东西,就是入门太难了,所以,给人一种高级感,一种神奇的魅力。但是,它的本质就是大家的约定俗成的协议和流程。科研的话,那个没涉及,不过,我感觉科研方面也有很多人深深陷入神话的传说之中了。牛顿晚年都信神学了。
之前,我就陷入这种对于技术的崇拜,疯狂学习,疯狂思考。但是,我有一整子休息了一下,看了一些管理和资本家视频我才醒悟过来。编码技术再牛逼又如何?会的编程语言再多再熟练又如何?项目开发又快又多又如何?我们在不断钻研技术,却是陷入了资本家的陷阱。大家都说工匠精神,但是,资本家喜欢的就是这种只知道听话和干事的牛马。他们天天只喜欢技术,对于技术有一种莫名其妙的优越感。但是,在老板眼里,就是牛马,只不过是厉害的牛马。所以,大家对于技术千万不要过度崇拜,而是要学会管理和统筹规划。任何一个刚毕业的大学生都可以使用C语言在一定时期内完成一个功能,但是怎么把功能整合起来,怎么去管理,怎么去维护,怎么去分配任务,这个才是最重要的,才是最可能在未来实现独立和创业的。
肯定要反驳我,说不会技术怎么创业啊?首先,要知道技术是一定要会的,因为我们很多人都是没有资本的,所以,只能靠技术来给自己建造城墙,但是会编程,会应用是真的没用的。会带队,会分配,会管理,会思考,会统筹。你会想这是cto的事情啊,所以,我们就要去学习去有目的的思考,系统的去思考。在日常工作中,把眼界跳出自己的目前的工作,去想想如果这个项目给到自己,自己该干什么?不要总是钻研技术,技术是最难赚钱,最难实现自由的,尤其是大厂,越大分的越细,虽然整体很美观很规范。
想起来一个段子,一个老板问程序员还要多久完成项目。程序员说一个月左右。老板说再加一个人呢?那就要两个月了。再加一个人呢?那就不知道了。
这个段子,其实就是说了一件事情,人越多它的效率其实是越低的,但是好处就是它可以可重复使用和相互配合,可以摆脱因为员工离职导致的问题。
对了,大家写代码和和钻研技术的时候,一定要学会模块化,一定要想办法做可重复使用的事情,做一些关联的事情。比如一个模拟spi,这个代码,只需要改引脚(还有位带、输入输出模式、反正就是电平变化的函数等),就可以实现快速移植和反复使用了,这里就有一个就是规划了,你未来想要干嘛,你现在做的事情对于未来有帮助吗?就像未来想搞linux驱动,但是现在在搞前端开发,那有用吗?完全没有一点可重复使用性。
有点偏题了,祛魅只是一个引子,主要是告诉大家,不要对技术有莫名其妙的崇拜和神话,我们要站在更高的角度和看待项目的过程。去思考一个人的时候怎么完成,去想想现在干的事情对于未来有没有用。不要今天学了modbus,明天就学can,然后洋洋得意,觉得我今天又学到了新的技术。
这有用吗?肯定有用啊,老板最喜欢这样的牛马了,35岁之后直接踢了,脑子只有技术的人,怎么带队啊,后面还不听管教,自以为有技术了不起的人多的是。
我们其实不需要太多太牛逼的技术,很多东西,都是有库的啊,有人写好的驱动的啊,为什么还要去干这些事情呢?我们只要有中等水平的编程能力,有高级水平的思考和架构能力就够了啊。具体实现,真的只要会c语言,啥功能都能实现的。只是效率和大小的问题,这个丢给大学生最好了,他们最喜欢干这种事情了。
然后,肯定就有人想问,怎么站在高处看待这些东西呢?我这里就给出一个简单的模型吧。归纳、思考、用途、设计、诞生因素、解决了什么、整体思路、行为定性等。
1.学习归纳、整体思路、思考。
我们用MCU举例子,MCU就是主控,好了,完了。那些DMA,USART、CAN、IIC、SPI、是不是就是为了和主从机通信?TIM 、VNIC、Callback是不是为了实现内部事件处理?内核指令需要吗?那些关中断、关事件、汇编代码,需要吗?系统一定是刚需吗?上系统带来什么好处?上系统解决那些多任务?那些是实现啊,给一个嵌入式毕业的会mcu的他自己会去实现的啊。
是不是每一个MCU都是这样的操作,不同的就是有一些HAL,有一些标准库,有些自己的库,但是。他们的实现都是一样的,实现开启时钟,然后结构体进行初始化,绑定和复用功能,配置复用和绑定功能的配置,初始化复用和绑定功能,开启功能完事,有中断写中断回调。
那我们学会了每一种MCU,看了一堆的数据手册。是不是我们就变得抢手?有用吗?CH32、GD32、AT32、STM32、瑞昱、TI、APT32、HC32够吗,孩子?学完了然后学thread-x 、freertos、ucos、rt-thread等够吗?他们是不是都是一样的思路,所以,我们学习的时候就要归纳去思考,去站在高处看待他们的流程和相似之处。
2.学习设计、解决问题。
我问一下,是怎么看待协议的,比如spi、https、dns、iic、modbus、udp、tcp等。是不是有点懵,因为,你只是见一个协议就用一个协议,你知道这个从机是这个协议通信,但是,那个从机设计的工程师为什么选择这个协议,因为好玩吗?我们要打开iso那个7层协议啦,别怀疑,就是这个。我们使用pcie举例子,我们要知道pcie是占据3层的,是物理层、数据链路层、事务层。三层,前面物理层和数据链路层,我们就看到是接口就完事了。pcie是多个物理接口,而且还有电平需求,然后上面还有版本需求,不同版本之间可能还要向下兼容。但是我们可以完全只是用物理层和数据链路层,就是写自己的pcie接口,电路自己设计,这样就利用了pcie的防呆口设计了一个好的电路,至于内部的走线就可以完全使用自己的协议了。所以,协议不是死的,是有目的的使用。
所以,就可以把协议分一下,有纯软件上位的,比如https、dns、pop、tfpt、fpt、mqtt等;还可以分成纯硬件的iic、 spi、485;接着就是软硬件结合的,can modbus,Lin、PCIE 、USB等。
然后就是不同协议之间的电气特性,传输距离,传输成本,传输速率,传输可靠性,这些很多时候,大家开发软件的时候都不会去在意的。这有点硬件工程师的味道了,但是软件要跳出软件的范畴,要去理解硬件的工作原理,知道所有流程,知道代码怎么走的,知道代码是否能够顺利执行任务。我们要想想为什么要这个,这个可以带来什么,换掉会怎么样。所以,这个设计不但是设计,还是整个项目的统筹。我们也可以系统的学习,去明白这些设计的本质,设计的意义和为什么这样设计。
3.用途和诞生因素
这个就比较杂了,你可以说我项目的用途,可以是技术的用途。但是要明白一点,你做的所有事情都是为了它的诞生因素,就是它存在的意义是什么?这话怎么理解?周鸿祎在他的视频里说过一句话,就是开发者很容易陷入疯狂的自嗨。这句话我是比较认可的,开发者总是因为自己搞出来一些牛逼的东西就很高兴很了不起,但是你干的这些事情真的有用吗?自然,自己干着玩当然没问题。但是在项目和未来创业上面,是千万不可以的,用户是不知道你为什么自嗨的,这样只会增加成本和无意义的开发浪费,这个不是预研而是自嗨,就是一堆人脱离实际的自嗨,到头来一事无成,市场根本不鸟自己,然后就乌拉(无啦)。
不要,天天写代码,知道现在世界上的科技走向,看看人们需要什么,预测未来的可能有的风口,而不是傻乎乎的写代码,要知道自己的做的这些事情有没有诞生的因素,再说一遍做着玩是完全没问题的,但是想要创业和工作室,就千万不要随随便便搞这些,严格按照市场调研和开发计划做才是最合理的。
所以,这里就有一个调研和思考,数据等诸多问题,这个才是一个工作室一个创业是否能成功的重要因素,就是一句话,有没有人买账!你的代码值不值钱?你的代码用途是什么?它诞生的意义是什么?是玩,还是赚钱?
4.行为定性
你要知道你做的事情,是为了什么,你做这个动作,这个行为是为了什么,不要感性的认识,更不要过度理性看待。你能控制自己的行为,知道自己行为可以带来什么,可以提供什么。说人话就是知道自己在干嘛。
注意了,有一点非常重要,就是千万不要用自己的标准去要求别人,尤其是,”为什么我可以你不可以“这种话,千万不要说,因为人与人之间本就是不对等的。知道自己说了什么,知道自己做了什么,做事情之前,问一下自己为什么要做?下决定之前,换一种语言来再次确认一篇,比如在心中用英语问自己一遍是否真的可以做这个决定。
还有就是别活得太束缚了,人不是理性的动物,人是感性的,人们喜欢骗自己是理性的,但是一切都是因为感性而发生剧变。我们要学会说废话,学会接触无用社交(不是狐朋狗友,而是可能不会带来利益的社交,但是不要过度损伤自身利益、合法的社交),给自己释放压力,不要把商业机密告诉任何非合作伙伴,因为外人是不会在乎你的利益的,只会在乎快乐,而合作伙伴之间是有利益链的。
这个就是你要对自己的行为下定义,为了社交,为了娱乐,为了效率,为了工作,为了生活,为了金钱,为了家人,为了事业等。千万不要活的迷迷糊糊,到最后,很多东西都会因为自己的无心之过而丢失哦。找几个好兄弟,在一个大排档喝上一顿吃上一餐,真的很快乐哦。可能会很累,但是,无权无利,真的很尴尬,一切都要以自己为重中之重,一切都要以家人整体利益为先,好兄弟,肯定可以两刃插刀。
说白了,是愿意成为自己人生的主导者,还是任劳任怨的牛马,其实都是一种活法,自然两个角度的思考、所承担的风险、难度也都是不一样的。活着累,是一种活法,活着轻松也是一种活法,因为我们都只有那么点时间和寿命的。及时行乐也是一种美丽的人生。
上面都是一些我个人的观点,肯定是有错误和偏见的,所以,大家千万不要带入去看,更不要看完就有啥大情绪和思想的波动,而是换位思考,批判思考,对自己的当前状态的考量,年龄,资本,技术,人脉等诸多情况。
这里,再阐述一下我的观点:千万不要陷入技术的黑窟窿之中,技术是学不完的,更加不要指望老板会养自己一辈子。人是活的,不是死的。如果宁愿当一潭死水,我是劝不动,但是,愿意走向大海的人,一定会有自己的行动。崇拜技术是大部分人、初出茅庐、老一辈的思想,千万千万千万千万不要只会写代码,写代码真的是在未来是人人具备的能力,因为AI已经开始可以根据上下文自动补全代码了,真的只会写代码,是真牛马。但是,所有代码都要有人审核、管理、运维。
所以,大家要么冲着CTO出发,那可以多学一点技术,但是一定要学管理和分配,还要跟对公司和老板,多关注市场和调研;要么就是自行创业、接单(咸鱼、小红书等商单私单)、外包(是你以工作室的名义去接单)、设计、方案提供等,这个时候就要多了解市场和未来了,这个肯定是赚的更多的,亏得也更多,更不确定的事情也多,很可能是独立开发者,也可能是一个小团队,这样的日子,可能会孤独,可能会快乐,可能会到头来一无所有。
如果,真的只是赚了最多10年的钱,就去卖炒饭,开个小店,做那些完全没涉及的行业,你觉得你能成功的话,你就继续给老板打工,做原始积累吧。其实打工也是有技巧的,打工也是有未来的,但是一定要公司有未来才行,然后深耕,一定一定一定要得到股份,一定要有分红,没有的话,立刻走,自己找后路。因为,在老板眼里,就是35岁立刻开除的牛马。未来是自己的,每一个人都是不一样的,这个没有老师,只有现实会不断教你做人。
所以,千万千万千万千万不要陷入只知道技术,得到技术就高高在上了,你会发现一下子就到了35岁了,但是自己都不知道该怎么办了。如果你能刚毕业就有一个规划,比如去那些公司学什么技术,然后去哪一家,或者深耕变成管理等都是可以的哦。别傻乎乎的只知道写代码和学技术,多思考,多想想未来,不要被当前的美好和高工资迷惑了双眼。读书和学习的过程就是一个祛魅的过程!不要高高在上了。
美好的童年快乐一下就没了,小学也是,初中,高中大学都是,虽然当时的我是一个彻头彻尾的屌丝和逗逼,但那些都是最真实的我啊。现在的我,一定会被儿时的自己所讨厌吧!
脚本小子
服务器远程办公
用途
很多时候,公司电脑都是用于开发的,当中自然有很多数据和配置好的环境,操作起来非常方便,但是,我们不可能天天在屏幕前啊,一定会离开岗位的,我之前就因为要去工厂实地查看电机生产,现场改测试,现场测试,现场编程,还好我有个笔记本,可以直接远程办公快速实现,这个功能,确实不错的。还有就是编译内核的时候,几个小时都常态,所以,ssh登录挂着就好了,编译完就走了,虽然应该都是服务器去编译的。
SSH登录
说到ssh,肯定都熟悉了,毕竟搞linux,搞git都或多或少用过,这个稳定可靠安全的通信协议。Secure Shell(SSH) 是由 IETF(The Internet Engineering Task Force) 制定的建立在应用层基础上的安全网络通信,它是专为远程登录会话(甚至可以用Windows远程登录Linux服务器进行文件互传)和其他网络服务提供安全性的协议,可有效弥补网络中的漏洞。通过SSH,可以把所有传输的数据进行加密,也能够防止DNS欺骗和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
实现原理就是非对称加密RSA了。所以私钥千万不要随便给别人,公钥可以公开哦。
ssh登录是干嘛,因为linux这种服务器系统,或者换个名称,应该是批处理系统,因为它是有多个用户的,所以每次ssh登录其实就是开辟了一个tty终端,这个终端给到我这个用户而已。ssh就干了这件事。
登录方法1:
指令行咯,前提就是双方都要ssh这个功能,都得提前安装ssh服务器。而且都启动了才行
1 | //ssh 客户端用户名@服务器ip地址 |
这个最好固定ip比较好。
登录方法2:
公钥登录
本地生成ssh,然后把公钥发给远程主机,自己保留私钥,通过这个私钥来解密登录。
其实用过github就知道了,其实就是github里面的令牌登录和ssh公私钥匙而已。
远程主机控制
其实,看到上面这个发现了端倪,上面的其实是生成一个伪tty终端,一个终端是不能代表这个主机,现在网上有非常多维修电脑的工程师都是远程控制电脑的,对的,这就是区别,别人远程控制是整个电脑啊。
这里我就来给大家提供一个好东西,向日葵远程控制,这个确实不错的。如下图所示,这个远程协助的时候就是从机啦,下面那个设备列表就是主机,同一时刻只能有一个主机,它可以控制其他从机,注意设备从机密码。还可以通过识别码和验证码实现远程协助办公哦。
远程开机
这个就是是一个非常麻烦的东西了,现在的方案有很多。
有智能云开关
有智能云排插
有调用windows本身实现网络唤醒,也就是利用了wake-on-LAN技术
短接开关,实现远程控制关机
有些不愿意捣鼓,想快速实现就可以使用 “ToDesk”这个软件就是可以直接满足一键配置,一键开机的功能啦,和向日葵很相似,都是运维常用的工具。
想玩的,可以自己去尝试一下,确实挺不错的。
总结
这个就是为了方便自己搭建服务器,方便自己远程控制和出差在外,却需要一台电脑进行开发测试,都可以选择这个好方法,远程就让有了很多方法和手段,你也可以不用跑到别人公司去实地了解情况,说不定简单线上测试就能解决呢。