- 2025-04-06
-
发表了主题帖:
《机器人智造的逻辑》第1、2章读后感
机器人简史
本书首先讲了古今中外对“类智能体”的孜孜不倦的探索,古希腊工匠之神制造了机械巨人塔罗斯,中国偃师智造的能歌善舞的伶人,鲁班发明的能飞三天三夜的“木鹊”。然后又讲了哲学方面的研究;中世界达 芬奇对自动机器、机器人的设计探索。
现代机器人的诞生,“机器人”一词来自捷克作家的《罗素姆万能机器人》的剧本中。之后的艺术创作中,很多出现了机器人。通用汽车公司在1961年的新泽西工厂进行试验安装,将机器人用于流水线作业,这项发明彻底改变了现代工业。近些年来,斯坦福大学、索尼公司、本田公司、特斯拉都前赴后继的投入到机器人的研究中,AI的发展给机器人带来了新的活力。
解剖机器人
机器人可以按照不同的方式进行分类,一般分为工业、服务、特种机器人。还可按照控制方式、结构形态进行分类
机器人的基本构成中核心系统包括:感知系统、中枢系统、运动系统。感知系统包括各类的传感器、信号调理电路、模数转化器、处理器等硬件及相关的软件。中枢系统相当于大脑的控制系统。运动系统采用轮式、履带式、轨道式等方式进行移动。
机器人的核心技术主要包括:传感器技术、视觉、自然语言处理;运动与控制;人机交互;语言交互。
自然语言处理专注于研究、开发、理解、生成自然语言的技术和算法。主要目的是设计和构建系统,使能识别、理解、阐释、生成和使用人类语言。深度学习通过模拟人脑神经元的工作原理,构建多层次、非线性的复杂模型结构,使机器人能够从海量数据中提炼层次的特征标石,并以此为基础进行模式识别和分析预测。人机交互的最终目标是打造能理解并响应人类需求、适应人类习惯的智能机器人。
感想
读这2个章节,感觉机器人设计了太多的内容,太多的学科。特别是核心技术的章节,感受到了,这个行业、产业的巨大。其中传感觉技术是硬件、语言交互涉及到了软件和算法的部分,想要摸清脉络十分的不容易,作为个人只能从一个小的方向加以研究可能能取得一点进步,如果胡子眉毛一般抓,都是一只半解,是很难在这个圈子做好的。
-
发表了日志:
《机器人智造的逻辑》第1、2章读后感
- 2025-03-31
-
发表了主题帖:
《机器人智造的逻辑》开箱与全书略读
本帖最后由 水手勇敢 于 2025-3-30 18:24 编辑
收到书后,第一感觉就是书挺不多,很厚实,装订印刷的都很好。
本书的作者顾浩楠是机器人产业的全方位的专业人士。作者阅历非常丰富,先后在新华社、机器人公司及相关产业的技术公司,做过相关产业的人文和科技方面的研究,做过微信公众号。作者丰富的阅历可以从不同的角度审视机器人行业,“横看成岭侧成峰,远近高低各不同”。
名家点评中有许多产业大佬、公司创始人对本书的一个点评,表达了对作者的认可及本书的高度评价。读过书的点评之后,我对本书的内容更加期待。
本书共分为八个章节:第一章是机器人简史,主要介绍机器人的前世今生,人类在漫长历史长河中对机器人的探索、遐想。机器人对工业发展的意义,今后将重塑人类的就业结构。第二章是“解剖”机器人,首先对机器人按照不同的方式进行分类。然后讲了基本构成:感知系统、中枢系统和运动系统。最后讲了对应基本构成需要的核心技术。第三章是一台机器人的诞生,本章主要讲解将机器人制作出来的步骤,包括:创意与需求、想法的验证与市场调研、产品的规划、产品创造过程等等。第四章是机器人的产业逻辑,包括:机器人的产业链全景图及相关的研究机构与组织、相关竞赛等活动、我国机器人公司的现状。第四章是机器人的投资价值,本章从投资的角度讲解,包括长逻辑的价值判断,相关企业的商业模式分析,投资人的分析。第五章是来吧!投身于机器人行业,首先讲了机器人公司的职能划分、如何选择适合自己的岗位,然后是如何自我提升以及学习资源清单,最后写了职业发展的建议,技术和市场路线的提升路线。第七章是幻境之舞:AI与机器人,这章讲了AI与机器人的相互关系,重点讲了人形机器人。第八章是中国机器人出海的内核,本章讲了我国机器人的全球化之旅及颠覆性的新机遇。
通过对本书的初略翻看,感觉这本书将使我对机器人行业有一个全新的认识,会修正我以前的很多错误的观点,也给我的技术方面的学习给了方向上的指引。
- 2025-03-24
-
回复了主题帖:
【入围名单】《机器人智造的逻辑》
个人信息无误,可以按时完成分析。
- 2025-02-15
-
回复了主题帖:
撒积分啦!!机器人开发圈公众号上线、还有多个新板块设立哦~~
恭喜恭喜开发新板块。。。。。。。。。。。。。。。。。。。。。
- 2025-02-10
-
加入了学习《自己动手写嵌入式操作系统》,观看 程序执行顺序切换的原理
-
加入了学习《自己动手写嵌入式操作系统》,观看 stc单片机的内存结构
-
加入了学习《自己动手写嵌入式操作系统》,观看 任务调度器的实现
-
加入了学习《自己动手写嵌入式操作系统》,观看 自己动手写操作系统
-
加入了学习《自己动手写嵌入式操作系统》,观看 操作系统相关概念
- 2025-02-04
-
发表了主题帖:
《Linux内核深度解析》-文件系统简单介绍的学习
一、文件系统架构
1、Linux文件系统的架构如下图,分为用户空间、内核空间和硬件3个部分。
用户空间层面
应用程序使用glibc库封装的标准I/O流函数访问文件。分别使用fopen(打开)、fclose(关闭)、fread(关闭)、fwrite(写)、fseek(设置文件偏移)等。
硬件层面
外部存储设备分别为块设备、闪存、NVDIMM设备。
内核空间层面
由于内核支持多种文件系统类型,为了给用户提供统一的操作接口,内核实现一个抽象层,虚拟文件系统(VFS)。文件系统分为以下4种:
块设备文件系统,机械硬盘和固态硬盘等块设备。常用的是文件系统EXT和btrfs。
闪存文件系统,存储设备为NAND闪存和NOR闪存。常用的是JFFS2、UBIFS。
内存文件系统,常用的是tmpfs。
伪文件系统,是为了使用虚拟文件系统的编程接口。常用的是sockfs、proc、sysfs、hugetlbfs、cgroup等。
二、虚拟文件系统的数据结构
虚拟文件系统定义一套统一的数据结构。
超级块。文件系统的开始部分是超级块,描述文件系统的总体信息,挂载文件系统时,内存中创建结构体super_block。
VFS在内存中把目录组织为一棵树,进程根据树目录访问对应的文件系统。
根据文件系统的超级块格式,注册文件系统类型file_system_type.
索引节点。每个文件对应一个索引节点,每个索引节点有唯一编号。当内核访问存储设备上的文件时,会在内存中创建索引节点的结构体inode。
目录项。当内核访问存储设备上的一个目录项时,会在内存中创建该目录项的一个副本:结构体dentry。
当进程打开一个文件的时候,VFS就会创建文件的一个file结构体,然后为文件表中分配一个文件描述符,最后把文件描述符和file结构体的映射添加到打开文件表中。
-
发表了日志:
《Linux内核深度解析》-文件系统简单介绍的学习
- 2025-02-01
-
回复了主题帖:
《Linux内核深度解析》-进程状态学习
秦天qintian0303 发表于 2025-2-1 08:09
过年都不休息啊,大家都好好卷啊
早上起早写的,你看7点多就写完了。
-
发表了主题帖:
《Linux内核深度解析》-进程状态学习
进程是在 CPU 及内存中运行的程序代码,而每个进程可以创建一个或多个进程(父子进程)。Linux有以下几种进程状态,分别是:
(1)就绪:进程描述符state是TASK_RUNNING,正在运行队列中等待调度器调度。
(2)运行:进程描述符state是TASK_RUNNING,被调度器选中,正在处理器上运行。
(3)轻度睡眠:进程描述符state是TASK_INTERRUPTIBLE,可以被信号打断。
(4)中度睡眠:进程描述符state是TASK_KILLABLE,只能被致命的信号打断。
(5)深度睡眠:进程描述符的字段state是TASK_UNINTERRUPTIBLE,不能被信号打断。
(6)僵尸:进程描述符state是TASKDEAD,字段exit_state是EXIT_ZOMBIE。如果父进程关注子进程退出事件,那么子进程在退出时发送SIGCHLD信号通知父进程,变成僵尸进程,父进程在查询子进程的终止原因后回收子进程的进程描述符。
(7)死亡:进程描述符的字段state是TASK_DEAD,如果父进程不关注子进程退出事件,那么子进程退出时自动消亡。
如图所示:
客户端进程查看脚本为:
ps aux
下图为centos运行的进程查看图。
Linux对进程状态的代码如下:
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
- 2025-01-31
-
发表了主题帖:
《Linux内核深度解析》-系统调用学习
一、系统调用
系统调用是内核给用户程序提供的编程接口。用户程序可使用glibc库对单个系统提供的函数,或使用syscall ( ):。系统调用fork()为例:
SYSCALL_DEFINE0(fork) //展开后为 asmlinkage long sys_fork(void)
{
#ifdef CONFIG_MMU
return _do_fork(SIGCHLD,0,0,NULL,NULL,0)
#else
Return -EINVAL;
#endif
}
需要在系统调用表中保存系统调用号和处理函数的映射关系,sys_call_table如下:
/source/arch/x86/kernel/syscall_64.c
asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] =
{
/*
* Smells like a compiler bug -- it doesn't work
* when the & below is removed.*/
[0 ... __NR_syscall_max] = &sys_ni_syscall,
#include <asm/syscalls_64.h>
};
二、执行系统调用
系统调用划分到同步异常,在异常级别1的异常向量表中,64位调用入口为el0_sync函数。
el0_sync:
kernel_entry 0
mrs x25, esr_el1 // 读异常情况寄存器
lsr x24, x25, #ESR_ELx_EC_SHIFT // 判断异常类别
cmp x24, #ESR_ELx_EC_SVC64 // 64-bit 系统调用
b.eq el0_svc //跳转到el0_svc
...
el0_svc负责执行系统调用,如果上层调用open系统调用打开文件时,就会从从sys_call_table,根据系统调用号,找到对应的sys_call_table元素,也即sys_open;并执行。代码如下:
sc_nr .reg x25 //系统调用数量
scno .req x26 //系统调用号
stbl .req x27 //系统调用表地址
Tsk .req x28 //当前进程的thread_info结构体的地址
el0_svc:
adrp stbl, sys_call_table // load syscall table pointer
uxtw scno, w8 // syscall number in w8
mov sc_nr, #__NR_syscalls //把寄存器x25设置为系统调用数量
el0_svc_naked: // compat entry point
stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number
enable_dbg //开启调试
enable_irq //开启中断
get_thread_info tsk
ldr x16, [tsk, #TI_FLAGS] // check for syscall tracing
tbnz x16, #TIF_SYSCALL_TRACE, __sys_trace // are we tracing syscalls?
adr lr, ret_fast_syscall // return address,用于返回用户空间
cmp scno, sc_nr // check upper syscall limit
b.hs ni_sys //如果超过系统调用限制,跳转到ni_sys 处理
ldr x16, [stbl, scno, lsl #3] // address in the syscall table
br x16 // call sys_* routine
ni_sys: //超过调用数量限制的处理
mov x0, sp
b do_ni_syscall
ENDPROC(el0_svc)
ret_fast_syscall从系统调用返回用户空间,代码如下
/*
* This is the fast syscall return path. We do as little as possible here,
* and this includes saving x0 back into the kernel stack.
*/
ret_fast_syscall:
disable_irq // disable interrupts
str x0, [sp, #S_X0] // returned x0
ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
and x2, x1, #_TIF_SYSCALL_WORK
cbnz x2, ret_fast_syscall_trace
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
enable_step_tsk x1, x2
kernel_exit 0
ret_fast_syscall_trace:
enable_irq // enable interrupts
b __sys_trace_return_skipped // we already saved x0
/*
* Ok, we need to do extra processing, enter the slow path.
*/
work_pending:
mov x0, sp // 'regs'
bl do_notify_resume
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_on // enabled while in userspace
#endif
ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for single-step
b finish_ret_to_user
/*
* "slow" syscall return path.
*/
ret_to_user:
disable_irq // disable interrupts
ldr x1, [tsk, #TSK_TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
finish_ret_to_user:
enable_step_tsk x1, x2
kernel_exit 0
ENDPROC(ret_to_user)
work_pending调用do_notify_resume函数,代码如下:
asmlinkage void do_notify_resume(struct pt_regs *regs,
unsigned int thread_flags)
{
/*
* The assembly code enters us with IRQs off, but it hasn't
* informed the tracing code of that for efficiency reasons.
* Update the trace code with the current status.
*/
trace_hardirqs_off();
do {
if (thread_flags & _TIF_NEED_RESCHED) {
schedule();
} else {
local_irq_enable();
if (thread_flags & _TIF_UPROBE)
uprobe_notify_resume(regs);
if (thread_flags & _TIF_SIGPENDING)
do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
}
if (thread_flags & _TIF_FOREIGN_FPSTATE)
fpsimd_restore_current_state();
}
local_irq_disable();
thread_flags = READ_ONCE(current_thread_info()->flags);
} while (thread_flags & _TIF_WORK_MASK);
}
-
发表了日志:
《Linux内核深度解析》-系统调用学习
- 2025-01-17
-
回复了主题帖:
《Linux内核深度解析》-异常处理
oxlm_1 发表于 2025-1-17 09:23
一个模块一个模块地啃还是可以搞懂,只是linux内核太大了,内容太多了,没书完全不知道从哪开始啃
操作系统要坚持看,睡觉前比起床前进步一点点,极少成多,慢慢就有感觉了。这种知识不是一会半会的功夫。
- 2025-01-16
-
回复了主题帖:
《Linux内核深度解析》-异常处理
T_T1111 发表于 2025-1-16 20:29
表示没有看懂,看着不像ARM或者X86
我写的不全,另外Linux内核确实比较难。
- 2025-01-14
-
回复了主题帖:
《Linux内核深度解析》-异常处理
风尘流沙 发表于 2025-1-14 14:35
已下载学习了,谢谢楼主的介绍。
共同进步
-
发表了主题帖:
《Linux内核深度解析》-异常处理
《Linux内核深度解析》-异常处理
一、异常级别
二、异常分类
异常分为同步异常和异步异常。如下图所示
三、异常处理
以出现用户模式(异常级别0)下访问数据时生成的页错误异常为例。
el0_sync:
kernel_entry 0
mrs x25, esr_el1 // read the syndrome register
lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class
cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state
b.eq el0_svc
cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0
b.eq el0_da //调用el0_da
cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0
b.eq el0_ia
cmp x24, #ESR_EL1_EC_FP_ASIMD // FP/ASIMD access
b.eq el0_fpsimd_acc
cmp x24, #ESR_EL1_EC_FP_EXC64 // FP/ASIMD exception
b.eq el0_fpsimd_exc
cmp x24, #ESR_EL1_EC_SYS64 // configurable trap
b.eq el0_undef
cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception
b.eq el0_sp_pc
cmp x24, #ESR_EL1_EC_PC_ALIGN // pc alignment exception
b.eq el0_sp_pc
cmp x24, #ESR_EL1_EC_UNKNOWN // unknown exception in EL0
b.eq el0_undef
cmp x24, #ESR_EL1_EC_BREAKPT_EL0 // debug exception in EL0
b.ge el0_dbg
b el0_inv
对于用户模式(异常级别0)下生成的同步异常,入口是el0_sync。该入口函数在arch/arm64/kernel/entry.s中
通过上面代码,跳到对应的异常处理函数,
其中:访问数据时生成的页错误异常,通过( b.eq el0_da //调用el0_da )这行代码,进入 el0_da 函数。
下面为 el0_da 函数代码
el0_da:
/*
* Data abort handling
*/
mrs x26, far_el1 //获取数据的虚拟地址
// enable interrupts before calling the main handler
enable_dbg_and_irq //开启调试异常和中断
ct_user_exit
bic x0, x26, #(0xff << 56)
mov x1, x25
mov x2, sp
bl do_mem_abort //调用do_mem_abort函数
b ret_to_user
通过do_mem_abort( ) 函数将异常信息进行处理。